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