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): |