| #!/usr/bin/env python |
| # |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you 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. |
| # |
| # |
| # |
| # transform_sql.py -- create a header file with the appropriate SQL variables |
| # from an SQL file |
| # |
| |
| |
| import os |
| import re |
| import sys |
| |
| |
| DEFINE_END = ' ""\n\n' |
| |
| |
| def usage_and_exit(msg): |
| if msg: |
| sys.stderr.write('%s\n\n' % msg) |
| sys.stderr.write( |
| 'USAGE: %s SQLITE_FILE [OUTPUT_FILE]\n' |
| ' stdout will be used if OUTPUT_FILE is not provided.\n' |
| % os.path.basename(sys.argv[0])) |
| sys.stderr.flush() |
| sys.exit(1) |
| |
| |
| def main(input, output, filename): |
| input = input.read() |
| |
| var_name = re.sub('[-.]', '_', filename).upper() |
| |
| output.write( |
| '/* This file is automatically generated from %s.\n' |
| ' * Do not edit this file -- edit the source and rerun gen-make.py */\n' |
| '\n' |
| % (filename,)) |
| |
| var_printed = False |
| stmt_count = 0 |
| |
| # only used once, but we need the flags. so re.compile it is! |
| re_comments = re.compile(r'/\*.*?\*/', re.MULTILINE|re.DOTALL) |
| input = re_comments.sub('', input) |
| |
| # a couple SQL comments that act as directives for this transform system |
| re_format = re.compile('-- *format: *([0-9]+)') |
| re_statement = re.compile('-- *STMT_([A-Z_]+)') |
| |
| for line in input.split('\n'): |
| line = line.replace('"', '\\"') |
| |
| if line.strip(): |
| match = re_format.match(line) |
| if match: |
| vsn = match.group(1) |
| if var_printed: |
| # end the previous #define |
| output.write(DEFINE_END) |
| output.write('#define %s_%s \\\n' % (var_name, match.group(1))) |
| var_printed = True |
| |
| # no need to put the directive into the file. skip this line. |
| continue |
| |
| match = re_statement.match(line) |
| if match: |
| name = match.group(1) |
| if var_printed: |
| # end the previous #define |
| output.write(DEFINE_END) |
| output.write('#define STMT_%s %d\n' % (match.group(1), stmt_count)) |
| output.write('#define STMT_%d \\\n' % (stmt_count,)) |
| var_printed = True |
| |
| stmt_count += 1 |
| |
| # no need to put the directive into the file. skip this line. |
| continue |
| |
| if not var_printed: |
| output.write('#define %s \\\n' % var_name) |
| var_printed = True |
| |
| # got something besides whitespace. write it out. include some whitespace |
| # to separate the SQL commands. and a backslash to continue the string |
| # onto the next line. |
| output.write(' "%s " \\\n' % line) |
| |
| # previous line had a continuation. end the madness. |
| assert var_printed |
| output.write(DEFINE_END) |
| |
| ### the STMT_%d naming precludes *multiple* transform_sql headers from |
| ### being used within the same .c file. for now, that's more than fine. |
| ### in the future, we can always add a var_name discriminator or use |
| ### the statement name itself (which should hopefully be unique across |
| ### all names in use; or can easily be made so) |
| if stmt_count > 0: |
| output.write('#define %s_DECLARE_STATEMENTS(varname) \\\n' % (var_name,) |
| + ' static const char * const varname[] = { \\\n' |
| + ', \\\n'.join(' STMT_%d' % (i,) for i in range(stmt_count)) |
| + ' \\\n }\n') |
| |
| |
| if __name__ == '__main__': |
| if len(sys.argv) < 2 or len(sys.argv) > 3: |
| usage_and_exit('Incorrect number of arguments') |
| |
| # Note: we could use stdin, but then we'd have no var_name |
| input_file = open(sys.argv[1], 'r') |
| |
| if len(sys.argv) > 2: |
| output_file = open(sys.argv[2], 'w') |
| else: |
| output_file = sys.stdout |
| |
| main(input_file, output_file, os.path.basename(sys.argv[1])) |