]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Sync to trunk
authorlarrybr <larrybr@noemail.net>
Sat, 31 Jul 2021 19:37:56 +0000 (19:37 +0000)
committerlarrybr <larrybr@noemail.net>
Sat, 31 Jul 2021 19:37:56 +0000 (19:37 +0000)
FossilOrigin-Name: d449941b81a796fa30382bd00e88dc744a6745dc3d5a0eb8377aa90e4966a391

1  2 
manifest
manifest.uuid
tool/mkshellc.tcl

diff --cc manifest
index 1eedcbe2b534fc5701377b6eb39895bcafa68f9b,e3ec8ecc4f781bebd075896bfb7d9c24e5047e56..8126f7423ba8843193110b19698d287040441cea
+++ 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 72eafa7ff740cc5e4d1d7a858b8b52ced30d9aba,639f1a3b267c2d52c89c4dfa1f15a357010f7518..ce080aaab1faf736c415a92c0dd3e386ad321a61
@@@ -1,1 -1,1 +1,1 @@@
- 0d41f7f93c273cd2d0b92269ac1705f66daefa4eb7c24ed8f3662ef45a5397f9
 -d2da62a9df63036b02dadca3798de9e623c2680b3ef0c37d2b18bb88693afd7f
++d449941b81a796fa30382bd00e88dc744a6745dc3d5a0eb8377aa90e4966a391
index a581dc6827eaad2cff5adb51536a64612998d4e6,82ecd2f61a6cf7adfef07217287074fbbdab0580..0a5c0ad73939dac05e74cc348fe8d6b8b8471a49
@@@ -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=<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)]} {