- C Manual\smerge\sof\snew\s.connection\sshell\scommand
- D 2021-07-26T01:35:47.674
-C Recognize\scertain\sstandard\sdatatypes\s("INT",\s"INTEGER",\s"REAL",\s"TEXT",\sand\n"BLOB")\sand\sif\sa\scolumn\shas\sone\sof\sthose\sdatatypes,\sstore\sthe\stype\spart\sof\nthe\sbit-field\sinformation\sin\sthe\sColumn\sstructure\sto\ssave\sspace.
-D 2021-07-30T23:30:30.921
++C Sync\sto\strunk
++D 2021-07-31T19:37:56.008
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/prepare.c 0d53d20532aada295c1690792a125adbd6435f5ce703ff0adf1b9b3605238b67
F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
- F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81
+ F src/resolve.c 047a822844cea769f6fdd8418a335dd4bcd8b75ab5e264f2506a0804f869b562
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
- F src/select.c 4fa607bab6bcc580f12dbaf9c800b2250a1e408f10321a1d3bcb1dd30c447e62
+ F src/select.c 99c36dd4e7c2207ebdfd8c30986ab5aaeae74d0cdbbc471420807d50c417c241
-F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e3
+F src/shell.c.in fbc62e5ac7f79dd5f31fcd4ca719bc9cc959e147ae8fbb8630883a250a539b54
- F src/sqlite.h.in ecf5aa981da30c33da3e9f353bf3ebf055d3c380c80d6a4f954e58d18ccd6df1
+ F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
- F src/sqliteInt.h fccf952bd572fe52f3bd2928982bd80933308c1118fdde27f667d0de7c77fb30
+ F src/sqliteInt.h e2fbf849a7e0ee1842a4775952a61c966f9eb25075297dd2f3aff5b5e4418415
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
- F tool/mkctimec.tcl 06b0d503ee0e6c2d4abe83563b43d4925a12e31ec9fb3249ce39661f53fbd1ce
+ F tool/mkctimec.tcl 5ef1891ed3d0e8143ff39bad7c01ed60c2817a2fb2d9a09487f7ccad2df621e4
F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c
F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33
- F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
+ F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
- F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1
- F tool/mkshellc.tcl ba339f8c33d7588cfe40243148de015f5a235c34a402d9a526df922b3f48ad1d
+ F tool/mkpragmatab.tcl 7f6db47d1995bc08247255622524567b2ab8962d98063f8aef97e35c3c54e3b8
-F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e89450
++F tool/mkshellc.tcl 16236d081adb274a95ed424fde56cd0d535fb2c659128ecc5b70becd4a9b63b8
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P 7738ce1b2b97fa29125ed8391670cda9343b87a476ad01f4421fea30e0d4dfe1
- R e40233741ba2186d11491dc0171c1a99
-P 3c954863f45271a3518acf51fd685a641878811fb5cfcbdbad85154aeccdc902
-R 6b5f2c664834813a7df89f39b77ebda9
-U drh
-Z 12d963d3ccf8007e48d95666e4982a9e
++P 0d41f7f93c273cd2d0b92269ac1705f66daefa4eb7c24ed8f3662ef45a5397f9 d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f
++R 59d1873fa96dbc489fa2d2a6c0fc8066
+U larrybr
- Z d7243f2870d6870902d201b4510ac8d9
++Z d73f10d55ae7d3c2f75b743673dac0f0
** Most of the code found below comes from the "src/shell.c.in" file in
** the canonical SQLite source tree. That main file contains "INCLUDE"
** lines that specify other files in the canonical source tree that are
-** inserted to getnerate this complete program source file.
+** inserted and transformed, (via macro invocations explained by running
+** "tool/mkshellc.tcl --help"), to generate this complete program source.
**
-** The code from multiple files is combined into this single "shell.c"
-** source file to help make the command-line program easier to compile.
+** By means of this generation process, creating this single "shell.c"
+** file, building the command-line program is made simpler and easier.
**
** To modify this program, get a copy of the canonical SQLite source tree,
-** edit the src/shell.c.in" and/or some of the other files that are included
-** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
+** edit file src/shell.c.in and/or some of the other files included by it,
+** then rerun the tool/mkshellc.tcl script.
*/}
-set in [open $topdir/src/shell.c.in]
+
+set customRun 0
+set lineDirectives 1
+set infiles {}
+array set ::incTypes [list "*" {}]
+
+while {[llength $argv] > 0} {
+ set argv [lassign $argv opt]
+ if {[regexp {^-{1,2}((help)|(details)|(parameters))$} $opt ma ho]} {
+ switch $ho {
+ help {set customRun 2}
+ details {set customRun 3}
+ parameters {set customRun 4}
+ }
+ } elseif {[regexp {^-it$} $opt]} {
+ set argv [lassign $argv nextOpt]
+ if {![regexp {^(\w+)=(.+)$} $nextOpt ma k v]} {
+ puts stderr "Get help with --help."
+ exit 1
+ }
+ set ::incTypes($k) $v
+ } elseif {$opt eq "-tcl"} {
+ puts stderr "Tcl extension not yet implemented." ; exit 1
+ } elseif {[regexp {^--?no-line-directives$} $opt]} {
+ set lineDirectives 0
+ } elseif {[regexp {^[^-]} $opt]} {
+ lappend infiles $opt
+ set customRun 1
+ } else {
+ puts stderr "Skipping unknown option: $opt"
+ }
+}
+if {[llength $infiles] == 0} {
- set in [open $topdir/src/shell.c.in rb]
++ set in [open $topdir/src/shell.c.in]
+} else {
+ set infiles [lassign $infiles infile]
- set in [open $infile rb]
++ set in [open $infile]
+}
+ fconfigure $in -translation binary
-proc omit_redundant_typedefs {line} {
+
+set ::cmd_help [dict create]
+set ::cmd_dispatch [dict create]
+set ::cmd_condition [dict create]
+set ::inc_type_files [dict create]
+set ::iShuffleErrors 0
+regexp {(\{)(\})} "{}" ma ::lb ::rb ; # Ease use of { and }.
+
+# Setup dispatching function signature and table entry struct .
+# The effect of these key/value pairs is as this --parameters output says:
+set ::parametersHelp {
+ The following parameters given to DISPATCH_CONFIG have these effects:
+ RETURN_TYPE sets the generated dispatchable function signature return type.
+ STORAGE_CLASS sets the dispatchable function linkage, (typically "static".)
+ ARGS_SIGNATURE sets the formal argument list for the dispatchable functions.
+ DISPATCH_ENTRY sets the text of each entry line in emitted dispatch table.
+ DISPATCHEE_NAME sets the name to be generated for dispatchable functions.
+ CMD_CAPTURE_RE sets a regular expression to be used for capturing the name
+ to be used for meta-commands within a line passed into COLLECT_DISPATCH,
+ (which is needed to permit them to be emitted in lexical order by name.)
+ DC_ARG_COUNT sets the effective argument count for DISPATCHABLE_COMMAND().
+ DC_ARG#_DEFAULT sets a default value, DISPATCHABLE_COMMAND() #'th argument.
+ Within values set for ARGS_SIGNATURE, DISPATCHEE_NAME, and DISPATCH_ENTRY
+ parameters, the variables $cmd and $arg# (where # is an integer) may appear,
+ to be replaced by the meta-command name or the #'th effective argument to
+ DISPATCHABLE_COMMAND(). The "effective" argument is either what is provided,
+ or a default value when the actual argument is missing (at the right end of
+ the provided argument list) or the argument has the value ? . The expansion
+ of $cmd and $arg# variables is done by Tcl evaluation (via subst), allowing
+ a wide range of logic to be employed in the derivation of effective values.
+}
+set ::dispCfg [dict create \
+ RETURN_TYPE int \
+ STORAGE_CLASS static \
+ ARGS_SIGNATURE "char *\$arg4\\\[\\\], int \$arg5, ShellState *\$arg6" \
+ DISPATCH_ENTRY \
+ "{ \"\$cmd\", \${cmd}Command, \$arg1,\$arg2,\$arg3 }," \
+ DISPATCHEE_NAME {${cmd}Command} \
+ CMD_CAPTURE_RE "^\\s*$::lb\\s*\"(\\w+)\"" \
+]
+# Other config keys:
+# DC_ARG_COUNT=<number of arguments to DISPATCHABLE_COMMAND()>
+# DC_ARG#_DEFAULT=<default value for the #th argument>
+# Variables $cmd and $arg# (where # = 0 .. DC_ARG_COUNT-1) have values
+# when ARGS_SIGNATURE, DISPATCH_ENTRY, and DISPATCHEE_NAME are evaluated.
+
+# proc dump_cfg {} {
+# foreach k [dict keys $::dispCfg] {
+# puts stderr "$k=[dict get $::dispCfg $k]"
+# }
+# }
+
+proc condition_command {cmd pp_expr} {
+ if {[regexp {^(!)?defined\(\s*(\w+)\s*\)} $pp_expr ma bang pp_var]} {
+ if {$bang eq "!"} {
+ set pp_expr "#ifndef $pp_var"
+ } else {
+ set pp_expr "#ifdef $pp_var"
+ }
+ } else {
+ set pp_expr "#if [string trim $pp_expr]"
+ }
+ dict set ::cmd_condition $cmd $pp_expr
+}
+
+proc emit_conditionally {cmd lines ostrm {indent ""}} {
+ set wrapped [dict exists $::cmd_condition $cmd]
+ if {$wrapped} {
+ puts $ostrm [dict get $::cmd_condition $cmd]
+ }
+ if {[regexp {^\s*(\d+)\s*$} $indent ma inum]} {
+ set lead [string repeat " " $inum]
+ foreach line $lines {
+ puts $ostrm "$lead[string trimleft $line]"
+ }
+ } else {
+ puts $ostrm [join $lines "\n"]
+ }
+ if {$wrapped} {
+ puts $ostrm "#endif"
+ }
+}
+
+# Convert list of help text lines into a dict.
+# Keys are the command names. Values are the help for the
+# commands as a list of lines, with .* logically first.
+# Any #if... #endif structures are maintained and do not
+# interact with "logically first" .* lines, except that
+# only one such line is seen within such a conditional.
+# (The effect of this is to defeat sorting by command if
+# help for multiple commands' is within one conditional.)
+proc chunkify_help {htin} {
+ set rv [dict create]
+ set if_depth 0
+ set cmd_seen ""
+ set chunk {}
+ foreach htx $htin {
+ if {[regexp {^\s*\"\.\w} $htx] && $cmd_seen ne "" && $if_depth == 0} {
+ # Flush accumulated chunk.
+ dict set rv $cmd_seen $chunk
+ set cmd_seen ""
+ set chunk {}
+ }
+ lappend chunk $htx
+ if {[regexp {^\s*#if} $htx]} {
+ incr if_depth
+ } elseif {[regexp {^\s*#endif} $htx]} {
+ incr if_depth -1
+ } else {
+ if {[regexp {^\s*\"\.(\w+)} $htx all cmd] && $cmd_seen eq ""} {
+ set cmd_seen $cmd
+ }
+ }
+ }
+ if {$if_depth != 0} {
+ puts stderr "Help chunk bad #conditional:"
+ puts stderr [join $htin "\n"]
+ puts stderr "Swallowed [join $chunk \n]"
+ incr ::iShuffleErrors
+ } else {
+ if {$cmd_seen ne "" && [llength $chunk] > 0} {
+ # Flush accumulated chunk.
+ dict set rv $cmd_seen $chunk
+ } elseif {$cmd_seen ne "" || [llength $chunk] > 0} {
+ puts stderr "Orphaned help: '$cmd_seen' [join $chunk \n]"
+ incr ::iShuffleErrors
+ }
+ }
+ return $rv
+}
+
+array set ::macroTailREs [list \
+ COLLECT_DISPATCH {^\(\s*([\w\*]+)\s*\)\[} \
+ COLLECT_HELP_TEXT {^\[} \
+ COMMENT {\s+(.*)$} \
+ CONDITION_COMMAND {^\(\s*(\w+)\s+([^;]+)\);} \
+ DISPATCH_CONFIG {^\[} \
+ DISPATCHABLE_COMMAND {^\(([\w\? ]+)\)(\S)\s*$} \
+ EMIT_DISPATCH {^\((\d*)\)} \
+ EMIT_HELP_TEXT {^\((\d*)\)} \
+ INCLUDE {^\(\s*(\w+)\s*\)} \
+]
+array set ::macroUsages [list \
+ COLLECT_DISPATCH "\[\n <dispatch table entry lines>\n \];" \
+ COLLECT_HELP_TEXT "\[\n <help text lines>\n \];" \
+ COMMENT " <arbitrary characters to end of line>" \
+ CONDITION_COMMAND "( name pp_expr );" \
+ DISPATCH_CONFIG "\[\n <NAME=value lines>\n \];" \
+ DISPATCHABLE_COMMAND "( name args... ){\n <implementation code lines>\n }" \
+ EMIT_DISPATCH "( indent );" \
+ EMIT_HELP_TEXT "( indent );" \
+ INCLUDE {( <inc_type> )} \
+]
+# RE for early discard of non-macro lines, matching all above keywords
+set ::macroKeywordTailRE {^\s{0,8}((?:(?:CO)|(?:DI)|(?:EM)|(?:IN))[A-Z_]+)\M(.+)$}
+
+# All macro processor procs return the count of extra input lines consumed.
+
+proc COLLECT_DISPATCH {hFile tailCapture ostrm} {
+ # Collect dispatch table entries, along with ordering info.
+ set iAte 0
+ set cmd [lindex $tailCapture 0]
+ set lx [gets $hFile]
+ while {![eof $hFile] && ![regexp {^\s*\];} $lx]} {
+ lappend disp_frag $lx
+ set grabCmd [dict get $::dispCfg CMD_CAPTURE_RE]
+ if {![regexp $grabCmd $lx ma dcmd]} {
+ puts stderr "malformed dispatch element:\n $lx"
+ incr ::iShuffleErrors
+ } elseif {$cmd ne "*" && $dcmd ne $cmd} {
+ puts stderr "misdeclared dispatch element:\n $lx"
+ incr ::iShuffleErrors
+ } else {
+ dict set ::cmd_dispatch $dcmd [list $lx]
+ }
+ set lx [gets $hFile]
+ incr iAte
+ }
+ incr iAte
+ return $iAte
+}
+
+proc COMMENT {hFile tailCaptureIgnore ostrm} {
+ # Allow comments in an input file which have no effect on output.
+ return 1
+}
+
+proc INCLUDE {hFile tailCaptureIncType ostrm} {
+ # If invoked with a bare filename, include the named file. If invoked
+ # with the parenthesized word form, include a file named by means of
+ # the '-it <inc_type>=filename' command line option, provided that the
+ # word matches a specified <inc_type>. Otherwise, do nothing.
+ set it [lindex $tailCaptureIncType 0]
+ if {[regexp {\s*([a-zA-Z\._\\/]+)\s*} $it ma it]} {
+ if {[info exists ::incTypes($it)]} {
+ set fname $::incTypes($it)
+ puts $ostrm "/* INCLUDE($it), of \"$fname\" skipped. */"
+ # ToDo: Get including done with a proc so it can be done from here.
+ # This will support emitting #line directives to aid debugging.
+ }
+ }
+ return 1
+}
+
+proc COLLECT_HELP_TEXT {hFile tailCaptureEmpty ostrm} {
+ # Collect help text table values, along with ordering info.
+ set iAte 0
+ set help_frag {}
+ set lx [gets $hFile]
+ while {![eof $hFile] && ![regexp {^\s*\];} $lx]} {
+ lappend help_frag $lx
+ set lx [gets $hFile]
+ incr iAte
+ }
+ incr iAte
+ set ::cmd_help [dict merge $::cmd_help [chunkify_help $help_frag]]
+ return $iAte
+}
+
+proc CONDITION_COMMAND {hFile tailCap ostrm} {
+ # Name a command to be conditionally available, with the condition.
+ condition_command [lindex $tailCap 0] [string trim [lindex $tailCap 1]]
+ return 0
+}
+
+proc DISPATCH_CONFIG {hFile tailCaptureEmpty ostrm} {
+ # Set parameters affecting generated dispatchable command function
+ # signatures and generated dispatch table entries.
+ set iAte 0
+ set def_disp {}
+ set lx [gets $hFile]
+ while {![eof $hFile] && ![regexp {^\s*\];} $lx]} {
+ lappend def_disp $lx
+ set lx [gets $hFile]
+ incr iAte
+ }
+ incr iAte
+ foreach line $def_disp {
+ if {[regexp {^\s*(\w+)=(.+)$} $line ma k v]} {
+ dict set ::dispCfg $k $v
+ }
+ }
+ return $iAte
+}
+
+proc DISPATCHABLE_COMMAND {hFile tailCapture ostrm} {
+ # Generate and emit a function definition, maybe wrapped as set by
+ # CONDITION_COMMAND(), and generate/collect its dispatch table entry,
+ # as determined by its actual arguments and DISPATCH_CONFIG parameters.
+ lassign $tailCapture args tc
+ if {$tc ne $::lb} {
+ yap_usage "DISPATCHABLE_COMMAND($args)$tc" DISPATCHABLE_COMMAND
+ incr $::iShuffleErrors
+ return 0
+ }
+ set iAte 0
+ set args [split [regsub {\s+} [string trim $args] " "]]
+ incr iAte
+ set na [llength $args]
+ set cmd [lindex $args 0]
+ set naPass [dict get $::dispCfg DC_ARG_COUNT]
+ if {$na > $naPass} {
+ puts stderr "Bad args: $lx"
+ } else {
+ while {$na < $naPass} {
+ if {![dict exists $::dispCfg "DC_ARG${na}_DEFAULT"]} {
+ puts stderr "Too few args: $lx (need $naPass)"
+ incr ::iShuffleErrors
+ break
+ } else {
+ lappend args [subst [dict get $::dispCfg "DC_ARG${na}_DEFAULT"]]
+ }
+ incr na
+ }
+ set body {}
+ while {![eof $hFile]} {
+ set bl [gets $hFile]
+ incr iAte
+ lappend body $bl
+ if {[regexp "^$::rb\\s*\$" $bl]} { break }
+ }
+ for {set aix 1} {$aix < $na} {incr aix} {
+ set av [lindex $args $aix]
+ if {$av eq "?"} {
+ set ai [expr {$aix + 1}]
+ set av [subst [dict get $::dispCfg "DC_ARG${ai}_DEFAULT"]]
+ }
+ set "arg$aix" $av
+ }
+ if {$cmd ne "?"} {
+ set rsct [dict get $::dispCfg STORAGE_CLASS]
+ set rsct "$rsct [dict get $::dispCfg RETURN_TYPE]"
+ set argexp [subst [dict get $::dispCfg ARGS_SIGNATURE]]
+ set fname [subst [dict get $::dispCfg DISPATCHEE_NAME]]
+ set funcOpen "$rsct $fname\($argexp\)$::lb"
+ set dispEntry [subst [dict get $::dispCfg DISPATCH_ENTRY]]
+ emit_conditionally $cmd [linsert $body 0 $funcOpen] $ostrm
+ dict set ::cmd_dispatch $cmd [list $dispEntry]
+ }
+ }
+ return $iAte
+}
+
+proc EMIT_DISPATCH {hFile tailCap ostrm} {
+ # Emit the collected dispatch table entries, in command order, maybe
+ # wrapped with a conditional construct as set by CONDITION_COMMAND().
+ foreach cmd [lsort [dict keys $::cmd_dispatch]] {
+ emit_conditionally $cmd [dict get $::cmd_dispatch $cmd] $ostrm $tailCap
+ }
+ return 0
+}
+
+proc EMIT_HELP_TEXT {hFile tailCap ostrm} {
+ # Emit the collected help text table entries, in command order, maybe
+ # wrapped with a conditional construct as set by CONDITION_COMMAND().
+ foreach htc [lsort [dict keys $::cmd_help]] {
+ emit_conditionally $htc [dict get $::cmd_help $htc] $ostrm $tailCap
+ }
+ return 0
+}
+
+proc say_usage {macros {extra {}}} {
+ puts stderr "Usage:$extra"
+ foreach m $macros {puts stderr " $m$::macroUsages($m)"}
+}
+proc yap_usage {got macro} {
+ puts stderr "Bad macro use: $got"
+ say_usage $macro
+}
+
+# Perform any input collection or deferred output emits.
+# This function may consume additional lines via hFile.
+# Return number of lines absorbed. A 0 return means the
+# input line lx had no meaning to the shuffle processing,
+# in which case it is emitted as-is.
+proc do_shuffle {hFile lx ostrm} {
+ set iAte 0
+ if {![regexp $::macroKeywordTailRE $lx ma macro tail] \
+ || ![info exists ::macroTailREs($macro)]} {
+ puts $ostrm $lx
+ } else {
+ # It's an attempted macro invocation line. Process or fail and yap.
+ incr iAte ; # Eat the macro and whatever it swallows (if invoked).
+ set tailCap [regexp -inline $::macroTailREs($macro) $tail]
+ if {[llength $tailCap]>0} {
+ # Call like-named proc with any args captured by the corresponding RE.
+ incr iAte [$macro $hFile [lrange $tailCap 1 end] $ostrm]
+ } else {
+ # ToDo: complain
+ incr $::iShuffleErrors
+ }
+ }
+ return $iAte
+}
+
+# Filter redundant typedefs and certain includes and qualifiers.
+proc transform_line {line nesting} {
global typedef_seen
if {[regexp {^typedef .*;} $line]} {
if {[info exists typedef_seen($line)]} {