1#!/usr/bin/env python
2# Copyright 2013 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Wrapper script for running ncval.
7"""
8
9import optparse
10import os
11import subprocess
12import sys
13
14import getos
15
16SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
17NACL_SDK_ROOT = os.path.dirname(SCRIPT_DIR)
18
19if sys.version_info < (2, 6, 0):
20  sys.stderr.write("python 2.6 or later is required run this script\n")
21  sys.exit(1)
22
23class Error(Exception):
24  pass
25
26def Log(msg):
27  if Log.verbose:
28    sys.stderr.write(str(msg) + '\n')
29Log.verbose = False
30
31def main(argv):
32  usage = 'Usage: %prog [options] <.nexe | .so>'
33  epilog = 'Example: ncval.py my_nexe.nexe'
34  parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog)
35  parser.add_option('-v', '--verbose', action='store_true',
36                    help='Verbose output')
37
38  # To enable bash completion for this command first install optcomplete
39  # and then add this line to your .bashrc:
40  #  complete -F _optcomplete ncval.py
41  try:
42    import optcomplete
43    optcomplete.autocomplete(parser)
44  except ImportError:
45    pass
46
47  options, args = parser.parse_args(argv)
48  if not args:
49    parser.error('No executable file specified')
50
51  nexe = args[0]
52  if options.verbose:
53    Log.verbose = True
54
55  # TODO(binji): http://crbug.com/321791. Fix ncval upstream to reduce the
56  # amount of additional checking done here.
57  osname = getos.GetPlatform()
58  if not os.path.exists(nexe):
59    raise Error('executable not found: %s' % nexe)
60  if not os.path.isfile(nexe):
61    raise Error('not a file: %s' % nexe)
62
63  ncval = os.path.join(SCRIPT_DIR, 'ncval')
64  if osname == 'win':
65    ncval += '.exe'
66
67  cmd = [ncval, nexe]
68  Log('Running %s' % ' '.join(cmd))
69  proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
70  proc_out, _ = proc.communicate()
71  if proc.returncode:
72    # ncval doesn't print anything to stderr.
73    sys.stderr.write('Validating %s failed:\n' % nexe)
74    sys.stderr.write(proc_out + '\n')
75
76    Log('Changing the modification time of %s to 0.' % nexe)
77    # "untouch" the executable; that is, change the modification time to be so
78    # old that it will be remade when `make` runs.
79    statinfo = os.stat(nexe)
80    mtime = 0
81    os.utime(nexe, (statinfo.st_atime, mtime))
82
83    return proc.returncode
84  elif options.verbose:
85    # By default, don't print anything on success.
86    Log(proc_out)
87
88
89if __name__ == '__main__':
90  try:
91    sys.exit(main(sys.argv[1:]))
92  except Error as e:
93    sys.stderr.write(str(e) + '\n')
94    sys.exit(1)
95