author | Matt Mackall <mpm@selenic.com> |
Sun, 26 Apr 2009 16:50:43 -0500 | |
changeset 8184 | 9189afe1eba3 |
parent 8183 | 2858ab754995 |
child 8185 | dc10a7a3f1d4 |
permissions | -rw-r--r-- |
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 = {} |
|
33 |
if data: |
|
34 |
for k in data._data: |
|
35 |
self._data[k] = data[k].copy() |
|
36 |
def copy(self): |
|
37 |
return config(self) |
|
38 |
def __contains__(self, section): |
|
39 |
return section in self._data |
|
40 |
def update(self, src, sections=None): |
|
41 |
if not sections: |
|
42 |
sections = src.sections() |
|
43 |
for s in sections: |
|
44 |
if s not in src: |
|
45 |
continue |
|
46 |
if s not in self: |
|
47 |
self._data[s] = sortdict() |
|
48 |
for k in src._data[s]: |
|
49 |
self._data[s][k] = src._data[s][k] |
|
50 |
def get(self, section, item, default=None): |
|
51 |
return self._data.get(section, {}).get(item, (default, ""))[0] |
|
52 |
def getsource(self, section, item): |
|
53 |
return self._data.get(section, {}).get(item, (None, ""))[1] |
|
54 |
def sections(self): |
|
55 |
return sorted(self._data.keys()) |
|
56 |
def items(self, section): |
|
57 |
return [(k, v[0]) for k,v in self._data.get(section, {}).items()] |
|
58 |
def set(self, section, item, value, source=""): |
|
59 |
if section not in self: |
|
60 |
self._data[section] = sortdict() |
|
61 |
self._data[section][item] = (value, source) |
|
62 |
||
8180 | 63 |
def read(self, path, fp=None): |
8144 | 64 |
sectionre = re.compile(r'\[([^\[]+)\]') |
65 |
itemre = re.compile(r'([^=\s]+)\s*=\s*(.*)') |
|
66 |
contre = re.compile(r'\s+(\S.*)') |
|
67 |
emptyre = re.compile(r'(;|#|\s*$)') |
|
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
68 |
unsetre = re.compile(r'%unset\s+(\S.*)') |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
69 |
includere = re.compile(r'%include\s+(\S.*)') |
8144 | 70 |
section = "" |
71 |
item = None |
|
72 |
line = 0 |
|
73 |
cont = 0 |
|
8180 | 74 |
|
75 |
if not fp: |
|
76 |
fp = open(path) |
|
77 |
||
8144 | 78 |
for l in fp: |
79 |
line += 1 |
|
80 |
if cont: |
|
81 |
m = contre.match(l) |
|
82 |
if m: |
|
83 |
v = self.get(section, item) + "\n" + m.group(1) |
|
84 |
self.set(section, item, v, "%s:%d" % (path, line)) |
|
85 |
continue |
|
86 |
item = None |
|
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
87 |
m = includere.match(l) |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
88 |
if m: |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
89 |
inc = m.group(1) |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
90 |
base = os.path.dirname(path) |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
91 |
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
|
92 |
incfp = open(inc) |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
93 |
self.read(inc, incfp) |
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
94 |
continue |
8144 | 95 |
if emptyre.match(l): |
96 |
continue |
|
97 |
m = sectionre.match(l) |
|
98 |
if m: |
|
99 |
section = m.group(1) |
|
100 |
if section not in self: |
|
101 |
self._data[section] = sortdict() |
|
102 |
continue |
|
103 |
m = itemre.match(l) |
|
104 |
if m: |
|
105 |
item = m.group(1) |
|
106 |
self.set(section, item, m.group(2), "%s:%d" % (path, line)) |
|
107 |
cont = 1 |
|
108 |
continue |
|
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
109 |
m = unsetre.match(l) |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
110 |
if m: |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
111 |
name = m.group(1) |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
112 |
if self.get(section, name) != None: |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
113 |
del self._data[section][name] |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
114 |
continue |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
115 |
|
8144 | 116 |
raise error.ConfigError(_('config error at %s:%d: \'%s\'') |
117 |
% (path, line, l.rstrip())) |