+#---------- parser error reporting ----------
+
+proc parser-control-create {w base invokebuttontext etl_title} {
+ frame $w
+ button $w.do -text $invokebuttontext -command invoke_$base
+
+ frame $w.resframe -width 120 -height 32
+ button $w.resframe.res -text {} -anchor nw \
+ -padx 1 -pady 1 -borderwidth 0 -justify left
+ glset deffont_$base [$w.resframe.res cget -font]
+ place $w.resframe.res -relx 0.5 -y 0 -anchor n
+
+ pack $w.do -side top
+ pack $w.resframe -side top -expand y -fill both
+
+ set eb .err_$base
+ toplevel $eb
+ wm withdraw $eb
+ wm title $eb "where-vessels - $etl_title"
+
+ label $eb.title -text $etl_title
+ pack $eb.title -side top
+
+ button $eb.close -text Close -command [list wm withdraw $eb]
+ pack $eb.close -side bottom
+
+ frame $eb.emsg -bd 2 -relief groove
+ label $eb.emsg.lab -text "Error:"
+ text $eb.emsg.text -height 1
+ pack $eb.emsg.text -side bottom
+ pack $eb.emsg.lab -side left
+
+ pack $eb.emsg -side top -pady 2
+
+ frame $eb.text -bd 2 -relief groove
+ pack $eb.text -side bottom -pady 2
+
+ label $eb.text.lab
+
+ text $eb.text.text -width 85 \
+ -xscrollcommand [list $eb.text.xscroll set] \
+ -yscrollcommand [list $eb.text.yscroll set]
+ $eb.text.text tag configure error \
+ -background red -foreground white
+
+ scrollbar $eb.text.xscroll -orient horizontal \
+ -command [list $eb.text.text xview]
+ scrollbar $eb.text.yscroll -orient vertical \
+ -command [list $eb.text.text yview]
+
+ grid configure $eb.text.lab -row 0 -column 0 -sticky w
+ grid configure $eb.text.text -row 1 -column 0
+ grid configure $eb.text.yscroll -sticky ns -row 1 -column 1
+ grid configure $eb.text.xscroll -sticky ew -row 2 -column 0
+}
+
+proc parser-control-ok-core {w base background show} {
+ debug "parser-control-ok-core $w $base $background $show"
+ upvar #0 deffont_$base deffont
+ $w.resframe.res configure \
+ -background $background -disabledforeground black -font $deffont \
+ -state disabled -command {} \
+ -text $show
+}
+proc parser-control-ok {w base show} {
+ parser-control-ok-core $w $base green $show
+}
+proc parser-control-none {w base show} {
+ parser-control-ok-core $w $base blue $show
+}
+proc parser-control-failed-core {w base foreground background smallfont
+ tiny summary fulldesc fulldata} {
+ debug "parser-control-failed-core $w $base $summary $fulldesc"
+ upvar #0 deffont_$base deffont
+ set eb .err_$base
+
+ $eb.emsg.text delete 0.0 end
+ $eb.emsg.text insert end $summary
+
+ $eb.text.lab configure -text $fulldesc
+ $eb.text.text delete 0.0 end
+ $eb.text.text insert end $fulldata
+
+ regsub -all {.{18}} $tiny "&\n" ewrap
+
+ if {$smallfont} {
+ set font fixed
+ } else {
+ set font $deffont
+ }
+
+ $w.resframe.res configure \
+ -background $background -foreground $foreground -font $font \
+ -state normal -command [list wm deiconify $eb] \
+ -text $ewrap
+}
+
+proc parser-control-failed-expected {w base emsg lno ei fulldesc newdata} {
+ set eb .err_$base
+
+ set line [lindex [split $ei "\n"] 0]
+ debug "parser-control-failed-expected: $w $base: $lno: $emsg\n $line"
+
+ parser-control-failed-core $w $base \
+ white red 1 \
+ "err: [string trim $emsg]: \"$line\"" \
+ "at line $lno: $emsg" \
+ $fulldesc $newdata
+
+ $eb.text.text tag add error $lno.0 $lno.end
+ $eb.text.text see $lno.0
+}
+proc parser-control-failed-unexpected {w base emsg ei} {
+ global errorInfo
+ parser-control-failed-core $w $base \
+ black yellow 1 \
+ $emsg $emsg "Details and stack trace:" $ei
+}
+
+proc reparse {base varname old fulldesc okshow noneshow parse ok} {
+ upvar #0 $varname var
+ manyset [errexpect-catch {
+ uplevel 1 $parse
+ if {[string length [string trim $var]]} {
+ parser-control-ok .ctrl.$base $base $okshow
+ } else {
+ parser-control-none .ctrl.$base $base $noneshow
+ }
+ }] failed emsg lno ei
+ if {$failed} {
+ parser-control-failed-expected .ctrl.$base $base \
+ $emsg $lno $ei $fulldesc $var
+ set var $old
+ uplevel 1 $parse
+ } else {
+ uplevel 1 $ok
+ }
+}
+
+#---------- main user interface ----------