1#!/usr/bin/tclsh 2# 3# Use this script to build C-language source code for a program that uses 4# tclsqlite.c together with custom TCL scripts and/or C extensions for 5# either SQLite or TCL. 6# 7# Usage example: 8# 9# tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c 10# 11# The demoapp.c.in file contains a mixture of C code, TCL script, and 12# processing directives used by mktclsqliteprog.tcl to build the final C-code 13# output file. Most lines of demoapp.c.in are copied straight through into 14# the output. The following control directives are recognized: 15# 16# BEGIN_STRING 17# 18# This marks the beginning of large string literal - usually a TCL 19# script of some kind. Subsequent lines of text through the first 20# line that begins with END_STRING are converted into a C-language 21# string literal. 22# 23# INCLUDE path 24# 25# The path argument is the name of a file to be inserted in place of 26# the INCLUDE line. The path can begin with $ROOT to signify the 27# root of the SQLite source tree, or $HOME to signify the directory 28# that contains the demoapp.c.in input script itself. If the path does 29# not begin with either $ROOT or $HOME, then it is interpreted relative 30# to the current working directory. 31# 32# If the INCLUDE occurs in the middle of BEGIN_STRING...END_STRING 33# then all of the text in the input file is converted into C-language 34# string literals. 35# 36# None of the control directives described above will nest. Only the 37# top-level input file ("demoapp.c.in" in the example) is interpreted. 38# referenced files are copied verbatim. 39# 40if {[llength $argv]!=1} { 41 puts stderr "Usage: $argv0 TEMPLATE >OUTPUT" 42 exit 1 43} 44set infile [lindex $argv 0] 45set ROOT [file normalize [file dir $argv0]/..] 46set HOME [file normalize [file dir $infile]] 47set in [open $infile rb] 48puts [subst {/* DO NOT EDIT 49** 50** This file was generated by \"$argv0 $infile\". 51** To make changes, edit $infile then rerun the generator 52** command. 53*/}] 54set instr 0 55while {1} { 56 set line [gets $in] 57 if {[eof $in]} break 58 if {[regexp {^INCLUDE (.*)} $line all path]} { 59 regsub {^\$ROOT\y} $path $ROOT path 60 regsub {^\$HOME\y} $path $HOME path 61 set in2 [open $path rb] 62 puts "/* INCLUDE $path */" 63 if {$instr} { 64 while {1} { 65 set line [gets $in2] 66 if {[eof $in2]} break 67 set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] 68 puts "\"$x\\n\"" 69 } 70 } else { 71 puts [read $in2] 72 } 73 puts "/* END $path */" 74 close $in2 75 continue 76 } 77 if {[regexp {^BEGIN_STRING} $line]} { 78 set instr 1 79 puts "/* BEGIN_STRING */" 80 continue 81 } 82 if {[regexp {^END_STRING} $line]} { 83 set instr 0 84 puts "/* END_STRING */" 85 continue 86 } 87 if {$instr} { 88 set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line] 89 puts "\"$x\\n\"" 90 } else { 91 puts $line 92 } 93} 94