##// END OF EJS Templates
config: split source data out into separate map
Matt Mackall -
r8185:dc10a7a3 default
parent child Browse files
Show More
@@ -1,117 +1,121
1 1 from i18n import _
2 2 import re, error, os
3 3
4 4 class sortdict(dict):
5 5 'a simple sorted dictionary'
6 6 def __init__(self, data=None):
7 7 self._list = []
8 8 if data:
9 9 if hasattr(data, '_list'):
10 10 self._list = list(data._list)
11 11 self.update(data)
12 12 def copy(self):
13 13 return sortdict(self)
14 14 def __setitem__(self, key, val):
15 15 if key in self:
16 16 self._list.remove(key)
17 17 self._list.append(key)
18 18 dict.__setitem__(self, key, val)
19 19 def __iter__(self):
20 20 return self._list.__iter__()
21 21 def update(self, src):
22 22 for k in src:
23 23 self[k] = src[k]
24 24 def items(self):
25 25 return [(k,self[k]) for k in self._list]
26 26 def __delitem__(self, key):
27 27 dict.__delitem__(self, key)
28 28 self._list.remove(key)
29 29
30 30 class config:
31 31 def __init__(self, data=None):
32 32 self._data = {}
33 self._source = {}
33 34 if data:
34 35 for k in data._data:
35 36 self._data[k] = data[k].copy()
37 self._source = data._source.copy()
36 38 def copy(self):
37 39 return config(self)
38 40 def __contains__(self, section):
39 41 return section in self._data
40 42 def update(self, src, sections=None):
41 43 if not sections:
42 44 sections = src.sections()
43 45 for s in sections:
44 46 if s not in src:
45 47 continue
46 48 if s not in self:
47 49 self._data[s] = sortdict()
48 50 for k in src._data[s]:
49 51 self._data[s][k] = src._data[s][k]
52 self._source[(s, k)] = src._source[(s, k)]
50 53 def get(self, section, item, default=None):
51 return self._data.get(section, {}).get(item, (default, ""))[0]
54 return self._data.get(section, {}).get(item, default)
52 55 def getsource(self, section, item):
53 return self._data.get(section, {}).get(item, (None, ""))[1]
56 return self._source.get((section, item), "")
54 57 def sections(self):
55 58 return sorted(self._data.keys())
56 59 def items(self, section):
57 return [(k, v[0]) for k,v in self._data.get(section, {}).items()]
60 return self._data.get(section, {}).items()
58 61 def set(self, section, item, value, source=""):
59 62 if section not in self:
60 63 self._data[section] = sortdict()
61 self._data[section][item] = (value, source)
64 self._data[section][item] = value
65 self._source[(section, item)] = source
62 66
63 67 def read(self, path, fp=None):
64 68 sectionre = re.compile(r'\[([^\[]+)\]')
65 69 itemre = re.compile(r'([^=\s]+)\s*=\s*(.*)')
66 70 contre = re.compile(r'\s+(\S.*)')
67 71 emptyre = re.compile(r'(;|#|\s*$)')
68 72 unsetre = re.compile(r'%unset\s+(\S.*)')
69 73 includere = re.compile(r'%include\s+(\S.*)')
70 74 section = ""
71 75 item = None
72 76 line = 0
73 77 cont = 0
74 78
75 79 if not fp:
76 80 fp = open(path)
77 81
78 82 for l in fp:
79 83 line += 1
80 84 if cont:
81 85 m = contre.match(l)
82 86 if m:
83 87 v = self.get(section, item) + "\n" + m.group(1)
84 88 self.set(section, item, v, "%s:%d" % (path, line))
85 89 continue
86 90 item = None
87 91 m = includere.match(l)
88 92 if m:
89 93 inc = m.group(1)
90 94 base = os.path.dirname(path)
91 95 inc = os.path.normpath(os.path.join(base, inc))
92 96 incfp = open(inc)
93 97 self.read(inc, incfp)
94 98 continue
95 99 if emptyre.match(l):
96 100 continue
97 101 m = sectionre.match(l)
98 102 if m:
99 103 section = m.group(1)
100 104 if section not in self:
101 105 self._data[section] = sortdict()
102 106 continue
103 107 m = itemre.match(l)
104 108 if m:
105 109 item = m.group(1)
106 110 self.set(section, item, m.group(2), "%s:%d" % (path, line))
107 111 cont = 1
108 112 continue
109 113 m = unsetre.match(l)
110 114 if m:
111 115 name = m.group(1)
112 116 if self.get(section, name) != None:
113 117 del self._data[section][name]
114 118 continue
115 119
116 120 raise error.ConfigError(_('config error at %s:%d: \'%s\'')
117 121 % (path, line, l.rstrip()))
General Comments 0
You need to be logged in to leave comments. Login now