Mercurial > public > mercurial-scm > hg
comparison mercurial/revset.py @ 14723:b9faf94ee196 stable
revset: fix aliases with 0 or more than 2 parameters
The existing code seemed to have incorrect assumptions about how parameter
lists are represented by the parser.
Now the match and replace functions have been merged and simplified by using
getlist().
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Wed, 22 Jun 2011 01:55:00 +0200 |
parents | c8ee2729e89f |
children | 805651777188 |
comparison
equal
deleted
inserted
replaced
14722:b6dc362b051c | 14723:b9faf94ee196 |
---|---|
952 return w + wa, (op, x[1], ta) | 952 return w + wa, (op, x[1], ta) |
953 return 1, x | 953 return 1, x |
954 | 954 |
955 class revsetalias(object): | 955 class revsetalias(object): |
956 funcre = re.compile('^([^(]+)\(([^)]+)\)$') | 956 funcre = re.compile('^([^(]+)\(([^)]+)\)$') |
957 args = () | 957 args = None |
958 | 958 |
959 def __init__(self, token, value): | 959 def __init__(self, name, value): |
960 '''Aliases like: | 960 '''Aliases like: |
961 | 961 |
962 h = heads(default) | 962 h = heads(default) |
963 b($1) = ancestors($1) - ancestors(default) | 963 b($1) = ancestors($1) - ancestors(default) |
964 ''' | 964 ''' |
965 if isinstance(token, tuple): | 965 if isinstance(name, tuple): # parameter substitution |
966 self.type, self.name = token | 966 self.tree = name |
967 else: | 967 self.replacement = value |
968 m = self.funcre.search(token) | 968 else: # alias definition |
969 m = self.funcre.search(name) | |
969 if m: | 970 if m: |
970 self.type = 'func' | 971 self.tree = ('func', ('symbol', m.group(1))) |
971 self.name = m.group(1) | |
972 self.args = [x.strip() for x in m.group(2).split(',')] | 972 self.args = [x.strip() for x in m.group(2).split(',')] |
973 for arg in self.args: | |
974 value = value.replace(arg, repr(arg)) | |
973 else: | 975 else: |
974 self.type = 'symbol' | 976 self.tree = ('symbol', name) |
975 self.name = token | 977 |
976 | |
977 if isinstance(value, str): | |
978 for arg in self.args: | |
979 value = value.replace(arg, repr(arg)) | |
980 self.replacement, pos = parse(value) | 978 self.replacement, pos = parse(value) |
981 if pos != len(value): | 979 if pos != len(value): |
982 raise error.ParseError(_('invalid token'), pos) | 980 raise error.ParseError(_('invalid token'), pos) |
983 else: | |
984 self.replacement = value | |
985 | |
986 def match(self, tree): | |
987 if not tree: | |
988 return False | |
989 if tree == (self.type, self.name): | |
990 return True | |
991 if tree[0] != self.type: | |
992 return False | |
993 if len(tree) > 1 and tree[1] != ('symbol', self.name): | |
994 return False | |
995 # 'func' + funcname + args | |
996 if ((self.args and len(tree) != 3) or | |
997 (len(self.args) == 1 and tree[2][0] == 'list') or | |
998 (len(self.args) > 1 and (tree[2][0] != 'list' or | |
999 len(tree[2]) - 1 != len(self.args)))): | |
1000 raise error.ParseError(_('invalid amount of arguments'), | |
1001 len(tree) - 2) | |
1002 return True | |
1003 | |
1004 def replace(self, tree): | |
1005 if tree == (self.type, self.name): | |
1006 return self.replacement | |
1007 result = self.replacement | |
1008 def getsubtree(i): | |
1009 if tree[2][0] == 'list': | |
1010 return tree[2][i + 1] | |
1011 return tree[i + 2] | |
1012 for i, v in enumerate(self.args): | |
1013 valalias = revsetalias(('string', v), getsubtree(i)) | |
1014 result = valalias.process(result) | |
1015 return result | |
1016 | 981 |
1017 def process(self, tree): | 982 def process(self, tree): |
1018 if self.match(tree): | |
1019 return self.replace(tree) | |
1020 if isinstance(tree, tuple): | 983 if isinstance(tree, tuple): |
984 if self.args is None: | |
985 if tree == self.tree: | |
986 return self.replacement | |
987 elif tree[:2] == self.tree: | |
988 l = getlist(tree[2]) | |
989 if len(l) != len(self.args): | |
990 raise error.ParseError( | |
991 _('invalid number of arguments: %s') % len(l)) | |
992 result = self.replacement | |
993 for a, v in zip(self.args, l): | |
994 valalias = revsetalias(('string', a), v) | |
995 result = valalias.process(result) | |
996 return result | |
1021 return tuple(map(self.process, tree)) | 997 return tuple(map(self.process, tree)) |
1022 return tree | 998 return tree |
1023 | 999 |
1024 def findaliases(ui, tree): | 1000 def findaliases(ui, tree): |
1025 for k, v in ui.configitems('revsetalias'): | 1001 for k, v in ui.configitems('revsetalias'): |