tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

write_buildflag_header.py (3525B)


      1 #!/usr/bin/env python3
      2 # Copyright 2015 The Chromium Authors
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 # This writes headers for build flags. See buildflag_header.gni for usage of
      7 # this system as a whole.
      8 #
      9 # The parameters are passed in a response file so we don't have to worry
     10 # about command line lengths. The name of the response file is passed on the
     11 # command line.
     12 #
     13 # The format of the response file is:
     14 #    [--flags <list of one or more flag values>]
     15 
     16 import optparse
     17 import os
     18 import re
     19 import shlex
     20 
     21 
     22 class Options:
     23  def __init__(self, output, rulename, header_guard, flags):
     24    self.output = output
     25    self.rulename = rulename
     26    self.header_guard = header_guard
     27    self.flags = flags
     28 
     29 
     30 def GetOptions():
     31  parser = optparse.OptionParser()
     32  parser.add_option('--output', help="Output header name inside --gen-dir.")
     33  parser.add_option('--rulename',
     34                    help="Helpful name of build rule for including in the " +
     35                         "comment at the top of the file.")
     36  parser.add_option('--gen-dir',
     37                    help="Path to root of generated file directory tree.")
     38  parser.add_option('--definitions',
     39                    help="Name of the response file containing the flags.")
     40  cmdline_options, cmdline_flags = parser.parse_args()
     41 
     42  # Compute a valid C++ header guard by replacing non valid chars with '_',
     43  # upper-casing everything and prepending '_' if first symbol is digit.
     44  header_guard = cmdline_options.output.upper()
     45  if header_guard[0].isdigit():
     46    header_guard = '_' + header_guard
     47  header_guard = re.sub(r'[^\w]', '_', header_guard)
     48  header_guard += '_'
     49 
     50  # The actual output file is inside the gen dir.
     51  output = os.path.join(cmdline_options.gen_dir, cmdline_options.output)
     52 
     53  # Definition file in GYP is newline separated, in GN they are shell formatted.
     54  # shlex can parse both of these.
     55  with open(cmdline_options.definitions, 'r') as def_file:
     56    defs = shlex.split(def_file.read())
     57  flags_index = defs.index('--flags')
     58 
     59  # Everything after --flags are flags. true/false are remapped to 1/0,
     60  # everything else is passed through.
     61  flags = []
     62  for flag in defs[flags_index + 1 :]:
     63    equals_index = flag.index('=')
     64    key = flag[:equals_index]
     65    value = flag[equals_index + 1:]
     66 
     67    # Canonicalize and validate the value.
     68    if value == 'true':
     69      value = '1'
     70    elif value == 'false':
     71      value = '0'
     72    flags.append((key, str(value)))
     73 
     74  return Options(output=output,
     75                 rulename=cmdline_options.rulename,
     76                 header_guard=header_guard,
     77                 flags=flags)
     78 
     79 
     80 def WriteHeader(options):
     81  with open(options.output, 'w') as output_file:
     82    output_file.write("// Generated by build/write_buildflag_header.py\n")
     83    if options.rulename:
     84      output_file.write('// From "' + options.rulename + '"\n')
     85 
     86    output_file.write('\n#ifndef %s\n' % options.header_guard)
     87    output_file.write('#define %s\n\n' % options.header_guard)
     88    output_file.write('#include "build/buildflag.h" // IWYU pragma: export\n\n')
     89    # Clangd does not detect BUILDFLAG_INTERNAL_* indirect usage, so mark the
     90    # header as "always_keep" to avoid "unused include" warning.
     91    output_file.write('// IWYU pragma: always_keep\n\n')
     92 
     93    for pair in options.flags:
     94      output_file.write('#define BUILDFLAG_INTERNAL_%s() (%s)\n' % pair)
     95 
     96    output_file.write('\n#endif  // %s\n' % options.header_guard)
     97 
     98 
     99 options = GetOptions()
    100 WriteHeader(options)