Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revsetlang.py @ 35596:a57acea31b3b
revsetlang: unnest inner functions from formatspec()
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 02 Jan 2018 21:05:40 +0900 |
parents | 91201737d07a |
children | ed0902e8053e |
comparison
equal
deleted
inserted
replaced
35595:91201737d07a | 35596:a57acea31b3b |
---|---|
553 >>> _quote(1) | 553 >>> _quote(1) |
554 "'1'" | 554 "'1'" |
555 """ | 555 """ |
556 return "'%s'" % util.escapestr(pycompat.bytestr(s)) | 556 return "'%s'" % util.escapestr(pycompat.bytestr(s)) |
557 | 557 |
558 def _formatargtype(c, arg): | |
559 if c == 'd': | |
560 return '%d' % int(arg) | |
561 elif c == 's': | |
562 return _quote(arg) | |
563 elif c == 'r': | |
564 parse(arg) # make sure syntax errors are confined | |
565 return '(%s)' % arg | |
566 elif c == 'n': | |
567 return _quote(node.hex(arg)) | |
568 elif c == 'b': | |
569 try: | |
570 return _quote(arg.branch()) | |
571 except AttributeError: | |
572 raise TypeError | |
573 raise error.ParseError(_('unexpected revspec format character %s') % c) | |
574 | |
575 def _formatlistexp(s, t): | |
576 l = len(s) | |
577 if l == 0: | |
578 return "_list('')" | |
579 elif l == 1: | |
580 return _formatargtype(t, s[0]) | |
581 elif t == 'd': | |
582 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s) | |
583 elif t == 's': | |
584 return "_list(%s)" % _quote("\0".join(s)) | |
585 elif t == 'n': | |
586 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s) | |
587 elif t == 'b': | |
588 try: | |
589 return "_list('%s')" % "\0".join(a.branch() for a in s) | |
590 except AttributeError: | |
591 raise TypeError | |
592 | |
593 m = l // 2 | |
594 return '(%s or %s)' % (_formatlistexp(s[:m], t), _formatlistexp(s[m:], t)) | |
595 | |
558 def formatspec(expr, *args): | 596 def formatspec(expr, *args): |
559 ''' | 597 ''' |
560 This is a convenience function for using revsets internally, and | 598 This is a convenience function for using revsets internally, and |
561 escapes arguments appropriately. Aliases are intentionally ignored | 599 escapes arguments appropriately. Aliases are intentionally ignored |
562 so that intended expression behavior isn't accidentally subverted. | 600 so that intended expression behavior isn't accidentally subverted. |
587 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd']) | 625 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd']) |
588 "root(_list('a\\\\x00b\\\\x00c\\\\x00d'))" | 626 "root(_list('a\\\\x00b\\\\x00c\\\\x00d'))" |
589 >>> formatspec('%ls', ['a', "'"]) | 627 >>> formatspec('%ls', ['a', "'"]) |
590 "_list('a\\\\x00\\\\'')" | 628 "_list('a\\\\x00\\\\'')" |
591 ''' | 629 ''' |
592 | |
593 def argtype(c, arg): | |
594 if c == 'd': | |
595 return '%d' % int(arg) | |
596 elif c == 's': | |
597 return _quote(arg) | |
598 elif c == 'r': | |
599 parse(arg) # make sure syntax errors are confined | |
600 return '(%s)' % arg | |
601 elif c == 'n': | |
602 return _quote(node.hex(arg)) | |
603 elif c == 'b': | |
604 try: | |
605 return _quote(arg.branch()) | |
606 except AttributeError: | |
607 raise TypeError | |
608 raise error.ParseError(_('unexpected revspec format character %s') % c) | |
609 | |
610 def listexp(s, t): | |
611 l = len(s) | |
612 if l == 0: | |
613 return "_list('')" | |
614 elif l == 1: | |
615 return argtype(t, s[0]) | |
616 elif t == 'd': | |
617 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s) | |
618 elif t == 's': | |
619 return "_list(%s)" % _quote("\0".join(s)) | |
620 elif t == 'n': | |
621 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s) | |
622 elif t == 'b': | |
623 try: | |
624 return "_list('%s')" % "\0".join(a.branch() for a in s) | |
625 except AttributeError: | |
626 raise TypeError | |
627 | |
628 m = l // 2 | |
629 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) | |
630 | |
631 expr = pycompat.bytestr(expr) | 630 expr = pycompat.bytestr(expr) |
632 argiter = iter(args) | 631 argiter = iter(args) |
633 ret = [] | 632 ret = [] |
634 pos = 0 | 633 pos = 0 |
635 while pos < len(expr): | 634 while pos < len(expr): |
658 try: | 657 try: |
659 d = expr[pos] | 658 d = expr[pos] |
660 except IndexError: | 659 except IndexError: |
661 raise error.ParseError(_('incomplete revspec format character')) | 660 raise error.ParseError(_('incomplete revspec format character')) |
662 try: | 661 try: |
663 ret.append(listexp(list(arg), d)) | 662 ret.append(_formatlistexp(list(arg), d)) |
664 except (TypeError, ValueError): | 663 except (TypeError, ValueError): |
665 raise error.ParseError(_('invalid argument for revspec')) | 664 raise error.ParseError(_('invalid argument for revspec')) |
666 else: | 665 else: |
667 try: | 666 try: |
668 ret.append(argtype(d, arg)) | 667 ret.append(_formatargtype(d, arg)) |
669 except (TypeError, ValueError): | 668 except (TypeError, ValueError): |
670 raise error.ParseError(_('invalid argument for revspec')) | 669 raise error.ParseError(_('invalid argument for revspec')) |
671 pos += 1 | 670 pos += 1 |
672 | 671 |
673 try: | 672 try: |