File size: 4,744 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
#!/usr/bin/tclsh
#
# Run this script to generate the "shell.c" source file from
# constituent parts.
#
# No arguments are required. This script determines the location
# of its input files relative to the location of the script itself.
# This script should be tool/mkshellc.tcl. If the directory holding
# the script is $DIR, then the component parts are located in $DIR/../src
# and $DIR/../ext/misc.
#
set topdir [file dir [file dir [file normal $argv0]]]
set out stdout
fconfigure stdout -translation binary
if {[lindex $argv 0]!=""} {
set output_file [lindex $argv 0]
file delete -force $output_file
set out [open $output_file wb]
} else {
set output_file {}
}
############################## FIRST PASS ################################
# Read through the shell.c.in source file to gather information. Do not
# yet generate any code
#
set in [open $topdir/src/shell.c.in]
fconfigure $in -translation binary
set allSource(src/shell.c.in) 1
set inUsage 0
set dotcmd {}
while {1} {
set lx [gets $in]
if {[eof $in]} break;
if {[regexp {^INCLUDE } $lx]} {
set cfile [lindex $lx 1]
if {[string match ../* $cfile]} {
set xfile [string range $cfile 3 end]
} else {
set xfile "src/$cfile"
}
set allSource($xfile) 1
} elseif {[regexp {^\*\* USAGE:\s+([^\s]+)} $lx all dotcmd]} {
set inUsage 1
set details [string trim [string range $lx 2 end]]
} elseif {$inUsage} {
if {![regexp {^\*\*} $lx] || [regexp { DOT-COMMAND: } $lx]} {
set inUsage 0
set Usage($dotcmd) [string trim $details]
} else {
append details \n
append details [string range [string trimright $lx] 3 end]
}
}
}
# Generate dot-command usage text based on the data accumulated in
# the Usage() array.
#
proc generate_usage {out} {
global Usage
puts $out "/**************************************************************"
puts $out "** \"Usage\" help text automatically generated from comments */"
puts $out "static const struct \173"
puts $out " const char *zCmd; /* Name of the dot-command */"
puts $out " const char *zUsage; /* Documentation */"
puts $out "\175 aUsage\[\] = \173"
foreach dotcmd [array names Usage] {
puts $out " \173 \"$dotcmd\","
foreach line [split $Usage($dotcmd) \n] {
set x [string map [list \\ \\\\ \" \\\"] $line]
puts $out "\"$x\\n\""
}
puts $out " \175,"
}
puts $out "\175;"
}
# generate_usage stderr
###### SECOND PASS #######
# Make a second pass through shell.c.in to generate the the final
# output, based on data gathered during the first pass.
#
puts $out {/*
** This is the amalgamated source code to the "sqlite3" or "sqlite3.exe"
** command-line shell (CLI) for SQLite. This file is automatically
** generated by the tool/mkshellc.tcl script from the following sources:
**}
foreach fn [lsort [array names allSource]] {
puts $out "** $fn"
}
puts $out {**
** To modify this program, get a copy of the canonical SQLite source tree,
** edit the src/shell.c.in file and/or some of the other files that are
** listed above, then rerun the rerun "make shell.c".
*/}
seek $in 0 start
puts $out "/************************* Begin src/shell.c.in ******************/"
proc omit_redundant_typedefs {line} {
global typedef_seen
if {[regexp {^typedef .* ([a-zA-Z0-9_]+);} $line all typename]} {
# --------------------\y jimtcl does not support \y
if {[info exists typedef_seen($typename)]} {
return "/* [string map {/* // */ //} $line] */"
}
set typedef_seen($typename) 1
}
return $line
}
set iLine 0
while {1} {
set lx [omit_redundant_typedefs [gets $in]]
if {[eof $in]} break;
incr iLine
if {[regexp {^INCLUDE } $lx]} {
set cfile [lindex $lx 1]
if {[string match ../* $cfile]} {
set xfile [string range $cfile 3 end]
} else {
set xfile "src/$cfile"
}
puts $out "/************************* Begin $xfile ******************/"
# puts $out "#line 1 \"$xfile\""
set in2 [open $topdir/$xfile]
fconfigure $in2 -translation binary
while {![eof $in2]} {
set lx [omit_redundant_typedefs [gets $in2]]
if {[regexp {^# *include "sqlite} $lx]} {
set lx "/* $lx */"
}
if {[regexp {^# *include "windirent.h"} $lx]} {
set lx "/* $lx */"
}
set lx [string map [list __declspec(dllexport) {}] $lx]
puts $out $lx
}
close $in2
puts $out "/************************* End $xfile ********************/"
# puts $out "#line [expr $iLine+1] \"shell.c.in\""
} elseif {[regexp {^INSERT-USAGE-TEXT-HERE} $lx]} {
generate_usage $out
} else {
puts $out $lx
}
}
puts $out "/************************* End src/shell.c.in ******************/"
close $in
close $out
|