diff --git a/AUTHORS b/AUTHORS
index f116bca..958670f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,13 +1,13 @@
-GTKWave Wave Viewer is Copyright (C) 1999-2020 Tony Bybell.
-Windows compatibility and PS/MIF routines are Copyright (C) 1999-2020 Udi Finkelstein.
-Context support is Copyright (C) 2007-2020 Kermin Elliott Fleming.
-Trace group support is  Copyright (C) 2009-2020 Donald Baltus.
-GHW and additional GUI support is Copyright (C) 2005-2020 Tristan Gingold.
-Analog support is Copyright (C) 2005-2020 Thomas Sailer.
-External DnD support is Copyright (C) 2008-2020 Concept Engineering GmbH.
-FastLZ is Copyright (C) 2005-2020 Ariya Hidayat.
+GTKWave Wave Viewer is Copyright (C) 1999-2021 Tony Bybell.
+Windows compatibility and PS/MIF routines are Copyright (C) 1999-2021 Udi Finkelstein.
+Context support is Copyright (C) 2007-2021 Kermin Elliott Fleming.
+Trace group support is  Copyright (C) 2009-2021 Donald Baltus.
+GHW and additional GUI support is Copyright (C) 2005-2021 Tristan Gingold.
+Analog support is Copyright (C) 2005-2021 Thomas Sailer.
+External DnD support is Copyright (C) 2008-2021 Concept Engineering GmbH.
+FastLZ is Copyright (C) 2005-2021 Ariya Hidayat.
 Some public domain clip art by contributors at http://www.sxc.hu/ website.
 Hierarchy marker icons from the Silk icons set by Mark James found at the http://www.famfamfam.com/lab/icons/silk/ website.
 Portions of the TCL implementation, tcl_np.c and tcl_np.h are copyrighted by the Regents of the University of California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState Corporation, and other parties.
-NSAlert is Copyright (C) 2011-2020 Philipp Mayerhofer.
-LZ4 is Copyright (C) 2011-2020 Yann Collet.
+NSAlert is Copyright (C) 2011-2021 Philipp Mayerhofer.
+LZ4 is Copyright (C) 2011-2021 Yann Collet.
diff --git a/ChangeLog b/ChangeLog
index ee06b06..e24b46e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,15 +3,15 @@
 		Added user's manual pdf file to distribution in doc/.
 		Added vertex and rtlbrowse for sourcecode annotation.
 3.0.1	09may06	Automatically add extensions to save filenames in gtkwave.
-		Cygwin compile fixes.  Add Cygwin functionality for fork() 
+		Cygwin compile fixes.  Add Cygwin functionality for fork()
 		related ops that do in fact work properly.
-3.0.2   09may06 More fixes for full function (except pthreads) in Cygwin.  
+3.0.2	09may06 More fixes for full function (except pthreads) in Cygwin.
 		Requires usage of Cygserver if rtlbrowse is to work.
-		Fixed fonts for Cygwin to improve readability.  
+		Fixed fonts for Cygwin to improve readability.
 		The Courier font is very bad looking and blitter mangled under
 		cygwin.
-3.0.3	29may06	Changed yylineno references in vlex.l in rtlbrowse to 
-		my_yylineno as newer versions of flex automatically define 
+3.0.3	29may06	Changed yylineno references in vlex.l in rtlbrowse to
+		my_yylineno as newer versions of flex automatically define
 		this and cause duplicate symbols.
 		Saw there were still problems with courier on debian.  Also
 		check for misc-fixed on non-cygwin systems just in case.
@@ -35,7 +35,7 @@
 		dumpfile loaders as the string length is known from the rc
 		of sprintf.
 		Fixed T_SCOPE rule in vcd.c as dotted hierarchies would
-		throw off the parser as hierarchies themselves are 
+		throw off the parser as hierarchies themselves are
 		(in practice) never really escaped.
 		In tree.c, treenamefix() would recurse more than necessary
 		such that some dotted hierarchies would cause an order of
@@ -57,7 +57,7 @@
 3.0.6	14jul06	Added "Real" option for data type display as passing around
 		real numbers in Verilog across modules needs to be done
 		with $realtobits and $bitstoreal.
-		Added scripting command flag --script in order to allow 
+		Added scripting command flag --script in order to allow
 		autosetup of things that are outside of config file control.
 		This also allows doing things such as automated print jobs.
 		Added --nowm to remove window manager control on most
@@ -68,9 +68,9 @@
 		Added --nomenus to remove menus for the case when used in
 		conjunction with --xid and it is desired to create an
 		embedded wave viewer applet that cannot initiate file I/O
-		on its own.  Note that earlier versions of GTK+ cannot 
+		on its own.  Note that earlier versions of GTK+ cannot
 		handle menu events properly from a GtkPlug.
-		Fixed problem with dead memory allocations for GtkColor 
+		Fixed problem with dead memory allocations for GtkColor
 		structs in color.c as found by Valgrind.
 		Moved .odt version of the user's guide into doc/ rather than
 		the pdf version as this is a sourcecode distribution so the
@@ -81,7 +81,7 @@
 		Found problem with directive-based string embedding in older
 		gcc compiler versions.
 		GTK+-1.2 doesn't handle GtkPlug.
-3.0.7   17jul06 Added support for dualview of waveforms using GtkPlug and
+3.0.7	17jul06 Added support for dualview of waveforms using GtkPlug and
 		shared memory IPC through use of the "twinwave" front end.
 		Updated documentation to add a section on twinwave.
 3.0.8	04aug06	Modified order of flags in twinwave as appending flags
@@ -91,7 +91,7 @@
 		not including getopt.h.
 		Removed unused "bus" element from struct fac.
 		Added interactive loading of vcd files with the routines in
-		vcd_partial.c.  Added shmidcat to the distribition to test 
+		vcd_partial.c.  Added shmidcat to the distribition to test
 		this new interactive loading functionality.
 		Added real_parameter vartype (Riviera Aldec 2006.6) in all
 		vcd loaders.
@@ -165,7 +165,7 @@
 		Fixed bug in draw_hptr_trace_vector_analog() that would
 		cause crashes on pure real vectors when zoomed out fully.
 		Added dynamic tooltips on current marker values for both
-		the left and middle mouse buttons (not tested for Win32 
+		the left and middle mouse buttons (not tested for Win32
 		yet so disabled there).
 		Added preliminary support for changing menu accelerators
 		through the rc file with an "accel" statement.
@@ -173,7 +173,7 @@
 		zero in the initial dumpvars.  (would be needed anyway for
 		dumpers that for some reason don't as the 1st value
 		change collapses into the second)
-3.0.18  28nov06	Fix in vcd saver for when units are in seconds: keeps 
+3.0.18  28nov06	Fix in vcd saver for when units are in seconds: keeps
 		timescale of "ss" being used instead of just "s".
 		Locale problem in printing of floating point numbers fixed
 		by setting up a local fixer routine in config.h for
@@ -181,7 +181,7 @@
 		Fix in all vcd loaders to handle "port" (along with other
 		keywords) that appear in non-keyword parts of the $VAR
 		declaration sequence.
-		Fixed long standing LXT bug with integer datatype on 
+		Fixed long standing LXT bug with integer datatype on
 		trivial LXT files.  (Overflow in lt_buf decoder buffer.)
 3.0.19	21dec06	More locale fixing with LC_ALL.
 		Added user patches from NIIBE Yutaka to remove requirement
@@ -196,14 +196,14 @@
 		reals.
 3.0.21	02feb07	Added support for in/out/inout evcd ports generated by
 		dumpports in ModelSim.
-		Fixed problem with hierarchy being out of order as 
+		Fixed problem with hierarchy being out of order as
 		treegraft needed to be followed by treesort.  This mostly
 		impacted recursive hierarchy imports by only allowing
 		two signals to import rather than all of them.  Also there
 		was an inconsistency with the signal ordering with VCD vs
 		the database formats because of this.
 3.0.22	19feb07	Bumped up hash size from 65519 to 500009 entries for VCD
-		parsers.  
+		parsers.
 		Bumped up max VCDID fastindex size to 8M entries.
 		Now use gperf for verilog datatypes for some speedup in
 		gtkwave vcd loaders.
@@ -218,7 +218,7 @@
 		PATH_MAX set if not defined in verilog.g for Vertex.
 		Regenerated configure for setenv()/unsetenv() presence
 		which impacts Solaris (use putenv() instead).
-		Regenerated configure to handle auto detect of -lnsl, 
+		Regenerated configure to handle auto detect of -lnsl,
 		-lrpc, and -lpthread.
 		Added -c to file install in top-level makefile (Solaris).
 		Use _LARGEFILE_SOURCE value from configure with linux
@@ -243,15 +243,15 @@
 		that code was leftover from the vzt2vcd).
 		Updated manpages for vzt2vcd, lxt2vcd, and vztminer.
 		On concatenated vector loads ('#'/':' in savefile), attempts
-		to do a load of a monolithic vector on fail.  This is 
+		to do a load of a monolithic vector on fail.  This is
 		somewhat related to the re-coalesce vectors feature above.
 		Implemented reverse of this for monolithic vectors into
 		the '#' bitstrand variants.
-3.0.25	10apr07	System Verilog with MTI fix for VCD declarations of form 
+3.0.25	10apr07	System Verilog with MTI fix for VCD declarations of form
 		$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end
-		...debussy implicitly escapes the varname during loading so 
+		...debussy implicitly escapes the varname during loading so
 		gtkwave does it too now for all VCD loaders.
-		More System Verilog with MTI fixes: VCD (parameter) vars of 
+		More System Verilog with MTI fixes: VCD (parameter) vars of
 		length zero are representative of reals with MTI: they don't
 		use real_parameter like Riviera does.
 		Updated vcd_saver.c to handle saving these implicit-var
@@ -305,14 +305,14 @@
 3.1.1	20sep07	Fixed crash in hierarchy search reload.  (Wrong
 		pointer type introduced from code cleanup.)  Adding
 		start of tabbed browsing support.  Put in window
