From: larrybr Date: Sat, 31 Jul 2021 19:37:56 +0000 (+0000) Subject: Sync to trunk X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad4e9155ee010558f5c8b1e85aa6ccbb117565a0;p=thirdparty%2Fsqlite.git Sync to trunk FossilOrigin-Name: d449941b81a796fa30382bd00e88dc744a6745dc3d5a0eb8377aa90e4966a391 --- ad4e9155ee010558f5c8b1e85aa6ccbb117565a0 diff --cc manifest index 1eedcbe2b5,e3ec8ecc4f..8126f7423b --- a/manifest +++ b/manifest @@@ -1,5 -1,5 +1,5 @@@ - 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 @@@ -542,14 -542,14 +542,14 @@@ F src/pragma.h a11b4798f9c49f156f130e1f 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 @@@ -1846,14 -1847,14 +1847,14 @@@ F tool/max-limits.c cbb635fbb37ae4d05f2 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 @@@ -1919,7 -1920,7 +1920,7 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9 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 diff --cc manifest.uuid index 72eafa7ff7,639f1a3b26..ce080aaab1 --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - 0d41f7f93c273cd2d0b92269ac1705f66daefa4eb7c24ed8f3662ef45a5397f9 -d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f ++d449941b81a796fa30382bd00e88dc744a6745dc3d5a0eb8377aa90e4966a391 diff --cc tool/mkshellc.tcl index a581dc6827,82ecd2f61a..0a5c0ad739 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@@ -22,411 -21,18 +22,412 @@@ set headComment {/* DO NOT EDIT ** 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= +# DC_ARG#_DEFAULT= +# 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 \n \];" \ + COLLECT_HELP_TEXT "\[\n \n \];" \ + COMMENT " " \ + CONDITION_COMMAND "( name pp_expr );" \ + DISPATCH_CONFIG "\[\n \n \];" \ + DISPATCHABLE_COMMAND "( name args... ){\n \n }" \ + EMIT_DISPATCH "( indent );" \ + EMIT_HELP_TEXT "( indent );" \ + INCLUDE {( )} \ +] +# 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 =filename' command line option, provided that the + # word matches a specified . 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)]} {