From: larrybr Date: Wed, 7 Jul 2021 18:23:07 +0000 (+0000) Subject: General cleanup of mkshellc.tcl, + help and options X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcc17dd03958091460a2a5d59e0df44fafa3a88d;p=thirdparty%2Fsqlite.git General cleanup of mkshellc.tcl, + help and options FossilOrigin-Name: d1952ff42b26e66d8df45dcf7ba37378d0818b1db3d6df9352db1e30b9ca844e --- diff --git a/manifest b/manifest index 836c2d1f8a..110e6573f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\scommands\sdispathed.\sDispatch\stranslation\sparameterized. -D 2021-07-06T02:07:21.072 +C General\scleanup\sof\smkshellc.tcl,\s+\shelp\sand\soptions +D 2021-07-07T18:23:07.856 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1853,7 +1853,7 @@ F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1 -F tool/mkshellc.tcl e671cba0dfdab17a652530c59ad7c44170f9aa31cda04222ec77079adbf73c9b +F tool/mkshellc.tcl 71dc8ab36456a3f6af18465695f373842fef258e45f2ff09efcd29f8ac74888f F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -1919,7 +1919,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dd76b41a72aca94450fb6f45ff56af95d2adb9275eebe9ca67ebd04a52a63c33 -R 8168cef1e5221cce40797275ada85323 +P 372e3241c9e87144ffb19f7e880e9c75ec80260b0db5aed24474bc2a8d7381e4 +R 5914069a310fab6276249f870b0f38bc U larrybr -Z b0378e746b391ae098a6bfe801e6d972 +Z 7876787ac3b198da43fb5e6bc711a15c diff --git a/manifest.uuid b/manifest.uuid index 60446aa03f..d35a1ca319 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -372e3241c9e87144ffb19f7e880e9c75ec80260b0db5aed24474bc2a8d7381e4 \ No newline at end of file +d1952ff42b26e66d8df45dcf7ba37378d0818b1db3d6df9352db1e30b9ca844e \ No newline at end of file diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index b47e4eb92e..dec2ae9a27 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -10,9 +10,10 @@ # and $DIR/../ext/misc. # set topdir [file dir [file dir [file normal $argv0]]] + set out stdout -fconfigure stdout -translation {auto lf} -puts $out {/* DO NOT EDIT! + +set headComment {/* DO NOT EDIT! ** This file is automatically generated by the script in the canonical ** SQLite source tree at tool/mkshellc.tcl. That script combines and ** transforms code from various constituent source files of SQLite into @@ -27,11 +28,44 @@ puts $out {/* DO NOT EDIT! ** source file to help make the command-line program easier to compile. ** ** 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 the src/shell.c.in" and/or some of the other files included by +** "src/shell.c.in", then rerun the tool/mkshellc.tcl script. */} -set in [open $topdir/src/shell.c.in rb] + # -it = + # -tcl + +set customRun 0 +set infiles {} +array set incTypes [list "*" {}] + +while {[llength $argv] > 0} { + set argv [lassign $argv opt] + if {[regexp {^-{1,2}((help)|(details))$} $opt ma ho]} { + if {$ho eq "help"} { set customRun 2 } else { set customRun 3 } + } 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 + puts stderr "Include types not yet implemented or needed." ; exit 1 + } elseif {$opt eq "-tcl"} { + puts stderr "Tcl extension not yet implemented." ; exit 1 + } 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] +} else { + set infiles [lassign $infiles infile] + set in [open $infile rb] +} set ::cmd_help [dict create] set ::cmd_dispatch [dict create] @@ -139,121 +173,199 @@ proc chunkify_help {htin} { return $rv } -# 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} { +array set ::macroTailREs [list \ + COLLECT_DISPATCH {^\(\s*([\w\*]+)\s*\)\[} \ + COLLECT_HELP_TEXT {^\[} \ + CONDITION_COMMAND {^\(\s*(\w+)\s+([^;]+)\);} \ + DISPATCH_CONFIG {^\[} \ + DISPATCHABLE_COMMAND {^\(([\w\? ]+)\)(\S)\s*$} \ + EMIT_DISPATCH {^\((\d*)\)} \ + EMIT_HELP_TEXT {^\((\d*)\)} \ +] +array set ::macroUsages [list \ + COLLECT_DISPATCH "\[\n \n \];" \ + COLLECT_HELP_TEXT "\[\n \n \];" \ + CONDITION_COMMAND "( name pp_expr );" \ + DISPATCH_CONFIG "\[\n \n \];" \ + DISPATCHABLE_COMMAND "( name args... )\x7B\n \n \x7D" \ + EMIT_DISPATCH "( indent );" \ + EMIT_HELP_TEXT "( indent );" \ +] +# RE for early discard of non-macro lines, matching all above keywords +set ::macroKeywordTailRE {^\s{0,8}((?:(?:CO)|(?:DI)|(?:EM))[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 - if {![regexp {^\s{0,4}[A-Z]+} $lx]} { - puts $ostrm $lx - } elseif {[regexp {^COLLECT_HELP_TEXT\[} $lx]} { - incr iAte - 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]] - } elseif {[regexp {^\s*DISPATCHABLE_COMMAND\(([\w\? ]+)\)(\S)\s*$} $lx ma args tc] - && $tc eq "\x7B"} { - 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" + 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 { - 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 lb [gets $hFile] - incr iAte - lappend body $lb - if {[regexp "^\x7D\\s*\$" $lb]} { 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\)\x7B" - set dispEntry [subst [dict get $::dispCfg DISPATCH_ENTRY]] - emit_conditionally $cmd [linsert $body 0 $funcOpen] $ostrm - dict set ::cmd_dispatch $cmd [list $dispEntry] - } + dict set ::cmd_dispatch $dcmd [list $lx] } - } elseif {[regexp {^\s*EMIT_HELP_TEXT\((\d*)\)} $lx ma indent]} { + set lx [gets $hFile] incr iAte - foreach htc [lsort [dict keys $::cmd_help]] { - emit_conditionally $htc [dict get $::cmd_help $htc] $ostrm - } - } elseif {[regexp {^COLLECT_DISPATCH\(\s*([\w\*]+)\s*\)\[} $lx ma cmd]} { + } + incr iAte + return $iAte +} + +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] - 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 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. + lassign $tailCapture args tc + if {$tc ne "\x7B"} { + 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 { - dict set ::cmd_dispatch $dcmd [list $lx] + lappend args [subst [dict get $::dispCfg "DC_ARG${na}_DEFAULT"]] } - set lx [gets $hFile] - incr iAte - } - incr iAte - } elseif {[regexp {^\s*EMIT_DISPATCH\((\d*)\)} $lx ma indent]} { - incr iAte - foreach cmd [lsort [dict keys $::cmd_dispatch]] { - emit_conditionally $cmd [dict get $::cmd_dispatch $cmd] $ostrm $indent + incr na } - } elseif {[regexp {^CONDITION_COMMAND\(\s*(\w+)\s+([^;]+)\);} $lx ma cmd pp_expr]} { - incr iAte - condition_command $cmd [string trim $pp_expr] - } elseif {[regexp {^DISPATCH_CONFIG\[} $lx]} { - incr iAte - set def_disp {} - set lx [gets $hFile] - while {![eof $hFile] && ![regexp {^\s*\];} $lx]} { - lappend def_disp $lx - set lx [gets $hFile] + set body {} + while {![eof $hFile]} { + set lb [gets $hFile] incr iAte + lappend body $lb + if {[regexp "^\x7D\\s*\$" $lb]} { break } } - incr iAte - foreach line $def_disp { - if {[regexp {^\s*(\w+)=(.+)$} $line ma k v]} { - dict set ::dispCfg $k $v + 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 } - } else { + 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\)\x7B" + 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 } @@ -279,6 +391,44 @@ proc transform_line {line nesting} { return [string map [list __declspec(dllexport) {}] $line] } +if {$customRun == 2} { + # Show options and usage + say_usage [lsort [array names ::macroUsages]] { + mkshellc.tcl + may be either --help, --details, or any sequence of: + + -it = + -tcl + If no input files are specified, /src/shell.c.in will be + read. Input files are read and processed, producing output to sdout. + They may include macro lines or line sequences matching any of: + INCUDE + INCUDE() } + puts stderr { Use --details option for effects of these macros.} + exit 0 +} elseif {$customRun == 3} { + set sfd [open $argv0 r] + while {![eof $sfd]} { + if {[regexp {^proc ([A-Z_]+\M)} [gets $sfd] ma macro]} { + if {[info exists ::macroTailREs($macro)]} { + set effects {} + while {[regexp {^\s+#\s*(.+)$} [gets $sfd] ma effect]} { + lappend effects " $effect" + } + puts stderr "\nThe $macro macro will:" + puts stderr [join $effects "\n"] + } + } + } + close $sfd + exit 0 +} + +fconfigure stdout -translation {auto lf} +if {$customRun == 0} { + puts $out $headComment +} + set iLine 0 while {1} { set lx [transform_line [gets $in] 0] @@ -300,11 +450,14 @@ while {1} { } set iAte [do_shuffle $in $lx $out] if {$iAte > 0} { +if {![regexp {^\d+$} $iAte]} {puts "??? $iAte"} incr iLine [expr {$iAte - 1}] } } -close $in +if {$customRun < 2} { + close $in +} close $out exit $::iShuffleErrors