-		select focus switching between tabs (e.g., on 
+		select focus switching between tabs (e.g., on
 		search windows).  Added locking in main iteration
 		loop to detect unexpected context switches and
 		fix/report them (wrong operation if it occurs).
 3.1.2	24dec07	Compiler warning cleanups from Sun compile logs.
 		Added named parameter support to vermin parser.
 		Added check for gperf back into configure.ac.
-		Added vlist_spill rc variable to control new 
+		Added vlist_spill rc variable to control new
 		feature of spilling vlists to a tempfile on disk.
 		Fixed vcd loader status bar on files > 2GB.
 		Removed non-growable vlists and also finalize
@@ -328,39 +328,39 @@
 		with the vlist_prepack rc variable.
 		Added --giga option to turn on vlist_spill and
 		vlist_prepack from the command line.
-3.1.3	13jan08	Added dynamic keypress detection in the Pattern Search 
-		Requester so users do not need to press enter for search 
-		strings.  Likewise, added the rc variable sst_dynamic_filter 
+3.1.3	13jan08	Added dynamic keypress detection in the Pattern Search
+		Requester so users do not need to press enter for search
+		strings.  Likewise, added the rc variable sst_dynamic_filter
 		to enable the same type behavior for the signal name filter in
 		the GTK2 signal search tree.
-		Fixed bug where filtered signal names did not reappear on 
+		Fixed bug where filtered signal names did not reappear on
 		reload.
 		Updated user manual as necessary.
-		Added "edge" left/right buttons for handy single signal edge 
+		Added "edge" left/right buttons for handy single signal edge
 		detection due to user requests.
 		Fixed long-standing backward edge seek bug in pattern search.
 		(It would miss the preceeding edge if the marker isn't already
 		on one.)
-		Added use_standard_clicking rc variable in order to enable 
+		Added use_standard_clicking rc variable in order to enable
 		"normal GTK" shift/click semantics in the signal window.
-		Collapse/uncollapse is now shift-ctrl when 
+		Collapse/uncollapse is now shift-ctrl when
 		use_standard_clicking is active.
 		Added prelim dnd for use_standard_clicking mode.
-		use_standard_clicking disabled in GTK-1.2 as there are dnd 
+		use_standard_clicking disabled in GTK-1.2 as there are dnd
 		issues.
 		Recalculate signal width on reload as sometimes it was missed.
 		Added input focus capability to signalwindow.
 		Moving menu options to standard GTK accelerator keys.
-		Added Ctrl-A/Shift-Ctrl-A handler to the treeview so it acts 
+		Added Ctrl-A/Shift-Ctrl-A handler to the treeview so it acts
 		like the signal window.
 		Added left/right scrolling hotkeys in signal window.
-		Added use_toolbutton_interface environment variable which 
+		Added use_toolbutton_interface environment variable which
 		enables new user interface at the top of screen.
-		More modifications to handle globals swapping in multi-tab 
+		More modifications to handle globals swapping in multi-tab
 		mode.
 		Update configure.ac to handle library order problem with
 		cygwin in rtlbrowse.
-		Added scrollwheel support in signal window when focused and 
+		Added scrollwheel support in signal window when focused and
 		standard clicking is active.
 		Added "Use Color" and "Use Black and White" (for screendumps)
 		View menu options from user requests.
@@ -431,8 +431,8 @@
 		calls causing similar problems as necessary.
 3.1.9	20apr08	Added missing init_filetrans_data() to reload function.
 		Updated manfiles to get them in line with Debian lintian.
-3.1.10	14may08	Added missing adjustment of t->shift in mouseover.c in 
-		order to allow the mouseover on shifted traces to display 
+3.1.10	14may08	Added missing adjustment of t->shift in mouseover.c in
+		order to allow the mouseover on shifted traces to display
 		properly.
 		Fixed problem with edgebutton going back two edges on a
 		combined vector.  (Cut and paste typo from strace.c.)
@@ -445,7 +445,7 @@
 3.1.12	14jul08 Compiler warning fixes.
 		Fixed crash in vcd recoder for b vs 01xz mixups in
 		malformed VCD files.
-		Fixed abort on VCD load for malformed size vs 
+		Fixed abort on VCD load for malformed size vs
 		[msi:lsi] syntax.  NC does this on arrays of wires.
 		Fix to vlist reader with --giga enabled in order to
 		handle reads which go off the end of the file.
@@ -466,10 +466,10 @@
 		for the horizontal scroller in the wavewindow.
 		Added sticky click semantics for clicks in signal
 		window.  To do this in the treesearch_gtk2 file
-		will require some additional future work with 
+		will require some additional future work with
 		view_selection_func() and/or signal handling and
 		trapping.
-3.2.0	16feb09	Fix for strings ('s' type) in recoder.  
+3.2.0	16feb09	Fix for strings ('s' type) in recoder.
 		Added timestart command to savefiles which indicates
 		what the leftmost position should be on reload.
 		Added support for as/zs small timescales as well as
@@ -477,12 +477,12 @@
 		Adding signal name DnD support from external apps.
 		Force open tree nodes on initial .sav file read.
 		Yet more new warning (-Wall) cleanups.
-		Fixed ExtractNodeSingleBit for vectors which do not 
+		Fixed ExtractNodeSingleBit for vectors which do not
 		have a zero in either the msb or lsb (e.g., [1:9]).
 		Added support for dragging files into the viewer
 		(i.e., dumpfile, savefile, stems file)
 		Added DnD of signal names from RTLBrowse source code
-		windows	directly into gtkwave.  
+		windows	directly into gtkwave.
 		GTK1 compiler compatibility fixes.
 		Improved search performance from rtlbrowse initiated
 		DnD searches.
@@ -496,7 +496,7 @@
 		Updated -f argument file handling in vermin.
 		Updated tcl_helper code so that signalwindow drags of bit-
 		blasted vectors are properly re-coalesced for client code
-		for the drag.		
+		for the drag.
 		Updated task definition in vermin so that identifiers with
 		dots in them can be used as task enable names.
 		Fixed problem in vermin preprocessor where defines in 0x0d0a
@@ -549,28 +549,28 @@
 		Added prelim auto-scrolling code for trace adds/copies.
 		Added support for Tcl repscripts.
 		Removed warnings found when compiling with -Wshadow.
-		Fix for stack crash in treesort() on dumpfiles with an 
+		Fix for stack crash in treesort() on dumpfiles with an
 		extremely large number of signals (e.g., 5 million).
 		Compile fixes for rtlbrowse in older versions of GTK2.
 		Remove stray tempfiles created by --giga writer under MinGW.
 		Removed stray file descriptor from lxt on reload.
 		Fixed repeat error problem in lxt.c introduced by -Wshadow fix.
-		Added prelim version of scale_to_time_dimension rc variable and 
+		Added prelim version of scale_to_time_dimension rc variable and
 		appropriate menu options.
 		Beginning to update user manual to reflect new 3.2 features.
-		Added Partial VCD Dynamic Zoom To End and related 
+		Added Partial VCD Dynamic Zoom To End and related
 		zoom_dynamic_end rc variables.
 		More mingw compile fixes: the whole tarball compiles now.
 		Use old file chooser (for now) in mingw as the new one seems
 		not to be re-sizeable.
 		Added "copy traces" to toolbar in gtkwave as copy function now
 		exists.
-		Added check for "server" in env var CYGWIN before printing 
+		Added check for "server" in env var CYGWIN before printing
 		warning about using shared memory.
 		Added vpi client lxt/lxt2/vzt writers in contrib/vpi, but these
 		currently are not built.
 		Compatibility fix for gcc 3.x.
-		Added extload capability which grabs data via popen().  This 
+		Added extload capability which grabs data via popen().  This
 		allows adding loaders for unsupported formats via data mining.
 		Added Tcl command setBaselineMarker.
 		Extload hardening on reload.
@@ -602,7 +602,7 @@
 		order to avoid unnecessary stack pushing.
 		Fixing reloader crashes in vcd_build_symbols().
 		Adding experimental support for bringing up gtkwave without a
-		trace like "every other" GUI app.  This is currently disabled 
+		trace like "every other" GUI app.  This is currently disabled
 		pending more testing.
 		Sort filename lists from DnD in order to allow both a
 		dumpfile and a savefile to be dragged into the viewer and
@@ -640,7 +640,7 @@
 		Warning fixes for printf format strings in lxt2/vzt/ghw.
 		Updated VCD parser to handle names like "a[1] [3:0]".
 		Added VCDNAM_ESCAPE cases in lxt, lxt2, and vzt loaders.
-		Updated VCD writers so they put spaces before bracketed 
+		Updated VCD writers so they put spaces before bracketed
 		signal ranges.
 		Added extra message for help requester if file type is
 		MISSING_FILE in order to direct users what to do.
@@ -693,7 +693,7 @@
 		Fix to attempt_vecmatch_2 when no suffix encountered.
 3.3.0	25dec09	Modified unformat_time() so it can also handle floating-
 		point exponential format.
-		Integration of a large amount of group handling sourcecode 
+		Integration of a large amount of group handling sourcecode
 		from Don Baltus / Bluespec, Inc.
 		Re-integrated original Simpod repscript handling.
 		Reworked force open tree node and moved to
@@ -734,7 +734,7 @@
 		file support as it is obsolete: all scripts are Tcl scripts
 		now.
 		Integrated user-provided rework of rgb.c.
-		Removed local lzma library and now use system xz if 
+		Removed local lzma library and now use system xz if
 		available. Old VZT files using -z 2 are no longer readable
 		but can be converted using vzt2vcd from an old version of
 		gtkwave.
@@ -745,7 +745,7 @@
 		In fstapi.c now use tmpfile() to generate tempfiles in
 		order to speed up operation on networked filesystems.
 		Fixed problem in fstapi.c with conflict between off_t
-		and unsigned longs on some 32-bit systems which cause a 
+		and unsigned longs on some 32-bit systems which cause a
 		"tsec uncompress" failure on reads.
 		Fixed missing dependencies in various Makefile.am files.
 3.3.2	05jan10	Emergency fix for ghw.c as it was missing a close comment
@@ -792,10 +792,10 @@
 		force_open_tree_nodes loop (spotted using an alternate
 		allocator).
 		Added optional preliminary Judy array support.
-		Fixed compiler warnings.		
+		Fixed compiler warnings.
 		Fixed toggle max hier so it toggles back and forth between
 		the most previously set hierarchy depth.
-		Added ".lxt2" to list of suffixes allowed by gtkwave.		
+		Added ".lxt2" to list of suffixes allowed by gtkwave.
 		Remove name field from struct fac.
 		Added missing hierarchy boundary sort for FST in order to
 		allow compatibility with compressed names (-C flag).
@@ -841,7 +841,7 @@
 		Compiler warning fix in lxt_write.c/fstapi.c for Open Solaris.
 		Added fstWriterGetDumpSizeLimitReached() to fstapi.c.
 		Fixes to Tcl string handling.
-		Applied user-supplied fixes for null pointer crashes in 
+		Applied user-supplied fixes for null pointer crashes in
 		rtlbrowse.
 		Moved gtk_grab_add() after gtk_widget_show() in order to work
 		with newer versions of GTK.
@@ -888,13 +888,13 @@
 		gtkwave::setCurrentTranslateFile,
 		gtkwave::setCurrentTranslateProc,
 		gtkwave::setCurrentTranslateTransProc, and
-		gtkwave::setCurrentTranslateEnums to give Tcl access to these 
+		gtkwave::setCurrentTranslateEnums to give Tcl access to these
 		features.
 		Add write combining in fstWriterEmitValueChange to speed
 		up execution on Cygwin.
 		Nested `ifdef fix for Vermin.
-                Fix for free to non-malloc'd address problem in repscripts
-                due to context changing in Tcl scripts when reload occurs.
+		Fix for free to non-malloc'd address problem in repscripts
+		due to context changing in Tcl scripts when reload occurs.
 		Added gtkwavetcl_setvar() for starting to build a framework
 		to support Tcl variable change callbacks.  This can be used
 		to closely monitor how a user manipulates the gtkwave GUI.
@@ -936,7 +936,7 @@
 3.3.15	10nov10	Added check in fstapi.c for corner case where
 		fstWriterEmitSectionHeader could make a file unusable if.hier
 		is not present.
-		Added more checks in fstapi reader to prevent crashes on 
+		Added more checks in fstapi reader to prevent crashes on
 		malformed files.
 		Add config.h #include to the fstapi.c code.
 		Add detection in vcd2fst for Verilog XL-style VCD identifiers
@@ -953,7 +953,7 @@
 		Added Jenkins hash routine to enable dynamic alias detection
 		for when Judy not available.
 3.3.17	28nov10	Added sanity check in dynamic alias reconstruct routine in
-		FST reader and also fixed bug where alias reconstruction in 
+		FST reader and also fixed bug where alias reconstruction in
 		current blocks doesn't overwrite previous, old block data.
 3.3.18	24dec10	Added extra allocation in fstWriterEmitValueChange in case
 		users modify the FST_BREAK_ADD_SIZE to a very small value.
@@ -961,7 +961,7 @@
 		into its compile.
 		Fixed x86_64 assembler =q vs =Q problem in lxt.c.
 		Preliminary support for variable length records in FST files.
-		Added fstUtilityBinToEsc and fstUtilityEscToBin for 
+		Added fstUtilityBinToEsc and fstUtilityEscToBin for
 		conversion of binary data to C-style strings.
 		Now allow escaped strings in VCD files to encode a richer
 		set of data for non-standard "s" VCD records.
@@ -1021,7 +1021,7 @@
 		bug.  (Would prevent pattern search from working on
 		64-bit big-endian architectures.)
 		Fixed broken "replace" signal option.
-3.3.24	03aug11	Improve the searching for the TCL libraries (when using 
+3.3.24	03aug11	Improve the searching for the TCL libraries (when using
 		stubs).
 		Fixed bug where Tcl_GetString was substituted with
 		brace removal preprocessing when unnecessary (would break
@@ -1039,7 +1039,7 @@
 		Fix in lxt2_read.c/.h for negative msb/lsb indices.
 		Fix in vzt_read.c/.h for negative msb/lsb indices.
 3.3.26	25sep11	Mac OSX fixes: removed restrictions for twinwave on OSX,
-		OSX compile fixes for Tcl detection, printf warning 
+		OSX compile fixes for Tcl detection, printf warning
 		fixes (xcode gcc uses stricter warnings).
 		More generic warning fixes from recent feature adds.
 3.3.27	20oct11	Fixes of suspicious NULL pointer warnings from scan-build.
@@ -1050,7 +1050,7 @@
 		or will change when files are loaded.
 		Added fix for DnD crash when Quartz is the GDK back-end
 		on Mac OSX.  Enable fix with --enable-quartz in configure.
-		Fixed fstWriterFlushContext() such that invocations 
+		Fixed fstWriterFlushContext() such that invocations
 		outside the fstapi are synced with time changes.
 		Modify main window size for twinwave on Quartz: GtkPlug
 		window does not fit into GtkSocket as with X11.
@@ -1067,14 +1067,14 @@
 		.gtkw itself being able to bring up the original dumpfile.
 		Numerous bug fixes.
 		Preliminary GConf support supporting session ID-based restore.
-		Preliminary GConf support to emulate OSX "open" 
+		Preliminary GConf support to emulate OSX "open"
 		functionality such that dumpfiles/savefiles can be targeted
 		to an open gtkwave viewer / session ID.
 		<< long descriptions >>
 		Fixed size of declaration of render_mutex_renderopt_c_1 as it
 		was one element too short.
 		Added transition code for shifting away from using
-		GtkItemFactoryEntry (also will help with OSX menubar 
+		GtkItemFactoryEntry (also will help with OSX menubar
 		integration which expects menu shells).
 		Added support for native Quartz menu bars.
 		Removed --enable-quartz as it is auto detected now if
@@ -1125,8 +1125,8 @@
 		Added .gtkw as a new save file extension.  When either .sav
 		or .gtkw is encountered, the rest of a tab's session adaptively
 		follows in expecting it as the save file suffix.
-		Added [savefile] tag to save files.  The intended use is to 
-		allow reconstruction of relative paths between dump and save 
+		Added [savefile] tag to save files.  The intended use is to
+		allow reconstruction of relative paths between dump and save
 		file.
 		Fixed --autosavename to use .gtkw as a suffix rather than the
 		.sav suffix.
@@ -1134,7 +1134,7 @@
 		matches gtkwave.icns.
 		Renamed .sav examples to .gtkw.
 		Added relative path comparisons for --save so when dumpfiles
-		and savefiles move in tandem, a successful load can be 
+		and savefiles move in tandem, a successful load can be
 		attempted.
 		Added [dumpfile_mtime] and [dumpfile_size] tags to save file.
 		Can now specify just an augmented save file at the command
@@ -1153,7 +1153,7 @@
 		Disable analog during mutually incompatible mode selection
 		(binary, filters, etc).
 		Added F/P/T flags to mouseover for the filters.
-		Fix problem where ungrab doesn't occur if button pressed + 
+		Fix problem where ungrab doesn't occur if button pressed +
 		simultaneous reload accelerator key occurs.
 		Fix combine direction in transaction filter to down.
 		Fix vector analog render/print routine to use skipcnt.
@@ -1179,25 +1179,25 @@
 		args to transaction filters via the args $comment.
 		Added string value of \000 which renders as high-z.
 		Integrated alt_wheel_mode code provided by Tom Browne.
-		Fixes for some rc file variables to keep them from getting 
+		Fixes for some rc file variables to keep them from getting
 		clobbered on 2nd tab opening.
 		Warning fixes when compiled on Ubuntu.
 3.3.33 27feb12	Scan-build fix in vcd_recoder.c.
 		Added $timezero tag to VCD files which allows offsetting all
-		the values in a trace to provide ability for negative time 
-		values.  Currently only VCD, LXT, LXT2, VZT, and FST support 
+		the values in a trace to provide ability for negative time
+		values.  Currently only VCD, LXT, LXT2, VZT, and FST support
 		this.
 		Fix for timescale 10s and 100s.
 3.3.34 12mar12	Fix for marker time deltas when $timezero is used.
 		Reduced size of alert requester icons to 64x64 pixels.
-3.3.35 04apr12	Polarity fix for vcd_preserve_glitches in rcfile.  Default 
+3.3.35 04apr12	Polarity fix for vcd_preserve_glitches in rcfile.  Default
 		is no/off. Use yes in the rcfile to enable (e.g., for
 		viewing interpolated analog waveforms).
 		Added vcd_preserve_glitches support to FST as --optimize
 		uses FST.
 		Added vcd_preserve_glitches_real (for VCD/FST) rcfile
 		variable that turns off deglitching only for real signals.
-		This removes the need for #define TRACK_AND_HOLD_FIX and 
+		This removes the need for #define TRACK_AND_HOLD_FIX and
 		prevents the case where interpolation of an analog waveform
 		is deformed as significant data points were removed by the
 		VCD or FST loader.
@@ -1215,9 +1215,9 @@
 		introduced in 3.3.19.
 3.3.37	10jun12	Added patch for savefile.c that corrects an issue in which the
 		parser for process filter lines assumed the associated id
-		number was always a single digit. 
+		number was always a single digit.
 		Added patch to bitvec.c catches one more case when locating
-		bitblasted signals in vcd files created by modelsim. 
+		bitblasted signals in vcd files created by modelsim.
 		Fix that kills stray pipeio_create() processes on
 		pipeio_destroy().
 		Additions to extload to handle hier types, component types,
@@ -1239,7 +1239,7 @@
 		broken in the GtkSocket/GtkPlug implementation for Win32.
 3.3.39	08aug12	Fixed relative pathnames when generated in MinGW and used
 		back on Linux.
-		Added --output filename option to fst2vcd, vzt2vcd, and 
+		Added --output filename option to fst2vcd, vzt2vcd, and
 		lxt2vcd.
 		Fix crash on OSX if gtk_widget_set_sensitive is called on
 		a separator.
@@ -1267,8 +1267,8 @@
 		Added scrollwheel support to rtlbrowse code windows.
 		Added fseeko() return checking in fstapi.c to prevent
 		errors with dynamically updated files.
-3.3.43	26jan13	Fix for rtlbrowse for gtk_adjustment_get_page_increment and 
-		gtk_adjustment_get_step_increment introduced in 2.14. 
+3.3.43	26jan13	Fix for rtlbrowse for gtk_adjustment_get_page_increment and
+		gtk_adjustment_get_step_increment introduced in 2.14.
 		Added VPD support via vpd2vcd.  To use, specify -o
 		at the command line.  (e.g., gtkwave -o test.vpd)
 		Added autodetect for LXT, LXT2, VZT, FST regardless of the
@@ -1278,7 +1278,7 @@
 		Added conditional compile for stat() being available.
 3.3.44	16feb13	gdk_draw_layout assertion `GDK_IS_DRAWABLE (drawable)'
 		assertion fix.
-3.3.45	28feb13	Fix for VCDNAM_ESCAPE character in treesearch window.  This 
+3.3.45	28feb13	Fix for VCDNAM_ESCAPE character in treesearch window.  This
 		sometimes occurs for structure identifiers.
 3.3.46	29apr13	Upgraded to autoconf 2.69.
 		Fixed as of yet undetected hdr_incomplete bug when running off
@@ -1303,7 +1303,7 @@
 		FSDB fix for new debug info output style to be parsed.
 		Added generate as scope type to VCD/FST/FSDB.
 		Preliminary add for module port direction for FSDB and FST.
-		Display signal direction column in SST if not all signals are 
+		Display signal direction column in SST if not all signals are
 		declared as FST_VD_IMPLICIT.
 		Fixed GTK warning when hide_sst is enabled and SST is opened
 		then closed.
@@ -1339,14 +1339,14 @@
 		Fixed ordering of static FSDB libraries for when dynamic ones
 		are not present.
 		Added direction filters to SST name filter search.  That is,
-		adding +I+, +O+, +IO+, +B+, or +L+ before the regular 
+		adding +I+, +O+, +IO+, +B+, or +L+ before the regular
 		expression adds additional filtering criteria.  Direction
 		filters are case-insensitive.
 		Relax FSDB loader to allow VHDL and mixed-language files.
-		Added VHDL hierarchy types to FST, internal VCD loaders and 
+		Added VHDL hierarchy types to FST, internal VCD loaders and
 		also vcdfst/fst2vcd.
 		Added in VHDL to FST (which will also allow other languages):
-		gtkwave can process these types (e.g., signal + std_ulogic), 
+		gtkwave can process these types (e.g., signal + std_ulogic),
 		but there are currently no simulators supporting them.  These
 		are written by using fstWriterCreateVar2().
 3.3.50	15oct13	Limit number of rows that can be displayed in mouseover in
@@ -1356,7 +1356,7 @@
 		Added missing $dumpvars emission in fst2vcd.
 		Added missing atto and zepto time prefix parsing in vcd2fst.
 		Added VHDL package type to FST.
-		Added red box around 'U' vector values for VHDL similar to 
+		Added red box around 'U' vector values for VHDL similar to
 		'X' for Verilog.
 		Used FST "attribute name" for variable types if specified.
 		CRLF fix for save file reading on LF-only systems.
@@ -1373,13 +1373,13 @@
 3.3.51	27oct13	MAINTAINERS: Please add gedit to the list of dependencies
 		for gtkwave in order to enable new function that Icarus
 		Verilog dumps into FST files.
-		Fix "/File/Grab To File" on OSX with an OSX patch as the 
-		_gdk_quartz_image_copy_to_image() function in the GTK 
+		Fix "/File/Grab To File" on OSX with an OSX patch as the
+		_gdk_quartz_image_copy_to_image() function in the GTK
 		toolkit for Quartz is broken.
 		Updated examples/gtkwaverc accel options to reflect the
 		current state of the gtkwave main window main menu.
 		Added "Open Source Definition" and "Open Source Instantiation"
-		options that invoke .gtkwaverc variable "editor" (or 
+		options that invoke .gtkwaverc variable "editor" (or
 		$GTKWAVE_EDITOR or gedit or open -t [OSX]) on sourcecode when
 		source stems are present in the dumpfile (currently FST only).
 		Fixed timezero in vcd2fst as it was only parsing unsigned
@@ -1409,7 +1409,7 @@
 		Standardized export feature to write vcd using lower case
 		for non 0/1 values.
 		Added perror() on errno-related exits in vcd loaders.
-		Added experimental wlf2vcd in contrib.  It is not currently 
+		Added experimental wlf2vcd in contrib.  It is not currently
 		compiled or used.
 		Corrected non-functional typos in documentation.
 3.3.54	02jan14	Added LZ4 double compression on hierarchy tree for FST when
@@ -1423,9 +1423,9 @@
 		in some cases on x86_64.
 3.3.55	06feb14	Fixed problem with FST_DYNAMIC_ALIAS_DISABLE enabled when
 		Judy arrays are not present.
-		FST writer performance tweaks for traces with millions of 
+		FST writer performance tweaks for traces with millions of
 		signal declarations.
-		Keep FSDB_VT_STREAM (FSDB transaction type) traces from 
+		Keep FSDB_VT_STREAM (FSDB transaction type) traces from
 		attempting to be read (for now) as they aren't yet processed.
 		Added more space efficient FST dynamic alias encoding.
 		Tempfile creation fix for Windows.  Using tmpnam() is not
@@ -1437,7 +1437,7 @@
 		VCD formatting.
 		Added very fast I/O write capability to fst2vcd.
 		Added support for FSDB_BYTES_PER_BIT_2B (EVCD) in FSDB loader.
-		Added experimental fsdb2vcd in contrib.  It is not currently 
+		Added experimental fsdb2vcd in contrib.  It is not currently
 		compiled or used.
 		Fix to treesearch to remove duplicate signal names because of
 		faulty dumpers.
@@ -1461,10 +1461,10 @@
 		Change [1] at end of struct to C99 [] notation with appropriate
 		allocation size modification.
 		System_profiler speed fix for OSX.
-3.3.59	26apr14	Use Duff's Device for 8 byte -> 1 byte binary value compression 
+3.3.59	26apr14	Use Duff's Device for 8 byte -> 1 byte binary value compression
 		algorithm in FST writer.
 		Warnings fixes from cppcheck.
-		Moved MinGW for FST to using different windows tempfile 
+		Moved MinGW for FST to using different windows tempfile
 		generation instead of tmpfile().
 		Removed fflush() in FST for MinGW in places that can cause
 		crashes with read only files.
@@ -1498,15 +1498,15 @@
 		-- for example filters all non-ports from search results.
 		Updated LZ4 for version r126.
 		Minor warnings fixes.
-                Moved TCL_LDADD/TK_LDADD before	FSDB_LDADD to avoid stale
-                Tcl library version conflicts.
+		Moved TCL_LDADD/TK_LDADD before	FSDB_LDADD to avoid stale
+		Tcl library version conflicts.
 		Removed appending [31:0] to vcd loaded integer names.
 		Reduced recursion depth in GHW signal loader to prevent
 		stack overflow crashes.
 		Added support for synthetic clocks in FST file.
 		Update timetrace marking so it runs quicker for large traces.
 3.3.66	05jul15	Faster fsdb initialization.
-		Fix vcd recoder loader crash for malformed vcd if signal is 
+		Fix vcd recoder loader crash for malformed vcd if signal is
 		declared as bits and a real valued change is encountered for
 		the value change.
 		Fixed crash in vcd2vzt for vcd files with no value changes
@@ -1519,7 +1519,7 @@
 3.3.68	18nov15	Update copyright date.
 		Added named markers capability to From: and To: time value
 		input boxes.
-		Added support for fixed point binary numbers for both signed 
+		Added support for fixed point binary numbers for both signed
 		and unsigned decimal display types.
 3.3.69	03feb16	Added missing EXTLOAD_CFLAGS declarations in configure.ac for
 		FSDB detection when only .a files are present (necessary for
@@ -1536,8 +1536,8 @@
 		share/icons/hicolor/scalable/apps/gtkwave.svg directory.
 		Make gtkwave interpret values as double precision FP for
 		plotting when BitsToReal is enabled. Also keeps analog mode
-		enabled when selecting numerical formats (which allows 
-		enabling/disabling BitsToReal without going out of analog 
+		enabled when selecting numerical formats (which allows
+		enabling/disabling BitsToReal without going out of analog
 		mode). Disabling analog mode can be done using the
 		existing Analog->Off menu option.
 		Fix broken non-canonical bit ordering (IBM) single bit
@@ -1545,7 +1545,7 @@
 		Fixed gtkwave::gtkwave::addSignalsFromList so it can handle
 		subset and forward/reverse extractions on signals.
 		Remove FST_WRITER_PARALLEL from MinGW CFLAGS as some recent
-		versions of MinGW have issues with struct timespec when 
+		versions of MinGW have issues with struct timespec when
 		pthread.h is included.
 		Added /Edit/Delete to destroy traces without affecting the
 		existing cut buffer.
@@ -1568,7 +1568,7 @@
 		it is imported to the waveform display as an integer instead of
 		a hex value. This works for dump file formats that show the
 		datatype in the SST window.
-		Added code that should prevent the primary marker from 
+		Added code that should prevent the primary marker from
 		disappearing unexpectedly as well as dynamic resizing being
 		stuck in the unset marker width.
 3.3.75	02aug16	Fix crash when -S and -W are used in tandem.
@@ -1576,7 +1576,7 @@
 		Crash fix in fstapi.c on read value at time accessing of
 		FST files that use new dynamic aliases, FastLZ, or LZ4.  This
 		primarily affects rtlbrowse.
-3.3.77	03oct16	Updated documentation to include an appendix on FST 
+3.3.77	03oct16	Updated documentation to include an appendix on FST
 		implementation details.
 		Removed '!A || (A && B)' is equivalent to '!A || B' redundant
 		condition checks where found in source.
@@ -1595,14 +1595,14 @@
 		allow copying values into the clipboard so they can be pasted
 		into text editors, etc.
 3.3.81	09jun17	Added max_fsdb_trees environment variable.
-		Fixed -C option so it is persistent across new tabs.		
+		Fixed -C option so it is persistent across new tabs.
 		Integrated updated GHW reader code.
 3.3.82	02jul17	Get sys_fst working with VCS VPI.
 		Added string concatenations for vectors.
 		Added asserts to ghwlib.c to make scan-view clean.
 3.3.83	04aug17	Preserve search type for regex search across reloads or
 		close/reopens of regex search widget.
-		Update local libz to current version.		
+		Update local libz to current version.
 3.3.84	03sep17	Updated FSDB reader with experimental FST tree build
 		routines for faster init.
 		Removed warnings found when compiling with -Wshadow.
@@ -1616,8 +1616,8 @@
 		not stored as a string. This then allows bitwise manipulations
 		of integers.
 3.3.86	03oct17	Added recurse import function (found before only in the hier
-		search) into the SST.  
-		Removed obsolete bundle functionality from SST as recurse 
+		search) into the SST.
+		Removed obsolete bundle functionality from SST as recurse
 		import more accurately imports recursively.
 		Made entrybox taller (using -1) as recent versions of
 		gnome have taller window titlebars and the widget was not
@@ -1630,20 +1630,20 @@
 		Makefile.am.
 3.3.88	20feb18	Added --sstexclude command line option to prune unwanted
 		clutter from the SST window.
-                Updated "/View/Mouseover Copies To Clipboard" menu option to
-                copying signal names into the clipboard so they can be pasted
-                into text editors, etc.
-                Fixed Write Save File to handle	getting	confused by initial
-                cancel then retry.
+		Updated "/View/Mouseover Copies To Clipboard" menu option to
+		copying signal names into the clipboard so they can be pasted
+		into text editors, etc.
+		Fixed Write Save File to handle	getting	confused by initial
+		cancel then retry.
 		Updated v2k input/output declarations to handle unpacked arrays.
 		Fix for pattern marks that could overshoot the left marker.
 3.3.89  17mar18 Added support for 32-bit conversions in	BitsToReal.
 		Crash fix for pattern search with reals using LXT, LXT2, VZT.
 3.3.90  08may18 For Cut Traces, fix up scroll position if there are traces
-                above the current row being cut.
-                Bits to	real crash fix for very	large floats.
+		above the current row being cut.
+		Bits to	real crash fix for very	large floats.
 		Fixed gray code conversions that were incomplete for right
-		justified vectors such that the vector length is not a 
+		justified vectors such that the vector length is not a
 		multiple of the radix size (4 for hex, 3 for oct).
 		Warray-bounds warning fix for 32-bit conversions in BitsToReal.
 3.3.91	29may18	Added support for GSettings for when GConf is removed from
@@ -1668,46 +1668,46 @@
 3.3.95	07oct18 Added fflush on stdout for help text as fix for possible
 		stdout problem with mingw/msys shells.
 		Added preliminary support for Time datatype.
-                Warnings fixes for Verilator integration.
-                Fixed install_proc_filter usage	for Tcl	invocation.
+		Warnings fixes for Verilator integration.
+		Fixed install_proc_filter usage	for Tcl	invocation.
 		Change integer type to "integer" in SST to differentiate it
 		from sv ints.
 		Premiminary support for enum tables embedded in FST files.
 3.3.96	15nov18	Changed to standardized zoom in/out/full hotkeys.
 		Added time backtracking warning (for partial mode) to lxt2vcd.
-                VCD time backtracking fix (not for interactive mode).
+		VCD time backtracking fix (not for interactive mode).
 		Added drag_failed handling (can press ESC) to DnD operations.
-                Prevent	missing	file in	savefile from causing savefile to be
-                read as	VCD by mistake.
+		Prevent	missing	file in	savefile from causing savefile to be
+		read as	VCD by mistake.
 		Changed to Dinotrace-like 0s/1s rendering for bit vectors so
 		values can be discerned without seeing the full value text.
-                Removed unneeded pango_layout_get_extents() inside call for
-                font_engine_draw_string().
+		Removed unneeded pango_layout_get_extents() inside call for
+		font_engine_draw_string().
 		Changed bsearch_trunc() to run in constant time when monospace
 		fonts are in use.
 		Added missing GDK_SCROLL_MASK to signal area (need for gtk3,
 		but not for other versions for some reason).
 3.3.97	23nov18	Need to	set menu_wlist entry NULL on gtk_widget_destroy().
-                Fix on vtype()/vtype2()	to detect 'x' and make the coloration
-                red on newly-displayed traces. 	(Bug new from Dinotrace-like
-                rendering in 3.3.96.)
+		Fix on vtype()/vtype2()	to detect 'x' and make the coloration
+		red on newly-displayed traces. 	(Bug new from Dinotrace-like
+		rendering in 3.3.96.)
 3.3.98	27dec18	Removed pccts and vermin.  Use xml2stems instead.
 3.3.99	09feb19	Added visible single bit glitches as a yellow dot (if enabled
 		with --rcvar 'vcd_preserve_glitches on').
-                Fixed print routine broken by bsearch_trunc() optimization in
-                version	3.3.96.
+		Fixed print routine broken by bsearch_trunc() optimization in
+		version	3.3.96.
 3.3.100	20mar19	FSDB fix for variable declarations of array of reals.
-                Added Real, Time, Enum, and Popcnt flags to Edit/Show-Change.
+		Added Real, Time, Enum, and Popcnt flags to Edit/Show-Change.
 		Ensure Show-Change regenerates analog traces.
-                Added braces inside Tcl source command to allow spaces in
-                filenames for Tcl scripts.
+		Added braces inside Tcl source command to allow spaces in
+		filenames for Tcl scripts.
 3.3.101	08may19	Added gtkwave::getFacDir, gtkwave::getFacVtype, and
 		gtkwave::getFacDtype Tcl accessor functions that function
 		similar to gtkwave::getFacName.
 		Pair $end with $dumpvars in VCD	writers.
-		Make %.16g printing in baseconvert.c more resistant to power  
+		Make %.16g printing in baseconvert.c more resistant to power
 		of 10 roundoff errors.
-                Remove register	keyword	where applicable as is deprecated.
+		Remove register	keyword	where applicable as is deprecated.
 		Added --saveonexit gtkwave command line option.
 3.3.102	21sep19	Remove redundant TREE_VHDL_ST_PACKAGE from SST exclude.
 		Added addCommentTracesFromList tcl command from user patch.
@@ -1715,11 +1715,43 @@
 		Preliminary VHDL support for wlf2vcd.
 		Add missing return value checks on mmap() in FST writer.
 3.3.103 03nov19 Fix MAP_FAILED missing for MinGW.
-                Fix to make the coloration red on 'u' traces.  (Bug from
-                Dinotrace-like rendering in 3.3.96.)
-                Typo fix on missing group start on vectors.
+		Fix to make the coloration red on 'u' traces.  (Bug from
+		Dinotrace-like rendering in 3.3.96.)
+		Typo fix on missing group start on vectors.
 3.3.104	24jan20	Added support for loading .vf files (provided FSDB reader
 		libraries are enabled).
 		Added support for dumping variable types in vcd saveer, not
 		just using "wire" for non-reals/strings.
 		Fix for uninitialized values at time 0 for FST, FSDB loaders.
+3.3.105	01jul20	Fix bad (void) of is_closing in fstDestroyMmaps when using
+		Cygwin or MinGW.
+		Fix left shift overflow in cvt_fpsdec().
+		Add in missing file/translate/process filter for reals.
+		Fix for bitvec merging in GHW so integers arrays can be viewed.
+		Added Shift-Up/Down highlight with scroll in order to assist
+		with left/right arrow based transition movement.
+		Fix Show Wave Highlight so it is not dependent on Show Grid.
+		Fix negative MSBs on VCD loaders for vectors.
+		Fix getpwuid() null pointer exception.
+		Add missing recursion case to treenamefix().
+		Fix lock/unlock misuse of pthread mutexes across threads.
+		Examine env var $HOME for home dir on geteuid failure.
+3.3.106	06jul20	Fix for GDK_KEY_* definitions missing in older GDK versions.
+		Fix Shift-Up/Down highlight to traverse inside groups.
+		Resync ghwlib to handled unbounded arrays.
+3.3.107 30sep20 Fix left shift overflow in cvt_fpsudec for fixed point.
+		Added Find First One trace type	options.
+		Fixed bug in Show-Change All Highlighted.
+3.3.108	30dec20	Fix VZT writer crash when dumpoff is invoked before first
+		timestep.
+		Fix convert_ffo() that scanned in wrong direction.
+		Fix use	after free in fstapi.c.
+3.3.109 10apr21	gtk_ctree_node_moveto bugfix in SST.
+		MSVC compiler fix for fstapi.
+		Update xml2stems and rtlbrowse to support generate.
+3.3.110 22may21 Removed ghwdump and ghwdump.1 from the distribution (now 
+		provided with GHDL).
+		Minor scan-build fixes.
+3.3.111 01sep21	Fix in fstapi for read start limit time.
+		Fix xml2stems when begin blocks are in functions.
+		Skip over decimal point in timescale in viewer.
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 0da355c..3319877 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,14 +1,14 @@
 ##########################################################################
 
-GTKWave 3.3.104 Wave Viewer is Copyright (C) 1999-2020 Tony Bybell.  
-Portions of GTKWave are Copyright (C) 1999-2020 Udi Finkelstein. 
-Context support is Copyright (C) 2007-2020 Kermin Elliott Fleming.
-Trace group support is  Copyright (C) 2009-2020 Donald Baltus.
-GHW and additional GUI support is Copyright (C) 2005-2020 Tristan Gingold.
-Analog support is Copyright (C) 2005-2020 Thomas Sailer.
-External DnD support is Copyright (C) 2008-2020 Concept Engineering GmbH.
-FastLZ is Copyright (C) 2005-2020 Ariya Hidayat.
-LZ4 is Copyright (C) 2011-2020 Yann Collet.
+GTKWave 3.3.111 Wave Viewer is Copyright (C) 1999-2021 Tony Bybell.  
+Portions of GTKWave are Copyright (C) 1999-2021 Udi Finkelstein. 
+Context support is Copyright (C) 2007-2021 Kermin Elliott Fleming.
+Trace group support is  Copyright (C) 2009-2021 Donald Baltus.
+GHW and additional GUI support is Copyright (C) 2005-2021 Tristan Gingold.
+Analog support is Copyright (C) 2005-2021 Thomas Sailer.
+External DnD support is Copyright (C) 2008-2021 Concept Engineering GmbH.
+FastLZ is Copyright (C) 2005-2021 Ariya Hidayat.
+LZ4 is Copyright (C) 2011-2021 Yann Collet.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the Free
diff --git a/configure b/configure
index 723354d..a8830e6 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gtkwave 3.3.104.
+# Generated by GNU Autoconf 2.69 for gtkwave 3.3.111.
 #
 # Report bugs to <bybell@rocketmail.com>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='gtkwave'
 PACKAGE_TARNAME='gtkwave'
-PACKAGE_VERSION='3.3.104'
-PACKAGE_STRING='gtkwave 3.3.104'
+PACKAGE_VERSION='3.3.111'
+PACKAGE_STRING='gtkwave 3.3.111'
 PACKAGE_BUGREPORT='bybell@rocketmail.com'
 PACKAGE_URL=''
 
@@ -1405,7 +1405,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures gtkwave 3.3.104 to adapt to many kinds of systems.
+\`configure' configures gtkwave 3.3.111 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1471,7 +1471,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of gtkwave 3.3.104:";;
+     short | recursive ) echo "Configuration of gtkwave 3.3.111:";;
    esac
   cat <<\_ACEOF
 
@@ -1630,7 +1630,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-gtkwave configure 3.3.104
+gtkwave configure 3.3.111
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2274,7 +2274,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by gtkwave $as_me 3.3.104, which was
+It was created by gtkwave $as_me 3.3.111, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3141,7 +3141,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='gtkwave'
- VERSION='3.3.104'
+ VERSION='3.3.111'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -11499,7 +11499,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by gtkwave $as_me 3.3.104, which was
+This file was extended by gtkwave $as_me 3.3.111, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -11565,7 +11565,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-gtkwave config.status 3.3.104
+gtkwave config.status 3.3.111
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index b893679..05f616b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(gtkwave, 3.3.104, bybell@rocketmail.com)
+AC_INIT(gtkwave, 3.3.111, bybell@rocketmail.com)
 AC_CONFIG_SRCDIR([src/vcd.c])
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADER([config.h])
diff --git a/contrib/bundle_for_osx/Info-gtkwave.plist b/contrib/bundle_for_osx/Info-gtkwave.plist
index 6c86069..218b736 100644
--- a/contrib/bundle_for_osx/Info-gtkwave.plist
+++ b/contrib/bundle_for_osx/Info-gtkwave.plist
@@ -8,7 +8,7 @@
     <key>CFBundleExecutable</key>
     <string>gtkwave</string>
     <key>CFBundleGetInfoString</key>
-    <string>3.3.104, (C) 1999-2020 Tony Bybell http://gtkwave.sourceforge.net</string>
+    <string>3.3.111, (C) 1999-2021 Tony Bybell http://gtkwave.sourceforge.net</string>
     <key>CFBundleIconFile</key>
     <string>gtkwave.icns</string>
     <key>CFBundleIdentifier</key>
@@ -18,13 +18,13 @@
     <key>CFBundlePackageType</key>
     <string>APPL</string>
     <key>CFBundleShortVersionString</key>
-    <string>3.3.104</string>
+    <string>3.3.111</string>
     <key>CFBundleSignature</key>
     <string>????</string>
     <key>CFBundleVersion</key>
-    <string>3.3.104</string>
+    <string>3.3.111</string>
     <key>NSHumanReadableCopyright</key>
-    <string>Copyright 1999 - 2020 Tony Bybell, GNU General Public License.</string>
+    <string>Copyright 1999 - 2021 Tony Bybell, GNU General Public License.</string>
     <key>LSMinimumSystemVersion</key>
     <string>10.6</string>
 
diff --git a/contrib/bundle_for_osx/gtkwave.bundle b/contrib/bundle_for_osx/gtkwave.bundle
index d692f24..e52a13b 100644
--- a/contrib/bundle_for_osx/gtkwave.bundle
+++ b/contrib/bundle_for_osx/gtkwave.bundle
@@ -26,7 +26,7 @@
 
     <!-- Comment this out to keep the install names in binaries -->
     <run-install-name-tool/>
- 
+
     <!-- Optionally specify a launcher script to use. If the
          application sets up everything needed itself, like
          environment variable, linker paths, etc, a launcher script is
@@ -56,7 +56,6 @@
   <binary>${prefix}/bin/evcd2vcd</binary>
   <binary>${prefix}/bin/fst2vcd</binary>
   <binary>${prefix}/bin/vcd2fst</binary>
-  <binary>${prefix}/bin/ghwdump</binary>
   <binary>${prefix}/bin/lxt2miner</binary>
   <binary>${prefix}/bin/lxt2vcd</binary>
   <binary>${prefix}/bin/shmidcat</binary>
@@ -174,9 +173,6 @@
   <data dest="${bundle}/Contents/Resources/man/fst2vcd.1">
     ${project}/../../man/fst2vcd.1
   </data>
-  <data dest="${bundle}/Contents/Resources/man/ghwdump.1">
-    ${project}/../../man/ghwdump.1
-  </data>
   <data dest="${bundle}/Contents/Resources/man/gtkwave.1">
     ${project}/../../man/gtkwave.1
   </data>
@@ -272,16 +268,16 @@
   </data>
 
 
-  <!-- Copy in the patches so users can recreate gtk from source. 
-       This might be obsolete in future versions of gtk. 
-       See bug #664894. 
+  <!-- Copy in the patches so users can recreate gtk from source.
+       This might be obsolete in future versions of gtk.
+       See bug #664894.
     -->
   <data dest="${bundle}/Contents/Resources/share/patches/gtk_diff_against_modulesets.patch">
     ${project}/gtk_diff_against_modulesets.patch
   </data>
 
   <!-- Copy in the patches so users can recreate gtk from source.
-       This might be obsolete in future versions of gtk. 
+       This might be obsolete in future versions of gtk.
        No bug reported yet: this fixes yellow bars from gdk_pixbuf_get_from_drawable()
        which invokes _gdk_quartz_image_copy_to_image() that attempts to use 24-bit
        RGB pixels instead of 32-bit RGBA ones.
diff --git a/contrib/rtlbrowse/stem_recurse.c b/contrib/rtlbrowse/stem_recurse.c
index 79d310b..1ff1f91 100644
--- a/contrib/rtlbrowse/stem_recurse.c
+++ b/contrib/rtlbrowse/stem_recurse.c
@@ -108,9 +108,27 @@ char *compname_full;
 char *txt, *txt2 = NULL;
 ds_Tree *tdup = malloc(sizeof(ds_Tree));
 int numcomps;
+char *colon;
+char *compname2 = compname ? strdup(compname) : NULL;
+char *compname_colon = NULL;
+
+if(compname2)
+        {
+	compname_colon = strchr(compname2, ':');
+        if(compname_colon)
+                {
+                *compname_colon = 0;
+                }
+        }
 
 memcpy(tdup, t, sizeof(ds_Tree));
 t = tdup;
+colon = strchr(t->item, ':');
+if(colon)
+        {
+        *colon = 0; /* remove generate hack */
+        }
+
 
 t->next_flat = flattened_mod_list_root;
 flattened_mod_list_root = t;
@@ -119,10 +137,10 @@ if(compname_build)
 	{
 	int cnl = strlen(compname_build);
 
-	compname_full = malloc(cnl + 1 + strlen(compname) + 1);
+	compname_full = malloc(cnl + 1 + strlen(compname2) + 1);
 	strcpy(compname_full, compname_build);
 	compname_full[cnl] = '.';
-	strcpy(compname_full + cnl + 1, compname);
+	strcpy(compname_full + cnl + 1, compname2);
 	}
 	else
 	{
@@ -130,7 +148,7 @@ if(compname_build)
 	}
 
 t->fullname = compname_full;
-txt = compname_build ? compname : t->item;
+txt = compname_build ? compname2 : t->item;
 if(!t->filename)
 	{
 	txt2 = malloc(strlen(txt) + strlen(" [MISSING]") + 1);
@@ -139,6 +157,11 @@ if(!t->filename)
 	txt = txt2;
 	}
 
+if(colon)
+	{
+	*colon = ':';
+        }
+
 comp = t->comp;
 if(comp)
 	{
@@ -192,6 +215,8 @@ while(comp)
 	}
 #endif
 
+free(compname2); compname2 = NULL;
+
 return(subtree);
 }
 
diff --git a/contrib/wlf2vcd/wlf2vcd.c b/contrib/wlf2vcd/wlf2vcd.c
index efa2a01..7b0770e 100644
--- a/contrib/wlf2vcd/wlf2vcd.c
+++ b/contrib/wlf2vcd/wlf2vcd.c
@@ -10,7 +10,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <time.h>
-#include "wlf_api.h"
+#include <wlf_api.h>
 
 /* skips using wlfValueToString() and determines string directly from value representation */
 #define BYPASS_USING_VALUE_TO_STRING
diff --git a/contrib/xml2stems/xml2stems.cc b/contrib/xml2stems/xml2stems.cc
index 48fc11f..1d4b155 100644
--- a/contrib/xml2stems/xml2stems.cc
+++ b/contrib/xml2stems/xml2stems.cc
@@ -28,15 +28,83 @@
 #include <string>
 #include <map>
 #include <stack>
+#include <queue>
 using namespace std;
 
 #define BUF_SIZ 65536
 
+std::map <string, string>* parse_xml_tags(char *s, int *oneline)
+{
+char sprev;
+std::map <string, string> *fId = new std::map <string, string>;
+if(oneline) *oneline = 0;
+
+while(*s)
+	{
+	if(!isspace(*s))
+		{
+		char *tag_s = s;
+		char *tag_e = NULL;
+		char *val_s = NULL;
+		char *val_e = NULL;
+
+		sprev = 0;
+		while(*s)
+			{
+			if(!s) goto bot;
+
+			if(*s == '>')
+				{
+				if(sprev == '/')
+					{
+					if(oneline) *oneline = 1;
+					}
+	
+				goto bot;
+				}
+			sprev = *s;
+
+			if(*s == '=') { tag_e = s; break; }
+			s++;
+			}
+
+		while(*s)
+			{
+			if(!s) goto bot;
+			if(*s == '"') { val_s = ++s; break; }
+			s++;
+			}
+
+		while(*s)
+			{
+			if(!s) goto bot;
+			if(*s == '"') { val_e = s; break; }
+			s++;
+			}
+
+		if(tag_e && val_e)
+			{
+			*tag_e = 0;
+			*val_e = 0;
+			fId->insert(pair <string, string> (tag_s, val_s));
+			}
+		}
+	s++;
+	}
+
+bot: return(fId);
+}
+
+
 
 void xml2stems(FILE *fi, FILE *fo, int is_verilator_sim)
 {
 std::map <string, string> fId;
 std::stack<string> mId;
+queue<string> bQueue;
+int in_files = 0;
+int geninst = 0;
+int func_nesting_cnt = 0;
 
 while(!feof(fi))
 	{
@@ -58,56 +126,96 @@ while(!feof(fi))
 
 	switch(*pnt)
 		{
-		case 'm':
-			if(!strncmp(pnt, "module", 6))
+		case 'b':
+			if(!strncmp(pnt, "begin", 5) && !func_nesting_cnt)
 				{
 				if(!endtag)
 					{
-					char *qts[6];
-					char *s = pnt + 6;
-					int numqt = 0;
-					int tm = 0;
-
-					while(*s)
+					char *s = pnt + 5;
+					int oneline = 0;
+					std::map <string, string>*xmt = parse_xml_tags(s, &oneline);
+					if(xmt)
 						{
-						if(*s == '"')
+						const char *nam = (*xmt)[string("name")].c_str();
+						const char *fl = (*xmt)[string("fl")].c_str();
+
+						if(!oneline) 
 							{
-							qts[numqt++] = s;
-							if(numqt == 6) break;
+							bQueue.push((*xmt)[string("name")]);
+							if(fl && nam && nam[0])
+								{
+								char fl_dup[strlen(fl)+1];
+								const char *s = fl; char *d = fl_dup;
+								while(isalpha(*s)) { *(d++) = *(s++); }
+								*d = 0;
+	
+								unsigned int lineno = atoi(s);
+								const char *mnam = fId[fl_dup].c_str();
+
+								fprintf(fo, "++ begin %s file %s line %d\n", nam, mnam, lineno);
+
+								char *genname = (char *)malloc(strlen(nam) + 32);
+								sprintf(genname, "%s:G%d", nam, geninst++);
+								fprintf(fo, "++ comp %s type %s parent %s\n", genname, genname, mId.top().c_str()); 
+								fprintf(fo, "++ module %s file %s lines %d - %d\n", genname, mnam, lineno, lineno); /* don't need line number it truly ends at */
+								mId.push(genname);
+								free(genname);
+								}
 							}
-						s++;
+
+						delete xmt;
 						}
-	
-					if(numqt == 6)
+					}
+				else
+					{
+					string bs = bQueue.front();
+					bQueue.pop();
+					const char *nam = bs.c_str();
+					if(nam && nam[0])
 						{
-						if(strstr(qts[3]+1, "topModule=\"1\""))
-							{
-							numqt = 4;
-							tm = is_verilator_sim;
-							}
+						mId.pop();
+						fprintf(fo, "++ endbegin %s\n", nam);
 						}
+					}
+				
+				}
+			break;
 
-					if(numqt == 4)
-						{
-						char *fl = qts[0] + 1;
-						char *nam = qts[2] + 1;
-						qts[1][0] = qts[3][0] = 0;
-	
-						mId.push(nam);
+		case 'm':
+			if(!strncmp(pnt, "module", 6) && strncmp(pnt, "module_files", 12))
+				{
+				if(!endtag)
+					{
+					char *s = pnt + 6;
 
-						char fl_dup[strlen(fl)+1];
-						char *s = fl; char *d = fl_dup;
-						while(isalpha(*s)) { *(d++) = *(s++); }
-						*d = 0;
+                                	std::map <string, string>*xmt = parse_xml_tags(s, NULL);
+					if(xmt)
+						{
+						const char *fl = (*xmt)[string("fl")].c_str();
+						const char *nam = (*xmt)[string("name")].c_str();
+						const char *tms = (*xmt)[string("topModule")].c_str();
 
-						unsigned int lineno = atoi(s);
-						const char *mnam = fId[fl_dup].c_str();
-						fprintf(fo, "++ module %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */
-						if(tm)
+						if(fl && nam && tms)
 							{
-							fprintf(fo, "++ module TOP file %s lines %d - %d\n", "(VerilatorTop)", 1, 1);
-							fprintf(fo, "++ comp %s type %s parent TOP\n", nam, nam);
+							int tm = (tms[0] == '1') ? is_verilator_sim : 0;
+
+							mId.push(nam);
+
+							char fl_dup[strlen(fl)+1];
+							const char *s = fl; char *d = fl_dup;
+							while(isalpha(*s)) { *(d++) = *(s++); }
+							*d = 0;
+	
+							unsigned int lineno = atoi(s);
+							const char *mnam = fId[fl_dup].c_str();
+							fprintf(fo, "++ module %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */
+							if(tm)
+								{
+								fprintf(fo, "++ module TOP file %s lines %d - %d\n", "(VerilatorTop)", 1, 1);
+								fprintf(fo, "++ comp %s type %s parent TOP\n", nam, nam);
+								}
 							}
+						delete xmt;
 						}
 					}
 					else
@@ -120,29 +228,34 @@ while(!feof(fi))
 				}
 
 		case 'f':
-			if((!endtag) && (!strncmp(pnt, "file id", 7)))
+			if(!strncmp(pnt, "func", 4))
 				{
-				char *qts[4];
-				char *s = pnt + 7;
-				int numqt = 0;
-			
-				while(*s)
+				func_nesting_cnt = (!endtag) ? (func_nesting_cnt+1) : (func_nesting_cnt-1);
+				}
+			else
+			if(!strncmp(pnt, "files", 5))
+				{
+				in_files = (!endtag);
+				}
+			else
+				{
+				if((!endtag) && (in_files) && (!strncmp(pnt, "file", 4)))
 					{
-					if(*s == '"')
-						{
-						qts[numqt++] = s;
-						if(numqt == 4) break;
+					char *s = pnt + 4;
+	                                std::map <string, string>*xmt = parse_xml_tags(s, NULL);
+	
+	                                if(xmt)
+	                                       	{
+	                                        const char *cod = (*xmt)[string("id")].c_str();
+	                                        const char *fil = (*xmt)[string("filename")].c_str();
+	
+						if(cod && fil)
+							{
+							fId.insert(pair <string, string> (cod, fil));
+							}
+	
+						delete xmt;
 						}
-					s++;
-					}
-
-				if(numqt == 4)
-					{
-					char *cod = qts[0] + 1;
-					char *fil = qts[2] + 1;
-					qts[1][0] = qts[3][0] = 0;
-
-					fId.insert(pair <string, string> (cod, fil));
 					}
 				}
 			break;
@@ -150,31 +263,19 @@ while(!feof(fi))
 		case 'i':
 			if((!endtag) && (!strncmp(pnt, "instance", 8)))
 				{
-				char *qts[6];
 				char *s = pnt + 8;
-				int numqt = 0;
+				std::map <string, string>*xmt = parse_xml_tags(s, NULL);
 			
-				while(*s)
+				if(xmt)
 					{
-					if(*s == '"')
-						{
-						qts[numqt++] = s;
-						if(numqt == 6) break;
-						}
-					s++;
-					}
-
-				if(numqt == 6)
-					{
-					char *cod = qts[0] + 1;
-					char *nam = qts[2] + 1;
-					char *defnam = qts[4] + 1;
-					qts[1][0] = qts[3][0] = qts[5][0] = 0;
-
-					if(!mId.empty())
+					const char *nam = (*xmt)[string("name")].c_str();
+					const char *defnam = (*xmt)[string("defName")].c_str();
+					if(!mId.empty() && nam && defnam)
 						{
 						fprintf(fo, "++ comp %s type %s parent %s\n", nam, defnam, mId.top().c_str()); 
 						}
+
+					delete xmt;
 					}
 				}
 			break;
@@ -185,36 +286,29 @@ while(!feof(fi))
 				{
 				if(!endtag)
 					{
-					char *qts[4];
 					char *s = pnt + 9;
-					int numqt = 0;
 
-					while(*s)
+                                	std::map <string, string>*xmt = parse_xml_tags(s, NULL);
+					if(xmt)
 						{
-						if(*s == '"')
+						const char *fl = (*xmt)[string("fl")].c_str();
+						const char *nam = (*xmt)[string("name")].c_str();
+	
+						if(fl && nam)
 							{
-							qts[numqt++] = s;
-							if(numqt == 6) break;
-							}
-						s++;
-						}
+							mId.push(nam);
 	
-					if(numqt == 4)
-						{
-						char *fl = qts[0] + 1;
-						char *nam = qts[2] + 1;
-						qts[1][0] = qts[3][0] = 0;
+							char fl_dup[strlen(fl)+1];
+							const char *s = fl; char *d = fl_dup;
+							while(isalpha(*s)) { *(d++) = *(s++); }
+							*d = 0;
 	
-						mId.push(nam);
-
-						char fl_dup[strlen(fl)+1];
-						char *s = fl; char *d = fl_dup;
-						while(isalpha(*s)) { *(d++) = *(s++); }
-						*d = 0;
+							unsigned int lineno = atoi(s);
+							const char *mnam = fId[fl_dup].c_str();
+							fprintf(fo, "++ udp %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */
+							}
 
-						unsigned int lineno = atoi(s);
-						const char *mnam = fId[fl_dup].c_str();
-						fprintf(fo, "++ udp %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */
+						delete xmt;
 						}
 					}
 					else
diff --git a/doc/gtkwave.odt b/doc/gtkwave.odt
index adb745b..aab3797 100644
Binary files a/doc/gtkwave.odt and b/doc/gtkwave.odt differ
diff --git a/man/Makefile.am b/man/Makefile.am
index 616fd67..36b5513 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,7 +1,7 @@
 ## -*- makefile -*-
 ##
 
-dist_man_MANS= evcd2vcd.1 fst2vcd.1 ghwdump.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \
+dist_man_MANS= evcd2vcd.1 fst2vcd.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \
 	lxt2vcd.1 rtlbrowse.1 shmidcat.1 \
 	twinwave.1 vcd2fst.1 vcd2lxt.1 vcd2lxt2.1 \
 	vcd2vzt.1 vzt2vcd.1 vztminer.1 fstminer.1 \
diff --git a/man/Makefile.in b/man/Makefile.in
index ef40e94..9ea63fd 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -299,7 +299,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-dist_man_MANS = evcd2vcd.1 fst2vcd.1 ghwdump.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \
+dist_man_MANS = evcd2vcd.1 fst2vcd.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \
 	lxt2vcd.1 rtlbrowse.1 shmidcat.1 \
 	twinwave.1 vcd2fst.1 vcd2lxt.1 vcd2lxt2.1 \
 	vcd2vzt.1 vzt2vcd.1 vztminer.1 fstminer.1 \
diff --git a/man/fstminer.1 b/man/fstminer.1
index 8961776..71ead77 100644
--- a/man/fstminer.1
+++ b/man/fstminer.1
@@ -43,4 +43,4 @@ cut down on the size of output files and to aid in following data such as addres
 Anthony Bybell <bybell@rocketmail.com>
 .SH "SEE ALSO"
 .LP 
-\fIvztminer\fP(1) \fIlxt2miner\fP(1) \fIfst2vcd\fP(1) \fIvcd2fst2\fP(1) \fIgtkwave\fP(1)
+\fIvztminer\fP(1) \fIlxt2miner\fP(1) \fIfst2vcd\fP(1) \fIvcd2fst\fP(1) \fIgtkwave\fP(1)
diff --git a/man/ghwdump.1 b/man/ghwdump.1
deleted file mode 100644
index 6d98c30..0000000
--- a/man/ghwdump.1
+++ /dev/null
@@ -1,39 +0,0 @@
-.TH "GHWDUMP" "1" "1.0" "Tristan Gingold" "GHW File Debugging Information"
-.SH "NAME"
-.LP 
-ghwdump \- Dumps info contained in GHW files
-.SH "SYNTAX"
-.LP 
-ghwdump [\fIoption\fP]... \fIGHWFILE\fP [[\fIGHWFILE\fP]...]
-
-.SH "DESCRIPTION"
-.LP 
-Dumps information contained in GHW files for debugging purposes.
-.SH "OPTIONS"
-.LP 
-.TP 
-
-\fB\-t\fR
-Display types
-.TP
-\fB\-h\fR
-Display hierarchy
-.TP
-\fB\-T\fR
-Display time
-.TP
-\fB\-s\fR
-Display signals (and time)
-.TP
-\fB\-l\fR
-Display list of sections
-.TP
-\fB\-v\fR
-Verbose
-
-.SH "AUTHORS"
-.LP 
-Tristan Gingold
-.SH "SEE ALSO"
-.LP 
-\fIgtkwave\fP(1)
diff --git a/man/gtkwaverc.5 b/man/gtkwaverc.5
index b01a6fb..2b92b9c 100644
--- a/man/gtkwaverc.5
+++ b/man/gtkwaverc.5
@@ -287,6 +287,9 @@ When nonzero, indicates that the signal window signal name justification should
 \fBlxt_clock_compress_to_z\fR <\fIvalue\fP>
 For LXT (not LXT2) allows clocks to compress to a 'z' value so that regular/periodic value changes may be noted.
 .TP
+\fBlz_removal\fR <\fIvalue\fP>
+When nonzero, suppresses the display of leading zeros on non-filtered traces.  This has no effect on filtered traces.
+.TP
 \fBmax_fsdb_trees\fR <\fIvalue\fP>
 sets the maximum number of hierarchy and signal trees to process for an FSDB file.  Default = 0 = unlimited.  The intent of this is to work around sim environments that accidentally call fsdbDumpVars multiple times. 
 .TP
diff --git a/src/Makefile.am b/src/Makefile.am
index ca4eed2..bb87999 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,7 +38,7 @@ gtkwave_SOURCES= \
 	debug.c debug.h discardbuttons.c edgebuttons.c \
 	entry.c extload.c extload.h fetchbuttons.c fgetdynamic.c fgetdynamic.h file.c fonts.c fonts.h fst.c fst.h \
 	gconf.c gconf.h getopt.c \
-	getopt1.c ghw.c ghw.h ghwlib.c ghwlib.h gnu-getopt.h gnu_regex.h gtk12compat.h \
+	getopt1.c ghw.c ghw.h libghw.c libghw.h gnu-getopt.h gnu_regex.h gtk12compat.h \
 	hierpack.c hierpack.h jrb.c jrb.h help.c helpers/lxt2_read.c \
 	helpers/lxt_write.c helpers/vzt_read.c hiersearch.c interp.c \
 	logfile.c lx2.c lx2.h lxt.c lxt.h main.c main.h markerbox.c menu.c menu.h mouseover.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index f3ab4fe..ed74160 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -98,7 +98,7 @@ am_gtkwave_OBJECTS = fsdb_wrapper_api.$(OBJEXT) globals.$(OBJEXT) \
 	entry.$(OBJEXT) extload.$(OBJEXT) fetchbuttons.$(OBJEXT) \
 	fgetdynamic.$(OBJEXT) file.$(OBJEXT) fonts.$(OBJEXT) \
 	fst.$(OBJEXT) gconf.$(OBJEXT) getopt.$(OBJEXT) \
-	getopt1.$(OBJEXT) ghw.$(OBJEXT) ghwlib.$(OBJEXT) \
+	getopt1.$(OBJEXT) ghw.$(OBJEXT) libghw.$(OBJEXT) \
 	hierpack.$(OBJEXT) jrb.$(OBJEXT) help.$(OBJEXT) \
 	lxt2_read.$(OBJEXT) lxt_write.$(OBJEXT) vzt_read.$(OBJEXT) \
 	hiersearch.$(OBJEXT) interp.$(OBJEXT) logfile.$(OBJEXT) \
@@ -434,7 +434,7 @@ gtkwave_SOURCES = \
 	debug.c debug.h discardbuttons.c edgebuttons.c \
 	entry.c extload.c extload.h fetchbuttons.c fgetdynamic.c fgetdynamic.h file.c fonts.c fonts.h fst.c fst.h \
 	gconf.c gconf.h getopt.c \
-	getopt1.c ghw.c ghw.h ghwlib.c ghwlib.h gnu-getopt.h gnu_regex.h gtk12compat.h \
+	getopt1.c ghw.c ghw.h libghw.c libghw.h gnu-getopt.h gnu_regex.h gtk12compat.h \
 	hierpack.c hierpack.h jrb.c jrb.h help.c helpers/lxt2_read.c \
 	helpers/lxt_write.c helpers/vzt_read.c hiersearch.c interp.c \
 	logfile.c lx2.c lx2.h lxt.c lxt.h main.c main.h markerbox.c menu.c menu.h mouseover.c \
@@ -574,13 +574,13 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghw.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwlib.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hierpack.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hiersearch.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libghw.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt.Po@am__quote@
diff --git a/src/analyzer.c b/src/analyzer.c
index ef57032..c7dc8ac 100644
--- a/src/analyzer.c
+++ b/src/analyzer.c
@@ -223,6 +223,22 @@ void ClearGroupTraces(Trptr t_grp)
     }
 }
 
+void MarkTraceCursor(Trptr t_curs)
+{
+if(t_curs)
+	{
+        Trptr t=GLOBALS->traces.first;
+
+        while(t)
+                {
+                t->is_cursor = 0;
+                t=t->t_next;
+                }
+
+        t_curs->is_cursor = 1;
+        }
+}
+
 /*
  * Add a trace to the display...
  */
diff --git a/src/analyzer.h b/src/analyzer.h
index 1a40015..5079396 100644
--- a/src/analyzer.h
+++ b/src/analyzer.h
@@ -513,6 +513,7 @@ typedef struct TraceEnt
     unsigned int t_color;	/* trace color index */
     unsigned char t_fpdecshift; /* for fixed point decimal */
 
+    unsigned is_cursor : 1;     /* set to mark a cursor trace */
     unsigned is_alias : 1;	/* set when it's an alias (safe to free t->name then) */
     unsigned is_depacked : 1;	/* set when it's been depacked from a compressed entry (safe to free t->name then) */
     unsigned vector : 1;	/* 1 if bit vector, 0 if node */
@@ -538,6 +539,8 @@ enum TraceEntFlagBits
   TR_FPDECSHIFT_B,
   TR_TIME_B,
   TR_ENUM_B,
+  TR_CURSOR_B,
+  TR_FFO_B,
 
   TR_RSVD_B /* for use internally such as temporary caching of highlighting, not for use in traces */
 };
@@ -574,6 +577,7 @@ enum TraceEntFlagBits
 #define TR_REAL2BITS            (UINT64_C(1)<<TR_REAL2BITS_B)
 
 #define TR_NUMMASK	(TR_ASCII|TR_HEX|TR_DEC|TR_BIN|TR_OCT|TR_SIGNED|TR_REAL|TR_TIME|TR_ENUM)
+#define TR_ATTRIBS      (TR_RJUSTIFY|TR_INVERT|TR_REVERSE|TR_EXCLUDE|TR_POPCNT|TR_FFO)
 
 #define TR_COLLAPSED	(UINT64_C(1)<<TR_COLLAPSED_B)
 #define TR_ISCOLLAPSED	(TR_BLANK|TR_COLLAPSED)
@@ -588,6 +592,9 @@ enum TraceEntFlagBits
 #define TR_TIME         (UINT64_C(1)<<TR_TIME_B)
 #define TR_ENUM         (UINT64_C(1)<<TR_ENUM_B)
 
+#define TR_CURSOR	(UINT64_C(1)<<TR_CURSOR_B)
+#define TR_FFO          (UINT64_C(1)<<TR_FFO_B)
+
 #define TR_ANALOGMASK	(TR_ANALOG_STEP|TR_ANALOG_INTERPOLATED)
 
 #define TR_RSVD		(UINT64_C(1)<<TR_RSVD_B)
@@ -647,6 +654,7 @@ void OpenTrace(Trptr t);
 void CloseTrace(Trptr t);
 void ClearTraces(void);
 void ClearGroupTraces(Trptr t);
+void MarkTraceCursor(Trptr t);
 
 char *varxt_fix(char *s);
 
diff --git a/src/baseconvert.c b/src/baseconvert.c
index 6a1fca4..22c4406 100644
--- a/src/baseconvert.c
+++ b/src/baseconvert.c
@@ -29,16 +29,186 @@
 #endif
 
 /*
- * convert binary <=> gray/popcnt in place
+ * filters mutually exclusive with file/translate/process filters
+ */
+static char *lzremoval(char *s)
+{
+char *p = s;
+
+if(*p)
+      	{
+	while((*p=='0') && *(p+1))
+                {
+                p++;
+                }
+        }
+
+if(p != s)
+	{
+	memmove(s, p, strlen(p) + 1);
+        }
+
+return(s);
+}
+
+/*
+ * file/translate/process filters
+ */
+static char *dofilter(Trptr t, char *s)
+{
+GLOBALS->xl_file_filter[t->f_filter] = xl_splay(s, GLOBALS->xl_file_filter[t->f_filter]);
+
+if(!strcasecmp(s, GLOBALS->xl_file_filter[t->f_filter]->item))
+	{
+	free_2(s);
+	s = malloc_2(strlen(GLOBALS->xl_file_filter[t->f_filter]->trans) + 1);
+	strcpy(s, GLOBALS->xl_file_filter[t->f_filter]->trans);
+	}
+
+if((*s == '?') && (!GLOBALS->color_active_in_filter))
+	{
+	char *s2a;
+	char *s2 = strchr(s+1, '?');
+	if(s2)
+		{
+		s2++;
+		s2a = malloc_2(strlen(s2)+1);
+		strcpy(s2a, s2);
+		free_2(s);
+		s = s2a;
+		}
+	}
+
+return(s);
+}
+
+static char *edofilter(Trptr t, char *s)
+{
+if(t->flags & TR_ENUM)
+	{
+	int filt = t->e_filter - 1;
+
+#ifdef _WAVE_HAVE_JUDY
+	PPvoid_t pv = JudyHSGet(GLOBALS->xl_enum_filter[filt], s, strlen(s));
+	if(pv)
+		{
+		free_2(s);
+		s = malloc_2(strlen(*pv) + 1);
+		strcpy(s, *pv);
+		}
+#else
+	GLOBALS->xl_enum_filter[filt] = xl_splay(s, GLOBALS->xl_enum_filter[filt]);
+
+	if(!strcasecmp(s, GLOBALS->xl_enum_filter[filt]->item))
+		{
+		free_2(s);
+		s = malloc_2(strlen(GLOBALS->xl_enum_filter[filt]->trans) + 1);
+		strcpy(s, GLOBALS->xl_enum_filter[filt]->trans);
+		}
+#endif
+	else
+		{
+		char *zerofind = s;
+		char *dst = s, *src;
+		while(*zerofind == '0') zerofind++;
+		if(zerofind != s)
+			{
+			src = (!*zerofind) ? (zerofind-1) : zerofind;
+			while(*src)
+				{
+				*(dst++) = *(src++);
+				}
+			*dst = 0;
+			}
+		}
+	}
+
+return(s);
+}
+
+static char *pdofilter(Trptr t, char *s)
+{
+struct pipe_ctx *p = GLOBALS->proc_filter[t->p_filter];
+char buf[1025];
+int n;
+
+if(p)
+	{
+#if !defined _MSC_VER && !defined __MINGW32__
+	fputs(s, p->sout);
+	fputc('\n', p->sout);
+	fflush(p->sout);
+
+	buf[0] = 0;
+
+	n = fgets(buf, 1024, p->sin) ? strlen(buf) : 0;
+	buf[n] = 0;
+#else
+	{
+	BOOL bSuccess;
+	DWORD dwWritten, dwRead;
+
+	WriteFile(p->g_hChildStd_IN_Wr, s, strlen(s), &dwWritten, NULL);
+	WriteFile(p->g_hChildStd_IN_Wr, "\n", 1, &dwWritten, NULL);
+
+	for(n=0;n<1024;n++)
+		{
+		do 	{
+			bSuccess = ReadFile(p->g_hChildStd_OUT_Rd, buf+n, 1, &dwRead, NULL);
+			if((!bSuccess)||(buf[n]=='\n'))
+				{
+				goto ex;
+				}
+
+			} while(buf[n]=='\r');
+		}
+ex:	buf[n] = 0;
+	}
+
+#endif
+
+	if(n)
+		{
+		if(buf[n-1] == '\n') { buf[n-1] = 0; n--; }
+		}
+
+	if(buf[0])
+		{
+		free_2(s);
+		s = malloc_2(n + 1);
+		strcpy(s, buf);
+		}
+	}
+
+if((*s == '?') && (!GLOBALS->color_active_in_filter))
+	{
+	char *s2a;
+	char *s2 = strchr(s+1, '?');
+	if(s2)
+		{
+		s2++;
+		s2a = malloc_2(strlen(s2)+1);
+		strcpy(s2a, s2);
+		free_2(s);
+		s = s2a;
+		}
+	}
+return(s);
+}
+
+
+/*
+ * convert binary <=> gray/ffo/popcnt in place
  */
 #define cvt_gray(f,p,n) \
 do { \
-if((f)&(TR_GRAYMASK|TR_POPCNT)) \
-	{ \
-	if((f)&TR_BINGRAY) { convert_bingray((p),(n)); } \
-	if((f)&TR_GRAYBIN) { convert_graybin((p),(n)); } \
-	if((f)&TR_POPCNT)  { convert_popcnt((p),(n)); } \
-	} \
+if((f)&(TR_GRAYMASK|TR_POPCNT|TR_FFO)) \
+        { \
+        if((f)&TR_BINGRAY) { convert_bingray((p),(n)); } \
+        if((f)&TR_GRAYBIN) { convert_graybin((p),(n)); } \
+	if((f)&TR_FFO)     { convert_ffo((p),(n)); } \
+        if((f)&TR_POPCNT)  { convert_popcnt((p),(n)); } \
+        } \
 } while(0)
 
 
@@ -168,6 +338,40 @@ for(i=nbits-1;i>=0;i--) /* always requires less number of bits */
 }
 
 
+static void convert_ffo(char *pnt, int nbits)
+{
+int i;
+int ffo = -1;
+
+for(i=(nbits-1);i>=0;i--)
+        {
+        char ch = pnt[i];
+
+        if((ch == AN_1) || (ch == AN_H))
+                {
+                ffo = (nbits-1) - i;
+                break;
+                }
+        }
+
+if(ffo >= 0)
+        {
+        for(i=nbits-1;i>=0;i--) /* always requires less number of bits */
+                {
+                pnt[i] = (ffo & 1) ? AN_1 : AN_0;
+                ffo >>= 1;
+                }
+        }
+	else
+	{
+	for(i=nbits-1;i>=0;i--) /* always requires less number of bits */
+                {
+                pnt[i] = AN_X;
+                }
+        }
+}
+
+
 static void dpr_e16(char *str, double d)
 {
 char *buf16;
@@ -196,7 +400,8 @@ static void cvt_fpsdec(Trptr t, TimeType val, char *os, int len, int nbits)
 
 int shamt = t->t_fpdecshift;
 TimeType lpart = val >> shamt;
-TimeType rmsk = (1 << shamt);
+TimeType rmsk = (ULLDescriptor(1) << shamt);
+
 TimeType rbit = (val >= 0) ? (val & (rmsk-1)) : ((-val) & (rmsk-1));
 double rfrac;
 int negflag = 0;
@@ -245,7 +450,7 @@ static void cvt_fpsudec(Trptr t, TimeType val, char *os, int len)
 {
 int shamt = t->t_fpdecshift;
 UTimeType lpart = ((UTimeType)val) >> shamt;
-TimeType rmsk = (1 << shamt);
+TimeType rmsk = (ULLDescriptor(1) << shamt);
 TimeType rbit = (val & (rmsk-1));
 double rfrac;
 char dbuf[32];
@@ -466,7 +671,7 @@ if(flags&TR_ASCII)
 	if(GLOBALS->show_base) { *(pnt++)='"'; }
 	*(pnt)=0x00; /* scan build : remove dead increment */
 	}
-else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&TR_POPCNT))))
+else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&(TR_POPCNT|TR_FFO)))))
 	{
 	char *parse;
 
@@ -896,6 +1101,30 @@ if(t && (t->flags & TR_REAL2BITS) && d) /* "real2bits" also allows other filters
 		}
 	}
 
+if(t)
+	{
+	if(!(t->f_filter|t->p_filter|t->e_filter))
+	        {
+		if(GLOBALS->lz_removal) lzremoval(rv);
+		}
+	        else
+	        {
+	        if(t->e_filter)
+	                {
+	                rv = edofilter(t, rv);
+	                }
+	        else
+	        if(t->f_filter)
+	                {
+	                rv = dofilter(t, rv);
+	                }
+	                else
+	                {
+	                rv = pdofilter(t, rv);
+	                }
+	        }
+	}
+
 return(rv);
 }
 
@@ -1215,7 +1444,7 @@ if(flags&TR_ASCII)
 	if(GLOBALS->show_base) { *(pnt++)='"'; }
 	*(pnt)=0x00; /* scan build : remove dead increment */
 	}
-else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&TR_POPCNT))))
+else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&(TR_POPCNT|TR_FFO)))))
 	{
 	char *parse;
 
@@ -1596,155 +1825,13 @@ return(os);
 }
 
 
-static char *dofilter(Trptr t, char *s)
-{
-GLOBALS->xl_file_filter[t->f_filter] = xl_splay(s, GLOBALS->xl_file_filter[t->f_filter]);
-
-if(!strcasecmp(s, GLOBALS->xl_file_filter[t->f_filter]->item))
-	{
-	free_2(s);
-	s = malloc_2(strlen(GLOBALS->xl_file_filter[t->f_filter]->trans) + 1);
-	strcpy(s, GLOBALS->xl_file_filter[t->f_filter]->trans);
-	}
-
-if((*s == '?') && (!GLOBALS->color_active_in_filter))
-	{
-	char *s2a;
-	char *s2 = strchr(s+1, '?');
-	if(s2)
-		{
-		s2++;
-		s2a = malloc_2(strlen(s2)+1);
-		strcpy(s2a, s2);
-		free_2(s);
-		s = s2a;
-		}
-	}
-
-return(s);
-}
-
-static char *edofilter(Trptr t, char *s)
-{
-if(t->flags & TR_ENUM)
-	{
-	int filt = t->e_filter - 1;
-
-#ifdef _WAVE_HAVE_JUDY
-	PPvoid_t pv = JudyHSGet(GLOBALS->xl_enum_filter[filt], s, strlen(s));
-	if(pv)
-		{
-		free_2(s);
-		s = malloc_2(strlen(*pv) + 1);
-		strcpy(s, *pv);
-		}
-#else
-	GLOBALS->xl_enum_filter[filt] = xl_splay(s, GLOBALS->xl_enum_filter[filt]);
-
-	if(!strcasecmp(s, GLOBALS->xl_enum_filter[filt]->item))
-		{
-		free_2(s);
-		s = malloc_2(strlen(GLOBALS->xl_enum_filter[filt]->trans) + 1);
-		strcpy(s, GLOBALS->xl_enum_filter[filt]->trans);
-		}
-#endif
-	else
-		{
-		char *zerofind = s;
-		char *dst = s, *src;
-		while(*zerofind == '0') zerofind++;
-		if(zerofind != s)
-			{
-			src = (!*zerofind) ? (zerofind-1) : zerofind;
-			while(*src)
-				{
-				*(dst++) = *(src++);
-				}
-			*dst = 0;
-			}
-		}
-	}
-
-return(s);
-}
-
-static char *pdofilter(Trptr t, char *s)
-{
-struct pipe_ctx *p = GLOBALS->proc_filter[t->p_filter];
-char buf[1025];
-int n;
-
-if(p)
-	{
-#if !defined _MSC_VER && !defined __MINGW32__
-	fputs(s, p->sout);
-	fputc('\n', p->sout);
-	fflush(p->sout);
-
-	buf[0] = 0;
-
-	n = fgets(buf, 1024, p->sin) ? strlen(buf) : 0;
-	buf[n] = 0;
-#else
-	{
-	BOOL bSuccess;
-	DWORD dwWritten, dwRead;
-
-	WriteFile(p->g_hChildStd_IN_Wr, s, strlen(s), &dwWritten, NULL);
-	WriteFile(p->g_hChildStd_IN_Wr, "\n", 1, &dwWritten, NULL);
-
-	for(n=0;n<1024;n++)
-		{
-		do 	{
-			bSuccess = ReadFile(p->g_hChildStd_OUT_Rd, buf+n, 1, &dwRead, NULL);
-			if((!bSuccess)||(buf[n]=='\n'))
-				{
-				goto ex;
-				}
-
-			} while(buf[n]=='\r');
-		}
-ex:	buf[n] = 0;
-	}
-
-#endif
-
-	if(n)
-		{
-		if(buf[n-1] == '\n') { buf[n-1] = 0; n--; }
-		}
-
-	if(buf[0])
-		{
-		free_2(s);
-		s = malloc_2(n + 1);
-		strcpy(s, buf);
-		}
-	}
-
-if((*s == '?') && (!GLOBALS->color_active_in_filter))
-	{
-	char *s2a;
-	char *s2 = strchr(s+1, '?');
-	if(s2)
-		{
-		s2++;
-		s2a = malloc_2(strlen(s2)+1);
-		strcpy(s2a, s2);
-		free_2(s);
-		s = s2a;
-		}
-	}
-return(s);
-}
-
-
 char *convert_ascii_vec(Trptr t, char *vec)
 {
 char *s = convert_ascii_vec_2(t, vec);
 
 if(!(t->f_filter|t->p_filter|t->e_filter))
 	{
+	if(GLOBALS->lz_removal) lzremoval(s);
 	}
 	else
 	{
@@ -1795,6 +1882,7 @@ if((!t->t_filter_converted) && (!(v->flags & HIST_STRING)))
 
 if(!(t->f_filter|t->p_filter|t->e_filter))
 	{
+	if(GLOBALS->lz_removal) lzremoval(s);
 	}
 	else
 	{
diff --git a/src/currenttime.c b/src/currenttime.c
index 4a0dfa1..c8ea313 100644
--- a/src/currenttime.c
+++ b/src/currenttime.c
@@ -28,7 +28,38 @@ char buf[32], sfx[2];
 int i, len;
 int prefix_idx = 0;
 
-if(*s != '0') return;
+if(*s != '0')
+        {
+        unsigned char *dot = strchr(s, '.');
+        unsigned char *src, *dst;
+        if(dot)
+                {
+                unsigned char *pnt = dot+1;
+                int alpha_found = 0;
+                while(*pnt)
+                        {
+                        if(isalpha(*pnt))
+                                {
+                                alpha_found = 1;
+                                break;
+                                }
+                        pnt++;
+                        }
+
+                if(alpha_found)
+                        {
+                        src = pnt;
+                        dst = dot;
+                        while(*src)
+                                {
+                                *dst = *src;
+                                dst++; src++;
+                                }
+                        *dst = 0;
+                        }
+                }
+        return;
+        }
 
 len = strlen(s);
 for(i=0;i<len;i++)
diff --git a/src/ghw.c b/src/ghw.c
index b287761..a5b4d61 100644
--- a/src/ghw.c
+++ b/src/ghw.c
@@ -20,7 +20,7 @@
 #include "globals.h"
 #include <config.h>
 #include "ghw.h"
-#include "ghwlib.h"
+#include "libghw.h"
 #include "tree.h"
 
 /************************ splay ************************/
@@ -173,42 +173,52 @@ for(i=0;i<GLOBALS->numfacs;i++)
 	{
 	if(psr)
 		{
-		char *fstr1 = GLOBALS->facs[i-1]->name;
-		char *fstr2 = GLOBALS->facs[i]->name;
-		int p1 = strand_pnt(fstr1);
-		int p2 = strand_pnt(fstr2);
+		int ev1 = GLOBALS->facs[i-1]->n->extvals;
+		int ev2 = GLOBALS->facs[i]->n->extvals;
 
-		if(!root)
+		if(!ev1 && !ev2)
 			{
-			if((p1>=0)&&(p1==p2))
+			char *fstr1 = GLOBALS->facs[i-1]->name;
+			char *fstr2 = GLOBALS->facs[i]->name;
+			int p1 = strand_pnt(fstr1);
+			int p2 = strand_pnt(fstr2);
+
+			if(!root)
 				{
-				if(!strncmp(fstr1, fstr2, p1))
+				if((p1>=0)&&(p1==p2))
 					{
-					root = GLOBALS->facs[i-1];
-					root->vec_root = root;
-					root->vec_chain = GLOBALS->facs[i];
-					GLOBALS->facs[i]->vec_root = root;
+					if(!strncmp(fstr1, fstr2, p1))
+						{
+						root = GLOBALS->facs[i-1];
+						root->vec_root = root;
+						root->vec_chain = GLOBALS->facs[i];
+						GLOBALS->facs[i]->vec_root = root;
+						}
 					}
 				}
-			}
-			else
-			{
-			if((p1>=0)&&(p1==p2))
+				else
 				{
-				if(!strncmp(fstr1, fstr2, p1))
+				if((p1>=0)&&(p1==p2))
 					{
-					psr->vec_chain = GLOBALS->facs[i];
-					GLOBALS->facs[i]->vec_root = root;
+					if(!strncmp(fstr1, fstr2, p1))
+						{
+						psr->vec_chain = GLOBALS->facs[i];
+						GLOBALS->facs[i]->vec_root = root;
+						}
+						else
+						{
+						root = NULL;
+						}
 					}
 					else
 					{
 					root = NULL;
 					}
 				}
-				else
-				{
-				root = NULL;
-				}
+			}
+			else
+			{
+			root = NULL;
 			}
 		}
 
@@ -233,9 +243,9 @@ if(t)
 	int i;
 	int cnt = 1;
 	struct tree **ar;
-	
+
 	while((t2 = t2->next)) { cnt++; }
-	
+
 	ar = malloc_2(cnt * sizeof(struct tree *));
 	t2 = t;
 	for(i=0;i<cnt;i++)
@@ -244,16 +254,16 @@ if(t)
 		if(t2->child) { recurse_tree_build_whichcache(t2->child); }
 		t2 = t2->next;
 		}
-	
+
 	for(i=cnt-1;i>=0;i--)
 		{
 		t = ar[i];
-		if(t->t_which >= 0) 
+		if(t->t_which >= 0)
 			{
 			GLOBALS->gwt_ghw_c_1 = ghw_insert(t, GLOBALS->gwt_ghw_c_1, t->t_which, GLOBALS->facs[t->t_which]);
 			}
 		}
-	
+
 	free_2(ar);
 	}
 }
@@ -266,9 +276,9 @@ if(t)
 	int i;
 	int cnt = 1;
 	struct tree **ar;
-	
+
 	while((t2 = t2->next)) { cnt++; }
-	
+
 	ar = malloc_2(cnt * sizeof(struct tree *));
 	t2 = t;
 	for(i=0;i<cnt;i++)
@@ -277,7 +287,7 @@ if(t)
 		if(t2->child) { recurse_tree_fix_from_whichcache(t2->child); }
 		t2 = t2->next;
 		}
-	
+
 	for(i=cnt-1;i>=0;i--)
 		{
 		t = ar[i];
@@ -285,11 +295,11 @@ if(t)
 			{
 			GLOBALS->gwt_ghw_c_1 = ghw_splay(t, GLOBALS->gwt_ghw_c_1);
 			GLOBALS->gwt_corr_ghw_c_1 = ghw_splay(GLOBALS->gwt_ghw_c_1->sym, GLOBALS->gwt_corr_ghw_c_1); /* all facs are in this tree so this is OK */
-	
+
 			t->t_which = GLOBALS->gwt_corr_ghw_c_1->val_old;
 			}
 		}
-	
+
 	free_2(ar);
 	}
 }
@@ -440,7 +450,8 @@ build_hierarchy_array (struct ghw_handler *h, union ghw_type *arr, int dim,
 		       const char *pfx, struct tree **res, unsigned int **sig)
 {
   union ghw_type *idx;
-  struct ghw_type_array *base = arr->sa.base;
+  struct ghw_type_array *base =
+    (struct ghw_type_array *) ghw_get_base_type (arr->sa.base);
   char *name = NULL;
 
   if ((unsigned int)dim == base->nbr_dim)
@@ -449,7 +460,7 @@ build_hierarchy_array (struct ghw_handler *h, union ghw_type *arr, int dim,
       sprintf (GLOBALS->asbuf, "%s]", pfx);
       name = strdup_2(GLOBALS->asbuf);
 
-      t = build_hierarchy_type (h, base->el, name, sig);
+      t = build_hierarchy_type (h, arr->sa.el, name, sig);
 
       if (*res != NULL)
 	(*res)->next = t;
diff --git a/src/globals.c b/src/globals.c
index a0c0c35..cf3330e 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -854,6 +854,7 @@ NULL, /* toggle2_showchange_c_1 364 */
 NULL, /* toggle3_showchange_c_1 364 */
 NULL, /* toggle4_showchange_c_1 364 */
 NULL, /* toggle5_showchange_c_1 364 */
+NULL, /* toggle6_showchange_c_1 364 */
 NULL, /* window_showchange_c_8 365 */
 NULL, /* cleanup_showchange_c_6 366 */
 NULL, /* tcache_showchange_c_1 367 */
@@ -1381,6 +1382,7 @@ WAVE_RAINBOW_INITIALIZER, /* gc_rainbow */
 0, /* ruler_origin */
 0, /* ruler_step */
 0, /* fill_waveform */
+0, /* lz_removal */
 FALSE, /*save_on_exit */
 
 
@@ -1902,6 +1904,7 @@ void reload_into_new_context_2(void)
  new_globals->display_grid = GLOBALS->display_grid;
  new_globals->highlight_wavewindow = GLOBALS->highlight_wavewindow;
  new_globals->fill_waveform = GLOBALS->fill_waveform;
+ new_globals->lz_removal = GLOBALS->lz_removal;
  new_globals->use_standard_trace_select = GLOBALS->use_standard_trace_select;
  new_globals->use_big_fonts = GLOBALS->use_big_fonts;
  new_globals->use_full_precision = GLOBALS->use_full_precision;
@@ -2849,6 +2852,7 @@ switch(type)
 							GLOBALS->display_grid = g_old->display_grid;
 							GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow;
 							GLOBALS->fill_waveform = g_old->fill_waveform;
+							GLOBALS->lz_removal = g_old->lz_removal;
 							GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select;
 							GLOBALS->disable_mouseover = g_old->disable_mouseover;
 							GLOBALS->clipboard_mouseover = g_old->clipboard_mouseover;
diff --git a/src/globals.h b/src/globals.h
index 01362aa..76b02ea 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -857,6 +857,7 @@ GtkWidget *toggle2_showchange_c_1; /* from showchange.c 389 */
 GtkWidget *toggle3_showchange_c_1; /* from showchange.c 390 */
 GtkWidget *toggle4_showchange_c_1; /* from showchange.c 391 */
 GtkWidget *toggle5_showchange_c_1; /* from showchange.c 391 */
+GtkWidget *toggle6_showchange_c_1; /* from showchange.c 391 */
 GtkWidget *window_showchange_c_8; /* from showchange.c 392 */
 void (*cleanup_showchange_c_6)(void); /* from showchange.c 393 */
 struct TraceEnt *tcache_showchange_c_1; /* from showchange.c 394 */
@@ -1370,6 +1371,7 @@ int str_wid_height;
 TimeType ruler_origin;
 TimeType ruler_step;
 char fill_waveform;
+char lz_removal;
 gboolean save_on_exit;
 
 
diff --git a/src/helpers/Makefile.am b/src/helpers/Makefile.am
index 8e56548..b52d9f2 100644
--- a/src/helpers/Makefile.am
+++ b/src/helpers/Makefile.am
@@ -8,7 +8,7 @@ LIBLZMA_LDADD  = $(LIBXZ_LDADD)
 
 AM_CFLAGS=	-I$(srcdir)/.. -I$(srcdir)/../.. $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBLZMA_CFLAGS) $(LIBJUDY_CFLAGS) $(EXTLOAD_CFLAGS) $(RPC_CFLAGS) -I$(srcdir)/fst -I$(srcdir)/../../contrib/rtlbrowse
 
-bin_PROGRAMS= evcd2vcd fst2vcd vcd2fst fstminer ghwdump lxt2miner lxt2vcd \
+bin_PROGRAMS= evcd2vcd fst2vcd vcd2fst fstminer lxt2miner lxt2vcd \
 	shmidcat vcd2lxt vcd2lxt2 vcd2vzt \
 	vzt2vcd vztminer
 
@@ -42,6 +42,4 @@ vztminer_LDADD= $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) $(RPC_LDADD)
 lxt2miner_SOURCES= lxt2miner.c lxt2_read.c lxt2_read.h
 lxt2miner_LDADD= $(LIBZ_LDADD)
 
-ghwdump_SOURCES= ghwdump.c $(srcdir)/../ghwlib.c
-
 evcd2vcd_SOURCES= evcd2vcd.c $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c
diff --git a/src/helpers/Makefile.in b/src/helpers/Makefile.in
index 19e407a..58599d2 100644
--- a/src/helpers/Makefile.in
+++ b/src/helpers/Makefile.in
@@ -77,10 +77,9 @@ NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 bin_PROGRAMS = evcd2vcd$(EXEEXT) fst2vcd$(EXEEXT) vcd2fst$(EXEEXT) \
-	fstminer$(EXEEXT) ghwdump$(EXEEXT) lxt2miner$(EXEEXT) \
-	lxt2vcd$(EXEEXT) shmidcat$(EXEEXT) vcd2lxt$(EXEEXT) \
-	vcd2lxt2$(EXEEXT) vcd2vzt$(EXEEXT) vzt2vcd$(EXEEXT) \
-	vztminer$(EXEEXT)
+	fstminer$(EXEEXT) lxt2miner$(EXEEXT) lxt2vcd$(EXEEXT) \
+	shmidcat$(EXEEXT) vcd2lxt$(EXEEXT) vcd2lxt2$(EXEEXT) \
+	vcd2vzt$(EXEEXT) vzt2vcd$(EXEEXT) vztminer$(EXEEXT)
 subdir = src/helpers
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -106,9 +105,6 @@ am_fstminer_OBJECTS = fstminer.$(OBJEXT) lz4.$(OBJEXT) \
 	fastlz.$(OBJEXT) fstapi.$(OBJEXT)
 fstminer_OBJECTS = $(am_fstminer_OBJECTS)
 fstminer_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am_ghwdump_OBJECTS = ghwdump.$(OBJEXT) ghwlib.$(OBJEXT)
-ghwdump_OBJECTS = $(am_ghwdump_OBJECTS)
-ghwdump_LDADD = $(LDADD)
 am_lxt2miner_OBJECTS = lxt2miner.$(OBJEXT) lxt2_read.$(OBJEXT)
 lxt2miner_OBJECTS = $(am_lxt2miner_OBJECTS)
 lxt2miner_DEPENDENCIES = $(am__DEPENDENCIES_1)
@@ -180,15 +176,14 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) $(fstminer_SOURCES) \
-	$(ghwdump_SOURCES) $(lxt2miner_SOURCES) $(lxt2vcd_SOURCES) \
+	$(lxt2miner_SOURCES) $(lxt2vcd_SOURCES) shmidcat.c \
+	$(vcd2fst_SOURCES) $(vcd2lxt_SOURCES) $(vcd2lxt2_SOURCES) \
+	$(vcd2vzt_SOURCES) $(vzt2vcd_SOURCES) $(vztminer_SOURCES)
+DIST_SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) \
+	$(fstminer_SOURCES) $(lxt2miner_SOURCES) $(lxt2vcd_SOURCES) \
 	shmidcat.c $(vcd2fst_SOURCES) $(vcd2lxt_SOURCES) \
 	$(vcd2lxt2_SOURCES) $(vcd2vzt_SOURCES) $(vzt2vcd_SOURCES) \
 	$(vztminer_SOURCES)
-DIST_SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) \
-	$(fstminer_SOURCES) $(ghwdump_SOURCES) $(lxt2miner_SOURCES) \
-	$(lxt2vcd_SOURCES) shmidcat.c $(vcd2fst_SOURCES) \
-	$(vcd2lxt_SOURCES) $(vcd2lxt2_SOURCES) $(vcd2vzt_SOURCES) \
-	$(vzt2vcd_SOURCES) $(vztminer_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -399,7 +394,6 @@ vztminer_SOURCES = vztminer.c vzt_read.c vzt_read.h $(srcdir)/../liblzma/LzmaLib
 vztminer_LDADD = $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) $(RPC_LDADD)
 lxt2miner_SOURCES = lxt2miner.c lxt2_read.c lxt2_read.h
 lxt2miner_LDADD = $(LIBZ_LDADD)
-ghwdump_SOURCES = ghwdump.c $(srcdir)/../ghwlib.c
 evcd2vcd_SOURCES = evcd2vcd.c $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c
 all: all-am
 
@@ -490,10 +484,6 @@ fstminer$(EXEEXT): $(fstminer_OBJECTS) $(fstminer_DEPENDENCIES) $(EXTRA_fstminer
 	@rm -f fstminer$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(fstminer_OBJECTS) $(fstminer_LDADD) $(LIBS)
 
-ghwdump$(EXEEXT): $(ghwdump_OBJECTS) $(ghwdump_DEPENDENCIES) $(EXTRA_ghwdump_DEPENDENCIES) 
-	@rm -f ghwdump$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(ghwdump_OBJECTS) $(ghwdump_LDADD) $(LIBS)
-
 lxt2miner$(EXEEXT): $(lxt2miner_OBJECTS) $(lxt2miner_DEPENDENCIES) $(EXTRA_lxt2miner_DEPENDENCIES) 
 	@rm -f lxt2miner$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(lxt2miner_OBJECTS) $(lxt2miner_LDADD) $(LIBS)
@@ -542,8 +532,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst2vcd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstapi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwdump.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwlib.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrb.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2_read.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2_write.Po@am__quote@
@@ -634,20 +622,6 @@ fstapi.obj: $(srcdir)/fst/fstapi.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fstapi.obj `if test -f '$(srcdir)/fst/fstapi.c'; then $(CYGPATH_W) '$(srcdir)/fst/fstapi.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/fstapi.c'; fi`
 
-ghwlib.o: $(srcdir)/../ghwlib.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ghwlib.o -MD -MP -MF $(DEPDIR)/ghwlib.Tpo -c -o ghwlib.o `test -f '$(srcdir)/../ghwlib.c' || echo '$(srcdir)/'`$(srcdir)/../ghwlib.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ghwlib.Tpo $(DEPDIR)/ghwlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(srcdir)/../ghwlib.c' object='ghwlib.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ghwlib.o `test -f '$(srcdir)/../ghwlib.c' || echo '$(srcdir)/'`$(srcdir)/../ghwlib.c
-
-ghwlib.obj: $(srcdir)/../ghwlib.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ghwlib.obj -MD -MP -MF $(DEPDIR)/ghwlib.Tpo -c -o ghwlib.obj `if test -f '$(srcdir)/../ghwlib.c'; then $(CYGPATH_W) '$(srcdir)/../ghwlib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../ghwlib.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ghwlib.Tpo $(DEPDIR)/ghwlib.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(srcdir)/../ghwlib.c' object='ghwlib.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ghwlib.obj `if test -f '$(srcdir)/../ghwlib.c'; then $(CYGPATH_W) '$(srcdir)/../ghwlib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../ghwlib.c'; fi`
-
 LzmaLib.o: $(srcdir)/../liblzma/LzmaLib.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT LzmaLib.o -MD -MP -MF $(DEPDIR)/LzmaLib.Tpo -c -o LzmaLib.o `test -f '$(srcdir)/../liblzma/LzmaLib.c' || echo '$(srcdir)/'`$(srcdir)/../liblzma/LzmaLib.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/LzmaLib.Tpo $(DEPDIR)/LzmaLib.Po
diff --git a/src/helpers/fst/CMakeLists.txt b/src/helpers/fst/CMakeLists.txt
new file mode 100644
index 0000000..942596f
--- /dev/null
+++ b/src/helpers/fst/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required (VERSION 3.0)
+
+project (fstlib)
+
+########################################################################################################################
+# Easiest way to get ZLib on windows is using vcpkg, to load vcpkg:
+# cmake -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake
+if(CMAKE_TOOLCHAIN_FILE)
+    message(STATUS "Using VCPKG from ${CMAKE_TOOLCHAIN_FILE}")
+endif()
+########################################################################################################################
+find_package(ZLIB REQUIRED)
+
+add_library(fstapi fstapi.c fstapi.h fst_win_unistd.h)
+target_link_libraries(fstapi PRIVATE ZLIB::ZLIB)
+# hack to avoid creating dummy config.h
+target_compile_definitions(fstapi PRIVATE -DFST_CONFIG_INCLUDE="fstapi.h")
+
+if(MSVC)
+    # define __MINGW32__ to minimize changes to upstream
+    target_compile_definitions(fstapi PRIVATE __MINGW32__  _CRT_SECURE_NO_WARNINGS  FST_DO_MISALIGNED_OPS)
+    target_compile_options(fstapi PRIVATE /wd4244 /wd4267 /wd4146 /wd4996)
+endif()
diff --git a/src/helpers/fst/Makefile.am b/src/helpers/fst/Makefile.am
index 1d6e857..5fa7179 100644
--- a/src/helpers/fst/Makefile.am
+++ b/src/helpers/fst/Makefile.am
@@ -5,6 +5,6 @@ AM_CFLAGS=      $(LIBZ_CFLAGS) $(LIBJUDY_CFLAGS)
 
 noinst_LIBRARIES=       libfst.a
 
-libfst_a_SOURCES= fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h
+libfst_a_SOURCES= fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h fst_win_unistd.h
 
-EXTRA_DIST=     block_format.txt
+EXTRA_DIST=     block_format.txt CMakeLists.txt
diff --git a/src/helpers/fst/Makefile.in b/src/helpers/fst/Makefile.in
index 59d95eb..e555cc0 100644
--- a/src/helpers/fst/Makefile.in
+++ b/src/helpers/fst/Makefile.in
@@ -315,8 +315,8 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CFLAGS = $(LIBZ_CFLAGS) $(LIBJUDY_CFLAGS)
 noinst_LIBRARIES = libfst.a
-libfst_a_SOURCES = fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h
-EXTRA_DIST = block_format.txt
+libfst_a_SOURCES = fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h fst_win_unistd.h
+EXTRA_DIST = block_format.txt CMakeLists.txt
 all: all-am
 
 .SUFFIXES:
diff --git a/src/helpers/fst/fastlz.c b/src/helpers/fst/fastlz.c
index 50bf56a..b52a799 100644
--- a/src/helpers/fst/fastlz.c
+++ b/src/helpers/fst/fastlz.c
@@ -22,6 +22,8 @@
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
+
+  SPDX-License-Identifier: MIT
 */
 
 #include "fastlz.h"
diff --git a/src/helpers/fst/fastlz.h b/src/helpers/fst/fastlz.h
index 8b4eac2..1ce44a3 100644
--- a/src/helpers/fst/fastlz.h
+++ b/src/helpers/fst/fastlz.h
@@ -22,6 +22,8 @@
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
+
+  SPDX-License-Identifier: MIT
 */
 
 #ifndef FASTLZ_H
diff --git a/src/helpers/fst/fst_win_unistd.h b/src/helpers/fst/fst_win_unistd.h
new file mode 100644
index 0000000..15ab2c1
--- /dev/null
+++ b/src/helpers/fst/fst_win_unistd.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009-2018 Tony Bybell.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef WIN_UNISTD_H
+#define WIN_UNISTD_H
+
+#include <stdlib.h>
+#ifdef _WIN64
+#include <io.h>
+#else
+#include <sys/io.h>
+#endif
+
+#include <process.h>
+
+#define ftruncate _chsize_s
+#define unlink _unlink
+#define fileno _fileno
+#define lseek _lseeki64
+
+#ifdef _WIN64
+#define ssize_t __int64
+#define SSIZE_MAX 9223372036854775807i64
+#else
+#define ssize_t long
+#define SSIZE_MAX 2147483647L
+#endif
+
+#include "stdint.h"
+
+#endif //WIN_UNISTD_H
diff --git a/src/helpers/fst/fstapi.c b/src/helpers/fst/fstapi.c
index 720116b..2e28e64 100644
--- a/src/helpers/fst/fstapi.c
+++ b/src/helpers/fst/fstapi.c
@@ -18,6 +18,8 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
  */
 
 /*
@@ -78,6 +80,12 @@
 #define PATH_MAX (4096)
 #endif
 
+#if defined(_MSC_VER)
+typedef int64_t fst_off_t;
+#else
+typedef off_t fst_off_t;
+#endif
+
 /* note that Judy versus Jenkins requires more experimentation: they are  */
 /* functionally equivalent though it appears Jenkins is slightly faster.  */
 /* in addition, Jenkins is not bound by the LGPL.                         */
@@ -153,8 +161,8 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
 #ifdef __MINGW32__
 #include <io.h>
 #ifndef HAVE_FSEEKO
-#define ftello ftell
-#define fseeko fseek
+#define ftello _ftelli64
+#define fseeko _fseeki64
 #endif
 #endif
 
@@ -282,7 +290,7 @@ static size_t fstFwrite(const void *buf, size_t siz, size_t cnt, FILE *fp)
 return(fwrite(buf, siz, cnt, fp));
 }
 
-static int fstFtruncate(int fd, off_t length)
+static int fstFtruncate(int fd, fst_off_t length)
 {
 return(ftruncate(fd, length));
 }
@@ -327,12 +335,12 @@ return(NULL);
 #define fstMmap(__addr,__len,__prot,__flags,__fd,__off) fstMmap2((__len), (__fd), (__off))
 #define fstMunmap(__addr,__len)                         free(__addr)
 
-static void *fstMmap2(size_t __len, int __fd, off_t __off)
+static void *fstMmap2(size_t __len, int __fd, fst_off_t __off)
 {
 (void)__off;
 
 unsigned char *pnt = (unsigned char *)malloc(__len);
-off_t cur_offs = lseek(__fd, 0, SEEK_CUR);
+fst_off_t cur_offs = lseek(__fd, 0, SEEK_CUR);
 size_t i;
 
 lseek(__fd, 0, SEEK_SET);
@@ -732,7 +740,7 @@ FILE *tchn_handle;
 
 unsigned char *vchg_mem;
 
-off_t hier_file_len;
+fst_off_t hier_file_len;
 
 uint32_t *valpos_mem;
 unsigned char *curval_mem;
@@ -752,7 +760,7 @@ unsigned fourpack : 1;
 unsigned fastpack : 1;
 
 int64_t timezero;
-off_t section_header_truncpos;
+fst_off_t section_header_truncpos;
 uint32_t tchn_cnt, tchn_idx;
 uint64_t curtime;
 uint64_t firsttime;
@@ -760,7 +768,7 @@ uint32_t vchg_siz;
 uint32_t vchg_alloc_siz;
 
 uint32_t secnum;
-off_t section_start;
+fst_off_t section_start;
 
 uint32_t numscopes;
 double nan; /* nan value for uninitialized doubles */
@@ -792,6 +800,7 @@ pthread_t thread;
 pthread_attr_t thread_attr;
 struct fstWriterContext *xc_parent;
 #endif
+unsigned in_pthread : 1;
 
 size_t fst_orig_break_size;
 size_t fst_orig_break_add_size;
@@ -817,7 +826,7 @@ fstEnumHandle max_enumhandle;
 };
 
 
-static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, off_t offset, int whence)
+static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, fst_off_t offset, int whence)
 {
 int rc = fseeko(stream, offset, whence);
 
@@ -984,7 +993,7 @@ if(pnt == MAP_FAILED)
 
 static void fstWriterCreateMmaps(struct fstWriterContext *xc)
 {
-off_t curpos = ftello(xc->handle);
+fst_off_t curpos = ftello(xc->handle);
 
 fflush(xc->hier_handle);
 
@@ -1024,7 +1033,9 @@ if(!xc->curval_mem)
 
 static void fstDestroyMmaps(struct fstWriterContext *xc, int is_closing)
 {
+#if !defined __CYGWIN__ && !defined __MINGW32__
 (void)is_closing;
+#endif
 
 fstMunmap(xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t));
 xc->valpos_mem = NULL;
@@ -1036,7 +1047,7 @@ if(xc->curval_mem)
                 {
                 unsigned char *pnt = xc->curval_mem;
                 int __fd = fileno(xc->curval_handle);
-                off_t cur_offs = lseek(__fd, 0, SEEK_CUR);
+                fst_off_t cur_offs = lseek(__fd, 0, SEEK_CUR);
                 size_t i;
                 size_t __len = xc->maxvalpos;
 
@@ -1277,14 +1288,14 @@ int cnt = 0;
 unsigned int i;
 unsigned char *vchg_mem;
 FILE *f;
-off_t fpos, indxpos, endpos;
+fst_off_t fpos, indxpos, endpos;
 uint32_t prevpos;
 int zerocnt;
 unsigned char *scratchpad;
 unsigned char *scratchpnt;
 unsigned char *tmem;
-off_t tlen;
-off_t unc_memreq = 0; /* for reader */
+fst_off_t tlen;
+fst_off_t unc_memreq = 0; /* for reader */
 unsigned char *packmem;
 unsigned int packmemlen;
 uint32_t *vm4ip;
@@ -1728,7 +1739,7 @@ if(tmem)
         unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen));
         int rc = compress2(dmem, &destlen, tmem, tlen, 9);
 
-        if((rc == Z_OK) && (((off_t)destlen) < tlen))
+        if((rc == Z_OK) && (((fst_off_t)destlen) < tlen))
                 {
                 fstFwrite(dmem, destlen, 1, xc->handle);
                 }
@@ -1776,7 +1787,7 @@ fstWriterFseeko(xc, xc->handle, endpos, SEEK_SET);
 xc2->section_header_truncpos = endpos;                          /* cache in case of need to truncate */
 if(xc->dump_size_limit)
         {
-        if(endpos >= ((off_t)xc->dump_size_limit))
+        if(endpos >= ((fst_off_t)xc->dump_size_limit))
                 {
                 xc2->skip_writing_section_hdr = 1;
                 xc2->size_limit_locked = 1;
@@ -1801,19 +1812,23 @@ xc->already_in_flush = 0;
 static void *fstWriterFlushContextPrivate1(void *ctx)
 {
 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
+struct fstWriterContext *xc_parent;
 
+pthread_mutex_lock(&(xc->xc_parent->mutex));
 fstWriterFlushContextPrivate2(xc);
 
-pthread_mutex_unlock(&(xc->xc_parent->mutex));
-
 #ifdef FST_REMOVE_DUPLICATE_VC
 free(xc->curval_mem);
 #endif
 free(xc->valpos_mem);
 free(xc->vchg_mem);
 tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam);
+xc_parent = xc->xc_parent;
 free(xc);
 
+xc_parent->in_pthread = 0;
+pthread_mutex_unlock(&(xc_parent->mutex));
+
 return(NULL);
 }
 
@@ -1861,7 +1876,15 @@ if(xc->parallel_enabled)
         xc->section_header_only = 0;
         xc->secnum++;
 
+	while (xc->in_pthread) 
+		{ 
+		pthread_mutex_lock(&xc->mutex); 
+		pthread_mutex_unlock(&xc->mutex); 
+		};
+
         pthread_mutex_lock(&xc->mutex);
+	xc->in_pthread = 1;
+        pthread_mutex_unlock(&xc->mutex);
 
         pthread_create(&xc->thread, &xc->thread_attr, fstWriterFlushContextPrivate1, xc2);
         }
@@ -1914,7 +1937,7 @@ if(xc)
 if(xc && !xc->already_in_close && !xc->already_in_flush)
         {
         unsigned char *tmem = NULL;
-        off_t fixup_offs, tlen, hlen;
+        fst_off_t fixup_offs, tlen, hlen;
 
         xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */
 
@@ -1943,6 +1966,12 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 #ifdef FST_WRITER_PARALLEL
                         pthread_mutex_lock(&xc->mutex);
                         pthread_mutex_unlock(&xc->mutex);
+
+			while (xc->in_pthread) 
+				{ 
+				pthread_mutex_lock(&xc->mutex); 
+				pthread_mutex_unlock(&xc->mutex); 
+				};
 #endif
                         }
                 }
