3 # Copyright 2014 The Rust Project Developers. See the COPYRIGHT
4 # file at the top-level directory of this distribution and at
5 # http://rust-lang.org/COPYRIGHT.
7 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10 # option. This file may not be copied, modified, or distributed
11 # except according to those terms.
19 if len(sys.argv) <= 1:
20 print('Usage: %s [ --apply ] filename1.rs filename2.rs ...'
22 elif sys.argv[1] == '--apply':
23 for filename in sys.argv[2:]:
26 for filename in sys.argv[1:]:
31 source = read(filename)
32 rewritten = rewrite_bytes_macros(source)
33 if rewritten is not None and rewritten != source:
34 write(filename, rewritten)
38 rewritten = rewrite_bytes_macros(read(filename))
39 if rewritten is not None:
40 p = subprocess.Popen(['diff', '-u', filename, '-'],
41 stdin=subprocess.PIPE)
42 p.stdin.write(rewritten)
48 with open(filename, 'rb') as f:
52 def write(filename, content):
53 with open(filename, 'wb') as f:
57 def rewrite_bytes_macros(source):
58 rewritten, num_occurrences = BYTES_MACRO_RE.subn(rewrite_one_macro, source)
59 if num_occurrences > 0:
63 BYTES_MACRO_RE = re.compile(br'bytes!\( (?P<args> [^)]* ) \)', re.VERBOSE)
66 def rewrite_one_macro(match):
68 bytes = parse_bytes(split_args(match.group('args')))
69 return b'b"' + b''.join(map(escape, bytes)) + b'"'
70 except SkipThisRewrite:
71 print('Skipped: %s' % match.group(0).decode('utf8', 'replace'))
75 class SkipThisRewrite(Exception):
81 for arg in args.split(b','):
83 arg = previous + b',' + arg
84 if arg.count(b'"') % 2 == 0:
93 def parse_bytes(args):
96 if (arg.startswith(b'"') and arg.endswith(b'"')) or (
97 arg.startswith(b"'") and arg.endswith(b"'")):
98 # Escaped newline means something different in Rust and Python.
100 raise SkipThisRewrite
101 for byte in eval(b'u' + arg).encode('utf8'):
104 if arg.endswith(b'u8'):
106 # Assume that all Rust integer literals
107 # are valid Python integer literals
108 value = int(eval(arg))
123 if escaped is not None:
125 elif b' ' <= c <= b'~':
128 return ('\\x%02X' % byte).encode('ascii')
134 chr = lambda x: bytes([x])
137 if __name__ == '__main__':