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