]> git.proxmox.com Git - rustc.git/blame - src/etc/2014-06-rewrite-bytes-macros.py
Imported Upstream version 1.1.0+dfsg1
[rustc.git] / src / etc / 2014-06-rewrite-bytes-macros.py
CommitLineData
1a4d82fc
JJ
1#!/usr/bin/env python
2#
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.
6#
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.
12
13import sys
14import subprocess
15import re
16
17
18def main():
19 if len(sys.argv) <= 1:
20 print('Usage: %s [ --apply ] filename1.rs filename2.rs ...'
21 % sys.argv[0])
22 elif sys.argv[1] == '--apply':
23 for filename in sys.argv[2:]:
24 patch(filename)
25 else:
26 for filename in sys.argv[1:]:
27 diff(filename)
28
29
30def patch(filename):
31 source = read(filename)
32 rewritten = rewrite_bytes_macros(source)
33 if rewritten is not None and rewritten != source:
34 write(filename, rewritten)
35
36
37def diff(filename):
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)
43 p.stdin.close()
44 p.wait()
45
46
47def read(filename):
48 with open(filename, 'rb') as f:
49 return f.read()
50
51
52def write(filename, content):
53 with open(filename, 'wb') as f:
54 f.write(content)
55
56
57def rewrite_bytes_macros(source):
58 rewritten, num_occurrences = BYTES_MACRO_RE.subn(rewrite_one_macro, source)
59 if num_occurrences > 0:
60 return rewritten
61
62
63BYTES_MACRO_RE = re.compile(br'bytes!\( (?P<args> [^)]* ) \)', re.VERBOSE)
64
65
66def rewrite_one_macro(match):
67 try:
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'))
72 return match.group(0)
73
74
75class SkipThisRewrite(Exception):
76 pass
77
78
79def split_args(args):
80 previous = b''
81 for arg in args.split(b','):
82 if previous:
83 arg = previous + b',' + arg
84 if arg.count(b'"') % 2 == 0:
85 yield arg
86 previous = b''
87 else:
88 previous = arg
89 if previous:
90 yield previous
91
92
93def parse_bytes(args):
94 for arg in args:
95 arg = arg.strip()
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.
99 if b'\\\n' in arg:
100 raise SkipThisRewrite
101 for byte in eval(b'u' + arg).encode('utf8'):
102 yield ord(byte)
103 else:
104 if arg.endswith(b'u8'):
105 arg = arg[:-2]
106 # Assume that all Rust integer literals
107 # are valid Python integer literals
108 value = int(eval(arg))
109 assert value <= 0xFF
110 yield value
111
112
113def escape(byte):
114 c = chr(byte)
115 escaped = {
116 b'\0': br'\0',
117 b'\t': br'\t',
118 b'\n': br'\n',
119 b'\r': br'\r',
120 b'\'': b'\\\'',
121 b'\\': br'\\',
122 }.get(c)
123 if escaped is not None:
124 return escaped
125 elif b' ' <= c <= b'~':
126 return chr(byte)
127 else:
128 return ('\\x%02X' % byte).encode('ascii')
129
130
131if str is not bytes:
132 # Python 3.x
133 ord = lambda x: x
134 chr = lambda x: bytes([x])
135
136
137if __name__ == '__main__':
138 main()