"""Driver of srpcgen for ppapi_proxy sources.
This must be run after modifying, adding, or removing .srpc files.
The lists of .srpc files are in this source file.
"""
import filecmp
import optparse
import os
import shutil
import subprocess
import sys
import tempfile
all_units = [
{'trusted_is_client': True,
'name': 'PppRpcs',
'file_basename': 'ppp_rpc',
'srpc_files': [
'completion_callback.srpc',
'ppp.srpc',
'ppp_audio.srpc',
'ppp_find.srpc',
'ppp_input_event.srpc',
'ppp_instance.srpc',
'ppp_messaging.srpc',
'ppp_mouse_lock.srpc',
'ppp_network_monitor_private.srpc',
'ppp_printing.srpc',
'ppp_selection.srpc',
'ppp_zoom.srpc',
]},
{'trusted_is_client': False,
'client_thread_check': True,
'name': 'PpbRpcs',
'file_basename': 'ppb_rpc',
'srpc_files': [
'ppb.srpc',
'ppb_audio.srpc',
'ppb_audio_config.srpc',
'ppb_core.srpc',
'ppb_file_io.srpc',
'ppb_file_ref.srpc',
'ppb_file_system.srpc',
'ppb_find.srpc',
'ppb_font.srpc',
'ppb_fullscreen.srpc',
'ppb_gamepad.srpc',
'ppb_graphics_2d.srpc',
'ppb_graphics_3d.srpc',
'ppb_host_resolver_private.srpc',
'ppb_image_data.srpc',
'ppb_input_event.srpc',
'ppb_instance.srpc',
'ppb_messaging.srpc',
'ppb_mouse_cursor.srpc',
'ppb_mouse_lock.srpc',
'ppb_net_address_private.srpc',
'ppb_network_list_private.srpc',
'ppb_network_monitor_private.srpc',
'ppb_tcp_server_socket_private.srpc',
'ppb_tcp_socket_private.srpc',
'ppb_testing.srpc',
'ppb_udp_socket_private.srpc',
'ppb_url_loader.srpc',
'ppb_url_request_info.srpc',
'ppb_url_response_info.srpc',
'ppb_websocket.srpc',
'ppb_zoom.srpc',
]},
{'trusted_is_client': False,
'name': 'PpbUpcalls',
'file_basename': 'upcall',
'srpc_files': [
'upcall.srpc',
]},
]
def GeneratorForUnit(options, unit, is_trusted, output_dir):
header_file_name = unit['file_basename'] + '.h'
server_file_name = unit['file_basename'] + '_server.cc'
client_file_name = unit['file_basename'] + '_client.cc'
header_guard = 'GEN_PPAPI_PROXY_%s_H_' % unit['file_basename'].upper()
is_client = is_trusted == unit['trusted_is_client']
thread_check = unit.get('client_thread_check', False) == is_client
header_dir = 'trusted' if is_trusted else 'untrusted'
header = os.path.join(header_dir, 'srpcgen', header_file_name)
source = client_file_name if is_client else server_file_name
command = [
sys.executable, options.srpcgen,
'--ppapi',
'--include=' + '/'.join([header_dir, 'srpcgen', header_file_name]),
'-c' if is_client else '-s',
]
if thread_check:
command.append('--thread-check')
command += [
unit['name'],
header_guard,
os.path.join(output_dir, header),
os.path.join(output_dir, source),
]
command += [os.path.join(options.source_dir, file)
for file in unit['srpc_files']]
return command, [header, source]
def RunOneUnit(options, unit, is_trusted):
result = 0
if options.diff_mode:
temp_dir = tempfile.mkdtemp(prefix='srpcdiff')
try:
command, files = GeneratorForUnit(options, unit, is_trusted, temp_dir)
result = subprocess.call(command)
if result != 0:
print 'Command failed: ' + ' '.join(command)
else:
for file in files:
output_file = os.path.join(options.output_dir, file)
generated_file = os.path.join(temp_dir, file)
if not filecmp.cmp(output_file, generated_file, shallow=False):
print '%s is out of date' % output_file
result = 1
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
else:
command, _ = GeneratorForUnit(options, unit, is_trusted, options.output_dir)
print 'Run: ' + ' '.join(command)
if not options.dry_run:
result = subprocess.call(command)
return result
def RunUnits(options, is_trusted):
result = 0
for unit in all_units:
this_result = RunOneUnit(options, unit, is_trusted)
if this_result != 0:
print 'Error %d on %s.' % (this_result, unit['name'])
result = this_result
return result
def RunAll(options):
trusted_result = RunUnits(options, True)
untrusted_result = RunUnits(options, False)
return trusted_result or untrusted_result
def Main(argv):
parser = optparse.OptionParser(usage='Usage: %prog [options]')
parser.add_option('-o', '--output_dir',
help='Directory to receive output files.')
parser.add_option('-d', '--source_dir',
help='Directory containing .srpc files.',
default=os.path.dirname(argv[0]))
parser.add_option('-s', '--srpcgen',
help='Path to the srpcgen.py script.')
parser.add_option('-n', '--dry_run', action='store_true',
help='Just print commands instead of running them.',
default=False)
parser.add_option('-c', '--diff_mode', action='store_true',
help='Touch no files, but complain if they would differ',
default=False)
options, args = parser.parse_args(argv[1:])
options.source_dir = os.path.normpath(options.source_dir)
if options.output_dir is None:
options.output_dir = options.source_dir
if options.srpcgen is None:
options.srpcgen = os.path.normpath(os.path.join(options.source_dir,
'..', '..', 'tools',
'srpcgen.py'))
if args:
parser.print_help()
return 1
return RunAll(options)
if __name__ == '__main__':
sys.exit(Main(sys.argv))