@@ -1968,7 +1997,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
                 unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen));
                 int rc = compress2(dmem, &destlen, tmem, tlen, 9);
 
-                if((rc != Z_OK) || (((off_t)destlen) > tlen))
+                if((rc != Z_OK) || (((fst_off_t)destlen) > tlen))
                         {
                         destlen = tlen;
                         }
@@ -1979,7 +2008,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
                 fstWriterUint64(xc->handle, tlen);              /* uncompressed */
                                                                 /* compressed len is section length - 24 */
                 fstWriterUint64(xc->handle, xc->maxhandle);     /* maxhandle */
-                fstFwrite((((off_t)destlen) != tlen) ? dmem : tmem, destlen, 1, xc->handle);
+                fstFwrite((((fst_off_t)destlen) != tlen) ? dmem : tmem, destlen, 1, xc->handle);
                 fflush(xc->handle);
 
                 fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET);
@@ -1995,7 +2024,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
         if(xc->num_blackouts)
                 {
                 uint64_t cur_bl = 0;
-                off_t bpos, eos;
+                fst_off_t bpos, eos;
                 uint32_t i;
 
                 fixup_offs = ftello(xc->handle);
@@ -2028,7 +2057,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
 
         if(xc->compress_hier)
                 {
-                off_t hl, eos;
+                fst_off_t hl, eos;
                 gzFile zhandle;
                 int zfd;
                 int fourpack_duo = 0;
@@ -2151,7 +2180,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
                 if(xc->repack_on_close)
                         {
                         FILE *fp;
-                        off_t offpnt, uclen;
+                        fst_off_t offpnt, uclen;
                         int flen = strlen(xc->filename);
                         char *hf = (char *)calloc(1, flen + 5);
 
@@ -2258,7 +2287,7 @@ struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc)
         {
         char s[FST_HDR_DATE_SIZE];
-        off_t fpos = ftello(xc->handle);
+        fst_off_t fpos = ftello(xc->handle);
         int len = strlen(dat);
 
         fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_DATE, SEEK_SET);
@@ -2277,7 +2306,7 @@ struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc && vers)
         {
         char s[FST_HDR_SIM_VERSION_SIZE];
-        off_t fpos = ftello(xc->handle);
+        fst_off_t fpos = ftello(xc->handle);
         int len = strlen(vers);
 
         fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET);
@@ -2297,7 +2326,7 @@ if(xc)
         {
         if(/*(filetype >= FST_FT_MIN) &&*/ (filetype <= FST_FT_MAX))
                 {
-                off_t fpos = ftello(xc->handle);
+                fst_off_t fpos = ftello(xc->handle);
 
                 xc->filetype = filetype;
 
@@ -2438,7 +2467,7 @@ void fstWriterSetTimescale(void *ctx, int ts)
 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc)
         {
-        off_t fpos = ftello(xc->handle);
+        fst_off_t fpos = ftello(xc->handle);
         fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET);
         fputc(ts & 255, xc->handle);
         fflush(xc->handle);
@@ -2496,7 +2525,7 @@ void fstWriterSetTimezero(void *ctx, int64_t tim)
 struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
 if(xc)
         {
-        off_t fpos = ftello(xc->handle);
+        fst_off_t fpos = ftello(xc->handle);
         fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET);
         fstWriterUint64(xc->handle, (xc->timezero = tim));
         fflush(xc->handle);
@@ -3338,7 +3367,7 @@ char date[FST_HDR_DATE_SIZE + 1];
 int64_t timezero;
 
 char *filename, *filename_unpacked;
-off_t hier_pos;
+fst_off_t hier_pos;
 
 uint32_t num_blackouts;
 uint64_t *blackout_times;
@@ -3353,10 +3382,10 @@ uint64_t *rvat_time_table;
 uint64_t rvat_beg_tim, rvat_end_tim;
 unsigned char *rvat_frame_data;
 uint64_t rvat_frame_maxhandle;
-off_t *rvat_chain_table;
+fst_off_t *rvat_chain_table;
 uint32_t *rvat_chain_table_lengths;
 uint64_t rvat_vc_maxhandle;
-off_t rvat_vc_start;
+fst_off_t rvat_vc_start;
 uint32_t *rvat_sig_offs;
 int rvat_packtype;
 
@@ -3395,7 +3424,7 @@ char *fh_nam;
 };
 
 
-int fstReaderFseeko(struct fstReaderContext *xc, FILE *stream, off_t offset, int whence)
+int fstReaderFseeko(struct fstReaderContext *xc, FILE *stream, fst_off_t offset, int whence)
 {
 int rc = fseeko(stream, offset, whence);
 
@@ -3888,11 +3917,11 @@ int pass_status = 1;
 
 if(!xc->fh)
         {
-        off_t offs_cache = ftello(xc->f);
+        fst_off_t offs_cache = ftello(xc->f);
         char *fnam = (char *)malloc(strlen(xc->filename) + 6 + 16 + 32 + 1);
         unsigned char *mem = (unsigned char *)malloc(FST_GZIO_LEN);
-        off_t hl, uclen;
-        off_t clen = 0;
+        fst_off_t hl, uclen;
+        fst_off_t clen = 0;
         gzFile zhandle = NULL;
         int zfd;
         int htyp = FST_BL_SKIP;
@@ -4512,8 +4541,8 @@ return(1);
  */
 int fstReaderInit(struct fstReaderContext *xc)
 {
-off_t blkpos = 0;
-off_t endfile;
+fst_off_t blkpos = 0;
+fst_off_t endfile;
 uint64_t seclen;
 int sectype;
 uint64_t vc_section_count_actual = 0;
@@ -4525,7 +4554,7 @@ sectype = fgetc(xc->f);
 if(sectype == FST_BL_ZWRAPPER)
         {
         FILE *fcomp;
-        off_t offpnt, uclen;
+        fst_off_t offpnt, uclen;
         char gz_membuf[FST_GZIO_LEN];
         gzFile zhandle;
         int zfd;
@@ -4958,15 +4987,13 @@ uint64_t *time_table = NULL;
 uint64_t tsec_nitems;
 unsigned int secnum = 0;
 int blocks_skipped = 0;
-off_t blkpos = 0;
+fst_off_t blkpos = 0;
 uint64_t seclen, beg_tim;
-#ifdef FST_DEBUG
 uint64_t end_tim;
-#endif
 uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle;
-off_t vc_start;
-off_t indx_pntr, indx_pos;
-off_t *chain_table = NULL;
+fst_off_t vc_start;
+fst_off_t indx_pntr, indx_pos;
+fst_off_t *chain_table = NULL;
 uint32_t *chain_table_lengths = NULL;
 unsigned char *chain_cmem;
 unsigned char *pnt;
@@ -5029,14 +5056,11 @@ for(;;)
         if(!seclen) break;
 
         beg_tim = fstReaderUint64(xc->f);
-#ifdef FST_DEBUG
-        end_tim =
-#endif
-        fstReaderUint64(xc->f);
+        end_tim = fstReaderUint64(xc->f);
 
         if(xc->limit_range_valid)
                 {
-                if(beg_tim < xc->limit_range_start)
+                if(end_tim < xc->limit_range_start)
                         {
                         blocks_skipped++;
                         blkpos += seclen;
@@ -5082,7 +5106,7 @@ for(;;)
         destlen = tsec_uclen;
         sourcelen = tsec_clen;
 
-        fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
+        fstReaderFseeko(xc, xc->f, -24 - ((fst_off_t)tsec_clen), SEEK_CUR);
 
         if(tsec_uclen != tsec_clen)
                 {
@@ -5323,11 +5347,11 @@ for(;;)
                                 }
 
                         free(mu);
-                        fstReaderFseeko(xc, xc->f, -((off_t)frame_clen), SEEK_CUR);
+                        fstReaderFseeko(xc, xc->f, -((fst_off_t)frame_clen), SEEK_CUR);
                         }
                 }
 
-        fstReaderFseeko(xc, xc->f, (off_t)frame_clen, SEEK_CUR); /* skip past compressed data */
+        fstReaderFseeko(xc, xc->f, (fst_off_t)frame_clen, SEEK_CUR); /* skip past compressed data */
 
         vc_maxhandle = fstReaderVarint64(xc->f);
         vc_start = ftello(xc->f);       /* points to '!' character */
@@ -5357,7 +5381,7 @@ for(;;)
                 free(chain_table_lengths);
 
                 vc_maxhandle_largest = vc_maxhandle;
-                chain_table = (off_t *)calloc((vc_maxhandle+1), sizeof(off_t));
+                chain_table = (fst_off_t *)calloc((vc_maxhandle+1), sizeof(fst_off_t));
                 chain_table_lengths = (uint32_t *)calloc((vc_maxhandle+1), sizeof(uint32_t));
                 }
 
@@ -5978,7 +6002,7 @@ return(buf);
 char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf)
 {
 struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
-off_t blkpos = 0, prev_blkpos;
+fst_off_t blkpos = 0, prev_blkpos;
 uint64_t beg_tim, end_tim, beg_tim2, end_tim2;
 int sectype;
 unsigned int secnum = 0;
@@ -5989,7 +6013,7 @@ uint64_t frame_uclen, frame_clen;
 #ifdef FST_DEBUG
 uint64_t mem_required_for_traversal;
 #endif
-off_t indx_pntr, indx_pos;
+fst_off_t indx_pntr, indx_pos;
 long chain_clen;
 unsigned char *chain_cmem;
 unsigned char *pnt;
@@ -6051,7 +6075,7 @@ for(;;)
                 {
                 if((tim == end_tim) && (tim != xc->end_time))
                         {
-                        off_t cached_pos = ftello(xc->f);
+                        fst_off_t cached_pos = ftello(xc->f);
                         fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
 
                         sectype = fgetc(xc->f);
@@ -6113,7 +6137,7 @@ ucdata = (unsigned char *)malloc(tsec_uclen);
 destlen = tsec_uclen;
 sourcelen = tsec_clen;
 
-fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR);
+fstReaderFseeko(xc, xc->f, -24 - ((fst_off_t)tsec_clen), SEEK_CUR);
 if(tsec_uclen != tsec_clen)
         {
         cdata = (unsigned char *)malloc(tsec_clen);
@@ -6198,7 +6222,7 @@ chain_cmem = (unsigned char *)malloc(chain_clen);
 fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET);
 fstFread(chain_cmem, chain_clen, 1, xc->f);
 
-xc->rvat_chain_table = (off_t *)calloc((xc->rvat_vc_maxhandle+1), sizeof(off_t));
+xc->rvat_chain_table = (fst_off_t *)calloc((xc->rvat_vc_maxhandle+1), sizeof(fst_off_t));
 xc->rvat_chain_table_lengths = (uint32_t *)calloc((xc->rvat_vc_maxhandle+1), sizeof(uint32_t));
 
 pnt = chain_cmem;
diff --git a/src/helpers/fst/fstapi.h b/src/helpers/fst/fstapi.h
index bbc82c2..e2ca178 100644
--- a/src/helpers/fst/fstapi.h
+++ b/src/helpers/fst/fstapi.h
@@ -18,6 +18,8 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
  */
 
 #ifndef FST_API_H
@@ -33,7 +35,11 @@ extern "C" {
 #include <ctype.h>
 #include <zlib.h>
 #include <inttypes.h>
-#include <unistd.h>
+#if defined(_MSC_VER)
+    #include "fst_win_unistd.h"
+#else
+    #include <unistd.h>
+#endif
 #include <time.h>
 
 #define FST_RDLOAD "FSTLOAD | "
diff --git a/src/helpers/fst/lz4.c b/src/helpers/fst/lz4.c
index 00fbcfc..55dc1a8 100644
--- a/src/helpers/fst/lz4.c
+++ b/src/helpers/fst/lz4.c
@@ -27,6 +27,8 @@
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+   SPDX-License-Identifier: BSD-2-Clause
+
    You can contact the author at :
    - LZ4 source repository : https://github.com/Cyan4973/lz4
    - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
diff --git a/src/helpers/fst/lz4.h b/src/helpers/fst/lz4.h
index 3e74002..bd5245e 100644
--- a/src/helpers/fst/lz4.h
+++ b/src/helpers/fst/lz4.h
@@ -28,6 +28,8 @@
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+   SPDX-License-Identifier: BSD-2-Clause
+
    You can contact the author at :
    - LZ4 source repository : https://github.com/Cyan4973/lz4
    - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
diff --git a/src/helpers/ghwdump.c b/src/helpers/ghwdump.c
deleted file mode 100644
index 98c9ee2..0000000
--- a/src/helpers/ghwdump.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*  Display a GHDL Wavefile for debugging.
-    Copyright (C) 2005-2008 Tristan Gingold
-
-    GHDL is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License as published by the Free
-    Software Foundation; either version 2, or (at your option) any later
-    version.
-
-    GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with GCC; see the file COPYING.  If not, write to the Free
-    Software Foundation, 51 Franklin Street - Suite 500, Boston, MA
-    02110-1335, USA.
-*/
-
-#include <config.h>
-#include <stdio.h>
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "ghwlib.h"
-
-#include "wave_locale.h"
-
-static const char *progname;
-void
-usage (void)
-{
-  printf ("usage: %s [OPTIONS] FILEs...\n", progname);
-  printf ("Options are:\n"
-	  " -t  display types\n"
-	  " -h  display hierarchy\n"
-	  " -T  display time\n"
-	  " -s  display signals (and time)\n"
-	  " -l  display list of sections\n"
-	  " -v  verbose\n");
-}
-
-int
-main (int argc, char **argv)
-{
-  int i;
-  int flag_disp_types;
-  int flag_disp_hierarchy;
-  int flag_disp_time;
-  int flag_disp_signals;
-  int flag_list;
-  int flag_verbose;
-  int eof;
-  enum ghw_sm_type sm;
-
-  progname = argv[0];
-  flag_disp_types = 0;
-  flag_disp_hierarchy = 0;
-  flag_disp_time = 0;
-  flag_disp_signals = 0;
-  flag_list = 0;
-  flag_verbose = 0;
-
-  WAVE_LOCALE_FIX
-
-  while (1)
-    {
-      int c;
-
-      c = getopt (argc, argv, "thTslv");
-      if (c == -1)
-	break;
-      switch (c)
-	{
-	case 't':
-	  flag_disp_types = 1;
-	  break;
-	case 'h':
-	  flag_disp_hierarchy = 1;
-	  break;
-	case 'T':
-	  flag_disp_time = 1;
-	  break;
-	case 's':
-	  flag_disp_signals = 1;
-	  flag_disp_time = 1;
-	  break;
-	case 'l':
-	  flag_list = 1;
-	  break;
-	case 'v':
-	  flag_verbose++;
-	  break;
-	default:
-	  usage ();
-	  exit (2);
-	}
-    }
-
-  if (optind >= argc)
-    {
-      usage ();
-      return 1;
-    }
-
-  for (i = optind; i < argc; i++)
-    {
-      struct ghw_handler h;
-      struct ghw_handler *hp = &h;
-
-      hp->flag_verbose = flag_verbose;
-
-      if (ghw_open (hp, argv[i]) != 0)
-	{
-	  fprintf (stderr, "cannot open ghw file %s\n", argv[i]);
-	  return 1;
-	}
-      if (flag_list)
-	{
-	  while (1)
-	    {
-	      int section;
-
-	      section = ghw_read_section (hp);
-	      if (section == -2)
-		{
-		  printf ("eof of file\n");
-		  break;
-		}
-	      else if (section < 0)
-		{
-		  printf ("Error in file\n");
-		  break;
-		}
-	      else if (section == 0)
-		{
-		  printf ("Unknown section\n");
-		  break;
-		}
-	      printf ("Section %s\n", ghw_sections[section].name);
-	      if ((*ghw_sections[section].handler)(hp) < 0)
-		break;
-	    }
-	}
-      else
-	{
-	  if (ghw_read_base (hp) < 0)
-	    {
-	      fprintf (stderr, "cannot read ghw file\n");
-	      return 2;
-	    }
-	  if (0)
-	    {
-	      unsigned ix;
-	      printf ("String table:\n");
-
-	      for (ix = 1; ix < hp->nbr_str; ix++)
-		printf (" %s\n", hp->str_table[ix]);
-	    }
-	  if (flag_disp_types)
-	    ghw_disp_types (hp);
-	  if (flag_disp_hierarchy)
-	    ghw_disp_hie (hp, hp->hie);
-
-#if 1
-	  sm = ghw_sm_init;
-	  eof = 0;
-	  while (!eof)
-	    {
-	      switch (ghw_read_sm (hp, &sm))
-		{
-		case ghw_res_snapshot:
-		case ghw_res_cycle:
-		  if (flag_disp_time)
-		    printf ("Time is "GHWPRI64" fs\n", hp->snap_time);
-		  if (flag_disp_signals)
-		    ghw_disp_values (hp);
-		  break;
-		case ghw_res_eof:
-		  eof = 1;
-		  break;
-		default:
-		  abort ();
-		}
-	    }
-
-#else
-	  if (ghw_read_dump (hp) < 0)
-	    {
-	      fprintf (stderr, "error in ghw dump\n");
-	      return 3;
-	    }
-#endif
-	}
-      ghw_close (&h);
-    }
-  return 0;
-}
-
diff --git a/src/helpers/vcd2fst.c b/src/helpers/vcd2fst.c
index c1dabd5..7777383 100644
--- a/src/helpers/vcd2fst.c
+++ b/src/helpers/vcd2fst.c
@@ -1154,6 +1154,11 @@ while(!feof(f))
 			{
 			exp+=2;
 			}
+		else
+		if(tv == 1000) /* nonstandard */
+			{
+			exp+=3;
+			}
 
 		fstWriterSetTimescale(ctx, exp);
 		}
diff --git a/src/helpers/vzt_write.c b/src/helpers/vzt_write.c
index 9604ab5..bb9c8f8 100644
--- a/src/helpers/vzt_write.c
+++ b/src/helpers/vzt_write.c
@@ -1859,6 +1859,17 @@ if(lt)
 	msk     = (~0U <<  lt->timepos);
 	msk_n   = ~msk;
 
+	if(!lt->emitted) 
+	        {
+	        vzt_wr_emitfacs(lt);
+	        lt->emitted = 1;
+	
+	        if(!lt->timeset)
+	                {
+	                vzt_wr_set_time(lt, 0);
+	                }
+	        }
+
 	for(j=0;j<lt->numfacs;j++)
 		{
 		struct vzt_wr_symbol *s = lt->sorted_facs[j];
diff --git a/src/ghwlib.c b/src/libghw.c
similarity index 83%
rename from src/ghwlib.c
rename to src/libghw.c
index 5b6c81c..eabc31c 100644
--- a/src/ghwlib.c
+++ b/src/libghw.c
@@ -1,41 +1,39 @@
-/*  GHDL Wavefile reader library.
-    Copyright (C) 2005 Tristan Gingold
-
-    GHDL is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License as published by the Free
-    Software Foundation; either version 2, or (at your option) any later
-    version.
-
-    GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with GCC; see the file COPYING.  If not, write to the Free
-    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-    02111-1307, USA.
+/* GHDL Wavefile reader library.
+  Copyright (C) 2005 Tristan Gingold
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <gnu.org/licenses>.
 */
 
+#include <assert.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
-#include <assert.h>
 
-#include "ghwlib.h"
+#include "libghw.h"
 
 /* Reopen H through decompressor DECOMP.  */
 
 static int
 ghw_openz (struct ghw_handler *h, const char *decomp, const char *filename)
 {
-  int plen = strlen (decomp) + 1 + strlen(filename) + 1;
+  int plen = strlen (decomp) + 1 + strlen (filename) + 1;
   char *p = malloc (plen);
 
   snprintf (p, plen, "%s %s", decomp, filename);
   fclose (h->stream);
-  h->stream = popen(p, "r");
+  h->stream = popen (p, "r");
   free (p);
 
   if (h->stream == NULL)
@@ -82,8 +80,7 @@ ghw_open (struct ghw_handler *h, const char *filename)
   if (memcmp (hdr, "GHDLwave\n", 9) != 0)
     return -2;
   /* Check version.  */
-  if (hdr[9] != 16
-      || hdr[10] != 0)
+  if (hdr[9] != 16 || hdr[10] != 0)
     return -2;
   h->version = hdr[11];
   if (h->version > 1)
@@ -98,7 +95,11 @@ ghw_open (struct ghw_handler *h, const char *filename)
   /* Endianness.  */
   {
     int endian;
-    union { unsigned char b[4]; uint32_t i;} v;
+    union
+    {
+      unsigned char b[4];
+      uint32_t i;
+    } v;
     v.i = 0x11223344;
     if (v.b[0] == 0x11)
       endian = 2;
@@ -149,7 +150,7 @@ ghw_get_i64 (struct ghw_handler *ghw_h, unsigned char *b)
       l = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0);
       h = (b[7] << 24) | (b[6] << 16) | (b[5] << 8) | (b[4] << 0);
     }
-  return (((int64_t)h) << 32) | l;
+  return (((int64_t) h) << 32) | l;
 }
 
 int
@@ -165,7 +166,7 @@ ghw_read_byte (struct ghw_handler *h, unsigned char *res)
 }
 
 int
-ghw_read_uleb128 (struct ghw_handler *h, uint32_t *res)
+ghw_read_uleb128 (struct ghw_handler *h, uint32_t * res)
 {
   uint32_t r = 0;
   unsigned int off = 0;
@@ -185,7 +186,7 @@ ghw_read_uleb128 (struct ghw_handler *h, uint32_t *res)
 }
 
 int
-ghw_read_sleb128 (struct ghw_handler *h, int32_t *res)
+ghw_read_sleb128 (struct ghw_handler *h, int32_t * res)
 {
   int32_t r = 0;
   unsigned int off = 0;
@@ -195,7 +196,7 @@ ghw_read_sleb128 (struct ghw_handler *h, int32_t *res)
       int v = fgetc (h->stream);
       if (v == EOF)
 	return -1;
-      r |= ((int32_t)(v & 0x7f)) << off;
+      r |= ((int32_t) (v & 0x7f)) << off;
       off += 7;
       if ((v & 0x80) == 0)
 	{
@@ -209,7 +210,7 @@ ghw_read_sleb128 (struct ghw_handler *h, int32_t *res)
 }
 
 int
-ghw_read_lsleb128 (struct ghw_handler *h, int64_t *res)
+ghw_read_lsleb128 (struct ghw_handler *h, int64_t * res)
 {
   static const int64_t r_mask = -1;
   int64_t r = 0;
@@ -220,7 +221,7 @@ ghw_read_lsleb128 (struct ghw_handler *h, int64_t *res)
       int v = fgetc (h->stream);
       if (v == EOF)
 	return -1;
-      r |= ((int64_t)(v & 0x7f)) << off;
+      r |= ((int64_t) (v & 0x7f)) << off;
       off += 7;
       if ((v & 0x80) == 0)
 	{
@@ -280,7 +281,7 @@ ghw_read_range (struct ghw_handler *h)
 	  goto err_b2;
 	if (ghw_read_byte (h, &r->right) != 0)
 	  goto err_b2;
-	return (union ghw_range *)r;
+	return (union ghw_range *) r;
       err_b2:
 	free (r);
 	return NULL;
@@ -295,7 +296,7 @@ ghw_read_range (struct ghw_handler *h)
 	  goto err_e8;
 	if (ghw_read_byte (h, &r->right) != 0)
 	  goto err_e8;
-	return (union ghw_range *)r;
+	return (union ghw_range *) r;
       err_e8:
 	free (r);
 	return NULL;
@@ -311,7 +312,7 @@ ghw_read_range (struct ghw_handler *h)
 	  goto err_i32;
 	if (ghw_read_sleb128 (h, &r->right) != 0)
 	  goto err_i32;
-	return (union ghw_range *)r;
+	return (union ghw_range *) r;
       err_i32:
 	free (r);
 	return NULL;
@@ -327,7 +328,7 @@ ghw_read_range (struct ghw_handler *h)
 	  goto err_i64;
 	if (ghw_read_lsleb128 (h, &r->right) != 0)
 	  goto err_i64;
-	return (union ghw_range *)r;
+	return (union ghw_range *) r;
       err_i64:
 	free (r);
 	return NULL;
@@ -342,7 +343,7 @@ ghw_read_range (struct ghw_handler *h)
 	  goto err_f64;
 	if (ghw_read_f64 (h, &r->right) != 0)
 	  goto err_f64;
-	return (union ghw_range *)r;
+	return (union ghw_range *) r;
       err_f64:
 	free (r);
 	return NULL;
@@ -369,8 +370,8 @@ ghw_read_str (struct ghw_handler *h)
   h->nbr_str = ghw_get_i32 (h, &hdr[4]);
   h->nbr_str++;
   h->str_size = ghw_get_i32 (h, &hdr[8]);
-  h->str_table = (char **)malloc ((h->nbr_str + 1) * sizeof (char *));
-  h->str_content = (char *)malloc (h->str_size + h->nbr_str + 1);
+  h->str_table = (char **) malloc ((h->nbr_str + 1) * sizeof (char *));
+  h->str_content = (char *) malloc (h->str_size + h->nbr_str + 1);
 
   if (h->flag_verbose)
     {
@@ -398,8 +399,7 @@ ghw_read_str (struct ghw_handler *h)
 	  c = fgetc (h->stream);
 	  if (c == EOF)
 	    return -1;
-	  if ((c >= 0 && c <= 31)
-	      || (c >= 128 && c <= 159))
+	  if ((c >= 0 && c <= 31) || (c >= 128 && c <= 159))
 	    break;
 	  *p++ = c;
 	}
@@ -439,11 +439,14 @@ ghw_get_base_type (union ghw_type *t)
     case ghdl_rtik_type_f64:
     case ghdl_rtik_type_p32:
     case ghdl_rtik_type_p64:
+    case ghdl_rtik_type_array:
       return t;
     case ghdl_rtik_subtype_scalar:
       return t->ss.base;
     case ghdl_rtik_subtype_array:
-      return (union ghw_type*)(t->sa.base);
+      return t->sa.base;
+    case ghdl_rtik_subtype_unbounded_array:
+      return t->sua.base;
     default:
       fprintf (stderr, "ghw_get_base_type: cannot handle type %d\n", t->kind);
       abort ();
@@ -474,6 +477,9 @@ get_nbr_elements (union ghw_type *t)
       return t->rec.nbr_scalars;
     case ghdl_rtik_subtype_record:
       return t->sr.nbr_scalars;
+    case ghdl_rtik_subtype_unbounded_record:
+    case ghdl_rtik_subtype_unbounded_array:
+      return -1;
     default:
       fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind);
       abort ();
@@ -515,27 +521,45 @@ ghw_get_range_length (union ghw_range *rng)
   return (res <= 0) ? 0 : res;
 }
 
+static union ghw_type *ghw_read_type_bounds (struct ghw_handler *h,
+					     union ghw_type *base);
+
 /* Create an array subtype using BASE and ranges read from H.  */
 
 struct ghw_subtype_array *
-ghw_read_array_subtype (struct ghw_handler *h, struct ghw_type_array *base)
+ghw_read_array_subtype (struct ghw_handler *h, union ghw_type *base)
 {
+  struct ghw_type_array *arr =
+    (struct ghw_type_array *) ghw_get_base_type (base);
   struct ghw_subtype_array *sa;
   unsigned j;
   int nbr_scalars;
+  int nbr_els;
 
   sa = malloc (sizeof (struct ghw_subtype_array));
   sa->kind = ghdl_rtik_subtype_array;
   sa->name = NULL;
   sa->base = base;
-  nbr_scalars = get_nbr_elements (base->el);
-  sa->rngs = malloc (base->nbr_dim * sizeof (union ghw_range *));
-  for (j = 0; j < base->nbr_dim; j++)
+  nbr_els = get_nbr_elements (arr->el);
+  nbr_scalars = 1;
+  sa->rngs = malloc (arr->nbr_dim * sizeof (union ghw_range *));
+  for (j = 0; j < arr->nbr_dim; j++)
     {
       sa->rngs[j] = ghw_read_range (h);
       nbr_scalars *= ghw_get_range_length (sa->rngs[j]);
     }
-  sa->nbr_scalars = nbr_scalars;
+  if (nbr_els >= 0)
+    {
+      /* Element type is bounded.  */
+      sa->el = arr->el;
+    }
+  else
+    {
+      /* Read bounds for the elements.  */
+      sa->el = ghw_read_type_bounds (h, arr->el);
+      nbr_els = get_nbr_elements (sa->el);
+    }
+  sa->nbr_scalars = nbr_scalars * nbr_els;
   return sa;
 }
 
@@ -560,7 +584,8 @@ ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base)
       unsigned j;
       int nbr_scalars;
 
-      sr->els = malloc (base->nbr_fields * sizeof (struct ghw_record_element));
+      sr->els =
+	malloc (base->nbr_fields * sizeof (struct ghw_record_element));
       nbr_scalars = 0;
       for (j = 0; j < base->nbr_fields; j++)
 	{
@@ -575,22 +600,7 @@ ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base)
 	    }
 	  else
 	    {
-	      switch (btype->kind)
-		{
-		case ghdl_rtik_type_array:
-		  sr->els[j].type = (union ghw_type *)
-		    ghw_read_array_subtype (h, &btype->ar);
-		  break;
-		case ghdl_rtik_type_record:
-		  sr->els[j].type = (union ghw_type *)
-		    ghw_read_record_subtype (h, &btype->rec);
-		  break;
-		default:
-		  fprintf
-		    (stderr, "ghw_read_record_subtype: unhandled kind %d\n",
-		     btype->kind);
-		  return NULL;
-		}
+	      sr->els[j].type = ghw_read_type_bounds (h, btype);
 	      el_nbr_scalars = get_nbr_elements (sr->els[j].type);
 	    }
 	  nbr_scalars += el_nbr_scalars;
@@ -600,6 +610,28 @@ ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base)
   return sr;
 }
 
+/* Read bounds for BASE and create a subtype.  */
+
+static union ghw_type *
+ghw_read_type_bounds (struct ghw_handler *h, union ghw_type *base)
+{
+  switch (base->kind)
+    {
+    case ghdl_rtik_type_array:
+    case ghdl_rtik_subtype_unbounded_array:
+      return (union ghw_type *) ghw_read_array_subtype (h, base);
+      break;
+    case ghdl_rtik_type_record:
+    case ghdl_rtik_subtype_unbounded_record:
+      return (union ghw_type *) ghw_read_record_subtype (h, &base->rec);
+      break;
+    default:
+      fprintf (stderr, "ghw_read_type_bounds: unhandled kind %d\n",
+	       base->kind);
+      return NULL;
+    }
+}
+
 int
 ghw_read_type (struct ghw_handler *h)
 {
@@ -612,8 +644,8 @@ ghw_read_type (struct ghw_handler *h)
   if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0)
     return -1;
   h->nbr_types = ghw_get_i32 (h, &hdr[4]);
-  h->types = (union ghw_type **)
-    malloc (h->nbr_types * sizeof (union ghw_type *));
+  h->types =
+    (union ghw_type **) malloc (h->nbr_types * sizeof (union ghw_type *));
 
   for (i = 0; i < h->nbr_types; i++)
     {
@@ -622,7 +654,8 @@ ghw_read_type (struct ghw_handler *h)
       t = fgetc (h->stream);
       if (t == EOF)
 	return -1;
-      /* printf ("type[%d]= %d\n", i, t); */
+      if (h->flag_verbose > 1)
+	printf ("type[%d]= %d\n", i, t);
       switch (t)
 	{
 	case ghdl_rtik_type_b2:
@@ -648,7 +681,7 @@ ghw_read_type (struct ghw_handler *h)
 	      }
 	    if (h->flag_verbose > 1)
 	      printf ("\n");
-	    h->types[i] = (union ghw_type *)e;
+	    h->types[i] = (union ghw_type *) e;
 	    break;
 	  err_b2:
 	    free (e);
@@ -666,9 +699,8 @@ ghw_read_type (struct ghw_handler *h)
 	    sc->name = ghw_read_strid (h);
 	    if (h->flag_verbose > 1)
 	      printf ("scalar: %s\n", sc->name);
-	    h->types[i] = (union ghw_type *)sc;
-	  }
-	  break;
+	    h->types[i] = (union ghw_type *) sc;
+	  } break;
 	case ghdl_rtik_type_p32:
 	case ghdl_rtik_type_p64:
 	  {
@@ -696,7 +728,7 @@ ghw_read_type (struct ghw_handler *h)
 	      }
 	    if (h->flag_verbose > 1)
 	      printf ("physical: %s\n", ph->name);
