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