##// END OF EJS Templates
revset: introduce "_parsealiasdecl" to parse alias declarations strictly...
FUJIWARA Katsunori -
r23845:0a7fd54d default
parent child Browse files
Show More
@@ -267,6 +267,40 b' def getargs(x, min, max, err):'
267 raise error.ParseError(err)
267 raise error.ParseError(err)
268 return l
268 return l
269
269
270 def isvalidsymbol(tree):
271 """Examine whether specified ``tree`` is valid ``symbol`` or not
272 """
273 return tree[0] == 'symbol' and len(tree) > 1
274
275 def getsymbol(tree):
276 """Get symbol name from valid ``symbol`` in ``tree``
277
278 This assumes that ``tree`` is already examined by ``isvalidsymbol``.
279 """
280 return tree[1]
281
282 def isvalidfunc(tree):
283 """Examine whether specified ``tree`` is valid ``func`` or not
284 """
285 return tree[0] == 'func' and len(tree) > 1 and isvalidsymbol(tree[1])
286
287 def getfuncname(tree):
288 """Get function name from valid ``func`` in ``tree``
289
290 This assumes that ``tree`` is already examined by ``isvalidfunc``.
291 """
292 return getsymbol(tree[1])
293
294 def getfuncargs(tree):
295 """Get list of function arguments from valid ``func`` in ``tree``
296
297 This assumes that ``tree`` is already examined by ``isvalidfunc``.
298 """
299 if len(tree) > 2:
300 return getlist(tree[2])
301 else:
302 return []
303
270 def getset(repo, subset, x):
304 def getset(repo, subset, x):
271 if not x:
305 if not x:
272 raise error.ParseError(_("missing argument"))
306 raise error.ParseError(_("missing argument"))
@@ -2118,6 +2152,87 b' def _checkaliasarg(tree, known=None):'
2118 for t in tree:
2152 for t in tree:
2119 _checkaliasarg(t, known)
2153 _checkaliasarg(t, known)
2120
2154
2155 # the set of valid characters for the initial letter of symbols in
2156 # alias declarations and definitions
2157 _aliassyminitletters = set(c for c in [chr(i) for i in xrange(256)]
2158 if c.isalnum() or c in '._@$' or ord(c) > 127)
2159
2160 def _tokenizealias(program, lookup=None):
2161 """Parse alias declaration/definition into a stream of tokens
2162
2163 This allows symbol names to use also ``$`` as an initial letter
2164 (for backward compatibility), and callers of this function should
2165 examine whether ``$`` is used also for unexpected symbols or not.
2166 """
2167 return tokenize(program, lookup=lookup,
2168 syminitletters=_aliassyminitletters)
2169
2170 def _parsealiasdecl(decl):
2171 """Parse alias declaration ``decl``
2172
2173 This returns ``(name, tree, args, errorstr)`` tuple:
2174
2175 - ``name``: of declared alias (may be ``decl`` itself at error)
2176 - ``tree``: parse result (or ``None`` at error)
2177 - ``args``: list of alias argument names (or None for symbol declaration)
2178 - ``errorstr``: detail about detected error (or None)
2179
2180 >>> _parsealiasdecl('foo')
2181 ('foo', ('symbol', 'foo'), None, None)
2182 >>> _parsealiasdecl('$foo')
2183 ('$foo', None, None, "'$' not for alias arguments")
2184 >>> _parsealiasdecl('foo::bar')
2185 ('foo::bar', None, None, 'invalid format')
2186 >>> _parsealiasdecl('foo bar')
2187 ('foo bar', None, None, 'at 4: invalid token')
2188 >>> _parsealiasdecl('foo()')
2189 ('foo', ('func', ('symbol', 'foo')), [], None)
2190 >>> _parsealiasdecl('$foo()')
2191 ('$foo()', None, None, "'$' not for alias arguments")
2192 >>> _parsealiasdecl('foo($1, $2)')
2193 ('foo', ('func', ('symbol', 'foo')), ['$1', '$2'], None)
2194 >>> _parsealiasdecl('foo(bar_bar, baz.baz)')
2195 ('foo', ('func', ('symbol', 'foo')), ['bar_bar', 'baz.baz'], None)
2196 >>> _parsealiasdecl('foo($1, $2, nested($1, $2))')
2197 ('foo($1, $2, nested($1, $2))', None, None, 'invalid argument list')
2198 >>> _parsealiasdecl('foo(bar($1, $2))')
2199 ('foo(bar($1, $2))', None, None, 'invalid argument list')
2200 >>> _parsealiasdecl('foo("string")')
2201 ('foo("string")', None, None, 'invalid argument list')
2202 >>> _parsealiasdecl('foo($1, $2')
2203 ('foo($1, $2', None, None, 'at 10: unexpected token: end')
2204 >>> _parsealiasdecl('foo("string')
2205 ('foo("string', None, None, 'at 5: unterminated string')
2206 """
2207 p = parser.parser(_tokenizealias, elements)
2208 try:
2209 tree, pos = p.parse(decl)
2210 if (pos != len(decl)):
2211 raise error.ParseError(_('invalid token'), pos)
2212
2213 if isvalidsymbol(tree):
2214 # "name = ...." style
2215 name = getsymbol(tree)
2216 if name.startswith('$'):
2217 return (decl, None, None, _("'$' not for alias arguments"))
2218 return (name, ('symbol', name), None, None)
2219
2220 if isvalidfunc(tree):
2221 # "name(arg, ....) = ...." style
2222 name = getfuncname(tree)
2223 if name.startswith('$'):
2224 return (decl, None, None, _("'$' not for alias arguments"))
2225 args = []
2226 for arg in getfuncargs(tree):
2227 if not isvalidsymbol(arg):
2228 return (decl, None, None, _("invalid argument list"))
2229 args.append(getsymbol(arg))
2230 return (name, ('func', ('symbol', name)), args, None)
2231
2232 return (decl, None, None, _("invalid format"))
2233 except error.ParseError, inst:
2234 return (decl, None, None, parseerrordetail(inst))
2235
2121 class revsetalias(object):
2236 class revsetalias(object):
2122 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
2237 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
2123 args = None
2238 args = None
General Comments 0
You need to be logged in to leave comments. Login now