-	    h->types[i] = (union ghw_type *)ph;
+	    h->types[i] = (union ghw_type *) ph;
 	    break;
 	  err_p32:
 	    free (ph->units);
@@ -715,9 +747,8 @@ ghw_read_type (struct ghw_handler *h)
 	    ss->rng = ghw_read_range (h);
 	    if (h->flag_verbose > 1)
 	      printf ("subtype scalar: %s\n", ss->name);
-	    h->types[i] = (union ghw_type *)ss;
-	  }
-	  break;
+	    h->types[i] = (union ghw_type *) ss;
+	  } break;
 	case ghdl_rtik_type_array:
 	  {
 	    struct ghw_type_array *arr;
@@ -729,13 +760,15 @@ ghw_read_type (struct ghw_handler *h)
 	    arr->el = ghw_read_typeid (h);
 	    if (ghw_read_uleb128 (h, &arr->nbr_dim) != 0)
 	      goto err_array;
-	    arr->dims = (union ghw_type **)
-	      malloc (arr->nbr_dim * sizeof (union ghw_type *));
+	    arr->dims =
+	      (union ghw_type **) malloc (arr->nbr_dim *
+					  sizeof (union ghw_type *));
 	    for (j = 0; j < arr->nbr_dim; j++)
 	      arr->dims[j] = ghw_read_typeid (h);
 	    if (h->flag_verbose > 1)
-	      printf ("array: %s\n", arr->name);
-	    h->types[i] = (union ghw_type *)arr;
+	      printf ("array: %s (ndim=%u) of %s\n", arr->name, arr->nbr_dim,
+		      arr->el->common.name);
+	    h->types[i] = (union ghw_type *) arr;
 	    break;
 	  err_array:
 	    free (arr);
@@ -746,17 +779,30 @@ ghw_read_type (struct ghw_handler *h)
 	  {
 	    struct ghw_subtype_array *sa;
 	    const char *name;
-	    struct ghw_type_array *base;
+	    union ghw_type *base;
 
 	    name = ghw_read_strid (h);
-	    base = (struct ghw_type_array *)ghw_read_typeid (h);
+	    base = ghw_read_typeid (h);
 
 	    sa = ghw_read_array_subtype (h, base);
 	    sa->name = name;
-	    h->types[i] = (union ghw_type *)sa;
+	    h->types[i] = (union ghw_type *) sa;
+	    if (h->flag_verbose > 1)
+	      printf ("subtype array: %s (nbr_scalars=%d)\n", sa->name,
+		      sa->nbr_scalars);
+	  }
+	  break;
+	case ghdl_rtik_subtype_unbounded_array:
+	  {
+	    struct ghw_subtype_unbounded_array *sua;
+
+	    sua = malloc (sizeof (struct ghw_subtype_unbounded_array));
+	    sua->kind = t;
+	    sua->name = ghw_read_strid (h);
+	    sua->base = ghw_read_typeid (h);
+	    h->types[i] = (union ghw_type *) sua;
 	    if (h->flag_verbose > 1)
-	      printf ("subtype array: %s (nbr_scalars=%d)\n",
-		      sa->name, sa->nbr_scalars);
+	      printf ("subtype unbounded array: %s\n", sua->name);
 	  }
 	  break;
 	case ghdl_rtik_type_record:
@@ -771,8 +817,8 @@ ghw_read_type (struct ghw_handler *h)
 	    rec->els = NULL;
 	    if (ghw_read_uleb128 (h, &rec->nbr_fields) != 0)
 	      goto err_record;
-	    rec->els = malloc
-	      (rec->nbr_fields * sizeof (struct ghw_record_element));
+	    rec->els =
+	      malloc (rec->nbr_fields * sizeof (struct ghw_record_element));
 	    nbr_scalars = 0;
 	    for (j = 0; j < rec->nbr_fields; j++)
 	      {
@@ -780,7 +826,8 @@ ghw_read_type (struct ghw_handler *h)
 		rec->els[j].type = ghw_read_typeid (h);
 		if (nbr_scalars != -1)
 		  {
-		    int field_nbr_scalars = get_nbr_elements (rec->els[j].type);
+		    int field_nbr_scalars =
+		      get_nbr_elements (rec->els[j].type);
 		    if (field_nbr_scalars == -1)
 		      nbr_scalars = -1;
 		    else
@@ -789,9 +836,9 @@ ghw_read_type (struct ghw_handler *h)
 	      }
 	    rec->nbr_scalars = nbr_scalars;
 	    if (h->flag_verbose > 1)
-	      printf ("record type: %s (nbr_scalars=%d)\n",
-		      rec->name, rec->nbr_scalars);
-	    h->types[i] = (union ghw_type *)rec;
+	      printf ("record type: %s (nbr_scalars=%d)\n", rec->name,
+		      rec->nbr_scalars);
+	    h->types[i] = (union ghw_type *) rec;
 	    break;
 	  err_record:
 	    free (rec->els);
@@ -806,14 +853,27 @@ ghw_read_type (struct ghw_handler *h)
 	    struct ghw_type_record *base;
 
 	    name = ghw_read_strid (h);
-	    base = (struct ghw_type_record *)ghw_read_typeid (h);
+	    base = (struct ghw_type_record *) ghw_read_typeid (h);
 
 	    sr = ghw_read_record_subtype (h, base);
 	    sr->name = name;
-	    h->types[i] = (union ghw_type *)sr;
+	    h->types[i] = (union ghw_type *) sr;
+	    if (h->flag_verbose > 1)
+	      printf ("subtype record: %s (nbr_scalars=%d)\n", sr->name,
+		      sr->nbr_scalars);
+	  }
+	  break;
+	case ghdl_rtik_subtype_unbounded_record:
+	  {
+	    struct ghw_subtype_unbounded_record *sur;
+
+	    sur = malloc (sizeof (struct ghw_subtype_unbounded_record));
+	    sur->kind = t;
+	    sur->name = ghw_read_strid (h);
+	    sur->base = (struct ghw_type_record *) ghw_read_typeid (h);
+	    h->types[i] = (union ghw_type *) sur;
 	    if (h->flag_verbose > 1)
-	      printf ("subtype record: %s (nbr_scalars=%d)\n",
-		      sr->name, sr->nbr_scalars);
+	      printf ("subtype unbounded record: %s\n", sur->name);
 	  }
 	  break;
 	default:
@@ -849,8 +909,7 @@ ghw_read_wk_types (struct ghw_handler *h)
 	break;
 
       tid = ghw_read_typeid (h);
-      if (tid->kind == ghdl_rtik_type_b2
-	  || tid->kind == ghdl_rtik_type_e8)
+      if (tid->kind == ghdl_rtik_type_b2 || tid->kind == ghdl_rtik_type_e8)
 	{
 	  if (h->flag_verbose > 0)
 	    printf ("%s: wkt=%d\n", tid->en.name, t);
@@ -863,7 +922,7 @@ ghw_read_wk_types (struct ghw_handler *h)
 void
 ghw_disp_typename (struct ghw_handler *h, union ghw_type *t)
 {
-  (void)h;
+  (void) h;
   printf ("%s", t->common.name);
 }
 
@@ -897,10 +956,10 @@ ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t)
 	int len;
 
 	len = t->sa.nbr_scalars;
-	stride = get_nbr_elements (t->sa.base->el);
+	stride = get_nbr_elements (t->sa.el);
 
 	for (i = 0; i < len; i += stride)
-	  if (ghw_read_signal (h, &sigs[i], t->sa.base->el) < 0)
+	  if (ghw_read_signal (h, &sigs[i], t->sa.el) < 0)
 	    return -1;
       }
       return 0;
