From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../generate_crash_reporter_sources.py | 205 +++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 toolkit/crashreporter/generate_crash_reporter_sources.py (limited to 'toolkit/crashreporter/generate_crash_reporter_sources.py') diff --git a/toolkit/crashreporter/generate_crash_reporter_sources.py b/toolkit/crashreporter/generate_crash_reporter_sources.py new file mode 100644 index 0000000000..9d066a814c --- /dev/null +++ b/toolkit/crashreporter/generate_crash_reporter_sources.py @@ -0,0 +1,205 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import string +import sys +import textwrap + +import yaml + +############################################################################### +# Language-agnostic functionality # +############################################################################### + +template_header = ( + "/* This file was autogenerated by " + "toolkit/crashreporter/generate_crash_reporter_sources.py. DO NOT EDIT */\n\n" +) + + +def validate_annotations(annotations): + """Ensure that the annotations have all the required fields""" + + for (name, data) in sorted(annotations.items()): + if "description" not in data: + print("Annotation " + name + " does not have a description\n") + sys.exit(1) + if "type" not in data: + print("Annotation " + name + " does not have a type\n") + sys.exit(1) + else: + annotation_type = data.get("type") + valid_types = ["boolean", "integer", "string"] + if not any(annotation_type == t for t in valid_types): + print( + "Annotation " + + name + + " has an unknown type: " + + annotation_type + + "\n" + ) + sys.exit(1) + + +def read_annotations(annotations_filename): + """Read the annotations from a YAML file. + If an error is encountered quit the program.""" + + try: + with open(annotations_filename, "r") as annotations_file: + annotations = yaml.safe_load(annotations_file) + except (IOError, ValueError) as e: + print("Error parsing " + annotations_filename + ":\n" + str(e) + "\n") + sys.exit(1) + + validate_annotations(annotations) + + return annotations + + +def read_template(template_filename): + """Read the contents of the template. + If an error is encountered quit the program.""" + + try: + with open(template_filename, "r") as template_file: + template = template_file.read() + except IOError as ex: + print("Error when reading " + template_filename + ":\n" + str(ex) + "\n") + sys.exit(1) + + return template + + +def extract_crash_ping_allowlist(annotations): + """Extract an array holding the names of the annotations allowlisted for + inclusion in the crash ping.""" + + return [ + name for (name, data) in sorted(annotations.items()) if data.get("ping", False) + ] + + +############################################################################### +# C++ code generation # +############################################################################### + + +def generate_strings(annotations): + """Generate strings corresponding to every annotation.""" + + names = [ + ' "' + data.get("altname", name) + '"' + for (name, data) in sorted(annotations.items()) + ] + + return ",\n".join(names) + + +def generate_enum(annotations): + """Generate the C++ typed enum holding all the annotations and return it + as a string.""" + + enum = "" + + for i, (name, _) in enumerate(sorted(annotations.items())): + enum += " " + name + " = " + str(i) + ",\n" + + enum += " Count = " + str(len(annotations)) + + return enum + + +def generate_array_initializer(contents): + """Generates the initializer for a C++ array of annotations.""" + + initializer = [" Annotation::" + name for name in contents] + + return ",\n".join(initializer) + + +def generate_header(template, annotations): + """Generate a header by filling the template with the the list of + annotations and return it as a string.""" + + allowlist = extract_crash_ping_allowlist(annotations) + + return template_header + string.Template(template).substitute( + { + "enum": generate_enum(annotations), + "strings": generate_strings(annotations), + "allowlist": generate_array_initializer(allowlist), + } + ) + + +def emit_header(output, template_filename, annotations_filename): + """Generate the C++ header from the template and write it out.""" + + annotations = read_annotations(annotations_filename) + template = read_template(template_filename) + generated_header = generate_header(template, annotations) + + try: + output.write(generated_header) + except IOError as ex: + print("Error while writing out the generated file:\n" + str(ex) + "\n") + sys.exit(1) + + +############################################################################### +# Java code generation # +############################################################################### + + +def generate_java_array_initializer(contents): + """Generates the initializer for an array of strings. + Effectively turns `["a", "b"]` into ' \"a\",\n \"b\"\n'.""" + + initializer = "" + + for name in contents: + initializer += ' "' + name + '",\n' + + return initializer.strip(",\n") + + +def generate_class(template, annotations): + """Fill the class template from the list of annotations.""" + + allowlist = extract_crash_ping_allowlist(annotations) + + return template_header + string.Template(template).substitute( + { + "allowlist": generate_java_array_initializer(allowlist), + } + ) + + +def emit_class(output, annotations_filename): + """Generate the CrashReporterConstants.java file.""" + + template = textwrap.dedent( + """\ + package org.mozilla.gecko; + + /** + * Constants used by the crash reporter. These are generated so that they + * are kept in sync with the other C++ and JS users. + */ + public class CrashReporterConstants { + public static final String[] ANNOTATION_ALLOWLIST = { + ${allowlist} + }; + }""" + ) + + annotations = read_annotations(annotations_filename) + generated_class = generate_class(template, annotations) + + try: + output.write(generated_class) + except IOError as ex: + print("Error while writing out the generated file:\n" + str(ex) + "\n") + sys.exit(1) -- cgit v1.2.3