blob: 269b1320cd9ed6e8749dd74c8de3af98aa660a75 [file]
#!/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]))