xref: /aosp_15_r20/external/angle/build/toolchain/win/rc/rc.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2017 The Chromium Authors
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker
6*8975f5c5SAndroid Build Coastguard Worker"""usage: rc.py [options] input.res
7*8975f5c5SAndroid Build Coastguard WorkerA resource compiler for .rc files.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Workeroptions:
10*8975f5c5SAndroid Build Coastguard Worker-h, --help     Print this message.
11*8975f5c5SAndroid Build Coastguard Worker-I<dir>        Add include path, used for both headers and resources.
12*8975f5c5SAndroid Build Coastguard Worker-imsvc<dir>    Add system include path, used for preprocessing only.
13*8975f5c5SAndroid Build Coastguard Worker/winsysroot<d> Set winsysroot, used for preprocessing only.
14*8975f5c5SAndroid Build Coastguard Worker-D<sym>        Define a macro for the preprocessor.
15*8975f5c5SAndroid Build Coastguard Worker/fo<out>       Set path of output .res file.
16*8975f5c5SAndroid Build Coastguard Worker/nologo        Ignored (rc.py doesn't print a logo by default).
17*8975f5c5SAndroid Build Coastguard Worker/showIncludes  Print referenced header and resource files."""
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Workerfrom collections import namedtuple
20*8975f5c5SAndroid Build Coastguard Workerimport codecs
21*8975f5c5SAndroid Build Coastguard Workerimport os
22*8975f5c5SAndroid Build Coastguard Workerimport re
23*8975f5c5SAndroid Build Coastguard Workerimport subprocess
24*8975f5c5SAndroid Build Coastguard Workerimport sys
25*8975f5c5SAndroid Build Coastguard Workerimport tempfile
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker
28*8975f5c5SAndroid Build Coastguard WorkerTHIS_DIR = os.path.abspath(os.path.dirname(__file__))
29*8975f5c5SAndroid Build Coastguard WorkerSRC_DIR = \
30*8975f5c5SAndroid Build Coastguard Worker    os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(THIS_DIR))))
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Workerdef ParseFlags():
34*8975f5c5SAndroid Build Coastguard Worker  """Parses flags off sys.argv and returns the parsed flags."""
35*8975f5c5SAndroid Build Coastguard Worker  # Can't use optparse / argparse because of /fo flag :-/
36*8975f5c5SAndroid Build Coastguard Worker  includes = []
37*8975f5c5SAndroid Build Coastguard Worker  imsvcs = []
38*8975f5c5SAndroid Build Coastguard Worker  winsysroot = []
39*8975f5c5SAndroid Build Coastguard Worker  defines = []
40*8975f5c5SAndroid Build Coastguard Worker  output = None
41*8975f5c5SAndroid Build Coastguard Worker  input = None
42*8975f5c5SAndroid Build Coastguard Worker  show_includes = False
43*8975f5c5SAndroid Build Coastguard Worker  # Parse.
44*8975f5c5SAndroid Build Coastguard Worker  for flag in sys.argv[1:]:
45*8975f5c5SAndroid Build Coastguard Worker    if flag == '-h' or flag == '--help':
46*8975f5c5SAndroid Build Coastguard Worker      print(__doc__)
47*8975f5c5SAndroid Build Coastguard Worker      sys.exit(0)
48*8975f5c5SAndroid Build Coastguard Worker    if flag.startswith('-I'):
49*8975f5c5SAndroid Build Coastguard Worker      includes.append(flag)
50*8975f5c5SAndroid Build Coastguard Worker    elif flag.startswith('-imsvc'):
51*8975f5c5SAndroid Build Coastguard Worker      imsvcs.append(flag)
52*8975f5c5SAndroid Build Coastguard Worker    elif flag.startswith('/winsysroot'):
53*8975f5c5SAndroid Build Coastguard Worker      winsysroot = [flag]
54*8975f5c5SAndroid Build Coastguard Worker    elif flag.startswith('-D'):
55*8975f5c5SAndroid Build Coastguard Worker      defines.append(flag)
56*8975f5c5SAndroid Build Coastguard Worker    elif flag.startswith('/fo'):
57*8975f5c5SAndroid Build Coastguard Worker      if output:
58*8975f5c5SAndroid Build Coastguard Worker        print('rc.py: error: multiple /fo flags', '/fo' + output, flag,
59*8975f5c5SAndroid Build Coastguard Worker              file=sys.stderr)
60*8975f5c5SAndroid Build Coastguard Worker        sys.exit(1)
61*8975f5c5SAndroid Build Coastguard Worker      output = flag[3:]
62*8975f5c5SAndroid Build Coastguard Worker    elif flag == '/nologo':
63*8975f5c5SAndroid Build Coastguard Worker      pass
64*8975f5c5SAndroid Build Coastguard Worker    elif flag == '/showIncludes':
65*8975f5c5SAndroid Build Coastguard Worker      show_includes = True
66*8975f5c5SAndroid Build Coastguard Worker    elif (flag.startswith('-') or
67*8975f5c5SAndroid Build Coastguard Worker          (flag.startswith('/') and not os.path.exists(flag))):
68*8975f5c5SAndroid Build Coastguard Worker      print('rc.py: error: unknown flag', flag, file=sys.stderr)
69*8975f5c5SAndroid Build Coastguard Worker      print(__doc__, file=sys.stderr)
70*8975f5c5SAndroid Build Coastguard Worker      sys.exit(1)
71*8975f5c5SAndroid Build Coastguard Worker    else:
72*8975f5c5SAndroid Build Coastguard Worker      if input:
73*8975f5c5SAndroid Build Coastguard Worker        print('rc.py: error: multiple inputs:', input, flag, file=sys.stderr)
74*8975f5c5SAndroid Build Coastguard Worker        sys.exit(1)
75*8975f5c5SAndroid Build Coastguard Worker      input = flag
76*8975f5c5SAndroid Build Coastguard Worker  # Validate and set default values.
77*8975f5c5SAndroid Build Coastguard Worker  if not input:
78*8975f5c5SAndroid Build Coastguard Worker    print('rc.py: error: no input file', file=sys.stderr)
79*8975f5c5SAndroid Build Coastguard Worker    sys.exit(1)
80*8975f5c5SAndroid Build Coastguard Worker  if not output:
81*8975f5c5SAndroid Build Coastguard Worker    output = os.path.splitext(input)[0] + '.res'
82*8975f5c5SAndroid Build Coastguard Worker  Flags = namedtuple('Flags', [
83*8975f5c5SAndroid Build Coastguard Worker      'includes', 'defines', 'output', 'imsvcs', 'winsysroot', 'input',
84*8975f5c5SAndroid Build Coastguard Worker      'show_includes'
85*8975f5c5SAndroid Build Coastguard Worker  ])
86*8975f5c5SAndroid Build Coastguard Worker  return Flags(includes=includes,
87*8975f5c5SAndroid Build Coastguard Worker               defines=defines,
88*8975f5c5SAndroid Build Coastguard Worker               output=output,
89*8975f5c5SAndroid Build Coastguard Worker               imsvcs=imsvcs,
90*8975f5c5SAndroid Build Coastguard Worker               winsysroot=winsysroot,
91*8975f5c5SAndroid Build Coastguard Worker               input=input,
92*8975f5c5SAndroid Build Coastguard Worker               show_includes=show_includes)
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Workerdef ReadInput(input):
96*8975f5c5SAndroid Build Coastguard Worker  """"Reads input and returns it. For UTF-16LEBOM input, converts to UTF-8."""
97*8975f5c5SAndroid Build Coastguard Worker  # Microsoft's rc.exe only supports unicode in the form of UTF-16LE with a BOM.
98*8975f5c5SAndroid Build Coastguard Worker  # Our rc binary sniffs for UTF-16LE.  If that's not found, if /utf-8 is
99*8975f5c5SAndroid Build Coastguard Worker  # passed, the input is treated as UTF-8.  If /utf-8 is not passed and the
100*8975f5c5SAndroid Build Coastguard Worker  # input is not UTF-16LE, then our rc errors out on characters outside of
101*8975f5c5SAndroid Build Coastguard Worker  # 7-bit ASCII.  Since the driver always converts UTF-16LE to UTF-8 here (for
102*8975f5c5SAndroid Build Coastguard Worker  # the preprocessor, which doesn't support UTF-16LE), our rc will either see
103*8975f5c5SAndroid Build Coastguard Worker  # UTF-8 with the /utf-8 flag (for UTF-16LE input), or ASCII input.
104*8975f5c5SAndroid Build Coastguard Worker  # This is compatible with Microsoft rc.exe.  If we wanted, we could expose
105*8975f5c5SAndroid Build Coastguard Worker  # a /utf-8 flag for the driver for UTF-8 .rc inputs too.
106*8975f5c5SAndroid Build Coastguard Worker  # TODO(thakis): Microsoft's rc.exe supports BOM-less UTF-16LE. We currently
107*8975f5c5SAndroid Build Coastguard Worker  # don't, but for chrome it currently doesn't matter.
108*8975f5c5SAndroid Build Coastguard Worker  is_utf8 = False
109*8975f5c5SAndroid Build Coastguard Worker  try:
110*8975f5c5SAndroid Build Coastguard Worker    with open(input, 'rb') as rc_file:
111*8975f5c5SAndroid Build Coastguard Worker      rc_file_data = rc_file.read()
112*8975f5c5SAndroid Build Coastguard Worker      if rc_file_data.startswith(codecs.BOM_UTF16_LE):
113*8975f5c5SAndroid Build Coastguard Worker        rc_file_data = rc_file_data[2:].decode('utf-16le').encode('utf-8')
114*8975f5c5SAndroid Build Coastguard Worker        is_utf8 = True
115*8975f5c5SAndroid Build Coastguard Worker  except IOError:
116*8975f5c5SAndroid Build Coastguard Worker    print('rc.py: failed to open', input, file=sys.stderr)
117*8975f5c5SAndroid Build Coastguard Worker    sys.exit(1)
118*8975f5c5SAndroid Build Coastguard Worker  except UnicodeDecodeError:
119*8975f5c5SAndroid Build Coastguard Worker    print('rc.py: failed to decode UTF-16 despite BOM', input, file=sys.stderr)
120*8975f5c5SAndroid Build Coastguard Worker    sys.exit(1)
121*8975f5c5SAndroid Build Coastguard Worker  return rc_file_data, is_utf8
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Workerdef Preprocess(rc_file_data, flags):
125*8975f5c5SAndroid Build Coastguard Worker  """Runs the input file through the preprocessor."""
126*8975f5c5SAndroid Build Coastguard Worker  clang = os.path.join(SRC_DIR, 'third_party', 'llvm-build',
127*8975f5c5SAndroid Build Coastguard Worker                       'Release+Asserts', 'bin', 'clang-cl')
128*8975f5c5SAndroid Build Coastguard Worker  # Let preprocessor write to a temp file so that it doesn't interfere
129*8975f5c5SAndroid Build Coastguard Worker  # with /showIncludes output on stdout.
130*8975f5c5SAndroid Build Coastguard Worker  if sys.platform == 'win32':
131*8975f5c5SAndroid Build Coastguard Worker    clang += '.exe'
132*8975f5c5SAndroid Build Coastguard Worker  temp_handle, temp_file = tempfile.mkstemp(suffix='.i')
133*8975f5c5SAndroid Build Coastguard Worker  # Closing temp_handle immediately defeats the purpose of mkstemp(), but I
134*8975f5c5SAndroid Build Coastguard Worker  # can't figure out how to let write to the temp file on Windows otherwise.
135*8975f5c5SAndroid Build Coastguard Worker  os.close(temp_handle)
136*8975f5c5SAndroid Build Coastguard Worker  clang_cmd = [clang, '/P', '/DRC_INVOKED', '/TC', '-', '/Fi' + temp_file]
137*8975f5c5SAndroid Build Coastguard Worker  if flags.imsvcs:
138*8975f5c5SAndroid Build Coastguard Worker    clang_cmd += ['/X']
139*8975f5c5SAndroid Build Coastguard Worker  if os.path.dirname(flags.input):
140*8975f5c5SAndroid Build Coastguard Worker    # This must precede flags.includes.
141*8975f5c5SAndroid Build Coastguard Worker    clang_cmd.append('-I' + os.path.dirname(flags.input))
142*8975f5c5SAndroid Build Coastguard Worker  if flags.show_includes:
143*8975f5c5SAndroid Build Coastguard Worker    clang_cmd.append('/showIncludes')
144*8975f5c5SAndroid Build Coastguard Worker  clang_cmd += flags.imsvcs + flags.winsysroot + flags.includes + flags.defines
145*8975f5c5SAndroid Build Coastguard Worker  p = subprocess.Popen(clang_cmd, stdin=subprocess.PIPE)
146*8975f5c5SAndroid Build Coastguard Worker  p.communicate(input=rc_file_data)
147*8975f5c5SAndroid Build Coastguard Worker  if p.returncode != 0:
148*8975f5c5SAndroid Build Coastguard Worker    sys.exit(p.returncode)
149*8975f5c5SAndroid Build Coastguard Worker  preprocessed_output = open(temp_file, 'rb').read()
150*8975f5c5SAndroid Build Coastguard Worker  os.remove(temp_file)
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Worker  # rc.exe has a wacko preprocessor:
153*8975f5c5SAndroid Build Coastguard Worker  # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381033(v=vs.85).aspx
154*8975f5c5SAndroid Build Coastguard Worker  # """RC treats files with the .c and .h extensions in a special manner. It
155*8975f5c5SAndroid Build Coastguard Worker  # assumes that a file with one of these extensions does not contain
156*8975f5c5SAndroid Build Coastguard Worker  # resources. If a file has the .c or .h file name extension, RC ignores all
157*8975f5c5SAndroid Build Coastguard Worker  # lines in the file except the preprocessor directives."""
158*8975f5c5SAndroid Build Coastguard Worker  # Thankfully, the Microsoft headers are mostly good about putting everything
159*8975f5c5SAndroid Build Coastguard Worker  # in the system headers behind `if !defined(RC_INVOKED)`, so regular
160*8975f5c5SAndroid Build Coastguard Worker  # preprocessing with RC_INVOKED defined works.
161*8975f5c5SAndroid Build Coastguard Worker  return preprocessed_output
162*8975f5c5SAndroid Build Coastguard Worker
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Workerdef RunRc(preprocessed_output, is_utf8, flags):
165*8975f5c5SAndroid Build Coastguard Worker  if sys.platform.startswith('linux'):
166*8975f5c5SAndroid Build Coastguard Worker    rc = os.path.join(THIS_DIR, 'linux64', 'rc')
167*8975f5c5SAndroid Build Coastguard Worker  elif sys.platform == 'darwin':
168*8975f5c5SAndroid Build Coastguard Worker    rc = os.path.join(THIS_DIR, 'mac', 'rc')
169*8975f5c5SAndroid Build Coastguard Worker  elif sys.platform == 'win32':
170*8975f5c5SAndroid Build Coastguard Worker    rc = os.path.join(THIS_DIR, 'win', 'rc.exe')
171*8975f5c5SAndroid Build Coastguard Worker  else:
172*8975f5c5SAndroid Build Coastguard Worker    print('rc.py: error: unsupported platform', sys.platform, file=sys.stderr)
173*8975f5c5SAndroid Build Coastguard Worker    sys.exit(1)
174*8975f5c5SAndroid Build Coastguard Worker  rc_cmd = [rc]
175*8975f5c5SAndroid Build Coastguard Worker  # Make sure rc-relative resources can be found:
176*8975f5c5SAndroid Build Coastguard Worker  if os.path.dirname(flags.input):
177*8975f5c5SAndroid Build Coastguard Worker    rc_cmd.append('/cd' + os.path.dirname(flags.input))
178*8975f5c5SAndroid Build Coastguard Worker  rc_cmd.append('/fo' + flags.output)
179*8975f5c5SAndroid Build Coastguard Worker  if is_utf8:
180*8975f5c5SAndroid Build Coastguard Worker    rc_cmd.append('/utf-8')
181*8975f5c5SAndroid Build Coastguard Worker  # TODO(thakis): cl currently always prints full paths for /showIncludes,
182*8975f5c5SAndroid Build Coastguard Worker  # but clang-cl /P doesn't.  Which one is right?
183*8975f5c5SAndroid Build Coastguard Worker  if flags.show_includes:
184*8975f5c5SAndroid Build Coastguard Worker    rc_cmd.append('/showIncludes')
185*8975f5c5SAndroid Build Coastguard Worker  # Microsoft rc.exe searches for referenced files relative to -I flags in
186*8975f5c5SAndroid Build Coastguard Worker  # addition to the pwd, so -I flags need to be passed both to both
187*8975f5c5SAndroid Build Coastguard Worker  # the preprocessor and rc.
188*8975f5c5SAndroid Build Coastguard Worker  rc_cmd += flags.includes
189*8975f5c5SAndroid Build Coastguard Worker  p = subprocess.Popen(rc_cmd, stdin=subprocess.PIPE)
190*8975f5c5SAndroid Build Coastguard Worker  p.communicate(input=preprocessed_output)
191*8975f5c5SAndroid Build Coastguard Worker
192*8975f5c5SAndroid Build Coastguard Worker  if flags.show_includes and p.returncode == 0:
193*8975f5c5SAndroid Build Coastguard Worker    TOOL_DIR = os.path.dirname(os.path.relpath(THIS_DIR)).replace("\\", "/")
194*8975f5c5SAndroid Build Coastguard Worker    # Since tool("rc") can't have deps, add deps on this script and on rc.py
195*8975f5c5SAndroid Build Coastguard Worker    # and its deps here, so that rc edges become dirty if rc.py changes.
196*8975f5c5SAndroid Build Coastguard Worker    print('Note: including file: {}/tool_wrapper.py'.format(TOOL_DIR))
197*8975f5c5SAndroid Build Coastguard Worker    print('Note: including file: {}/rc/rc.py'.format(TOOL_DIR))
198*8975f5c5SAndroid Build Coastguard Worker    print(
199*8975f5c5SAndroid Build Coastguard Worker        'Note: including file: {}/rc/linux64/rc.sha1'.format(TOOL_DIR))
200*8975f5c5SAndroid Build Coastguard Worker    print('Note: including file: {}/rc/mac/rc.sha1'.format(TOOL_DIR))
201*8975f5c5SAndroid Build Coastguard Worker    print(
202*8975f5c5SAndroid Build Coastguard Worker        'Note: including file: {}/rc/win/rc.exe.sha1'.format(TOOL_DIR))
203*8975f5c5SAndroid Build Coastguard Worker
204*8975f5c5SAndroid Build Coastguard Worker  return p.returncode
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker
207*8975f5c5SAndroid Build Coastguard Workerdef CompareToMsRcOutput(preprocessed_output, is_utf8, flags):
208*8975f5c5SAndroid Build Coastguard Worker  msrc_in = flags.output + '.preprocessed.rc'
209*8975f5c5SAndroid Build Coastguard Worker
210*8975f5c5SAndroid Build Coastguard Worker  # Strip preprocessor line markers.
211*8975f5c5SAndroid Build Coastguard Worker  preprocessed_output = re.sub(br'^#.*$', b'', preprocessed_output, flags=re.M)
212*8975f5c5SAndroid Build Coastguard Worker  if is_utf8:
213*8975f5c5SAndroid Build Coastguard Worker    preprocessed_output = preprocessed_output.decode('utf-8').encode('utf-16le')
214*8975f5c5SAndroid Build Coastguard Worker  with open(msrc_in, 'wb') as f:
215*8975f5c5SAndroid Build Coastguard Worker    f.write(preprocessed_output)
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker  msrc_out = flags.output + '_ms_rc'
218*8975f5c5SAndroid Build Coastguard Worker  msrc_cmd = ['rc', '/nologo', '/x', '/fo' + msrc_out]
219*8975f5c5SAndroid Build Coastguard Worker
220*8975f5c5SAndroid Build Coastguard Worker  # Make sure rc-relative resources can be found. rc.exe looks for external
221*8975f5c5SAndroid Build Coastguard Worker  # resource files next to the file, but the preprocessed file isn't where the
222*8975f5c5SAndroid Build Coastguard Worker  # input was.
223*8975f5c5SAndroid Build Coastguard Worker  # Note that rc searches external resource files in the order of
224*8975f5c5SAndroid Build Coastguard Worker  # 1. next to the input file
225*8975f5c5SAndroid Build Coastguard Worker  # 2. relative to cwd
226*8975f5c5SAndroid Build Coastguard Worker  # 3. next to -I directories
227*8975f5c5SAndroid Build Coastguard Worker  # Changing the cwd means we'd have to rewrite all -I flags, so just add
228*8975f5c5SAndroid Build Coastguard Worker  # the input file dir as -I flag. That technically gets the order of 1 and 2
229*8975f5c5SAndroid Build Coastguard Worker  # wrong, but in Chromium's build the cwd is the gn out dir, and generated
230*8975f5c5SAndroid Build Coastguard Worker  # files there are in obj/ and gen/, so this difference doesn't matter in
231*8975f5c5SAndroid Build Coastguard Worker  # practice.
232*8975f5c5SAndroid Build Coastguard Worker  if os.path.dirname(flags.input):
233*8975f5c5SAndroid Build Coastguard Worker    msrc_cmd += [ '-I' + os.path.dirname(flags.input) ]
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker  # Microsoft rc.exe searches for referenced files relative to -I flags in
236*8975f5c5SAndroid Build Coastguard Worker  # addition to the pwd, so -I flags need to be passed both to both
237*8975f5c5SAndroid Build Coastguard Worker  # the preprocessor and rc.
238*8975f5c5SAndroid Build Coastguard Worker  msrc_cmd += flags.includes
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker  # Input must come last.
241*8975f5c5SAndroid Build Coastguard Worker  msrc_cmd += [ msrc_in ]
242*8975f5c5SAndroid Build Coastguard Worker
243*8975f5c5SAndroid Build Coastguard Worker  rc_exe_exit_code = subprocess.call(msrc_cmd)
244*8975f5c5SAndroid Build Coastguard Worker  # Assert Microsoft rc.exe and rc.py produced identical .res files.
245*8975f5c5SAndroid Build Coastguard Worker  if rc_exe_exit_code == 0:
246*8975f5c5SAndroid Build Coastguard Worker    import filecmp
247*8975f5c5SAndroid Build Coastguard Worker    assert filecmp.cmp(msrc_out, flags.output)
248*8975f5c5SAndroid Build Coastguard Worker  return rc_exe_exit_code
249*8975f5c5SAndroid Build Coastguard Worker
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Workerdef main():
252*8975f5c5SAndroid Build Coastguard Worker  # This driver has to do these things:
253*8975f5c5SAndroid Build Coastguard Worker  # 1. Parse flags.
254*8975f5c5SAndroid Build Coastguard Worker  # 2. Convert the input from UTF-16LE to UTF-8 if needed.
255*8975f5c5SAndroid Build Coastguard Worker  # 3. Pass the input through a preprocessor (and clean up the preprocessor's
256*8975f5c5SAndroid Build Coastguard Worker  #    output in minor ways).
257*8975f5c5SAndroid Build Coastguard Worker  # 4. Call rc for the heavy lifting.
258*8975f5c5SAndroid Build Coastguard Worker  flags = ParseFlags()
259*8975f5c5SAndroid Build Coastguard Worker  rc_file_data, is_utf8 = ReadInput(flags.input)
260*8975f5c5SAndroid Build Coastguard Worker  preprocessed_output = Preprocess(rc_file_data, flags)
261*8975f5c5SAndroid Build Coastguard Worker  rc_exe_exit_code = RunRc(preprocessed_output, is_utf8, flags)
262*8975f5c5SAndroid Build Coastguard Worker
263*8975f5c5SAndroid Build Coastguard Worker  # 5. On Windows, we also call Microsoft's rc.exe and check that we produced
264*8975f5c5SAndroid Build Coastguard Worker  #   the same output.
265*8975f5c5SAndroid Build Coastguard Worker  # Since Microsoft's rc has a preprocessor that only accepts 32 characters
266*8975f5c5SAndroid Build Coastguard Worker  # for macro names, feed the clang-preprocessed source into it instead
267*8975f5c5SAndroid Build Coastguard Worker  # of using ms rc's preprocessor.
268*8975f5c5SAndroid Build Coastguard Worker  if sys.platform == 'win32' and rc_exe_exit_code == 0:
269*8975f5c5SAndroid Build Coastguard Worker    rc_exe_exit_code = CompareToMsRcOutput(preprocessed_output, is_utf8, flags)
270*8975f5c5SAndroid Build Coastguard Worker
271*8975f5c5SAndroid Build Coastguard Worker  return rc_exe_exit_code
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker
274*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
275*8975f5c5SAndroid Build Coastguard Worker  sys.exit(main())
276