@@ -942,10 +1001,9 @@ ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t)
     }
 }
 
-
 int
-ghw_read_value (struct ghw_handler *h,
-		union ghw_val *val, union ghw_type *type)
+ghw_read_value (struct ghw_handler *h, union ghw_val *val,
+		union ghw_type *type)
 {
   switch (ghw_get_base_type (type)->kind)
     {
@@ -1021,10 +1079,10 @@ ghw_read_hie (struct ghw_handler *h)
   h->nbr_sigs = ghw_get_i32 (h, &hdr[12]);
 
   if (h->flag_verbose)
-    printf ("%u scopes, %u signals, %u signal elements\n",
-	    nbr_scopes, nbr_sigs, h->nbr_sigs);
+    printf ("%u scopes, %u signals, %u signal elements\n", nbr_scopes,
+	    nbr_sigs, h->nbr_sigs);
 
-  blk = (struct ghw_hie *)malloc (sizeof (struct ghw_hie));
+  blk = (struct ghw_hie *) malloc (sizeof (struct ghw_hie));
   blk->kind = ghw_hie_design;
   blk->name = NULL;
   blk->parent = NULL;
@@ -1090,6 +1148,7 @@ ghw_read_hie (struct ghw_handler *h)
 	  /* Should not be here.  */
 	  abort ();
 	case ghw_hie_process:
+	  el->u.blk.child = NULL;
 	  break;
 	case ghw_hie_block:
 	case ghw_hie_generate_if:
@@ -1104,8 +1163,8 @@ ghw_read_hie (struct ghw_handler *h)
 	    {
 	      el->u.blk.iter_type = ghw_read_typeid (h);
 	      el->u.blk.iter_value = malloc (sizeof (union ghw_val));
-	      if (ghw_read_value (h, el->u.blk.iter_value,
-				  el->u.blk.iter_type) < 0)
+	      if (ghw_read_value
+		  (h, el->u.blk.iter_value, el->u.blk.iter_type) < 0)
 		return -1;
 	    }
 	  blk = el;
@@ -1126,8 +1185,8 @@ ghw_read_hie (struct ghw_handler *h)
 	    nbr_el = get_nbr_elements (el->u.sig.type);
 	    if (nbr_el < 0)
 	      return -1;
-	    sigs = (unsigned int *) malloc
-	      ((nbr_el + 1) * sizeof (unsigned int));
+	    sigs =
+	      (unsigned int *) malloc ((nbr_el + 1) * sizeof (unsigned int));
 	    el->u.sig.sigs = sigs;
 	    /* Last element is NULL.  */
 	    sigs[nbr_el] = 0;
@@ -1200,8 +1259,7 @@ ghw_get_hie_name (struct ghw_hie *h)
     }
 }
 
