mirror of
https://github.com/sqlite/sqlite.git
synced 2025-12-21 13:38:01 +03:00
implementations into the CLI ".help" command output. FossilOrigin-Name: 046bfab4a01e8a7cc58d1bdf0756c90ba354562d79e5453c08202daf648e76a6
159 lines
4.9 KiB
Tcl
159 lines
4.9 KiB
Tcl
#!/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
|
|
|
|
# Try to disable write permissions on the generate file, to prevent
|
|
# accidentally editing the generated file rather than source files.
|
|
#
|
|
if {$output_file ne ""} {
|
|
catch {file attributes $output_file -readonly 1}
|
|
catch {file attributes $output_file -permissions -w}
|
|
catch {exec chmod -w $output_file}
|
|
}
|