blob: 1bcfc6ae2860f492e0852e1ca59ec10ee2eacf63 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generates C++ source and header files defining function to create an
in-memory representation of a static catalog manifest at runtime."""
import argparse
import imp
import json
import os.path
import sys
sys.path.append(os.path.join(
os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir,
"build", "android", "gyp"))
from util import build_utils
_H_FILE_TEMPLATE = "catalog.h.tmpl"
_CC_FILE_TEMPLATE = "catalog.cc.tmpl"
# Disable lint check for finding modules:
# pylint: disable=F0401
def _GetDirAbove(dirname):
"""Returns the directory "above" this file containing |dirname| (which must
also be "above" this file)."""
path = os.path.abspath(__file__)
while True:
path, tail = os.path.split(path)
assert tail
if tail == dirname:
return path
try:
imp.find_module("jinja2")
except ImportError:
sys.path.append(os.path.join(_GetDirAbove("services"), "third_party"))
import jinja2
def ApplyTemplate(path_to_template, output_path, global_vars, **kwargs):
def make_ascii(maybe_unicode):
if type(maybe_unicode) is str:
return maybe_unicode
assert type(maybe_unicode) is unicode
return maybe_unicode.encode("ascii", "ignore")
with build_utils.AtomicOutput(output_path) as output_file:
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
keep_trailing_newline=True, **kwargs)
jinja_env.globals.update(global_vars)
jinja_env.filters.update({
"is_dict": lambda x : type(x) is dict,
"is_list": lambda x : type(x) is list,
"is_number": lambda x : type(x) is int or type(x) is float,
"is_bool": lambda x: type(x) is bool,
"is_string": lambda x: type(x) is str,
"is_unicode": lambda x: type(x) is unicode,
"make_ascii": make_ascii,
})
output_file.write(jinja_env.get_template(path_to_template).render())
def main():
parser = argparse.ArgumentParser(
description="Generates a C++ constant containing a catalog manifest.")
parser.add_argument("--input")
parser.add_argument("--output-filename-base")
parser.add_argument("--output-function-name")
parser.add_argument("--module-path")
args, _ = parser.parse_known_args()
if args.input is None:
raise Exception("--input is required")
if args.output_filename_base is None:
raise Exception("--output-filename-base is required")
if args.output_function_name is None:
raise Exception("--output-function-name is required")
if args.module_path is None:
raise Exception("--module-path is required")
with open(args.input, "r") as input_file:
catalog = json.load(input_file)
qualified_function_name = args.output_function_name.split("::")
namespaces = qualified_function_name[0:-1]
function_name = qualified_function_name[-1]
def raise_error(error, value):
raise Exception(error)
global_vars = {
"catalog": catalog,
"function_name": function_name,
"namespaces": namespaces,
"path": args.module_path,
"raise": raise_error,
}
input_h_filename = _H_FILE_TEMPLATE
output_h_filename = "%s.h" % args.output_filename_base
ApplyTemplate(input_h_filename, output_h_filename, global_vars)
input_cc_filename = _CC_FILE_TEMPLATE
output_cc_filename = "%s.cc" % args.output_filename_base
ApplyTemplate(input_cc_filename, output_cc_filename, global_vars)
return 0
if __name__ == "__main__":
sys.exit(main())