861 """``user(string)`` |
861 """``user(string)`` |
862 User name contains string. The match is case-insensitive. |
862 User name contains string. The match is case-insensitive. |
863 """ |
863 """ |
864 return author(repo, subset, x) |
864 return author(repo, subset, x) |
865 |
865 |
|
866 # for internal use |
|
867 def _list(repo, subset, x): |
|
868 s = getstring(x, "internal error") |
|
869 if not s: |
|
870 return [] |
|
871 if not isinstance(subset, set): |
|
872 subset = set(subset) |
|
873 ls = [repo[r].rev() for r in s.split('\0')] |
|
874 return [r for r in ls if r in subset] |
|
875 |
866 symbols = { |
876 symbols = { |
867 "adds": adds, |
877 "adds": adds, |
868 "all": getall, |
878 "all": getall, |
869 "ancestor": ancestor, |
879 "ancestor": ancestor, |
870 "ancestors": ancestors, |
880 "ancestors": ancestors, |
1093 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()")) |
1104 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()")) |
1094 '(10 or 11):: and ((this()) or (that()))' |
1105 '(10 or 11):: and ((this()) or (that()))' |
1095 >>> formatspec('%d:: and not %d::', 10, 20) |
1106 >>> formatspec('%d:: and not %d::', 10, 20) |
1096 '10:: and not 20::' |
1107 '10:: and not 20::' |
1097 >>> formatspec('%ld or %ld', [], [1]) |
1108 >>> formatspec('%ld or %ld', [], [1]) |
1098 '(0-0) or 1' |
1109 "_list('') or 1" |
1099 >>> formatspec('keyword(%s)', 'foo\\xe9') |
1110 >>> formatspec('keyword(%s)', 'foo\\xe9') |
1100 "keyword('foo\\\\xe9')" |
1111 "keyword('foo\\\\xe9')" |
1101 >>> b = lambda: 'default' |
1112 >>> b = lambda: 'default' |
1102 >>> b.branch = b |
1113 >>> b.branch = b |
1103 >>> formatspec('branch(%b)', b) |
1114 >>> formatspec('branch(%b)', b) |
1104 "branch('default')" |
1115 "branch('default')" |
1105 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd']) |
1116 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd']) |
1106 "root((('a' or 'b') or ('c' or 'd')))" |
1117 "root(_list('a\\x00b\\x00c\\x00d'))" |
1107 ''' |
1118 ''' |
1108 |
1119 |
1109 def quote(s): |
1120 def quote(s): |
1110 return repr(str(s)) |
1121 return repr(str(s)) |
1111 |
1122 |
1121 return quote(nodemod.hex(arg)) |
1132 return quote(nodemod.hex(arg)) |
1122 elif c == 'b': |
1133 elif c == 'b': |
1123 return quote(arg.branch()) |
1134 return quote(arg.branch()) |
1124 |
1135 |
1125 def listexp(s, t): |
1136 def listexp(s, t): |
1126 "balance a list s of type t to limit parse tree depth" |
|
1127 l = len(s) |
1137 l = len(s) |
1128 if l == 0: |
1138 if l == 0: |
1129 return '(0-0)' # a minimal way to represent an empty set |
1139 return "_list('')" |
1130 if l == 1: |
1140 elif l == 1: |
1131 return argtype(t, s[0]) |
1141 return argtype(t, s[0]) |
|
1142 elif t == 'd': |
|
1143 return "_list('%s')" % "\0".join(str(int(a)) for a in s) |
|
1144 elif t == 's': |
|
1145 return "_list('%s')" % "\0".join(s) |
|
1146 elif t == 'n': |
|
1147 return "_list('%s')" % "\0".join(nodemod.hex(a) for a in s) |
|
1148 elif t == 'b': |
|
1149 return "_list('%s')" % "\0".join(a.branch() for a in s) |
|
1150 |
1132 m = l // 2 |
1151 m = l // 2 |
1133 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) |
1152 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) |
1134 |
1153 |
1135 ret = '' |
1154 ret = '' |
1136 pos = 0 |
1155 pos = 0 |