| import os |
| import sys |
| |
| _copyright = """/* |
| * Copyright 2011-2014 Software Freedom Conservancy |
| * |
| * Licensed under the Apache License, Version 2.0 (the \"License\"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an \"AS IS\" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| """ |
| |
| |
| def get_atom_name(name): |
| # We had a todo here to convert camelCase and snake_case to BIG_SNAKE_CASE, but this code |
| # will be removed when BiDi is the default, so we're not going to bother with that. |
| name = os.path.basename(name) |
| return name.upper() |
| |
| |
| def write_atom_literal(out, name, contents, lang, utf8): |
| # Escape the contents of the file so it can be stored as a literal. |
| contents = contents.replace("\\", "\\\\") |
| contents = contents.replace("\f", "\\f") |
| contents = contents.replace("\n", "\\n") |
| contents = contents.replace("\r", "\\r") |
| contents = contents.replace("\t", "\\t") |
| contents = contents.replace('"', '\\"') |
| |
| if "cc" == lang or "hh" == lang: |
| if utf8: |
| line_format = ' "{}",\n' |
| else: |
| line_format = ' L"{}",\n' |
| elif "java" == lang: |
| line_format = ' .append\("{}")\n' |
| else: |
| raise RuntimeError("Unknown language: %s " % lang) |
| |
| name = get_atom_name(name) |
| |
| if "cc" == lang or "hh" == lang: |
| char_type = "char" if utf8 else "wchar_t" |
| out.write("const %s* const %s[] = {\n" % (char_type, name)) |
| elif "java" == lang: |
| out.write(" %s(new StringBuilder()\n" % name) |
| else: |
| raise RuntimeError("Unknown language: %s " % lang) |
| |
| # Make the header file play nicely in a terminal: limit lines to 80 |
| # characters, but make sure we don't cut off a line in the middle |
| # of an escape sequence. |
| while len(contents) > 70: |
| diff = 70 |
| while contents[diff - 1] == "\\": |
| diff = diff - 1 |
| line = contents[0:diff] |
| contents = contents[diff:] |
| |
| out.write(line_format.format(line)) |
| if len(contents) > 0: |
| out.write(line_format.format(contents)) |
| |
| if "cc" == lang or "hh" == lang: |
| out.write(" NULL\n};\n\n") |
| elif "java" == lang: |
| out.write(" .toString()),\n") |
| |
| |
| def generate_header(file_name, out, js_map, just_declare, utf8): |
| define_guard = "WEBDRIVER_%s" % os.path.basename(file_name.upper()).replace( |
| ".", "_" |
| ) |
| include_stddef = "" if utf8 else "\n#include <stddef.h> // For wchar_t." |
| out.write( |
| """%s |
| |
| /* AUTO GENERATED - DO NOT EDIT BY HAND */ |
| #ifndef %s |
| #define %s |
| %s |
| #include <string> // For std::(w)string. |
| |
| namespace webdriver { |
| namespace atoms { |
| |
| """ |
| % (_copyright, define_guard, define_guard, include_stddef) |
| ) |
| |
| string_type = "std::string" if utf8 else "std::wstring" |
| char_type = "char" if utf8 else "wchar_t" |
| |
| for name, file in js_map.items(): |
| if just_declare: |
| out.write("extern const %s* const %s[];\n" % (char_type, name.upper())) |
| else: |
| contents = open(file, "r").read() |
| write_atom_literal(out, name, contents, "hh", utf8) |
| |
| out.write( |
| """ |
| static inline %s asString(const %s* const atom[]) { |
| %s source; |
| for (int i = 0; atom[i] != NULL; i++) { |
| source += atom[i]; |
| } |
| return source; |
| } |
| |
| } // namespace atoms |
| } // namespace webdriver |
| |
| #endif // %s |
| """ |
| % (string_type, char_type, string_type, define_guard) |
| ) |
| |
| |
| def generate_cc_source(out, js_map, utf8): |
| out.write( |
| """%s |
| |
| /* AUTO GENERATED - DO NOT EDIT BY HAND */ |
| |
| #include <stddef.h> // For NULL. |
| #include "atoms.h" |
| |
| namespace webdriver { |
| namespace atoms { |
| |
| """ |
| % _copyright |
| ) |
| |
| for name, file in js_map.items(): |
| contents = open(file, "r").read() |
| write_atom_literal(out, name, contents, "cc", utf8) |
| |
| out.write(""" |
| } // namespace atoms |
| } // namespace webdriver |
| |
| """) |
| |
| |
| def generate_java_source(file_name, out, preamble, js_map): |
| if not file_name.endswith(".java"): |
| raise RuntimeError("File name must end in .java") |
| class_name = os.path.basename(file_name[:-5]) |
| |
| out.write(_copyright) |
| out.write("\n") |
| out.write(preamble) |
| out.write("") |
| out.write( |
| """ |
| public enum %s { |
| |
| // AUTO GENERATED - DO NOT EDIT BY HAND |
| """ |
| % class_name |
| ) |
| |
| for name, file in js_map.items(): |
| contents = open(file, "r").read() |
| write_atom_literal(out, name, contents, "java", True) |
| |
| out.write( |
| """ |
| ; |
| private final String value; |
| |
| public String getValue() { |
| return value; |
| } |
| |
| public String toString() { |
| return getValue(); |
| } |
| |
| %s(String value) { |
| this.value = value; |
| } |
| } |
| """ |
| % class_name |
| ) |
| |
| |
| def main(argv=[]): |
| lang = argv[1] |
| file_name = argv[2] |
| preamble = argv[3] |
| utf8 = argv[4] == "true" |
| |
| js_map = {} |
| for i in range(5, len(argv), 2): |
| js_map[argv[i]] = argv[i + 1] |
| |
| with open(file_name, "w") as out: |
| if "cc" == lang: |
| generate_cc_source(out, js_map, utf8) |
| elif "hdecl" == lang: |
| generate_header(file_name, out, js_map, True, utf8) |
| elif "hh" == lang: |
| generate_header(file_name, out, js_map, False, utf8) |
| elif "java" == lang: |
| generate_java_source(file_name, out, preamble, js_map) |
| else: |
| raise RuntimeError("Unknown lang: %s" % lang) |
| |
| |
| if __name__ == "__main__": |
| main(sys.argv) |