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