-void
-ghw_disp_value (union ghw_val *val, union ghw_type *type);
+void ghw_disp_value (union ghw_val *val, union ghw_type *type);
 
 static void
 print_name (struct ghw_hie *hie, int full_names)
@@ -1313,8 +1371,8 @@ ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top)
 	    ghw_disp_subtype_indication (h, hie->u.sig.type);
 	    printf (":");
 	    k = 0;
-	    assert (sigs[0] != GHW_NO_SIG);
-	    while (1)
+	    /* There can be 0-length signals.  */
+	    while (sigs[k] != GHW_NO_SIG)
 	      {
 		/* First signal of the range.  */
 		printf (" #%u", sigs[k]);
@@ -1324,9 +1382,6 @@ ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top)
 		if (num > 1)
 		  printf ("-#%u", sigs[k + num - 1]);
 		k += num;
-		/* End of signals ? */
-		if (sigs[k] == GHW_NO_SIG)
-		  break;
 	      }
 	    n = hie->brother;
 	  }
@@ -1351,7 +1406,7 @@ ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top)
 int
 ghw_read_eoh (struct ghw_handler *h)
 {
-  (void)h;
+  (void) h;
   return 0;
 }
 
@@ -1498,7 +1553,6 @@ ghw_read_cycle_next (struct ghw_handler *h)
   return 1;
 }
 
