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