76 |
76 |
77 By default, character ``c`` is recognized as valid for non-initial |
77 By default, character ``c`` is recognized as valid for non-initial |
78 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``. |
78 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``. |
79 |
79 |
80 Check that @ is a valid unquoted token character (issue3686): |
80 Check that @ is a valid unquoted token character (issue3686): |
81 >>> list(tokenize("@::")) |
81 >>> list(tokenize(b"@::")) |
82 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)] |
82 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)] |
83 |
83 |
84 ''' |
84 ''' |
85 program = pycompat.bytestr(program) |
85 program = pycompat.bytestr(program) |
86 if syminitletters is None: |
86 if syminitletters is None: |
250 return tree |
250 return tree |
251 |
251 |
252 def _build(tmplspec, *repls): |
252 def _build(tmplspec, *repls): |
253 """Create raw parsed tree from a template revset statement |
253 """Create raw parsed tree from a template revset statement |
254 |
254 |
255 >>> _build('f(_) and _', ('string', '1'), ('symbol', '2')) |
255 >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2')) |
256 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2')) |
256 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2')) |
257 """ |
257 """ |
258 template = _cachedtree(tmplspec) |
258 template = _cachedtree(tmplspec) |
259 return parser.buildtree(template, ('symbol', '_'), *repls) |
259 return parser.buildtree(template, ('symbol', '_'), *repls) |
260 |
260 |
261 def _match(patspec, tree): |
261 def _match(patspec, tree): |
262 """Test if a tree matches the given pattern statement; return the matches |
262 """Test if a tree matches the given pattern statement; return the matches |
263 |
263 |
264 >>> _match('f(_)', parse('f()')) |
264 >>> _match(b'f(_)', parse(b'f()')) |
265 >>> _match('f(_)', parse('f(1)')) |
265 >>> _match(b'f(_)', parse(b'f(1)')) |
266 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')] |
266 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')] |
267 >>> _match('f(_)', parse('f(1, 2)')) |
267 >>> _match(b'f(_)', parse(b'f(1, 2)')) |
268 """ |
268 """ |
269 pattern = _cachedtree(patspec) |
269 pattern = _cachedtree(patspec) |
270 return parser.matchtree(pattern, tree, ('symbol', '_'), |
270 return parser.matchtree(pattern, tree, ('symbol', '_'), |
271 {'keyvalue', 'list'}) |
271 {'keyvalue', 'list'}) |
272 |
272 |
476 _aliassyminitletters = _syminitletters | {'$'} |
476 _aliassyminitletters = _syminitletters | {'$'} |
477 |
477 |
478 def _parsewith(spec, lookup=None, syminitletters=None): |
478 def _parsewith(spec, lookup=None, syminitletters=None): |
479 """Generate a parse tree of given spec with given tokenizing options |
479 """Generate a parse tree of given spec with given tokenizing options |
480 |
480 |
481 >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters) |
481 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters) |
482 ('func', ('symbol', 'foo'), ('symbol', '$1')) |
482 ('func', ('symbol', 'foo'), ('symbol', '$1')) |
483 >>> _parsewith('$1') |
483 >>> _parsewith(b'$1') |
484 Traceback (most recent call last): |
484 Traceback (most recent call last): |
485 ... |
485 ... |
486 ParseError: ("syntax error in revset '$1'", 0) |
486 ParseError: ("syntax error in revset '$1'", 0) |
487 >>> _parsewith('foo bar') |
487 >>> _parsewith(b'foo bar') |
488 Traceback (most recent call last): |
488 Traceback (most recent call last): |
489 ... |
489 ... |
490 ParseError: ('invalid token', 4) |
490 ParseError: ('invalid token', 4) |
491 """ |
491 """ |
492 p = parser.parser(elements) |
492 p = parser.parser(elements) |
580 %n = hex(arg), single-quoted |
580 %n = hex(arg), single-quoted |
581 %% = a literal '%' |
581 %% = a literal '%' |
582 |
582 |
583 Prefixing the type with 'l' specifies a parenthesized list of that type. |
583 Prefixing the type with 'l' specifies a parenthesized list of that type. |
584 |
584 |
585 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()")) |
585 >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()")) |
586 '(10 or 11):: and ((this()) or (that()))' |
586 '(10 or 11):: and ((this()) or (that()))' |
587 >>> formatspec('%d:: and not %d::', 10, 20) |
587 >>> formatspec(b'%d:: and not %d::', 10, 20) |
588 '10:: and not 20::' |
588 '10:: and not 20::' |
589 >>> formatspec('%ld or %ld', [], [1]) |
589 >>> formatspec(b'%ld or %ld', [], [1]) |
590 "_list('') or 1" |
590 "_list('') or 1" |
591 >>> formatspec('keyword(%s)', 'foo\\xe9') |
591 >>> formatspec(b'keyword(%s)', b'foo\\xe9') |
592 "keyword('foo\\\\xe9')" |
592 "keyword('foo\\\\xe9')" |
593 >>> b = lambda: 'default' |
593 >>> b = lambda: b'default' |
594 >>> b.branch = b |
594 >>> b.branch = b |
595 >>> formatspec('branch(%b)', b) |
595 >>> formatspec(b'branch(%b)', b) |
596 "branch('default')" |
596 "branch('default')" |
597 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd']) |
597 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd']) |
598 "root(_list('a\\x00b\\x00c\\x00d'))" |
598 "root(_list('a\\x00b\\x00c\\x00d'))" |
599 ''' |
599 ''' |
600 |
600 |
601 def argtype(c, arg): |
601 def argtype(c, arg): |
602 if c == 'd': |
602 if c == 'd': |