-
 int
 ghw_read_cycle_end (struct ghw_handler *h)
 {
@@ -1548,8 +1602,7 @@ ghw_disp_value (union ghw_val *val, union ghw_type *type)
       printf ("%g", val->f64);
       break;
     default:
-      fprintf (stderr, "ghw_disp_value: cannot handle type %d\n",
-	       type->kind);
+      fprintf (stderr, "ghw_disp_value: cannot handle type %d\n", type->kind);
       abort ();
     }
 }
@@ -1615,8 +1668,8 @@ is_skip_signal (int *signals_to_keep, int nb_signals_to_keep, int signal)
 }
 
 void
-ghw_filter_signals (struct ghw_handler *h,
-		    int *signals_to_keep, int nb_signals_to_keep)
+ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep,
+		    int nb_signals_to_keep)
 {
   unsigned i;
 
@@ -1628,8 +1681,8 @@ ghw_filter_signals (struct ghw_handler *h,
 	}
       for (i = 0; i < h->nbr_sigs; ++i)
 	{
-	  h->skip_sigs[i] = is_skip_signal (signals_to_keep,
-					    nb_signals_to_keep, i);
+	  h->skip_sigs[i] =
+	    is_skip_signal (signals_to_keep, nb_signals_to_keep, i);
 	}
     }
   else
@@ -1658,6 +1711,7 @@ ghw_disp_values (struct ghw_handler *h)
 	}
     }
 }
+
 int
 ghw_read_directory (struct ghw_handler *h)
 {
@@ -1750,8 +1804,8 @@ ghw_read_sm_hdr (struct ghw_handler *h, int *list)
     }
   else
     {
-      fprintf (stderr, "unknown GHW section %c%c%c%c\n",
-	       hdr[0], hdr[1], hdr[2], hdr[3]);
+      fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1],
+	       hdr[2], hdr[3]);
       return -1;
     }
   if (res != 0)
@@ -1830,7 +1884,6 @@ ghw_read_cycle (struct ghw_handler *h)
       if (0)
 	ghw_disp_values (h);
 
-
       res = ghw_read_cycle_next (h);
       if (res < 0)
 	return res;
@@ -1876,8 +1929,8 @@ ghw_read_dump (struct ghw_handler *h)
 	}
       else
 	{
-	  fprintf (stderr, "unknown GHW section %c%c%c%c\n",
-		   hdr[0], hdr[1], hdr[2], hdr[3]);
+	  fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1],
+		   hdr[2], hdr[3]);
 	  return -1;
 	}
       if (res != 0)
@@ -1885,17 +1938,16 @@ ghw_read_dump (struct ghw_handler *h)
     }
 }
 
-struct ghw_section ghw_sections[] = {
-  { "\0\0\0", NULL },
-  { "STR", ghw_read_str },
-  { "HIE", ghw_read_hie },
-  { "TYP", ghw_read_type },
-  { "WKT", ghw_read_wk_types },
-  { "EOH", ghw_read_eoh },
-  { "SNP", ghw_read_snapshot },
-  { "CYC", ghw_read_cycle },
-  { "DIR", ghw_read_directory },
-  { "TAI", ghw_read_tailer }
+struct ghw_section ghw_sections[] = { {"\0\0\0", NULL},
+{"STR", ghw_read_str},
+{"HIE", ghw_read_hie},
+{"TYP", ghw_read_type},
+{"WKT", ghw_read_wk_types},
+{"EOH", ghw_read_eoh},
+{"SNP", ghw_read_snapshot},
+{"CYC", ghw_read_cycle},
+{"DIR", ghw_read_directory},
+{"TAI", ghw_read_tailer}
 };
 
 int
@@ -1916,8 +1968,8 @@ ghw_read_section (struct ghw_handler *h)
     if (memcmp (hdr, ghw_sections[i].name, 4) == 0)
       return i;
 
-  fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n",
-	   hdr[0], hdr[1], hdr[2], hdr[3]);
+  fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n", hdr[0],
+	   hdr[1], hdr[2], hdr[3]);
   return 0;
 }
 
@@ -1956,17 +2008,17 @@ ghw_disp_range (union ghw_type *type, union ghw_range *rng)
       break;
     case ghdl_rtik_type_i32:
     case ghdl_rtik_type_p32:
-      printf (GHWPRI32 " %s " GHWPRI32,
-	      rng->i32.left, ghw_get_dir (rng->i32.dir), rng->i32.right);
+      printf (GHWPRI32 " %s " GHWPRI32, rng->i32.left,
+	      ghw_get_dir (rng->i32.dir), rng->i32.right);
       break;
     case ghdl_rtik_type_i64:
     case ghdl_rtik_type_p64:
-      printf (GHWPRI64 " %s " GHWPRI64,
-	      rng->i64.left, ghw_get_dir (rng->i64.dir), rng->i64.right);
+      printf (GHWPRI64 " %s " GHWPRI64, rng->i64.left,
+	      ghw_get_dir (rng->i64.dir), rng->i64.right);
       break;
     case ghdl_rtik_type_f64:
-      printf ("%g %s %g",
-	      rng->f64.left, ghw_get_dir (rng->f64.dir), rng->f64.right);
+      printf ("%g %s %g", rng->f64.left, ghw_get_dir (rng->f64.dir),
+	      rng->f64.right);
       break;
     default:
       printf ("?(%d)", rng->kind);
@@ -1977,13 +2029,15 @@ static void
 ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a)
 {
   unsigned i;
+  struct ghw_type_array *base =
+    (struct ghw_type_array *) ghw_get_base_type (a->base);
 
   printf (" (");
-  for (i = 0; i < a->base->nbr_dim; i++)
+  for (i = 0; i < base->nbr_dim; i++)
     {
       if (i != 0)
 	printf (", ");
-      ghw_disp_range (a->base->dims[i], a->rngs[i]);
+      ghw_disp_range (base->dims[i], a->rngs[i]);
     }
   printf (")");
 }
@@ -2035,24 +2089,28 @@ ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t)
 	ghw_disp_typename (h, s->base);
 	printf (" range ");
 	ghw_disp_range (s->base, s->rng);
-      }
-      break;
+      } break;
     case ghdl_rtik_subtype_array:
       {
 	struct ghw_subtype_array *a = &t->sa;
 
-	ghw_disp_typename (h, (union ghw_type *)a->base);
+	ghw_disp_typename (h, (union ghw_type *) a->base);
 	ghw_disp_array_subtype_bounds (a);
-      }
-      break;
+      } break;
     case ghdl_rtik_subtype_record:
       {
 	struct ghw_subtype_record *sr = &t->sr;
 
-	ghw_disp_typename (h, (union ghw_type *)sr->base);
+	ghw_disp_typename (h, (union ghw_type *) sr->base);
 	ghw_disp_record_subtype_bounds (sr);
-      }
-      break;
+      } break;
+    case ghdl_rtik_subtype_unbounded_array:
+    case ghdl_rtik_subtype_unbounded_record:
+      {
+	struct ghw_subtype_unbounded_record *sur = &t->sur;
+
+	ghw_disp_typename (h, (union ghw_type *) sur->base);
+      } break;
     default:
       printf ("ghw_disp_subtype_definition: unhandled type kind %d\n",
 	      t->kind);
@@ -2106,8 +2164,7 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
       {
 	struct ghw_type_scalar *s = &t->sc;
 	printf ("type %s is range <>;\n", s->name);
-      }
-      break;
+      } break;
     case ghdl_rtik_type_p32:
     case ghdl_rtik_type_p64:
       {
@@ -2118,12 +2175,11 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
 	for (i = 0; i < p->nbr_units; i++)
 	  {
 	    struct ghw_unit *u = &p->units[i];
-	    printf ("  %s = " GHWPRI64 " %s;\n",
-		    u->name, u->val, p->units[0].name);
+	    printf ("  %s = " GHWPRI64 " %s;\n", u->name, u->val,
+		    p->units[0].name);
 	  }
 	printf ("end units\n");
-      }
-      break;
+      } break;
     case ghdl_rtik_type_array:
       {
 	struct ghw_type_array *a = &t->ar;
@@ -2160,13 +2216,14 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t)
     case ghdl_rtik_subtype_array:
     case ghdl_rtik_subtype_scalar:
     case ghdl_rtik_subtype_record:
+    case ghdl_rtik_subtype_unbounded_array:
+    case ghdl_rtik_subtype_unbounded_record:
       {
 	struct ghw_type_common *c = &t->common;
 	printf ("subtype %s is ", c->name);
 	ghw_disp_subtype_definition (h, t);
 	printf (";\n");
-      }
-      break;
+      } break;
     default:
       printf ("ghw_disp_type: unhandled type kind %d\n", t->kind);
     }
diff --git a/src/ghwlib.h b/src/libghw.h
similarity index 70%
rename from src/ghwlib.h
rename to src/libghw.h
index cd5df1c..a6d22d0 100644
--- a/src/ghwlib.h
+++ b/src/libghw.h
@@ -1,51 +1,50 @@
-/*  GHDL Wavefile reader library.
-    Copyright (C) 2005-2017 Tristan Gingold
-
-    GHDL is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License as published by the Free
-    Software Foundation; either version 2, or (at your option) any later
-    version.
-
-    GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with GCC; see the file COPYING.  If not, write to the Free
-    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-    02111-1307, USA.
-*/
+/* GHDL Wavefile reader library.
+  Copyright (C) 2005-2017 Tristan Gingold
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
 
-#ifndef _GHWLIB_H_
-#define _GHWLIB_H_
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <gnu.org/licenses>.
+*/
+
+#ifndef _LIBGHW_H_
+#define _LIBGHW_H_
 
 #include <stdio.h>
 #include <stdlib.h>
 
+/* To be libraries friendly.  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-/* The ghwlib uses the standard c99 int32_t and int64_t.  They are declared
+/* The libghw uses the standard c99 int32_t and int64_t.  They are declared
    in stdint.h.  Header inttypes.h includes stdint.h and provides macro for
    printf and co specifiers.  Use it if known to be available.  */
 
-#if defined(__cplusplus) \
-  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \
-  || defined(HAVE_INTTYPES_H)
+#if defined(__cplusplus) ||                                                    \
+    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||            \
+    defined(HAVE_INTTYPES_H)
 /* Use C99 standard header.  */
-# include <inttypes.h>
-# define GHWPRI64 "%"PRId64
-# define GHWPRI32 "%"PRId32
+#include <inttypes.h>
+#define GHWPRI64 "%" PRId64
+#define GHWPRI32 "%" PRId32
 #else
-# include <stdint.h>
-# define GHWPRI64 "%lld"
-# define GHWPRI32 "%d"
+#include <stdint.h>
+#define GHWPRI64 "%lld"
+#define GHWPRI32 "%d"
 #endif
 
-enum ghdl_rtik {
+enum ghdl_rtik
+{
   ghdl_rtik_top,		/* 0  */
   ghdl_rtik_library,
   ghdl_rtik_package,
@@ -82,21 +81,25 @@ enum ghdl_rtik {
   ghdl_rtik_type_file,
   ghdl_rtik_subtype_scalar,
   ghdl_rtik_subtype_array,	/* 35 */
-  ghdl_rtik_subtype_array_ptr,             /* Obsolete.  */
-  ghdl_rtik_subtype_unconstrained_array,   /* Obsolete.  */
+  ghdl_rtik_subtype_array_ptr,	/* Obsolete.  */
+  ghdl_rtik_subtype_unbounded_array,
   ghdl_rtik_subtype_record,
-  ghdl_rtik_subtype_access,
+  ghdl_rtik_subtype_unbounded_record,
+#if 0
+  ghdl_rtik_subtype_access,	/* 40 */
   ghdl_rtik_type_protected,
   ghdl_rtik_element,
   ghdl_rtik_unit,
   ghdl_rtik_attribute_transaction,
   ghdl_rtik_attribute_quiet,
   ghdl_rtik_attribute_stable,
+#endif
   ghdl_rtik_error
 };
 
 /* Well-known types.  */
-enum ghw_wkt_type {
+enum ghw_wkt_type
+{
   ghw_wkt_unknown,
   ghw_wkt_boolean,
   ghw_wkt_bit,
@@ -105,47 +108,47 @@ enum ghw_wkt_type {
 
 struct ghw_range_b2
 {
-  enum ghdl_rtik kind : 8;
-  int dir : 8; /* 0: to, !0: downto.  */
+  enum ghdl_rtik kind:8;
+  int dir:8;			/* 0: to, !0: downto.  */
   unsigned char left;
   unsigned char right;
 };
 
 struct ghw_range_e8
 {
-  enum ghdl_rtik kind : 8;
-  int dir : 8; /* 0: to, !0: downto.  */
+  enum ghdl_rtik kind:8;
+  int dir:8;			/* 0: to, !0: downto.  */
   unsigned char left;
   unsigned char right;
 };
 
 struct ghw_range_i32
 {
-  enum ghdl_rtik kind : 8;
-  int dir : 8; /* 0: to, !0: downto.  */
+  enum ghdl_rtik kind:8;
+  int dir:8;			/* 0: to, !0: downto.  */
   int32_t left;
   int32_t right;
 };
 
 struct ghw_range_i64
 {
-  enum ghdl_rtik kind : 8;
-  int dir : 8;
+  enum ghdl_rtik kind:8;
+  int dir:8;
   int64_t left;
   int64_t right;
 };
 
 struct ghw_range_f64
 {
-  enum ghdl_rtik kind : 8;
-  int dir : 8;
+  enum ghdl_rtik kind:8;
+  int dir:8;
   double left;
   double right;
 };
 
 union ghw_range
 {
-  enum ghdl_rtik kind : 8;
+  enum ghdl_rtik kind:8;
   struct ghw_range_b2 b2;
   struct ghw_range_e8 e8;
   struct ghw_range_i32 i32;
@@ -202,14 +205,23 @@ struct ghw_type_array
   union ghw_type **dims;
 };
 
+struct ghw_subtype_unbounded_array
+{
+  enum ghdl_rtik kind;
+  const char *name;
+
+  union ghw_type *base;
+};
+
 struct ghw_subtype_array
 {
   enum ghdl_rtik kind;
   const char *name;
 
-  struct ghw_type_array *base;
+  union ghw_type *base;
   int nbr_scalars;
   union ghw_range **rngs;
+  union ghw_type *el;
 };
 
 struct ghw_subtype_scalar
@@ -233,7 +245,7 @@ struct ghw_type_record
   const char *name;
 
   unsigned int nbr_fields;
-  int nbr_scalars;	/* Number of scalar elements (ie nbr of signals).  */
+  int nbr_scalars;		/* Number of scalar elements (ie nbr of signals).  */
   struct ghw_record_element *els;
 };
 
@@ -243,10 +255,18 @@ struct ghw_subtype_record
   const char *name;
 
   struct ghw_type_record *base;
-  int nbr_scalars;	/* Number of scalar elements (ie nbr of signals).  */
+  int nbr_scalars;		/* Number of scalar elements (ie nbr of signals).  */
   struct ghw_record_element *els;
 };
 
+struct ghw_subtype_unbounded_record
+{
+  enum ghdl_rtik kind;
+  const char *name;
+
+  struct ghw_type_record *base;
+};
+
 union ghw_type
 {
   enum ghdl_rtik kind;
@@ -255,10 +275,12 @@ union ghw_type
   struct ghw_type_scalar sc;
   struct ghw_type_physical ph;
   struct ghw_subtype_scalar ss;
-  struct ghw_subtype_array sa;
-  struct ghw_subtype_record sr;
   struct ghw_type_array ar;
   struct ghw_type_record rec;
+  struct ghw_subtype_array sa;
+  struct ghw_subtype_unbounded_array sua;
+  struct ghw_subtype_record sr;
+  struct ghw_subtype_unbounded_record sur;
 };
 
 union ghw_val
@@ -277,22 +299,23 @@ struct ghw_sig
   union ghw_val *val;
 };
 
-enum ghw_hie_kind {
-  ghw_hie_eoh          = 0,
-  ghw_hie_design       = 1,
-  ghw_hie_block        = 3,
-  ghw_hie_generate_if  = 4,
+enum ghw_hie_kind
+{
+  ghw_hie_eoh = 0,
+  ghw_hie_design = 1,
+  ghw_hie_block = 3,
+  ghw_hie_generate_if = 4,
   ghw_hie_generate_for = 5,
-  ghw_hie_instance     = 6,
-  ghw_hie_package      = 7,
-  ghw_hie_process      = 13,
-  ghw_hie_generic      = 14,
-  ghw_hie_eos          = 15,
-  ghw_hie_signal       = 16,
-  ghw_hie_port_in      = 17,
-  ghw_hie_port_out     = 18,
-  ghw_hie_port_inout   = 19,
-  ghw_hie_port_buffer  = 20,
+  ghw_hie_instance = 6,
+  ghw_hie_package = 7,
+  ghw_hie_process = 13,
+  ghw_hie_generic = 14,
+  ghw_hie_eos = 15,
+  ghw_hie_signal = 16,
+  ghw_hie_port_in = 17,
+  ghw_hie_port_out = 18,
+  ghw_hie_port_inout = 19,
+  ghw_hie_port_buffer = 20,
   ghw_hie_port_linkage = 21
 };
 
@@ -316,7 +339,7 @@ struct ghw_hie
     {
       union ghw_type *type;
       /* Array of signal elements.
-	 Last element is GHW_NO_SIG (0).  */
+         Last element is GHW_NO_SIG (0).  */
       unsigned int *sigs;
     } sig;
   } u;
@@ -376,8 +399,8 @@ int ghw_get_range_length (union ghw_range *rng);
 
 /* Put the ASCII representation of VAL into BUF, whose size if LEN.
    A NUL is always written to BUF.  */
-void ghw_get_value (char *buf, int len,
-		    union ghw_val *val, union ghw_type *type);
+void ghw_get_value (char *buf, int len, union ghw_val *val,
+		    union ghw_type *type);
 
 const char *ghw_get_hie_name (struct ghw_hie *h);
 
@@ -385,7 +408,8 @@ void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top);
 
 int ghw_read_base (struct ghw_handler *h);
 
-void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep);
+void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep,
+			 int nb_signals_to_keep);
 
 void ghw_disp_values (struct ghw_handler *h);
 
@@ -397,7 +421,8 @@ int ghw_read_cycle_next (struct ghw_handler *h);
 
 int ghw_read_cycle_end (struct ghw_handler *h);
 
