/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe:


0000: 23 21 2f 75 73 72 2f 62 69 6e 2f 74 63 6c 73 68  #!/usr/bin/tclsh
0010: 0a 23 0a 23 20 55 73 65 20 74 68 69 73 20 73 63  .#.# Use this sc
0020: 72 69 70 74 20 74 6f 20 62 75 69 6c 64 20 43 2d  ript to build C-
0030: 6c 61 6e 67 75 61 67 65 20 73 6f 75 72 63 65 20  language source 
0040: 63 6f 64 65 20 66 6f 72 20 61 20 70 72 6f 67 72  code for a progr
0050: 61 6d 20 74 68 61 74 20 75 73 65 73 0a 23 20 74  am that uses.# t
0060: 63 6c 73 71 6c 69 74 65 2e 63 20 74 6f 67 65 74  clsqlite.c toget
0070: 68 65 72 20 77 69 74 68 20 63 75 73 74 6f 6d 20  her with custom 
0080: 54 43 4c 20 73 63 72 69 70 74 73 20 61 6e 64 2f  TCL scripts and/
0090: 6f 72 20 43 20 65 78 74 65 6e 73 69 6f 6e 73 20  or C extensions 
00a0: 66 6f 72 0a 23 20 65 69 74 68 65 72 20 53 51 4c  for.# either SQL
00b0: 69 74 65 20 6f 72 20 54 43 4c 2e 0a 23 0a 23 20  ite or TCL..#.# 
00c0: 55 73 61 67 65 20 65 78 61 6d 70 6c 65 3a 0a 23  Usage example:.#
00d0: 0a 23 20 20 20 20 20 74 63 6c 73 68 20 6d 6b 74  .#     tclsh mkt
00e0: 63 6c 73 71 6c 69 74 65 70 72 6f 67 2e 74 63 6c  clsqliteprog.tcl
00f0: 20 64 65 6d 6f 61 70 70 2e 63 2e 69 6e 20 3e 64   demoapp.c.in >d
0100: 65 6d 6f 61 70 70 2e 63 0a 23 0a 23 20 54 68 65  emoapp.c.#.# The
0110: 20 64 65 6d 6f 61 70 70 2e 63 2e 69 6e 20 66 69   demoapp.c.in fi
0120: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 6d 69  le contains a mi
0130: 78 74 75 72 65 20 6f 66 20 43 20 63 6f 64 65 2c  xture of C code,
0140: 20 54 43 4c 20 73 63 72 69 70 74 2c 20 61 6e 64   TCL script, and
0150: 0a 23 20 70 72 6f 63 65 73 73 69 6e 67 20 64 69  .# processing di
0160: 72 65 63 74 69 76 65 73 20 75 73 65 64 20 62 79  rectives used by
0170: 20 6d 6b 74 63 6c 73 71 6c 69 74 65 70 72 6f 67   mktclsqliteprog
0180: 2e 74 63 6c 20 74 6f 20 62 75 69 6c 64 20 74 68  .tcl to build th
0190: 65 20 66 69 6e 61 6c 20 43 2d 63 6f 64 65 0a 23  e final C-code.#
01a0: 20 6f 75 74 70 75 74 20 66 69 6c 65 2e 20 20 4d   output file.  M
01b0: 6f 73 74 20 6c 69 6e 65 73 20 6f 66 20 64 65 6d  ost lines of dem
01c0: 6f 61 70 70 2e 63 2e 69 6e 20 61 72 65 20 63 6f  oapp.c.in are co
01d0: 70 69 65 64 20 73 74 72 61 69 67 68 74 20 74 68  pied straight th
01e0: 72 6f 75 67 68 20 69 6e 74 6f 0a 23 20 74 68 65  rough into.# the
01f0: 20 6f 75 74 70 75 74 2e 20 20 54 68 65 20 66 6f   output.  The fo
0200: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 74 72 6f 6c 20  llowing control 
0210: 64 69 72 65 63 74 69 76 65 73 20 61 72 65 20 72  directives are r
0220: 65 63 6f 67 6e 69 7a 65 64 3a 0a 23 0a 23 20 42  ecognized:.#.# B
0230: 45 47 49 4e 5f 53 54 52 49 4e 47 0a 23 0a 23 20  EGIN_STRING.#.# 
0240: 20 20 20 20 20 54 68 69 73 20 6d 61 72 6b 73 20       This marks 
0250: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66  the beginning of
0260: 20 6c 61 72 67 65 20 73 74 72 69 6e 67 20 6c 69   large string li
0270: 74 65 72 61 6c 20 2d 20 75 73 75 61 6c 6c 79 20  teral - usually 
0280: 61 20 54 43 4c 0a 23 20 20 20 20 20 20 73 63 72  a TCL.#      scr
0290: 69 70 74 20 6f 66 20 73 6f 6d 65 20 6b 69 6e 64  ipt of some kind
02a0: 2e 20 20 53 75 62 73 65 71 75 65 6e 74 20 6c 69  .  Subsequent li
02b0: 6e 65 73 20 6f 66 20 74 65 78 74 20 74 68 72 6f  nes of text thro
02c0: 75 67 68 20 74 68 65 20 66 69 72 73 74 0a 23 20  ugh the first.# 
02d0: 20 20 20 20 20 6c 69 6e 65 20 74 68 61 74 20 62       line that b
02e0: 65 67 69 6e 73 20 77 69 74 68 20 45 4e 44 5f 53  egins with END_S
02f0: 54 52 49 4e 47 20 61 72 65 20 63 6f 6e 76 65 72  TRING are conver
0300: 74 65 64 20 69 6e 74 6f 20 61 20 43 2d 6c 61 6e  ted into a C-lan
0310: 67 75 61 67 65 0a 23 20 20 20 20 20 20 73 74 72  guage.#      str
0320: 69 6e 67 20 6c 69 74 65 72 61 6c 2e 0a 23 0a 23  ing literal..#.#
0330: 20 49 4e 43 4c 55 44 45 20 70 61 74 68 0a 23 0a   INCLUDE path.#.
0340: 23 20 20 20 20 20 20 54 68 65 20 70 61 74 68 20  #      The path 
0350: 61 72 67 75 6d 65 6e 74 20 69 73 20 74 68 65 20  argument is the 
0360: 6e 61 6d 65 20 6f 66 20 61 20 66 69 6c 65 20 74  name of a file t
0370: 6f 20 62 65 20 69 6e 73 65 72 74 65 64 20 69 6e  o be inserted in
0380: 20 70 6c 61 63 65 20 6f 66 0a 23 20 20 20 20 20   place of.#     
0390: 20 74 68 65 20 49 4e 43 4c 55 44 45 20 6c 69 6e   the INCLUDE lin
03a0: 65 2e 20 20 54 68 65 20 70 61 74 68 20 63 61 6e  e.  The path can
03b0: 20 62 65 67 69 6e 20 77 69 74 68 20 24 52 4f 4f   begin with $ROO
03c0: 54 20 74 6f 20 73 69 67 6e 69 66 79 20 74 68 65  T to signify the
03d0: 0a 23 20 20 20 20 20 20 72 6f 6f 74 20 6f 66 20  .#      root of 
03e0: 74 68 65 20 53 51 4c 69 74 65 20 73 6f 75 72 63  the SQLite sourc
03f0: 65 20 74 72 65 65 2c 20 6f 72 20 24 48 4f 4d 45  e tree, or $HOME
0400: 20 74 6f 20 73 69 67 6e 69 66 79 20 74 68 65 20   to signify the 
0410: 64 69 72 65 63 74 6f 72 79 0a 23 20 20 20 20 20  directory.#     
0420: 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
0430: 68 65 20 64 65 6d 6f 61 70 70 2e 63 2e 69 6e 20  he demoapp.c.in 
0440: 69 6e 70 75 74 20 73 63 72 69 70 74 20 69 74 73  input script its
0450: 65 6c 66 2e 20 20 49 66 20 74 68 65 20 70 61 74  elf.  If the pat
0460: 68 20 64 6f 65 73 0a 23 20 20 20 20 20 20 6e 6f  h does.#      no
0470: 74 20 62 65 67 69 6e 20 77 69 74 68 20 65 69 74  t begin with eit
0480: 68 65 72 20 24 52 4f 4f 54 20 6f 72 20 24 48 4f  her $ROOT or $HO
0490: 4d 45 2c 20 74 68 65 6e 20 69 74 20 69 73 20 69  ME, then it is i
04a0: 6e 74 65 72 70 72 65 74 65 64 20 72 65 6c 61 74  nterpreted relat
04b0: 69 76 65 0a 23 20 20 20 20 20 20 74 6f 20 74 68  ive.#      to th
04c0: 65 20 63 75 72 72 65 6e 74 20 77 6f 72 6b 69 6e  e current workin
04d0: 67 20 64 69 72 65 63 74 6f 72 79 2e 0a 23 0a 23  g directory..#.#
04e0: 20 20 20 20 20 20 49 66 20 74 68 65 20 49 4e 43        If the INC
04f0: 4c 55 44 45 20 6f 63 63 75 72 73 20 69 6e 20 74  LUDE occurs in t
0500: 68 65 20 6d 69 64 64 6c 65 20 6f 66 20 42 45 47  he middle of BEG
0510: 49 4e 5f 53 54 52 49 4e 47 2e 2e 2e 45 4e 44 5f  IN_STRING...END_
0520: 53 54 52 49 4e 47 0a 23 20 20 20 20 20 20 74 68  STRING.#      th
0530: 65 6e 20 61 6c 6c 20 6f 66 20 74 68 65 20 74 65  en all of the te
0540: 78 74 20 69 6e 20 74 68 65 20 69 6e 70 75 74 20  xt in the input 
0550: 66 69 6c 65 20 69 73 20 63 6f 6e 76 65 72 74 65  file is converte
0560: 64 20 69 6e 74 6f 20 43 2d 6c 61 6e 67 75 61 67  d into C-languag
0570: 65 0a 23 20 20 20 20 20 20 73 74 72 69 6e 67 20  e.#      string 
0580: 6c 69 74 65 72 61 6c 73 2e 0a 23 0a 23 20 4e 6f  literals..#.# No
0590: 6e 65 20 6f 66 20 74 68 65 20 63 6f 6e 74 72 6f  ne of the contro
05a0: 6c 20 64 69 72 65 63 74 69 76 65 73 20 64 65 73  l directives des
05b0: 63 72 69 62 65 64 20 61 62 6f 76 65 20 77 69 6c  cribed above wil
05c0: 6c 20 6e 65 73 74 2e 20 20 4f 6e 6c 79 20 74 68  l nest.  Only th
05d0: 65 0a 23 20 74 6f 70 2d 6c 65 76 65 6c 20 69 6e  e.# top-level in
05e0: 70 75 74 20 66 69 6c 65 20 28 22 64 65 6d 6f 61  put file ("demoa
05f0: 70 70 2e 63 2e 69 6e 22 20 69 6e 20 74 68 65 20  pp.c.in" in the 
0600: 65 78 61 6d 70 6c 65 29 20 69 73 20 69 6e 74 65  example) is inte
0610: 72 70 72 65 74 65 64 2e 0a 23 20 72 65 66 65 72  rpreted..# refer
0620: 65 6e 63 65 64 20 66 69 6c 65 73 20 61 72 65 20  enced files are 
0630: 63 6f 70 69 65 64 20 76 65 72 62 61 74 69 6d 2e  copied verbatim.
0640: 0a 23 0a 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20  .#.if {[llength 
0650: 24 61 72 67 76 5d 21 3d 31 7d 20 7b 0a 20 20 70  $argv]!=1} {.  p
0660: 75 74 73 20 73 74 64 65 72 72 20 22 55 73 61 67  uts stderr "Usag
0670: 65 3a 20 24 61 72 67 76 30 20 54 45 4d 50 4c 41  e: $argv0 TEMPLA
0680: 54 45 20 3e 4f 55 54 50 55 54 22 0a 20 20 65 78  TE >OUTPUT".  ex
0690: 69 74 20 31 0a 7d 0a 73 65 74 20 69 6e 66 69 6c  it 1.}.set infil
06a0: 65 20 5b 6c 69 6e 64 65 78 20 24 61 72 67 76 20  e [lindex $argv 
06b0: 30 5d 0a 73 65 74 20 52 4f 4f 54 20 5b 66 69 6c  0].set ROOT [fil
06c0: 65 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b 66 69 6c  e normalize [fil
06d0: 65 20 64 69 72 20 24 61 72 67 76 30 5d 2f 2e 2e  e dir $argv0]/..
06e0: 5d 0a 73 65 74 20 48 4f 4d 45 20 5b 66 69 6c 65  ].set HOME [file
06f0: 20 6e 6f 72 6d 61 6c 69 7a 65 20 5b 66 69 6c 65   normalize [file
0700: 20 64 69 72 20 24 69 6e 66 69 6c 65 5d 5d 0a 73   dir $infile]].s
0710: 65 74 20 69 6e 20 5b 6f 70 65 6e 20 24 69 6e 66  et in [open $inf
0720: 69 6c 65 20 72 62 5d 0a 70 75 74 73 20 5b 73 75  ile rb].puts [su
0730: 62 73 74 20 7b 2f 2a 20 44 4f 20 4e 4f 54 20 45  bst {/* DO NOT E
0740: 44 49 54 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66  DIT.**.** This f
0750: 69 6c 65 20 77 61 73 20 67 65 6e 65 72 61 74 65  ile was generate
0760: 64 20 62 79 20 5c 22 24 61 72 67 76 30 20 24 69  d by \"$argv0 $i
0770: 6e 66 69 6c 65 5c 22 2e 0a 2a 2a 20 54 6f 20 6d  nfile\"..** To m
0780: 61 6b 65 20 63 68 61 6e 67 65 73 2c 20 65 64 69  ake changes, edi
0790: 74 20 24 69 6e 66 69 6c 65 20 74 68 65 6e 20 72  t $infile then r
07a0: 65 72 75 6e 20 74 68 65 20 67 65 6e 65 72 61 74  erun the generat
07b0: 6f 72 0a 2a 2a 20 63 6f 6d 6d 61 6e 64 2e 0a 2a  or.** command..*
07c0: 2f 7d 5d 0a 73 65 74 20 69 6e 73 74 72 20 30 0a  /}].set instr 0.
07d0: 77 68 69 6c 65 20 7b 31 7d 20 7b 0a 20 20 73 65  while {1} {.  se
07e0: 74 20 6c 69 6e 65 20 5b 67 65 74 73 20 24 69 6e  t line [gets $in
07f0: 5d 0a 20 20 69 66 20 7b 5b 65 6f 66 20 24 69 6e  ].  if {[eof $in
0800: 5d 7d 20 62 72 65 61 6b 0a 20 20 69 66 20 7b 5b  ]} break.  if {[
0810: 72 65 67 65 78 70 20 7b 5e 49 4e 43 4c 55 44 45  regexp {^INCLUDE
0820: 20 28 2e 2a 29 7d 20 24 6c 69 6e 65 20 61 6c 6c   (.*)} $line all
0830: 20 70 61 74 68 5d 7d 20 7b 0a 20 20 20 20 72 65   path]} {.    re
0840: 67 73 75 62 20 7b 5e 5c 24 52 4f 4f 54 5c 79 7d  gsub {^\$ROOT\y}
0850: 20 24 70 61 74 68 20 24 52 4f 4f 54 20 70 61 74   $path $ROOT pat
0860: 68 0a 20 20 20 20 72 65 67 73 75 62 20 7b 5e 5c  h.    regsub {^\
0870: 24 48 4f 4d 45 5c 79 7d 20 24 70 61 74 68 20 24  $HOME\y} $path $
0880: 48 4f 4d 45 20 70 61 74 68 0a 20 20 20 20 73 65  HOME path.    se
0890: 74 20 69 6e 32 20 5b 6f 70 65 6e 20 24 70 61 74  t in2 [open $pat
08a0: 68 20 72 62 5d 0a 20 20 20 20 70 75 74 73 20 22  h rb].    puts "
08b0: 2f 2a 20 49 4e 43 4c 55 44 45 20 24 70 61 74 68  /* INCLUDE $path
08c0: 20 2a 2f 22 0a 20 20 20 20 69 66 20 7b 24 69 6e   */".    if {$in
08d0: 73 74 72 7d 20 7b 0a 20 20 20 20 20 20 77 68 69  str} {.      whi
08e0: 6c 65 20 7b 31 7d 20 7b 0a 20 20 20 20 20 20 20  le {1} {.       
08f0: 20 73 65 74 20 6c 69 6e 65 20 5b 67 65 74 73 20   set line [gets 
0900: 24 69 6e 32 5d 0a 20 20 20 20 20 20 20 20 69 66  $in2].        if
0910: 20 7b 5b 65 6f 66 20 24 69 6e 32 5d 7d 20 62 72   {[eof $in2]} br
0920: 65 61 6b 0a 20 20 20 20 20 20 20 20 73 65 74 20  eak.        set 
0930: 78 20 5b 73 74 72 69 6e 67 20 6d 61 70 20 22 5c  x [string map "\
0940: 5c 5c 5c 20 5c 5c 5c 5c 5c 5c 5c 5c 20 5c 5c 5c  \\\ \\\\\\\\ \\\
0950: 22 20 5c 5c 5c 5c 5c 22 22 20 24 6c 69 6e 65 5d  " \\\\\"" $line]
0960: 0a 20 20 20 20 20 20 20 20 70 75 74 73 20 22 5c  .        puts "\
0970: 22 24 78 5c 5c 6e 5c 22 22 0a 20 20 20 20 20 20  "$x\\n\"".      
0980: 7d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20  }.    } else {. 
0990: 20 20 20 20 20 70 75 74 73 20 5b 72 65 61 64 20       puts [read 
09a0: 24 69 6e 32 5d 0a 20 20 20 20 7d 0a 20 20 20 20  $in2].    }.    
09b0: 70 75 74 73 20 22 2f 2a 20 45 4e 44 20 24 70 61  puts "/* END $pa
09c0: 74 68 20 2a 2f 22 0a 20 20 20 20 63 6c 6f 73 65  th */".    close
09d0: 20 24 69 6e 32 0a 20 20 20 20 63 6f 6e 74 69 6e   $in2.    contin
09e0: 75 65 0a 20 20 7d 0a 20 20 69 66 20 7b 5b 72 65  ue.  }.  if {[re
09f0: 67 65 78 70 20 7b 5e 42 45 47 49 4e 5f 53 54 52  gexp {^BEGIN_STR
0a00: 49 4e 47 7d 20 24 6c 69 6e 65 5d 7d 20 7b 0a 20  ING} $line]} {. 
0a10: 20 20 20 73 65 74 20 69 6e 73 74 72 20 31 0a 20     set instr 1. 
0a20: 20 20 20 70 75 74 73 20 22 2f 2a 20 42 45 47 49     puts "/* BEGI
0a30: 4e 5f 53 54 52 49 4e 47 20 2a 2f 22 0a 20 20 20  N_STRING */".   
0a40: 20 63 6f 6e 74 69 6e 75 65 0a 20 20 7d 0a 20 20   continue.  }.  
0a50: 69 66 20 7b 5b 72 65 67 65 78 70 20 7b 5e 45 4e  if {[regexp {^EN
0a60: 44 5f 53 54 52 49 4e 47 7d 20 24 6c 69 6e 65 5d  D_STRING} $line]
0a70: 7d 20 7b 0a 20 20 20 20 73 65 74 20 69 6e 73 74  } {.    set inst
0a80: 72 20 30 0a 20 20 20 20 70 75 74 73 20 22 2f 2a  r 0.    puts "/*
0a90: 20 45 4e 44 5f 53 54 52 49 4e 47 20 2a 2f 22 0a   END_STRING */".
0aa0: 20 20 20 20 63 6f 6e 74 69 6e 75 65 0a 20 20 7d      continue.  }
0ab0: 0a 20 20 69 66 20 7b 24 69 6e 73 74 72 7d 20 7b  .  if {$instr} {
0ac0: 0a 20 20 20 20 73 65 74 20 78 20 5b 73 74 72 69  .    set x [stri
0ad0: 6e 67 20 6d 61 70 20 22 5c 5c 5c 5c 20 5c 5c 5c  ng map "\\\\ \\\
0ae0: 5c 5c 5c 5c 5c 20 5c 5c 5c 22 20 5c 5c 5c 5c 5c  \\\\\ \\\" \\\\\
0af0: 22 22 20 24 6c 69 6e 65 5d 0a 20 20 20 20 70 75  "" $line].    pu
0b00: 74 73 20 22 5c 22 24 78 5c 5c 6e 5c 22 22 0a 20  ts "\"$x\\n\"". 
0b10: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 70 75   } else {.    pu
0b20: 74 73 20 24 6c 69 6e 65 0a 20 20 7d 0a 7d 0a     ts $line.  }.}.