##// END OF EJS Templates
ui: move configlist parser to config.py...
Jun Wu -
r31481:a7c687c3 default
parent child Browse files
Show More
@@ -179,3 +179,86 class config(object):
179 fp, fp.mode))
179 fp, fp.mode))
180 self.parse(path, fp.read(),
180 self.parse(path, fp.read(),
181 sections=sections, remap=remap, include=self.read)
181 sections=sections, remap=remap, include=self.read)
182
183 def parselist(value):
184 """parse a configuration value as a list of comma/space separated strings
185
186 >>> parselist('this,is "a small" ,test')
187 ['this', 'is', 'a small', 'test']
188 """
189
190 def _parse_plain(parts, s, offset):
191 whitespace = False
192 while offset < len(s) and (s[offset:offset + 1].isspace()
193 or s[offset:offset + 1] == ','):
194 whitespace = True
195 offset += 1
196 if offset >= len(s):
197 return None, parts, offset
198 if whitespace:
199 parts.append('')
200 if s[offset:offset + 1] == '"' and not parts[-1]:
201 return _parse_quote, parts, offset + 1
202 elif s[offset:offset + 1] == '"' and parts[-1][-1] == '\\':
203 parts[-1] = parts[-1][:-1] + s[offset:offset + 1]
204 return _parse_plain, parts, offset + 1
205 parts[-1] += s[offset:offset + 1]
206 return _parse_plain, parts, offset + 1
207
208 def _parse_quote(parts, s, offset):
209 if offset < len(s) and s[offset:offset + 1] == '"': # ""
210 parts.append('')
211 offset += 1
212 while offset < len(s) and (s[offset:offset + 1].isspace() or
213 s[offset:offset + 1] == ','):
214 offset += 1
215 return _parse_plain, parts, offset
216
217 while offset < len(s) and s[offset:offset + 1] != '"':
218 if (s[offset:offset + 1] == '\\' and offset + 1 < len(s)
219 and s[offset + 1:offset + 2] == '"'):
220 offset += 1
221 parts[-1] += '"'
222 else:
223 parts[-1] += s[offset:offset + 1]
224 offset += 1
225
226 if offset >= len(s):
227 real_parts = _configlist(parts[-1])
228 if not real_parts:
229 parts[-1] = '"'
230 else:
231 real_parts[0] = '"' + real_parts[0]
232 parts = parts[:-1]
233 parts.extend(real_parts)
234 return None, parts, offset
235
236 offset += 1
237 while offset < len(s) and s[offset:offset + 1] in [' ', ',']:
238 offset += 1
239
240 if offset < len(s):
241 if offset + 1 == len(s) and s[offset:offset + 1] == '"':
242 parts[-1] += '"'
243 offset += 1
244 else:
245 parts.append('')
246 else:
247 return None, parts, offset
248
249 return _parse_plain, parts, offset
250
251 def _configlist(s):
252 s = s.rstrip(' ,')
253 if not s:
254 return []
255 parser, parts, offset = _parse_plain, [''], 0
256 while parser:
257 parser, parts, offset = parser(parts, s, offset)
258 return parts
259
260 if value is not None and isinstance(value, bytes):
261 result = _configlist(value.lstrip(' ,\n'))
262 else:
263 result = value
264 return result or []
@@ -562,85 +562,11 class ui(object):
562 >>> u.configlist(s, 'list1')
562 >>> u.configlist(s, 'list1')
563 ['this', 'is', 'a small', 'test']
563 ['this', 'is', 'a small', 'test']
564 """
564 """
565
565 # default is not always a list
566 def _parse_plain(parts, s, offset):
566 if isinstance(default, bytes):
567 whitespace = False
567 default = config.parselist(default)
568 while offset < len(s) and (s[offset:offset + 1].isspace()
568 return self.configwith(config.parselist, section, name, default or [],
569 or s[offset:offset + 1] == ','):
569 'list', untrusted)
570 whitespace = True
571 offset += 1
572 if offset >= len(s):
573 return None, parts, offset
574 if whitespace:
575 parts.append('')
576 if s[offset:offset + 1] == '"' and not parts[-1]:
577 return _parse_quote, parts, offset + 1
578 elif s[offset:offset + 1] == '"' and parts[-1][-1] == '\\':
579 parts[-1] = parts[-1][:-1] + s[offset:offset + 1]
580 return _parse_plain, parts, offset + 1
581 parts[-1] += s[offset:offset + 1]
582 return _parse_plain, parts, offset + 1
583
584 def _parse_quote(parts, s, offset):
585 if offset < len(s) and s[offset:offset + 1] == '"': # ""
586 parts.append('')
587 offset += 1
588 while offset < len(s) and (s[offset:offset + 1].isspace() or
589 s[offset:offset + 1] == ','):
590 offset += 1
591 return _parse_plain, parts, offset
592
593 while offset < len(s) and s[offset:offset + 1] != '"':
594 if (s[offset:offset + 1] == '\\' and offset + 1 < len(s)
595 and s[offset + 1:offset + 2] == '"'):
596 offset += 1
597 parts[-1] += '"'
598 else:
599 parts[-1] += s[offset:offset + 1]
600 offset += 1
601
602 if offset >= len(s):
603 real_parts = _configlist(parts[-1])
604 if not real_parts:
605 parts[-1] = '"'
606 else:
607 real_parts[0] = '"' + real_parts[0]
608 parts = parts[:-1]
609 parts.extend(real_parts)
610 return None, parts, offset
611
612 offset += 1
613 while offset < len(s) and s[offset:offset + 1] in [' ', ',']:
614 offset += 1
615
616 if offset < len(s):
617 if offset + 1 == len(s) and s[offset:offset + 1] == '"':
618 parts[-1] += '"'
619 offset += 1
620 else:
621 parts.append('')
622 else:
623 return None, parts, offset
624
625 return _parse_plain, parts, offset
626
627 def _configlist(s):
628 s = s.rstrip(' ,')
629 if not s:
630 return []
631 parser, parts, offset = _parse_plain, [''], 0
632 while parser:
633 parser, parts, offset = parser(parts, s, offset)
634 return parts
635
636 result = self.config(section, name, untrusted=untrusted)
637 if result is None:
638 result = default or []
639 if isinstance(result, bytes):
640 result = _configlist(result.lstrip(' ,\n'))
641 if result is None:
642 result = default or []
643 return result
644
570
645 def hasconfig(self, section, name, untrusted=False):
571 def hasconfig(self, section, name, untrusted=False):
646 return self._data(untrusted).hasitem(section, name)
572 return self._data(untrusted).hasitem(section, name)
@@ -23,6 +23,7 def testmod(name, optionflags=0, testtar
23
23
24 testmod('mercurial.changegroup')
24 testmod('mercurial.changegroup')
25 testmod('mercurial.changelog')
25 testmod('mercurial.changelog')
26 testmod('mercurial.config')
26 testmod('mercurial.dagparser', optionflags=doctest.NORMALIZE_WHITESPACE)
27 testmod('mercurial.dagparser', optionflags=doctest.NORMALIZE_WHITESPACE)
27 testmod('mercurial.dispatch')
28 testmod('mercurial.dispatch')
28 testmod('mercurial.encoding')
29 testmod('mercurial.encoding')
General Comments 0
You need to be logged in to leave comments. Login now