-enum ghw_sm_type {
+enum ghw_sm_type
+{
   /* At init;
      Read section name.  */
   ghw_sm_init = 0,
@@ -405,7 +430,8 @@ enum ghw_sm_type {
   ghw_sm_cycle = 2
 };
 
-enum ghw_res {
+enum ghw_res
+{
   ghw_res_error = -1,
   ghw_res_eof = -2,
   ghw_res_ok = 0,
@@ -414,13 +440,16 @@ enum ghw_res {
   ghw_res_other = 3
 };
 
+enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list);
+
 int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm);
 
 int ghw_read_dump (struct ghw_handler *h);
 
-struct ghw_section {
+struct ghw_section
+{
   const char name[4];
-  int (*handler)(struct ghw_handler *h);
+  int (*handler) (struct ghw_handler * h);
 };
 
 extern struct ghw_section ghw_sections[];
@@ -439,7 +468,4 @@ void ghw_disp_range (union ghw_type *type, union ghw_range *rng);
 void ghw_disp_type (struct ghw_handler *h, union ghw_type *t);
 
 void ghw_disp_types (struct ghw_handler *h);
-
-enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list);
-
-#endif /* _GHWLIB_H_ */
+#endif /* _LIBGHW_H_ */
diff --git a/src/main.c b/src/main.c
index 6360d68..7276c62 100644
--- a/src/main.c
+++ b/src/main.c
@@ -117,6 +117,7 @@ GLOBALS->show_base = g_old->show_base;
 GLOBALS->display_grid = g_old->display_grid;
 GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow;
 GLOBALS->fill_waveform = g_old->fill_waveform;
+GLOBALS->lz_removal = g_old->lz_removal;
 GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select;
 GLOBALS->disable_mouseover = g_old->disable_mouseover;
 GLOBALS->clipboard_mouseover = g_old->clipboard_mouseover;
@@ -634,6 +635,7 @@ if(!GLOBALS)
 	GLOBALS->enable_ghost_marker = old_g->enable_ghost_marker;
 	GLOBALS->enable_horiz_grid = old_g->enable_horiz_grid;
 	GLOBALS->fill_waveform = old_g->fill_waveform;
+	GLOBALS->lz_removal = old_g->lz_removal;
 	GLOBALS->make_vcd_save_file = old_g->make_vcd_save_file;
 	GLOBALS->enable_vert_grid = old_g->enable_vert_grid;
 	GLOBALS->force_toolbars = old_g->force_toolbars;
@@ -649,7 +651,6 @@ if(!GLOBALS)
 	GLOBALS->show_base = old_g->show_base;
 	GLOBALS->display_grid = old_g->display_grid;
 	GLOBALS->highlight_wavewindow = old_g->highlight_wavewindow;
-	GLOBALS->fill_waveform = old_g->fill_waveform;
 	GLOBALS->use_standard_trace_select = old_g->use_standard_trace_select;
 	GLOBALS->use_big_fonts = old_g->use_big_fonts;
 	GLOBALS->use_full_precision = old_g->use_full_precision;
diff --git a/src/menu.c b/src/menu.c
index 7842766..e24b7bc 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -4483,12 +4483,12 @@ TraceFlagsType flags;
 t=GLOBALS->showchangeall_menu_c_1;
 if(t)
 	{
-	flags = t->flags & (TR_NUMMASK | TR_HIGHLIGHT);
+	flags = t->flags & (TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS);
 	while(t)
 		{
 		if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name))
 			{
-			t->flags = (t->flags & ~(TR_NUMMASK | TR_HIGHLIGHT)) | flags;
+			t->flags = (t->flags & ~(TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS)) | flags;
 			t->minmax_valid = 0; /* force analog traces to regenerate if necessary */
 			}
 		t=t->t_next;
@@ -6771,6 +6771,49 @@ if(GLOBALS->helpbox_is_active)
 dataformat( ~(TR_POPCNT), 0 );
 }
 
+void
+menu_dataformat_ffo_on(gpointer null_data, guint callback_action, GtkWidget *widget)
+{
+(void)null_data;
+(void)callback_action;
+(void)widget;
+
+if(GLOBALS->helpbox_is_active)
+        {
+	help_text_bold("\n\nData Format-Find First Rightmost One Index-On");
+        help_text(
+                " will step through all highlighted traces and ensure that"
+                " bits and vectors with this qualifier will be displayed after"
+                " going through a right->left FFO index conversion.  This is a filter"
+                " which sits before other Data Format options such as hex, etc."
+        );
+	return;
+        }
+
+dataformat( ~(TR_FFO), TR_FFO );
+}
+
+void
+menu_dataformat_ffo_off(gpointer null_data, guint callback_action, GtkWidget *widget)
+{
+(void)null_data;
+(void)callback_action;
+(void)widget;
+
+if(GLOBALS->helpbox_is_active)
+        {
+	help_text_bold("\n\nData Format-Find First Rightmost One Index-Off");
+        help_text(
+                " will step through all highlighted traces and ensure that"
+                " bits and vectors with this qualifier will be displayed with"
+                " normal encoding."
+        );
+        return;
+        }
+
+dataformat( ~(TR_FFO), 0 );
+}
+
 
 void
 menu_dataformat_time(gpointer null_data, guint callback_action, GtkWidget *widget)
@@ -7787,6 +7830,42 @@ GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,
 #endif
 }
 
+/**/
+void menu_lz_removal(gpointer null_data, guint callback_action, GtkWidget *widget)
+{
+(void)null_data;
+(void)callback_action;
+(void)widget;
+
+if(GLOBALS->helpbox_is_active)
+        {
+        help_text_bold("\n\nShow Filled High Values");
+        help_text(
+		" toggles the display of leading zeros on non-filtered traces.  This has no effect on filtered traces."
+        );
+        }
+	else
+	{
+#ifndef WAVE_USE_MLIST_T
+	GLOBALS->lz_removal=(GLOBALS->lz_removal)?0:~0;
+#else
+	GLOBALS->lz_removal = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LZ_REMOVAL]));
+#endif
+        if(GLOBALS->signalarea && GLOBALS->wavearea)
+                {
+                GLOBALS->signalwindow_width_dirty=1;
+                MaxSignalLength();
+                signalarea_configure_event(GLOBALS->signalarea, NULL);
+                wavearea_configure_event(GLOBALS->wavearea, NULL);
+                }
+	DEBUG(printf("Leading Zero Removal\n"));
+	}
+
+#ifndef WAVE_USE_MLIST_T
+GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LZ_REMOVAL].path))->active=(GLOBALS->lz_removal)?TRUE:FALSE;
+#endif
+}
+
 /**/
 void menu_show_mouseover(gpointer null_data, guint callback_action, GtkWidget *widget)
 {
@@ -7990,6 +8069,8 @@ static gtkwave_mlist_t menu_items[] =
     WAVE_GTKIFE("/Edit/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray,    WV_MENU_GBNONE, "<Item>"),
     WAVE_GTKIFE("/Edit/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, "<Item>"),
     WAVE_GTKIFE("/Edit/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off,    WV_MENU_POPOFF, "<Item>"),
+    WAVE_GTKIFE("/Edit/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, "<Item>"),
+    WAVE_GTKIFE("/Edit/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off,    WV_MENU_FFOOFF, "<Item>"),
     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, "<Item>"),
     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off,    WV_MENU_FPSHIFTOFF, "<Item>"),
     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify,    WV_MENU_FPSHIFTVAL, "<Item>"),
@@ -8108,6 +8189,7 @@ static gtkwave_mlist_t menu_items[] =
     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP9, "<Separator>"),
     WAVE_GTKIFE("/View/Show Wave Highlight", NULL, menu_show_wave_highlight, WV_MENU_SHW, "<ToggleItem>"),
     WAVE_GTKIFE("/View/Show Filled High Values", NULL, menu_show_filled_high_values, WV_MENU_FILL1, "<ToggleItem>"),
+    WAVE_GTKIFE("/View/Leading Zero Removal", NULL, menu_lz_removal, WV_MENU_LZ_REMOVAL, "<ToggleItem>"),
     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP9B, "<Separator>"),
     WAVE_GTKIFE("/View/Show Mouseover", NULL, menu_show_mouseover, WV_MENU_VSMO, "<ToggleItem>"),
 #ifdef WAVE_USE_GTK2
@@ -8239,6 +8321,8 @@ GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,
 
 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FILL1].path))->active=(GLOBALS->fill_waveform)?TRUE:FALSE;
 
+GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LZ_REMOVAL].path))->active=(GLOBALS->lz_removal)?TRUE:FALSE;
+
 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HSWM].path))->active=(GLOBALS->alt_wheel_mode)?TRUE:FALSE;
 
 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,menu_items[WV_MENU_VSMO].path))->active=(GLOBALS->disable_mouseover)?FALSE:TRUE;
@@ -8295,6 +8379,7 @@ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZPS]), GL
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG]), GLOBALS->display_grid);
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW]), GLOBALS->highlight_wavewindow);
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FILL1]), GLOBALS->fill_waveform);
+gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LZ_REMOVAL]), GLOBALS->lz_removal);
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HSWM]), GLOBALS->alt_wheel_mode);
 
 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO]), !GLOBALS->disable_mouseover);
@@ -8696,6 +8781,8 @@ static gtkwave_mlist_t popmenu_items[] =
     WAVE_GTKIFE("/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray,    WV_MENU_GBNONE, "<Item>"),
     WAVE_GTKIFE("/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, "<Item>"),
     WAVE_GTKIFE("/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off,    WV_MENU_POPOFF, "<Item>"),
+    WAVE_GTKIFE("/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, "<Item>"),
+    WAVE_GTKIFE("/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off,    WV_MENU_FFOOFF, "<Item>"),
     WAVE_GTKIFE("/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, "<Item>"),
     WAVE_GTKIFE("/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off,    WV_MENU_FPSHIFTOFF, "<Item>"),
     WAVE_GTKIFE("/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify,    WV_MENU_FPSHIFTVAL, "<Item>"),
diff --git a/src/menu.h b/src/menu.h
index 1844a72..2746ca8 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -167,6 +167,8 @@ WV_MENU_G2B,
 WV_MENU_GBNONE,
 WV_MENU_POPON,
 WV_MENU_POPOFF,
+WV_MENU_FFOON,
+WV_MENU_FFOOFF,
 WV_MENU_FPSHIFTON,
 WV_MENU_FPSHIFTOFF,
 WV_MENU_FPSHIFTVAL,
@@ -264,6 +266,7 @@ WV_MENU_VSG,
 WV_MENU_SEP9,
 WV_MENU_SHW,
 WV_MENU_FILL1,
+WV_MENU_LZ_REMOVAL,
 WV_MENU_SEP9B,
 WV_MENU_VSMO,
 #ifdef WAVE_USE_GTK2
diff --git a/src/mouseover.c b/src/mouseover.c
index abbb20d..5168391 100644
--- a/src/mouseover.c
+++ b/src/mouseover.c
@@ -84,16 +84,19 @@ if((flags & TR_PTRANSLATED) != 0) { ch[pos++] = 'P'; }
 if((flags & TR_TTRANSLATED) != 0) { ch[pos++] = 'T'; }
 
 /* [14] */
-if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; }
+if((flags & TR_FFO) != 0) { ch[pos++] = 'f'; }
 
 /* [15] */
+if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; }
+
+/* [16] */
 if((flags & TR_FPDECSHIFT) != 0)
         {       
         int ln = sprintf(ch+pos, "s(%d)", t->t_fpdecshift);
         pos += ln;
         }
 
-/* [16+] */
+/* [17+] */
 ch[pos] = 0;
 
 return(pos);
diff --git a/src/mouseover_sigs.c b/src/mouseover_sigs.c
index c671109..9be4263 100644
--- a/src/mouseover_sigs.c
+++ b/src/mouseover_sigs.c
@@ -110,16 +110,19 @@ if((flags & TR_PTRANSLATED) != 0) { ch[pos++] = 'P'; }
 if((flags & TR_TTRANSLATED) != 0) { ch[pos++] = 'T'; }
 
 /* [14] */
-if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; }
+if((flags & TR_FFO) != 0) { ch[pos++] = 'f'; }
 
 /* [15] */
+if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; }
+
+/* [16] */
 if((flags & TR_FPDECSHIFT) != 0) 
 	{ 
 	int ln = sprintf(ch+pos, "s(%d)", t->t_fpdecshift);
 	pos += ln;
 	}
 
-/* [16+] */
+/* [17+] */
 ch[pos] = 0;
 
 if(!t->vector)
diff --git a/src/rc.c b/src/rc.c
index 9d2548b..804fcc7 100644
--- a/src/rc.c
+++ b/src/rc.c
@@ -280,6 +280,13 @@ GLOBALS->fill_waveform=atoi_64(str)?1:0;
 return(0);
 }
 
+int f_lz_removal(char *str)
+{
+DEBUG(printf("f_lz_removal(\"%s\")\n",str));
+GLOBALS->lz_removal=atoi_64(str)?1:0;
+return(0);
+}
+
 int f_fontname_logfile(char *str)
 {
 DEBUG(printf("f_fontname_logfile(\"%s\")\n",str));
@@ -942,6 +949,7 @@ static struct rc_entry rcitems[]=
 { "keep_xz_colors", f_keep_xz_colors },
 { "left_justify_sigs", f_left_justify_sigs },
 { "lxt_clock_compress_to_z", f_lxt_clock_compress_to_z },
+{ "lz_removal", f_lz_removal },
 { "max_fsdb_trees", f_max_fsdb_trees },
 { "page_divisor", f_page_divisor },
 { "ps_maxveclen", f_ps_maxveclen },
@@ -1098,7 +1106,7 @@ return(ok);
 
 void read_rc_file(char *override_rc)
 {
-FILE *handle;
+FILE *handle = NULL;
 int i;
 int num_rcitems = sizeof(rcitems)/sizeof(struct rc_entry);
 
@@ -1123,16 +1131,30 @@ else
 #if !defined __MINGW32__ && !defined _MSC_VER
 if(!(handle=fopen(rcname,"rb")))
 	{
-	char *home;
-	char *rcpath;
+	struct passwd *pw = NULL;
+	char *home = NULL;
+	char *rcpath = NULL;
+
+	pw=getpwuid(geteuid());
+	if(pw)
+		{
+		home=pw->pw_dir;
+		}
+
+	if(!home)
+		{
+		home = getenv("HOME");
+		}
 
-	home=getpwuid(geteuid())->pw_dir;
-	rcpath=(char *)alloca(strlen(home)+1+strlen(rcname)+1);
-	strcpy(rcpath,home);
-	strcat(rcpath,"/");
-	strcat(rcpath,rcname);
+	if(home)
+		{
+		rcpath=(char *)alloca(strlen(home)+1+strlen(rcname)+1);
+		strcpy(rcpath,home);
+		strcat(rcpath,"/");
+		strcat(rcpath,rcname);
+		}
 
-	if(!(handle=fopen(rcpath,"rb")))
+	if( !rcpath || !(handle=fopen(rcpath,"rb")) )
 		{
 #ifdef MAC_INTEGRATION
 		const gchar *bundle_id = gtkosx_application_get_bundle_id();
diff --git a/src/showchange.c b/src/showchange.c
index 4e0eda7..3b1cd2e 100644
--- a/src/showchange.c
+++ b/src/showchange.c
@@ -61,6 +61,12 @@ static void toggle5_callback(GtkWidget *widget, GtkWidget *nothing)
 
 toggle_generic(widget, TR_POPCNT);
 }
+static void toggle6_callback(GtkWidget *widget, GtkWidget *nothing)
+{
+(void)nothing;
+
+toggle_generic(widget, TR_FFO);
+}
 
 static void enter_callback(GtkWidget *widget, GtkWidget *nothing)
 {
@@ -289,6 +295,12 @@ void showchange(char *title, Trptr t, GtkSignalFunc func)
   gtk_widget_show (GLOBALS->toggle5_showchange_c_1);
   gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle5_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle5_callback), NULL);
 
+  GLOBALS->toggle6_showchange_c_1=gtk_check_button_new_with_label("Find First One");
+  gtk_box_pack_start (GTK_BOX (box1), GLOBALS->toggle6_showchange_c_1, TRUE, TRUE, 0);
+  if(GLOBALS->flags_showchange_c_1&TR_FFO)gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(GLOBALS->toggle6_showchange_c_1), TRUE);
+  gtk_widget_show (GLOBALS->toggle6_showchange_c_1);
+  gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle6_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle6_callback), NULL);
+
   gtk_container_add (GTK_CONTAINER (main_vbox), hbox);
 
   separator = gtk_hseparator_new ();
diff --git a/src/signalwindow.c b/src/signalwindow.c
index 5133395..2752725 100644
--- a/src/signalwindow.c
+++ b/src/signalwindow.c
@@ -20,6 +20,18 @@
 #ifndef GDK_KEY_equal
 #define GDK_KEY_equal GDK_equal
 #endif
+#ifndef GDK_KEY_Up
+#define GDK_KEY_Up GDK_Up
+#endif
+#ifndef GDK_KEY_KP_Up
+#define GDK_KEY_KP_Up GDK_KP_Up
+#endif
+#ifndef GDK_KEY_Down
+#define GDK_KEY_Down GDK_Down
+#endif
+#ifndef GDK_KEY_KP_Down
+#define GDK_KEY_KP_Down GDK_KP_Down
+#endif
 
 #undef FOCUS_DEBUG_MSGS
 
@@ -471,6 +483,7 @@ int target;
 int which;
 gint rc = FALSE;
 int yscroll;
+int ud_kill = 0;
 
 #ifdef FOCUS_DEBUG_MSGS
 printf("focus: %d %08x %08x %08x\n", GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box),
@@ -549,7 +562,128 @@ if(GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box))
 			num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
 			num_traces_displayable--;   /* for the time trace that is always there */
 
-			if(num_traces_displayable<GLOBALS->traces.visible)
+                        if(event->state & GDK_SHIFT_MASK)
+                                {
+                                Trptr t = NULL, t2 = NULL;
+				Trptr tc = NULL, th = NULL;
+				int num_high = 0;
+
+                                if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up))
+                                        {
+                                        ud_kill = 1;
+                                        for(t=GLOBALS->traces.first;t;t=t->t_next)
+                                                {
+                                                if(t->flags&TR_HIGHLIGHT)
+                                                        {
+                                                        if(!th) th = t;
+                                                        num_high++;
+                                                        }
+
+                                                if(t->is_cursor)
+                                                        {
+                                                        tc = t;
+                                                        }
+                                                }
+
+                                        if(num_high <= 1)
+                                                {
+                                                t = th ? GivePrevTrace(th) : GLOBALS->topmost_trace;
+                                                }
+                                                else
+                                                {
+                                                t = tc ? GivePrevTrace(tc) : GLOBALS->topmost_trace;
+                                                }
+
+                                        MarkTraceCursor(t);
+                                        }
+                                else
+                                if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down))
+                                        {
+                                        ud_kill = 1;
+                                        for(t=GLOBALS->traces.first;t;t=t->t_next)
+                                                {
+                                                if(t->flags&TR_HIGHLIGHT)
+                                                        {
+                                                        th = t;
+                                                        num_high++;
+                                                        }
+                                                if(t->is_cursor)
+                                                        {
+                                                        tc = t;
+                                                        }
+                                                }
+
+                                        if(num_high <= 1)
+                                                {
+                                                t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace;
+                                                }
+                                                else
+                                                {
+                                                if(tc)
+                                                      	{
+                                                        t = GiveNextTrace(tc);
+                                                        }
+                                                else
+                                                    	{
+                                                        t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace;
+                                                        }
+                                                }
+
+                                        MarkTraceCursor(t);
+                                        }
+
+                                if(t)
+                                     	{
+                                        int top_target = 0;
+                                        target = 0;
+                                        which=num_traces_displayable-1;
+
+                                        ClearTraces();
+                                        t->flags |= TR_HIGHLIGHT;
+                                        t2 = t;
+
+                                        for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t))
+                                                {
+                                                if(t == GLOBALS->topmost_trace) break;
+                                                top_target++;
+                                                }
+
+                                        for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t))
+                                                {
+                                                if(t2 == t) break;
+                                                target++;
+                                                }
+
+                                        if((target >= top_target) && (target <= top_target+which))
+                                                {
+                                                /* nothing */
+                                                }
+                                                else
+                                                {
+                                                if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up))
+                                                        {
+                                                        if(target<0) target=0;
+                                                        }
+                                                else
+                                                if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down))
+                                                        {
+                                                        target = target - which;
+                                                        if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1;
+                                                        }
+
+						wadj->value = target;
+                                                }
+
+                                        if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */
+
+                                        gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
+                                        gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
+					signalarea_configure_event(GLOBALS->signalarea, NULL);
+					wavearea_configure_event(GLOBALS->wavearea, NULL);
+                                        }
+                                }
+
+			if((num_traces_displayable<GLOBALS->traces.visible) && (!ud_kill))
 				{
 				switch(event->keyval)
 					{
@@ -568,6 +702,8 @@ if(GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box))
 
                         			gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
                         			gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
+						signalarea_configure_event(GLOBALS->signalarea, NULL);
+						wavearea_configure_event(GLOBALS->wavearea, NULL);
 						break;
 
 					case GDK_Up:
@@ -1228,14 +1364,14 @@ if((GLOBALS->traces.visible)&&(GLOBALS->signalpixmap))
 		    }
 		  else
 		    {
-		      t->flags ^= TR_HIGHLIGHT;
+		      t->flags ^= TR_HIGHLIGHT; MarkTraceCursor(t);
 		    }
 		  }
 		}
 	else
 	if((event->state&GDK_SHIFT_MASK)&&(GLOBALS->starting_unshifted_trace))
 		{
-		int src = -1, dst = -1;
+		int src = -1, dst = -1, dsto = -1;
 		int cnt = 0;
 
 		t2=GLOBALS->traces.first;
@@ -1265,6 +1401,7 @@ if((GLOBALS->traces.visible)&&(GLOBALS->signalpixmap))
 				  cnt++;
 				}
 
+			dsto = dst;
 			if(src > dst) { int cpy; cpy = src; src = dst; dst = cpy; }
 			cnt = 0;
 			t2=GLOBALS->traces.first;
@@ -1275,6 +1412,8 @@ if((GLOBALS->traces.visible)&&(GLOBALS->signalpixmap))
 					  t2->flags |= TR_HIGHLIGHT;
 					}
 
+				if(cnt == dsto) { MarkTraceCursor(t2); }
+
 				cnt++;
 				t2=t2->t_next;
 				}
@@ -1298,7 +1437,7 @@ else if( (!GLOBALS->use_standard_trace_select) || (GLOBALS->standard_trace_dnd_d
 			t2 = t2->t_next;
 			}
 
-		if(t) { t->flags |= TR_HIGHLIGHT; } /* scan-build */
+		if(t) { t->flags |= TR_HIGHLIGHT; MarkTraceCursor(t); } /* scan-build */
 		}
 
 	GLOBALS->standard_trace_dnd_degate = 0;
diff --git a/src/tree.c b/src/tree.c
index fc1da60..b984605 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -352,6 +352,7 @@ tnext = t->next;
 
 while(tnext)
 	{
+	if(tnext->child) treenamefix(tnext->child);
 	if(tnext->name) treenamefix_str(tnext->name);
 	tnext=tnext->next;
 	}
diff --git a/src/tree.h b/src/tree.h
index a6c6159..e8cbf20 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -116,7 +116,7 @@ int t_which;		/* 'i' for facs[i] table, value of < 0 means not a full signame */
 uint32_t t_stem;	/* source stem (if >0) for Open Hierarchy Source Def,  see stem_struct_t */
 uint32_t t_istem;	/* source stem (if >0) for Open Hierarchy Source Inst, see stem_struct_t */
 
-unsigned kind : 7; 	/* Kind of the leaf: ghwlib reads this as val & 0x7f so only 7 bits needed */
+unsigned kind : 7; 	/* Kind of the leaf: libghw reads this as val & 0x7f so only 7 bits needed */
 unsigned children_in_gui : 1; /* indicates that the child nodes are in the gtk2 tree, but gets borrowed during tree creation for fast judy sort */
 char name[];		/* C99 */
 };
diff --git a/src/treesearch_gtk2.c b/src/treesearch_gtk2.c
index 4d3265f..a1efb1f 100644
--- a/src/treesearch_gtk2.c
+++ b/src/treesearch_gtk2.c
@@ -371,7 +371,7 @@ int force_open_tree_node(char *name, int keep_path_nodes_open, struct tree **t_p
 	  gtk_clist_thaw(GTK_CLIST(ctree));
 
 	  gtk_ctree_node_moveto(ctree, nodehist[depth-1],
-				depth /*column*/,
+				0, /*column*/ /* was originally depth instead of zero */
 				0.5 /*row_align*/,
 				0.5 /*col_align*/);
 	  /* printf("[treeopennode] '%s' ok\n", name); */
diff --git a/src/vcd.c b/src/vcd.c
index 6113572..c836955 100644
--- a/src/vcd.c
+++ b/src/vcd.c
@@ -2213,7 +2213,7 @@ while(v)
 		str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
 		strcpy(str,v->name);
 
-		if(v->msi>=0)
+		if((v->msi>=0)||(v->msi != v->lsi))
 			{
 			strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
 			slen++;
diff --git a/src/vcd_partial.c b/src/vcd_partial.c
index fae01fd..a178507 100644
--- a/src/vcd_partial.c
+++ b/src/vcd_partial.c
@@ -2055,7 +2055,7 @@ while(v)
 		str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
 		strcpy(str,v->name);
 
-		if(v->msi>=0)
+		if((v->msi>=0)||(v->msi != v->lsi))
 			{
 			strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
 			slen++;
diff --git a/src/vcd_recoder.c b/src/vcd_recoder.c
index 4e754c2..a17e4cd 100644
--- a/src/vcd_recoder.c
+++ b/src/vcd_recoder.c
@@ -2448,7 +2448,7 @@ while(v)
 		str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */
 		strcpy(str,v->name);
 
-		if(v->msi>=0)
+		if((v->msi>=0)||(v->msi != v->lsi))
 			{
 			strcpy(str+slen,GLOBALS->vcd_hier_delimeter);
 			slen++;
diff --git a/src/wavealloca.h b/src/wavealloca.h
index 8627664..951d7b2 100644
--- a/src/wavealloca.h
+++ b/src/wavealloca.h
@@ -18,6 +18,8 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
  */
 
 #ifndef WAVE_ALLOCA_H
diff --git a/src/wavewindow.c b/src/wavewindow.c
index 6171856..e1643f8 100644
--- a/src/wavewindow.c
+++ b/src/wavewindow.c
@@ -3237,19 +3237,17 @@ if(((t)&&(t->flags&TR_INVERT))&&(!is_event))
 yu=(_y0+_y1)/2;
 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
 
+if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)&&(!kill_grid))
+	{
+	gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+		TRUE,0, liney - GLOBALS->fontheight,
+		GLOBALS->wavewidth, GLOBALS->fontheight);
+	}
+else
 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)&&(!kill_grid))
 	{
-	if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
-		{
-		gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-			TRUE,0, liney - GLOBALS->fontheight,
-			GLOBALS->wavewidth, GLOBALS->fontheight);
-		}
-		else
-		{
-		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-			(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
-		}
+	gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+		(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
 	}
 
 if((h)&&(GLOBALS->tims.start==h->time))
@@ -3996,31 +3994,33 @@ _y0=liney-2;
 yu=(_y0+_y1)/2;
 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
 
+if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
+	{
+	Trptr tn = GiveNextTrace(t);
+	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
+		{
+                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+                        TRUE,0, liney - GLOBALS->fontheight,
+                        GLOBALS->wavewidth, GLOBALS->fontheight);
+		}
+		else
+                {
+                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+                        TRUE,0, liney - GLOBALS->fontheight,
+                        GLOBALS->wavewidth, GLOBALS->fontheight);
+                }
+	}
+else
 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid))
 	{
 	Trptr tn = GiveNextTrace(t);
 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
 		{
-	 	if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
-	                {
-	                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-	                        TRUE,0, liney - GLOBALS->fontheight,
-	                        GLOBALS->wavewidth, GLOBALS->fontheight);
-	                }
 		}
 		else
 		{
-	 	if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
-	                {
-	                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-	                        TRUE,0, liney - GLOBALS->fontheight,
-	                        GLOBALS->wavewidth, GLOBALS->fontheight);
-	                }
-	                else
-	                {
-			gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-				(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
-			}
+		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+			(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
 		}
 	}
 
@@ -4817,31 +4817,33 @@ _y0=liney-2;
 yu=(_y0+_y1)/2;
 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
 
+if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
+	{
+	Trptr tn = GiveNextTrace(t);
+	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
+		{
+                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+                        TRUE,0, liney - GLOBALS->fontheight,
+                        GLOBALS->wavewidth, GLOBALS->fontheight);
+		}
+		else
+                {
+                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+                        TRUE,0, liney - GLOBALS->fontheight,
+                        GLOBALS->wavewidth, GLOBALS->fontheight);
+                }
+	}
+else
 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid))
 	{
 	Trptr tn = GiveNextTrace(t);
 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
 		{
-	 	if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
-	                {
-	                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-	                        TRUE,0, liney - GLOBALS->fontheight,
-	                        GLOBALS->wavewidth, GLOBALS->fontheight);
-	                }
 		}
 		else
 		{
-	 	if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
-	                {
-	                gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-	                        TRUE,0, liney - GLOBALS->fontheight,
-	                        GLOBALS->wavewidth, GLOBALS->fontheight);
-	                }
-	                else
-	                {
-			gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
-				(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
-			}
+		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
+			(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
 		}
 	}