#!/usr/bin/env python # Copyright JS Foundation and other contributors, http://js.foundation # # 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. # # This file converts ./js/*.js to a C-array in ./source/jerry-targetjs.h file import argparse import glob import os import re import sys special_chars = re.compile(r'[-\\?\'".]') def extractName(path): return special_chars.sub('_', os.path.splitext(os.path.basename(path))[0]) def writeLine(fo, content, indent=0): buf = ' ' * indent + content + '\n' fo.write(buf) def regroup(l, n): return [ l[i:i+n] for i in range(0, len(l), n) ] def removeComments(code): pattern = r'(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)' regex = re.compile(pattern, re.MULTILINE | re.DOTALL) def _replacer(match): if match.group(2) is not None: return "" else: return match.group(1) return regex.sub(_replacer, code) def removeWhitespaces(code): return re.sub('\n+', '\n', re.sub('\n +', '\n', code)) LICENSE = '''/* Copyright JS Foundation and other contributors, http://js.foundation * * 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. * * This file is generated by js2c.py. Please do not modify. */ ''' HEADER = '''#ifndef JERRY_TARGETJS_H #define JERRY_TARGETJS_H ''' FOOTER = ''' #endif ''' parser = argparse.ArgumentParser(description="js2c") parser.add_argument('--build-type', help='build type', default='release', choices=['release', 'debug']) parser.add_argument('--ignore', help='files to ignore', dest='ignore_files', default=[], action='append') parser.add_argument('--no-main', help="don't require a 'main.js' file", dest='main', action='store_false', default=True) parser.add_argument('--js-source', dest='js_source_path', default='./js', help='Source directory of JavaScript files" (default: %(default)s)') parser.add_argument('--dest', dest='output_path', default='./source', help="Destination directory of 'jerry-targetjs.h' (default: %(default)s)") args = parser.parse_args() # argument processing build_type = args.build_type ignore_files = args.ignore_files fout = open(os.path.join(args.output_path, 'jerry-targetjs.h'), 'w') fout.write(LICENSE); fout.write(HEADER); def exportOneFile(path, name): fout.write('const static char ' + name + '_n[] = "' + name + '";\n') fout.write('const static char ' + name + '_s[] =\n{\n') fin = open(path, 'r'); code = fin.read() + '\0' # minimize code when release mode if build_type != 'debug': code = removeComments(code) code = removeWhitespaces(code) for line in regroup(code, 10): buf = ', '.join(map(lambda ch: format(ord(ch),"#04x"), line)) if line[-1] != '\0': buf += ',' writeLine(fout, buf, 1) writeLine(fout, '};') writeLine(fout, 'const static int ' + name + '_l = ' + str(len(code)-1) + ';') writeLine(fout, '') fin.close(); def exportOneName(name): writeLine(fout, '{ ' + name + '_n, ' + name + '_s, ' + name + '_l }, \\', 1) files = glob.glob(os.path.join(args.js_source_path, '*.js')) for path in files: name = extractName(path) if os.path.basename(path) not in ignore_files: exportOneFile(path, name) NATIVE_STRUCT = ''' struct js_source_all { const char* name; const char* source; const int length; }; #define DECLARE_JS_CODES \\ struct js_source_all js_codes[] = \\ { \\ ''' fout.write(NATIVE_STRUCT) if args.main: exportOneName('main') for filename in files: name = extractName(filename) if name != 'main' and os.path.basename(filename) not in ignore_files: exportOneName(name) writeLine(fout, '{ NULL, NULL, 0 } \\', 1) writeLine(fout, '};') fout.write(FOOTER) fout.close()