Snapshot of upstream SQLite 3.34.1
[sqlcipher.git] / tool / mkccode.tcl
blob41b09f1e8100d4258b12c233c993109bcc993a1b
1 #!/usr/bin/tclsh
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.
7 # Usage example:
9 # tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c
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:
16 # BEGIN_STRING
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.
23 # INCLUDE path
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.
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.
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.
40 if {[llength $argv]!=1} {
41 puts stderr "Usage: $argv0 TEMPLATE >OUTPUT"
42 exit 1
44 set infile [lindex $argv 0]
45 set ROOT [file normalize [file dir $argv0]/..]
46 set HOME [file normalize [file dir $infile]]
47 set in [open $infile rb]
48 puts [subst {/* DO NOT EDIT
50 ** This file was generated by \"$argv0 $infile\".
51 ** To make changes, edit $infile then rerun the generator
52 ** command.
53 */}]
54 set instr 0
55 while {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\""
70 } else {
71 puts [read $in2]
73 puts "/* END $path */"
74 close $in2
75 continue
77 if {[regexp {^BEGIN_STRING} $line]} {
78 set instr 1
79 puts "/* BEGIN_STRING */"
80 continue
82 if {[regexp {^END_STRING} $line]} {
83 set instr 0
84 puts "/* END_STRING */"
85 continue
87 if {$instr} {
88 set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
89 puts "\"$x\\n\""
90 } else {
91 puts $line