comparison mercurial/revset.py @ 15595:a585d78e7b2f stable

revset: balance %l or-expressions (issue3129)
author Matt Mackall <mpm@selenic.com>
date Wed, 30 Nov 2011 22:43:24 -0600
parents 5edaf47cd462
children 2555f441a32f
comparison
equal deleted inserted replaced
15593:f9c6a575baa4 15595:a585d78e7b2f
1071 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()")) 1071 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
1072 '(10 or 11):: and ((this()) or (that()))' 1072 '(10 or 11):: and ((this()) or (that()))'
1073 >>> formatspec('%d:: and not %d::', 10, 20) 1073 >>> formatspec('%d:: and not %d::', 10, 20)
1074 '10:: and not 20::' 1074 '10:: and not 20::'
1075 >>> formatspec('%ld or %ld', [], [1]) 1075 >>> formatspec('%ld or %ld', [], [1])
1076 '(0-0) or (1)' 1076 '(0-0) or 1'
1077 >>> formatspec('keyword(%s)', 'foo\\xe9') 1077 >>> formatspec('keyword(%s)', 'foo\\xe9')
1078 "keyword('foo\\\\xe9')" 1078 "keyword('foo\\\\xe9')"
1079 >>> b = lambda: 'default' 1079 >>> b = lambda: 'default'
1080 >>> b.branch = b 1080 >>> b.branch = b
1081 >>> formatspec('branch(%b)', b) 1081 >>> formatspec('branch(%b)', b)
1082 "branch('default')" 1082 "branch('default')"
1083 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd']) 1083 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
1084 "root(('a' or 'b' or 'c' or 'd'))" 1084 "root((('a' or 'b') or ('c' or 'd')))"
1085 ''' 1085 '''
1086 1086
1087 def quote(s): 1087 def quote(s):
1088 return repr(str(s)) 1088 return repr(str(s))
1089 1089
1097 return '(%s)' % arg 1097 return '(%s)' % arg
1098 elif c == 'n': 1098 elif c == 'n':
1099 return quote(nodemod.hex(arg)) 1099 return quote(nodemod.hex(arg))
1100 elif c == 'b': 1100 elif c == 'b':
1101 return quote(arg.branch()) 1101 return quote(arg.branch())
1102
1103 def listexp(s, t):
1104 "balance a list s of type t to limit parse tree depth"
1105 l = len(s)
1106 if l == 0:
1107 return '(0-0)' # a minimal way to represent an empty set
1108 if l == 1:
1109 return argtype(t, s[0])
1110 m = l / 2
1111 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
1102 1112
1103 ret = '' 1113 ret = ''
1104 pos = 0 1114 pos = 0
1105 arg = 0 1115 arg = 0
1106 while pos < len(expr): 1116 while pos < len(expr):
1115 arg += 1 1125 arg += 1
1116 elif d == 'l': 1126 elif d == 'l':
1117 # a list of some type 1127 # a list of some type
1118 pos += 1 1128 pos += 1
1119 d = expr[pos] 1129 d = expr[pos]
1120 if args[arg]: 1130 ret += listexp(args[arg], d)
1121 lv = ' or '.join(argtype(d, e) for e in args[arg])
1122 else:
1123 lv = '0-0' # a minimal way to represent an empty set
1124 ret += '(%s)' % lv
1125 arg += 1 1131 arg += 1
1126 else: 1132 else:
1127 raise util.Abort('unexpected revspec format character %s' % d) 1133 raise util.Abort('unexpected revspec format character %s' % d)
1128 else: 1134 else:
1129 ret += c 1135 ret += c