##// END OF EJS Templates
config.sortdict: override clear method...
Sune Foldager -
r14696:5fb3cb72 stable
parent child Browse files
Show More
@@ -1,146 +1,149
1 # config.py - configuration parsing for Mercurial
1 # config.py - configuration parsing for Mercurial
2 #
2 #
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import error, util
9 import error, util
10 import re, os, errno
10 import re, os, errno
11
11
12 class sortdict(dict):
12 class sortdict(dict):
13 'a simple sorted dictionary'
13 'a simple sorted dictionary'
14 def __init__(self, data=None):
14 def __init__(self, data=None):
15 self._list = []
15 self._list = []
16 if data:
16 if data:
17 self.update(data)
17 self.update(data)
18 def copy(self):
18 def copy(self):
19 return sortdict(self)
19 return sortdict(self)
20 def __setitem__(self, key, val):
20 def __setitem__(self, key, val):
21 if key in self:
21 if key in self:
22 self._list.remove(key)
22 self._list.remove(key)
23 self._list.append(key)
23 self._list.append(key)
24 dict.__setitem__(self, key, val)
24 dict.__setitem__(self, key, val)
25 def __iter__(self):
25 def __iter__(self):
26 return self._list.__iter__()
26 return self._list.__iter__()
27 def update(self, src):
27 def update(self, src):
28 for k in src:
28 for k in src:
29 self[k] = src[k]
29 self[k] = src[k]
30 def clear(self):
31 dict.clear(self)
32 self._list = []
30 def items(self):
33 def items(self):
31 return [(k, self[k]) for k in self._list]
34 return [(k, self[k]) for k in self._list]
32 def __delitem__(self, key):
35 def __delitem__(self, key):
33 dict.__delitem__(self, key)
36 dict.__delitem__(self, key)
34 self._list.remove(key)
37 self._list.remove(key)
35
38
36 class config(object):
39 class config(object):
37 def __init__(self, data=None):
40 def __init__(self, data=None):
38 self._data = {}
41 self._data = {}
39 self._source = {}
42 self._source = {}
40 if data:
43 if data:
41 for k in data._data:
44 for k in data._data:
42 self._data[k] = data[k].copy()
45 self._data[k] = data[k].copy()
43 self._source = data._source.copy()
46 self._source = data._source.copy()
44 def copy(self):
47 def copy(self):
45 return config(self)
48 return config(self)
46 def __contains__(self, section):
49 def __contains__(self, section):
47 return section in self._data
50 return section in self._data
48 def __getitem__(self, section):
51 def __getitem__(self, section):
49 return self._data.get(section, {})
52 return self._data.get(section, {})
50 def __iter__(self):
53 def __iter__(self):
51 for d in self.sections():
54 for d in self.sections():
52 yield d
55 yield d
53 def update(self, src):
56 def update(self, src):
54 for s in src:
57 for s in src:
55 if s not in self:
58 if s not in self:
56 self._data[s] = sortdict()
59 self._data[s] = sortdict()
57 self._data[s].update(src._data[s])
60 self._data[s].update(src._data[s])
58 self._source.update(src._source)
61 self._source.update(src._source)
59 def get(self, section, item, default=None):
62 def get(self, section, item, default=None):
60 return self._data.get(section, {}).get(item, default)
63 return self._data.get(section, {}).get(item, default)
61 def source(self, section, item):
64 def source(self, section, item):
62 return self._source.get((section, item), "")
65 return self._source.get((section, item), "")
63 def sections(self):
66 def sections(self):
64 return sorted(self._data.keys())
67 return sorted(self._data.keys())
65 def items(self, section):
68 def items(self, section):
66 return self._data.get(section, {}).items()
69 return self._data.get(section, {}).items()
67 def set(self, section, item, value, source=""):
70 def set(self, section, item, value, source=""):
68 if section not in self:
71 if section not in self:
69 self._data[section] = sortdict()
72 self._data[section] = sortdict()
70 self._data[section][item] = value
73 self._data[section][item] = value
71 self._source[(section, item)] = source
74 self._source[(section, item)] = source
72
75
73 def parse(self, src, data, sections=None, remap=None, include=None):
76 def parse(self, src, data, sections=None, remap=None, include=None):
74 sectionre = re.compile(r'\[([^\[]+)\]')
77 sectionre = re.compile(r'\[([^\[]+)\]')
75 itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
78 itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
76 contre = re.compile(r'\s+(\S|\S.*\S)\s*$')
79 contre = re.compile(r'\s+(\S|\S.*\S)\s*$')
77 emptyre = re.compile(r'(;|#|\s*$)')
80 emptyre = re.compile(r'(;|#|\s*$)')
78 commentre = re.compile(r'(;|#)')
81 commentre = re.compile(r'(;|#)')
79 unsetre = re.compile(r'%unset\s+(\S+)')
82 unsetre = re.compile(r'%unset\s+(\S+)')
80 includere = re.compile(r'%include\s+(\S|\S.*\S)\s*$')
83 includere = re.compile(r'%include\s+(\S|\S.*\S)\s*$')
81 section = ""
84 section = ""
82 item = None
85 item = None
83 line = 0
86 line = 0
84 cont = False
87 cont = False
85
88
86 for l in data.splitlines(True):
89 for l in data.splitlines(True):
87 line += 1
90 line += 1
88 if cont:
91 if cont:
89 if commentre.match(l):
92 if commentre.match(l):
90 continue
93 continue
91 m = contre.match(l)
94 m = contre.match(l)
92 if m:
95 if m:
93 if sections and section not in sections:
96 if sections and section not in sections:
94 continue
97 continue
95 v = self.get(section, item) + "\n" + m.group(1)
98 v = self.get(section, item) + "\n" + m.group(1)
96 self.set(section, item, v, "%s:%d" % (src, line))
99 self.set(section, item, v, "%s:%d" % (src, line))
97 continue
100 continue
98 item = None
101 item = None
99 cont = False
102 cont = False
100 m = includere.match(l)
103 m = includere.match(l)
101 if m:
104 if m:
102 inc = util.expandpath(m.group(1))
105 inc = util.expandpath(m.group(1))
103 base = os.path.dirname(src)
106 base = os.path.dirname(src)
104 inc = os.path.normpath(os.path.join(base, inc))
107 inc = os.path.normpath(os.path.join(base, inc))
105 if include:
108 if include:
106 try:
109 try:
107 include(inc, remap=remap, sections=sections)
110 include(inc, remap=remap, sections=sections)
108 except IOError, inst:
111 except IOError, inst:
109 if inst.errno != errno.ENOENT:
112 if inst.errno != errno.ENOENT:
110 raise error.ParseError(_("cannot include %s (%s)")
113 raise error.ParseError(_("cannot include %s (%s)")
111 % (inc, inst.strerror),
114 % (inc, inst.strerror),
112 "%s:%s" % (src, line))
115 "%s:%s" % (src, line))
113 continue
116 continue
114 if emptyre.match(l):
117 if emptyre.match(l):
115 continue
118 continue
116 m = sectionre.match(l)
119 m = sectionre.match(l)
117 if m:
120 if m:
118 section = m.group(1)
121 section = m.group(1)
119 if remap:
122 if remap:
120 section = remap.get(section, section)
123 section = remap.get(section, section)
121 if section not in self:
124 if section not in self:
122 self._data[section] = sortdict()
125 self._data[section] = sortdict()
123 continue
126 continue
124 m = itemre.match(l)
127 m = itemre.match(l)
125 if m:
128 if m:
126 item = m.group(1)
129 item = m.group(1)
127 cont = True
130 cont = True
128 if sections and section not in sections:
131 if sections and section not in sections:
129 continue
132 continue
130 self.set(section, item, m.group(2), "%s:%d" % (src, line))
133 self.set(section, item, m.group(2), "%s:%d" % (src, line))
131 continue
134 continue
132 m = unsetre.match(l)
135 m = unsetre.match(l)
133 if m:
136 if m:
134 name = m.group(1)
137 name = m.group(1)
135 if sections and section not in sections:
138 if sections and section not in sections:
136 continue
139 continue
137 if self.get(section, name) is not None:
140 if self.get(section, name) is not None:
138 del self._data[section][name]
141 del self._data[section][name]
139 continue
142 continue
140
143
141 raise error.ParseError(l.rstrip(), ("%s:%s" % (src, line)))
144 raise error.ParseError(l.rstrip(), ("%s:%s" % (src, line)))
142
145
143 def read(self, path, fp=None, sections=None, remap=None):
146 def read(self, path, fp=None, sections=None, remap=None):
144 if not fp:
147 if not fp:
145 fp = util.posixfile(path)
148 fp = util.posixfile(path)
146 self.parse(path, fp.read(), sections, remap, self.read)
149 self.parse(path, fp.read(), sections, remap, self.read)
General Comments 0
You need to be logged in to leave comments. Login now