comparison mercurial/ui.py @ 31481:a7c687c35119

ui: move configlist parser to config.py The list parser is complex and reusable without ui. Let's move it to config.py. This allows us to parse a list from a "pure" config object without going through ui. Like, we can make "_trustusers" calculated from raw configs, instead of making sure it's synchronized by calling "fixconfig"s.
author Jun Wu <quark@fb.com>
date Fri, 17 Mar 2017 09:19:56 -0700
parents 96929bd6e58d
children 8122cc5cb543
comparison
equal deleted inserted replaced
31480:07fe520280d2 31481:a7c687c35119
560 >>> u = ui(); s = 'foo' 560 >>> u = ui(); s = 'foo'
561 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test') 561 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
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)
647 573
648 def has_section(self, section, untrusted=False): 574 def has_section(self, section, untrusted=False):