1#!/usr/bin/env python 2 3# Copyright JS Foundation and other contributors, http://js.foundation 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17# This file converts ./js/*.js to a C-array in ./source/jerry-targetjs.h file 18 19import argparse 20import glob 21import os 22import re 23 24from gen_c_source import LICENSE, format_code 25 26 27HEADER = '''#ifndef JERRY_TARGETJS_H 28#define JERRY_TARGETJS_H 29''' 30 31FOOTER = ''' 32#endif 33''' 34 35NATIVE_STRUCT = ''' 36struct js_source_all { 37 const char* name; 38 const char* source; 39 const int length; 40}; 41 42#define DECLARE_JS_CODES \\ 43struct js_source_all js_codes[] = \\ 44{ \\''' 45 46 47def extract_name(path): 48 special_chars = re.compile(r'[-\\?\'".]') 49 return special_chars.sub('_', os.path.splitext(os.path.basename(path))[0]) 50 51 52def reduce_code(code): 53 code = re.sub(r"/\*.*?\*/", "", code, flags=re.DOTALL) # remove all occurance streamed comments 54 code = re.sub(r"//.*?\n", "", code) # remove all occurance singleline comments 55 code = re.sub('\n+', '\n', re.sub('\n +', '\n', code)) # remove white spaces 56 return code 57 58 59def js_to_native_code(path, name, build_type): 60 with open(path, 'r') as js_source: 61 code = js_source.read() 62 63 if build_type != 'debug': 64 code = reduce_code(code) 65 66 data = format_code(code, 1, 2) 67 68 native_code = """const static char {0}_n[] = "{0}"; 69const static char {0}_s[] = 70{{ 71{1} 72}}; 73const static int {0}_l = {2}; 74""".format(name, data, len(code)) 75 76 return native_code 77 78 79def main(): 80 parser = argparse.ArgumentParser(description="js2c") 81 parser.add_argument('--build-type', help='build type', default='release', choices=['release', 'debug']) 82 parser.add_argument('--ignore', help='files to ignore', dest='ignore_files', default=[], action='append') 83 parser.add_argument('--no-main', 84 help="don't require a 'main.js' file", 85 dest='main', 86 action='store_false', 87 default=True) 88 parser.add_argument('--js-source', 89 dest='js_source_path', 90 default='./js', 91 help='Source directory of JavaScript files" (default: %(default)s)') 92 parser.add_argument('--dest', 93 dest='output_path', 94 default='./source', 95 help="Destination directory of 'jerry-targetjs.h' (default: %(default)s)") 96 97 script_args = parser.parse_args() 98 99 gen_line = "/* This file is generated by %s. Please do not modify. */" % os.path.basename(__file__) 100 101 gen_output = [LICENSE, "", gen_line, "", HEADER] 102 gen_structs = [NATIVE_STRUCT] 103 104 if script_args.main: 105 gen_structs.append(' {{ {0}_n, {0}_s, {0}_l }}, \\'.format("main")) 106 107 files = glob.glob(os.path.join(script_args.js_source_path, '*.js')) 108 109 for path in files: 110 if os.path.basename(path) not in script_args.ignore_files: 111 name = extract_name(path) 112 gen_output.append(js_to_native_code(path, name, script_args.build_type)) 113 if name != 'main': 114 gen_structs.append(' {{ {0}_n, {0}_s, {0}_l }}, \\'.format(name)) 115 116 gen_structs.append(' { NULL, NULL, 0 } \\\n};') 117 118 gen_output.append("\n".join(gen_structs)) 119 gen_output.append(FOOTER) 120 121 with open(os.path.join(script_args.output_path, 'jerry-targetjs.h'), 'w') as gen_file: 122 gen_file.write("\n".join(gen_output)) 123 124 125if __name__ == "__main__": 126 main() 127