[Git][debian-gis-team/ncview][upstream] New upstream version 2.1.11+ds

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Wed Nov 27 06:26:41 GMT 2024



Bas Couwenberg pushed to branch upstream at Debian GIS Project / ncview


Commits:
e46db18e by Bas Couwenberg at 2024-11-27T04:59:55+01:00
New upstream version 2.1.11+ds
- - - - -


23 changed files:

- + '
- INSTALL
- Makefile.am
- README
- README.sgi
- − README_LOCAL
- RELEASE_NOTES
- + a/configure.in
- configure.in
- data/ncview.1.sed
- src/file.c
- src/file_netcdf.c
- src/interface/dataedit.c
- src/interface/filesel.c
- src/interface/x_interface.c
- src/ncview.c
- src/ncview.defines.h
- src/ncview.protos.h
- src/stringlist.c
- src/stringlist.h
- src/util.c
- src/view.c
- + t.patch


Changes:

=====================================
'
=====================================
@@ -0,0 +1,510 @@
+/*
+ * Ncview by David W. Pierce.  A visual netCDF file viewer.
+ * Copyright (C) 1993 through 2008 by David W. Pierce
+ *
+ * This program  is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as 
+ * published by the Free Software Foundation.
+ *
+ * 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, version 3, for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * David W. Pierce
+ * 6259 Caminito Carrena 
+ * San Diego, CA   92122
+ * pierce at cirrus.ucsd.edu
+ */
+
+/*
+	ncview.defines.h
+
+	#defines, and structure definitions
+*/
+
+#ifdef INC_UDUNITS
+#include <udunits.h>
+#endif
+
+#define PROGRAM_ID	"Ncview 1.93f David W. Pierce  12 September 2008"
+#define PROGRAM_VERSION 1.93
+#define APP_RES_VERSION 1.93
+
+#ifndef TRUE
+#define TRUE		1
+#endif
+#ifndef FALSE
+#define FALSE		0
+#endif
+
+/******************** Buttons in the user interface **********************/
+#define	BUTTON_REWIND			1
+#define	BUTTON_BACKWARDS		2
+#define	BUTTON_PAUSE			3
+#define	BUTTON_FORWARD			4
+#define	BUTTON_FASTFORWARD		5
+#define	BUTTON_COLORMAP_SELECT		6	/* this is also a label */
+#define	BUTTON_INVERT_PHYSICAL		7
+#define	BUTTON_INVERT_COLORMAP		8
+#define	BUTTON_MINIMUM			9
+#define	BUTTON_MAXIMUM			10
+#define	BUTTON_QUIT			11
+#define BUTTON_BLOWUP			12	/* this is also a label */
+#define	BUTTON_RESTART			13
+#define	BUTTON_TRANSFORM		14	/* this is also a label */
+#define BUTTON_DIMSET			15
+#define BUTTON_RANGE			16
+#define BUTTON_BLOWUP_TYPE		17	/* this is also a label */
+#define BUTTON_SKIP			18	/* this is also a label */
+#define BUTTON_EDIT			19
+#define BUTTON_INFO			20
+#define BUTTON_PRINT			21
+#define BUTTON_OPTIONS			22
+
+/***************************************************************************
+ * These are the overlays we know about
+ */
+#define OVERLAY_NONE			0
+#define OVERLAY_P8DEG			1
+#define OVERLAY_P08DEG			2
+#define OVERLAY_USA			3
+#define OVERLAY_CUSTOM			4
+
+#define OVERLAY_N_OVERLAYS		5
+
+
+/***************************************************************************
+ * General purpose writable labels in the user interface.  These are the 
+ * 'real' names; to actually use them, associate a more easily 
+ * remembered #define with them, as shown below.
+ */
+#define LABEL_1			1
+#define LABEL_2			2
+#define LABEL_3			3
+#define LABEL_4			4
+#define LABEL_5			11
+/* Specific purpose writable labels in the user interface. */
+#define LABEL_COLORMAP_NAME	5		/* this is also a button */
+#define LABEL_BLOWUP		6		/* this is also a button */
+#define LABEL_TRANSFORM		7
+#define LABEL_CCINFO_1		8
+#define LABEL_CCINFO_2		9
+#define LABEL_BLOWUP_TYPE	10		/* this is also a button */
+#define LABEL_SKIP		12		/* this is also a button */
+
+#define LABEL_TITLE		LABEL_1
+#define LABEL_SCANVAR_NAME	LABEL_2
+#define LABEL_SCAN_PLACE	LABEL_3
+#define LABEL_DATA_EXTREMA	LABEL_4
+#define LABEL_DATA_VALUE	LABEL_5
+
+/*****************************************************************************/
+/* Transforming the data before turning it into pixels is supported */
+#define N_TRANSFORMS		3
+#define TRANSFORM_NONE		1
+#define TRANSFORM_LOW		2
+#define TRANSFORM_HI		3
+
+/*****************************************************************************
+ * Maximum number of X-Y plot windows which can pop up, and the max
+ * number of lines on one plot.
+ */
+#define MAX_PLOT_XY		10
+#define MAX_LINES_PER_PLOT	5
+
+/*****************************************************************************
+ * This is for the popup windows which show all of a variable's attributes.
+ */
+#define MAX_DISPLAY_POPUPS	10
+
+/*****************************************************************************/
+/* Types of file data formats supported */
+#define FILE_TYPE_NETCDF	1
+
+/*****************************************************************************/
+/* Maximum name length of a variable */
+#define MAX_VAR_NAME_LEN	132
+
+/*****************************************************************************/
+/* Maximum name length of a file */
+#define MAX_FILE_NAME_LEN	1024
+
+/*****************************************************************************/
+/* Maximum name length of a recdim units */
+#define MAX_RECDIM_UNITS_LEN	1024
+
+/*****************************************************************************/
+/* Possible interpretations for the change_view routine; either change
+ * the specified number of FRAMES or the specified PERCENT.
+ */
+#define FRAMES	1
+#define PERCENT	2
+
+/*****************************************************************************/
+/* Truncate displayed strings which are longer than this */
+#define MAX_DISPLAYED_STRING_LENGTH 	250
+
+/*****************************************************************************/
+/* What dimension button sets we have */
+#define DIMENSION_X	1
+#define DIMENSION_Y	2
+#define DIMENSION_SCAN	3
+#define DIMENSION_NONE	4
+
+/*****************************************************************************/
+/* Button-press modification indicators */
+#define	MOD_1		1
+#define	MOD_2		2
+#define	MOD_3		3
+#define	MOD_4		4
+
+/*****************************************************************************/
+/* Messages which a dialog popup can return */
+#define MESSAGE_OK	1
+#define MESSAGE_CANCEL	2
+
+/*****************************************************************************/
+/* This is used in x_interface.c, even though it has nothing to do with
+ * the X interface, because the X mechanism has a way of
+ * reading in resource files, and there is no point in reading in TWO
+ * different configuration files.  Sigh.  For use of this, see routine
+ * 'check_app_res' in file x_interface.c
+ */
+#define DEFAULT_DELTA_STEP	10
+
+/*****************************************************************************/
+/* Ways in which the file's min and max can be calculated */
+#define MIN_MAX_METHOD_FAST	1
+#define MIN_MAX_METHOD_MED	2
+#define MIN_MAX_METHOD_SLOW	3
+#define MIN_MAX_METHOD_EXHAUST	4
+
+/*****************************************************************************/
+/* Data which has the fill_value is IGNORED.  It is assumed to represent 
+ * out of domain or out of range data.  Netcdf has its own values for this
+ * which replace this value, so in Netcdf implementations, this particular
+ * value is not the one which is actually used.
+ */
+#define DEFAULT_FILL_VALUE	1.0e35
+
+/*******************************************************************
+ * Ways to expand a small pixmap into a large one.
+ */
+#define BLOWUP_REPLICATE	1
+#define BLOWUP_BILINEAR		2
+
+/*******************************************************************
+ * Ways to contract a large pixmap into a small one.
+ */
+#define SHRINK_METHOD_MEAN	0
+#define SHRINK_METHOD_MODE	1
+
+/*********************************************************************
+ * Possible states which the data inside the current buffer can be in
+ */
+#define VDS_VALID	1
+#define VDS_INVALID	2
+#define VDS_EDITED	3
+
+/*******************************************************************
+ * Where postscript output can go.
+ */
+#define DEVICE_PRINTER	1
+#define DEVICE_FILE	2
+
+/*******************************************************************
+ * Ways of handling the variable-select area.  We can either list
+ * all the variables, or make a pull-down menu for selecting them.
+ */
+#define VARSEL_LIST	1
+#define VARSEL_MENU	2
+
+/*******************************************************************
+ * Recognized standards by which the time axis may be described
+ */
+#define TSTD_UDUNITS		1	/* Ex: units="days since 1900-01-01" */
+#define TSTD_EPIC_0		2	/* Ex: units="True Julian Day" w/att epic_code=624 */
+#define TSTD_MONTHS		3	/* Ex: units="months", Jan 1 AD = month 1 */
+
+/*******************************************************************
+ * Kinds of time-like granularity.
+ */
+#define TGRAN_SEC	1
+#define TGRAN_MIN	2
+#define TGRAN_HOUR	3
+#define TGRAN_DAY	4
+#define TGRAN_MONTH	5
+#define TGRAN_YEAR	6
+
+/*******************************************************************
+ *
+ * 	The main concept here is the 'variable'.  Variables are
+ *	things which might possibly be displayed by ncview.  Variables
+ *	live in one or more files, and within each of those files 
+ *	have a size, and minimum and maximum values.  Different 
+ *	variables can be in different files, but if you have the 
+ *	same variable in different files it must have the EXACT SAME
+ *	layout in all files, with the exception of the first index
+ *	(which is the time index in netCDF files).  So, you can have
+ *	20 time entries in the first file, then 7 in the second, and
+ *	14 in the third; but you can't have the resolution of the 
+ *	variable be different in the different files.
+ *
+ ********************************************************************/
+
+/*****************************************************************************/
+typedef unsigned char ncv_pixel;/* If you change this, make sure to change
+				 * routine 'data_to_pixels' in util.c!  It
+				 * assumes a size of one byte.  Some of the
+				 * X routines do also.
+				 */
+
+/*****************************************************************************/
+/* A general purpose list of character strings */
+typedef struct {
+	char	*string;
+	void	*next, *prev;
+	int	index;		/* initialized to position in list */
+	void	*aux;		/* auxilliary data */
+} Stringlist;
+
+/*****************************************************************************/
+/* This describes the file which the relevant variable lives in */
+typedef struct {
+	void	*next, *prev;
+	int	id;		/* internally used ID number */
+	char	*filename;
+	void	*aux_data;	/* For specific datafile implementations */
+	size_t	*var_size;	/* Multi-dimensional size of variables which live in this file */
+	float	data_min, data_max; /* for a specific variable in the file */
+
+	/* Following is an ugly hack for an ugly problem.  Basically, different files can have
+	 * different units for the unlimited dimension, and some people actually do this.  So
+	 * we must store the recdim units for each file.  In a way this is a property more of
+	 * the dimensions, so maybe should be in the NCDim structure somehow, but the units live
+	 * in each file and have a 1-1 association with each file, so I'm putting them here.
+	 */
+	char	*recdim_units;
+#ifdef INC_UDUNITS
+	utUnit	*udunits;	/* only non-null if utScan worked on these units */
+#endif
+} FDBlist;	
+
+/*****************************************************************************
+ * A specific set of data for netCDF-type files.  These won't necessarily 
+ * be applicable to different types of data file formats.
+ */
+typedef struct {
+	int	valid_range_set,
+		valid_min_set,
+		valid_max_set,
+		scale_factor_set,
+		add_offset_set;
+
+	float	valid_range[2],
+		valid_min,
+		valid_max,
+		scale_factor,
+		add_offset;
+
+} NetCDFOptions;
+	
+/*****************************************************************************/
+/* The dimension structure.  This is more for convienence and efficiency
+ * than because dimensions are so fundamental; actually, it's the variables
+ * which are more important.
+ */
+typedef struct {
+	char	*name, *long_name, *units;
+	int	units_change;	/* if 1, then a virtully concatenated timelike dimension has different units in different input files */
+	float	min, max, *values;
+	int	have_calc_minmax;  /* 0 initially, 1 after min & max have been calculated */
+	size_t	size;
+	int	timelike;	/* 0 if NOT timelike, 1 if is.  If is, MUST */
+				/* have an identified time standard (below). */
+	int	time_std;	/* TSTD_UDUNITS, TSTD_EPIC_0, TSTD_MONTHS */
+	char	*calendar;	/* ONLY applicable if time_std==TSTD_UDUNITS; can be any CF-1.0 value. Defaults to "standard" */
+	int	tgran; 		/* time granularity; i.e., frequency of entries (daily, hourly, etc). Must be one of the TGRAN_* defined above */
+	int	global_id;	/* Used internally, goes from 1..total number of dims we know about */
+	int	is_lat, is_lon; /* Just a guess if these are lat/lon. Used to put on coastlines automatically */
+} NCDim;
+
+/*****************************************************************************/
+/* A dimension can be "mapped", by which it means that, for example, the lat
+ * or lon coordinates are two dimensional, and a variable is supplied that
+ * gives the lat and/or lon values as a function of X and Y.
+ */
+typedef struct {
+
+	void	*var_i_map;		/* this is a NCVar * ; it gives the "var that I map".  */
+	char	*coord_att;		/* Contents of the "coordinates" attribute */
+	char	*coord_var_name;	/* Name of the VAR in the file that holds mapping info */
+	int	coord_var_ndims;	/* # of dims in the mapping var */
+	size_t	*coord_var_size;	/* size of the mapping var (MULTIDIMENSIONAL) */
+	int	*matching_var_dims;	/* This has n_dims equal to the DATA VARIABLE, NOT the coord var! */
+	float	*data_cache;		/* Cached info from the mapping var */
+	size_t	*index_place_factor;	/* Array of size var_i_map->n_dims, is 0 or factor to mult loc by */
+	
+} NCDim_map_info;
+
+/*****************************************************************************/
+/* Here it is: the variable structure.  Aspects of the variable which are
+ * different from file to file are kept in the pointed-to file descriptor 
+ * blocks (FDBs).
+ */
+typedef struct {
+	char	*name;
+	void	*next, *prev;			/* for global list of variables */
+	float	fill_value;			/* Any data with this special
+						 * value will be IGNORED. It
+						 * is assumed to indicate 
+						 * out-of-range or out-of-domain
+						 * data.
+						 */
+	int	have_set_range;			/* boolean -- have we set the
+						 * valid range for this var yet?
+						 */
+	int	n_dims;				/* how many dimensions this var has */
+	FDBlist	*first_file, *last_file;	/* What files this variable lives in */
+	float	global_min, global_max,		/* These are diffferent from the */
+	        user_min, user_max;	 	/* min & max in the FDBs because these
+					 	* are global, rather than local to
+					 	* a file.
+					 	*/
+	size_t	*size;				/* The accumulated size of
+						 * this variable, from all 
+						 * the files which hold it.
+						 */
+	int  	effective_dimensionality;	/* # of entries in 'size' array > 1 */
+	NCDim	**dim;				/* An array of 'n_dim' pointers to
+	 					 * Dimension structures.  This
+	 					 * is only filled out for 
+	 					 * scannable dimensions!! If
+	 					 * the dim is not scannable,
+	 					 * a NULL is inserted instead.
+	 					 */
+	NCDim_map_info	**dim_map_info;		/* Pointer to the first entry in an
+						   array of NCDim_map_info pointers
+						   that hold information describing
+						   the 2-D mapping for this dim. 
+						   This itself should never be null,
+						   but the entries CAN BE NULL, 
+						   in which event that dim has
+						   no mapping.  Note that the
+						   dim mapping is a function of
+						   the VARIABLE rather than the
+						   dim, which is an oddity of the
+						   way CF conventions handle mapping.
+						 */
+	int	is_virtual;			/* Boolean -- true if this var lives
+						 * in more than one input file, false
+						 * otherwise.
+						 */
+} NCVar;
+
+/*****************************************************************************/
+/* Our current view--the view is the 2D field which is being color-contoured.
+ */
+typedef struct {
+	NCVar	*variable;
+	size_t	*var_place;	/* Where we currently are in that var's space, in that file */
+	void	*data;		/* The actual 2-D data to colorcontour */
+	int	data_status;	/* Either valid, invalid, or edited (changed) */
+	unsigned char *pixels;	/* Scaled, replicated, byte array version of data */
+	int	x_axis_id, 	/* which axes the 2-D data lies on.  'scan' */
+		y_axis_id,	/* is the one accessed by the pushbuttons */
+		scan_axis_id;
+	int	skip;		/* Number of time entries to stride each time */
+	int	plot_XY_axis,	/* Which axis to plot along in XY plots */
+		plot_XY_nlines;	/* # of XY lines for this variable on current plot */
+	size_t	plot_XY_position[MAX_LINES_PER_PLOT][10];
+} View;
+
+/*****************************************************************************
+ * Place to store the frames in, if we want in-core displaying.
+ */
+typedef struct {
+	int	valid;		/* Is ANYTHING in the frame store valid? */
+	size_t	n;		/* # of frames in the store.  Can be > than nt cuz we allocate some extra to handle file growth */
+	ncv_pixel *frame;	/* Actual store of the frames */
+	int	*frame_valid;	/* Is this particular frame valid? */
+} FrameStore;
+
+/*****************************************************************************/
+/* program options */
+
+/* Options for the overlay feature */
+typedef struct {
+	int	doit;
+	int	*overlay;
+} OverlayOptions;
+
+typedef struct {
+	int	invert_physical,
+		invert_colors,
+		t_conv,
+		debug,
+		show_sel,
+		no_autoflip,
+		no_char_dims,
+		private_colormap,
+		want_extra_info,
+		n_colors,
+		small,
+		dump_frames,
+		no_1d_vars,
+		min_max_method,
+		delta_step,	/* if > 0, percent of total frames to step when pressing the 
+				 * 'forward' or 'backward' button and holding down the Ctrl 
+				 * key; if < 0, absolute number of frames to step.
+				 */
+		transform,
+		varsel_style,	/* can be VARSEL_LIST or VARSEL_MENU */
+		listsel_max,	/* if # of vars is more than this, auto switch from VARSEL_LIST to VARSEL_MENU */
+		color_by_ndims,	/* if 1, then button is color coded by # of effective dims */
+		beep_on_restart,
+		auto_overlay,	/* if 1, then tries to figure out if coastlines should automatically be added */
+		blowup,
+		maxsize_pct,	/* -1 if a width/height pair specified instead */
+		maxsize_width,	/* in pixels */
+		maxsize_height,	/* in pixels */
+		shrink_method,
+		blowup_default_size,
+		display_type;	/* This uses std 'X' defines; PseudoColor, DirectColor, etc */
+
+	char	*ncview_base_dir,
+		*window_title,
+		*calendar;	/* This OVERRIDES any 'calendar' attribute in the data file */
+
+	int	blowup_type;	/* can be BLOWUP_REPLICATE or BLOWUP_BILINEAR */
+
+	int	save_frames;	/* If true, try to save frames in core for faster display */
+	float	frame_delay;	/* Normalied to be between 0.0 and 1.0 */
+
+	OverlayOptions *overlay;
+} Options;
+
+/* Postscript printer output options */
+typedef struct {
+	float	page_width, page_height,		/* In inches */
+		page_x_margin, page_upper_y_margin,	/* In inches */
+		page_lower_y_margin, ppi;		/* Points per inch */
+	int	font_size,
+		leading,
+		header_font_size;		/* In points */
+	char	font_name[132],			/* Postscript name */
+		out_file_name[1024];
+	int	output_device,
+		include_outline, 
+		include_id,
+		include_title,
+		include_axis_labels,
+		include_extra_info,
+		test_only;
+} PrintOptions;
+


=====================================
INSTALL
=====================================
@@ -116,7 +116,7 @@ You can also install by hand if you want.  A quick overview:
 Copying, etc.
 -------------
 Ncview is freely redistributable, but is not public domain.
-It is copyright (C) 1993 through 2008 David W. Pierce.
+It is copyright (C) 1993 through 2024 David W. Pierce.
 This program  is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License version 3 as 
 published by the Free Software Foundation.
@@ -136,7 +136,5 @@ http://www.ae.utexas.edu/~rwmcm/SciPlot.html.
 
 ------------------------
 David W. Pierce
-6259 Caminito Carrena
-San Diego, CA  92122
-dpierce at ucsd.edu
+davidwilliampierce at gmail.com
 


=====================================
Makefile.am
=====================================
@@ -1 +1,6 @@
 SUBDIRS = src 
+
+AUTOMAKE_OPTIONS = subdir-objects
+bin_PROGRAMS=ncview
+noinst_PROGRAMS=geteuid
+geteuid_SOURCES=geteuid.c


=====================================
README
=====================================
@@ -1,4 +1,4 @@
-Ncview 1.93d  June 13, 2008 -- (C) David W. Pierce
+Ncview 2.1.11  Nov 5, 2024 -- (C) David W. Pierce
 --------------------------------------------------
 
 Overview: What Ncview *is*.
@@ -61,6 +61,4 @@ http://www.ae.utexas.edu/~rwmcm/SciPlot.html.
 
 ------------------------
 David W. Pierce
-6259 Caminito Carrena
-San Diego, CA  92122
-dpierce at ucsd.edu
+davidwilliampierce at gmail.com


=====================================
README.sgi
=====================================
@@ -4,4 +4,4 @@ to have a 32 bit version of the netcdf library to link to if you
 want to build from scratch.  Otherwise, you can contact me about
 getting a pre-made binary version for IRIX 6.2.
 
-dpierce at ucsd.edu
+davidwilliampierce at gmail.com


=====================================
README_LOCAL deleted
=====================================
@@ -1,2 +0,0 @@
-./configure --prefix=$HOME --with-udunits2_incdir=/home/pierce/src/packages/data/udunits/udunits-2.2.26/install_dir/include --with-udunits2_libdir=/home/pierce/src/packages/data/udunits/udunits-2.2.26/install_dir/lib --with-nc-config=/home/pierce/src/packages/data/netcdf/netcdf-c-4.3.2/install/bin/nc-config
-


=====================================
RELEASE_NOTES
=====================================
@@ -1,4 +1,8 @@
-2.0: 21 Jan 2010
+2.1.11: 5 Nov 2024
+
+* Some patches and updates courtesy of Sebastiaan Couwenberg 
+
+---
 
 * ncview now REQUIRES netcdf version 4 with full HDF5 support.  I am not
   going to maintain two code bases, one of which supports netcdf-4 and


=====================================
a/configure.in
=====================================
@@ -0,0 +1,330 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl set version
+m4_define([ncview_major_version],[2])
+m4_define([ncview_minor_version],[0])
+m4_define([ncview_micro_version],[0])
+m4_define([ncview_version],[ncview_major_version.ncview_minor_version.ncview_micro_version])
+m4_define([ncview_release_date],[15 Feb 2010])
+
+AC_INIT([ncview],[ncview_version],[dpierce at ucsd.edu])
+
+# Handle netcdf
+AC_PATH_NETCDF
+
+# For ncview-2.0, I've chosen to REQUIRE the netcdf V4 interface.
+if test $NETCDF_V4 = "no"; then
+	echo "-------------------------------------------------------------------"
+	echo "ncview version 2.0 REQUIRES the netcdf library be version 4 or above,"
+	echo "AND installed with HDF-5 support (i.e., the netcdf library must be"
+	echo "compiled with the --enable-netcdf-4 flag). If you don't want to install"
+	echo "the full version of netcdf-4 with HDF-5 support, then please install"
+	echo "ncview version 1.93g instead."
+	echo "-------------------------------------------------------------------"
+	exit -1
+fi
+
+#------------------------------------------------------------------------
+# Check for C compiler. NOTE that this must come AFTER the netcdf check. 
+# The netcdf library could have been compiled with, for example, Intel C;
+# we have to specifically check if the same compiler used to compile the
+# netcdf library exists.
+#------------------------------------------------------------------------
+AC_PROG_CC( $NETCDF_CC )
+AC_ISC_POSIX
+AC_HEADER_STDC
+
+
+AC_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE([ncview],[ncview_version])
+
+AC_PATH_X
+if test "x$no_x" == "xyes"; then
+	echo "------------------------------------------------------------------------------------"
+	echo "Error, the X libraries and development headers must be installed for ncview to work!"
+	echo "------------------------------------------------------------------------------------"
+	echo "More information: You are trying to compile ncview. The machine you are compiling on"
+	echo "probably already has the X windows *runtime* libraries installed, but to *compile*"
+	echo "a program you need more than just the runtime libraries.  You need what are usually"
+	echo "called the 'development headers', named because they are used when developing or"
+	echo "compiling X windows programs.  The best advice I can give you is to use your package"
+	echo "manager to look for a package whose name is something along the lines of x11-devel,"
+	echo "or xorg-x11-proto-devel, or something along those lines that indicates the package"
+	echo "contains the X windows development headers.  Install that package first, then try to"
+	echo "remake ncview.  "
+	echo "Note: If that still fails, even after you've installed the X windows *development*"
+	echo "headers, then you may be on a machine where the automatic configuration system is not"
+	echo "set up quite as it probably should be.  In that case, you might have to specify the"
+	echo "location of the X libraries and X headers manually.  For example, on some machines"
+	echo "the following will work:"
+	echo "   ./configure  --x-libraries=/usr/lib64 --x-includes=/usr/include/X11"
+	echo "                              ^^^^^^^^^^              ^^^^^^^^^^^^^^^^ these are what"
+	echo "you want to set to reflect the location of files such as libX11.so and X.h on your"
+	echo "particular system."
+	exit -1
+fi
+AC_PATH_XTRA
+
+#looking for Athena widgets
+#
+# This snippet of code is Copyright (c) 2009 Magnus Hagdorn <Magnus.Hagdorn at ed.ac.uk>
+# released under GPL-3; extended by David Pierce to check Xaw3d if Xaw fails, apparently
+# Fedoras ship with Xaw3d but not Xaw
+#
+haveAthena=yes
+LIBSsave=$LIBS
+CFLAGSsave=$CFLAGS
+CFLAGS=$X_CFLAGS
+LIBS=$X_LIBS
+AC_MSG_CHECKING([for the Athena widgets])
+AC_MSG_RESULT()
+AC_CHECK_LIB(Xt,XtWindow,[],[haveAthena=no])
+AC_CHECK_LIB(Xaw, XawScrollbarSetThumb,[],[haveAthena=no])
+if test x"$haveAthena"x = "xnox"; then
+	haveAthena=yes
+	AC_MSG_CHECKING([for the Athena 3d widgets instead])
+	AC_CHECK_LIB(Xaw3d, XawScrollbarSetThumb,[],[haveAthena=no])
+fi
+AC_CHECK_HEADER([X11/Intrinsic.h],[],[haveAthena=no])
+AC_CHECK_HEADER([X11/Xaw/Simple.h],[],[haveAthena=no])
+if test x"$haveAthena"x != "xyesx"; then
+  # On AIX this fails because the Xmu header needs to be there as well...
+  AC_CHECK_HEADER([X11/Xaw/Simple.h],[],[haveAthena=no],[[
+#include<X11/Xmu/Xmu.h>
+]])
+  if test x"$haveAthena"x != "xyesx"; then
+    AC_MSG_ERROR([Could not find Athena widgets library and header (checked w/Xmu.h included as well).  Use your package manager to install the X windows development libraries and headers.])
+  fi
+fi
+XAW_LIBS=$LIBS
+echo "X Athena widget (Xaw) libraries: $XAW_LIBS"
+AC_SUBST(XAW_LIBS)
+LIBS=$LIBSsave
+CFLAGS=$CFLAGSsave
+
+#------------------------------------------------------------------------------
+# Check for X11 library. It's not clear to me why this is necessary, yet Darwin 
+# requires a separate check
+#------------------------------------------------------------------------------
+haveX11=yes
+LIBSsave=$LIBS
+CFLAGSsave=$CFLAGS
+CFLAGS=$X_CFLAGS
+LIBS=$X_LIBS
+AC_MSG_CHECKING([for X11 library])
+AC_MSG_RESULT()
+AC_CHECK_LIB(X11,XPutImage,[],[haveX11=no])
+if test x"$haveX11"x != "xyesx"; then
+  AC_MSG_ERROR([Could not find X11 library.  Use your package manager to install the X windows development libraries and headers.])
+fi
+X11_LIBS=$LIBS
+echo "X11 libraries: $X11_LIBS"
+AC_SUBST(X11_LIBS)
+LIBS=$LIBSsave
+CFLAGS=$CFLAGSsave
+
+# Handle udunits2
+AC_PATH_UDUNITS2
+do_udunits2=false
+if test x$UDUNITS2_INCDIR != x; then
+	if test x$UDUNITS2_LIBDIR != x; then
+		do_udunits2=true
+	fi
+fi
+if test $do_udunits2 = true; then
+	echo "****************************************************************************"
+	echo "Udunits library version 2 support enabled.   "
+	echo "udunits2 dirs: include: $UDUNITS2_INCDIR  library: $UDUNITS2_LIBDIR  libname: $UDUNITS2_LIBNAME"
+	echo "****************************************************************************"
+	DO_UDUNITS2_LINE="INC_UDUNITS2   = -DINC_UDUNITS2"
+	DO_UDUNITS2_INCDIR="UDUNITS2INCDIR = -I$UDUNITS2_INCDIR"
+	DO_UDUNITS2_LIBDIR="UDUNITS2LIBDIR = -L$UDUNITS2_LIBDIR"
+	DO_UDUNITS2_LIBNAME="UDUNITS2LIB = -l$UDUNITS2_LIBNAME"
+else
+	echo "************************************************************************"
+	echo "Note: udunits2 support is NOT enabled, because I could not find the "
+	echo "location of the udunits2 include file 'udunits2.h' or library file"
+	echo "'libudunits2.a'.  Ncview uses the udunits2 package to format date strings"
+	echo "with units of the form 'days since 1900-01-01'.  If you do not use"
+	echo "these udunits2-standard date formats, then don't worry about the lack"
+	echo "of udunits2 support.  If you DO use udunits2 format date strings, and"
+	echo "you want the udunits2 support, then you must tell me where to find"
+	echo "the udunits2 package by giving arguments to configure, as follows:"
+	echo "  ./configure --with-udunits2_incdir=include_directory --with-udunits2_libdir=library_directory"
+	echo "************************************************************************"
+	DO_UDUNITS2_LINE="#INC_UDUNITS2   = -DINC_UDUNITS2"
+	DO_UDUNITS2_INCDIR="#UDUNITS2INCDIR = -I$UDUNITS2_INCDIR"
+	DO_UDUNITS2_LIBDIR="#UDUNITS2LIBDIR = -I$UDUNITS2_LIBDIR"
+	DO_UDUNITS2_LIBNAME="#UDUNITS2LIB = -l$UDUNITS2_LIBNAME"
+fi
+AC_SUBST(DO_UDUNITS2_LINE)
+AC_SUBST(DO_UDUNITS2_INCDIR)
+AC_SUBST(DO_UDUNITS2_LIBDIR)
+AC_SUBST(DO_UDUNITS2_LIBNAME)
+
+# Handle png
+AC_PATH_PNG
+do_png=false
+if test x$PNG_INCDIR != x; then
+	if test x$PNG_LIBDIR != x; then
+		do_png=true
+	fi
+fi
+if test $do_png = true; then
+	DO_PNG_LINE="INC_PNG   = -DINC_PNG"
+	DO_PNG_INCDIR="PNGINCDIR = -I$PNG_INCDIR"
+	DO_PNG_LIBDIR="PNGLIBDIR = -L$PNG_LIBDIR"
+	DO_PNG_LIBNAME="PNGLIB = -l$PNG_LIBNAME"
+else
+	echo "************************************************************************"
+	echo "Note: the -frames option is NOT enabled, because I could not find the "
+	echo "location of the PNG include file 'png.h' or library file"
+	echo "'libpng.so'.  Ncview uses the png package to dump out the frames viewed,"
+	echo "which is an easy way to make an mpeg video of the data if you want."
+	echo "If you do not want this feature, then don't worry about the lack"
+	echo "of png support.  If you DO want this, then you must install libpng, or tell "
+	echo "me where to find the png package by giving arguments to configure, as follows:"
+	echo "  ./configure -with-png_incdir=include_directory -with-png_libdir=library_directory"
+	echo "************************************************************************"
+	DO_PNG_LINE="#INC_PNG   = -DINC_PNG"
+	DO_PNG_INCDIR="#PNGINCDIR = -I$PNG_INCDIR"
+	DO_PNG_LIBDIR="#PNGLIBDIR = -I$PNG_LIBDIR"
+	DO_PNG_LIBNAME="#PNGLIB = -l$PNG_LIBNAME"
+fi
+AC_SUBST(DO_PNG_LINE)
+AC_SUBST(DO_PNG_INCDIR)
+AC_SUBST(DO_PNG_LIBDIR)
+AC_SUBST(DO_PNG_LIBNAME)
+PREFIX=${prefix}
+
+AC_PROG_INSTALL
+
+AC_SUBST(PREFIX)
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(X_INCLUDES)
+
+
+#----------------------------------------------------------------------------
+# We want to test if the same compiler was used for the netcdf library as for
+# ncview.  This might be complicated by the fact that often "gcc" and "cc"
+# end up invoking the same compiler.  Use an ugly hack that I have no idea
+# if it generally works or not.  Probably not.
+#----------------------------------------------------------------------------
+CC_TEST_SAME=$CC
+#-----------------------------------------------------------------------
+# Point of following obscure manipulations is that $CC can have multiple
+# words, for example, it could be "gcc -fPIC -lm". We want to keep only
+# the first word, so use 'set' and then take the first arg ($1).
+#-----------------------------------------------------------------------
+set $CC_TEST_SAME
+CC_TEST_SAME=$1
+if test x$CC_TEST_SAME = xcc; then
+	CC_TEST_SAME=gcc			
+fi
+NETCDF_CC_TEST_SAME=$NETCDF_CC
+set $NETCDF_CC_TEST_SAME
+NETCDF_CC_TEST_SAME=$1
+if test x$NETCDF_CC_TEST_SAME = xcc; then
+	NETCDF_CC_TEST_SAME=gcc
+fi
+if test x$CC_TEST_SAME != x$NETCDF_CC_TEST_SAME; then
+	echo "======================================================================"
+	echo "Configuration error: You specified that the \"$CC\" C compiler should be"
+	echo "used to build ncview, but the netcdf library was compiled with the \"$NETCDF_CC\""
+	echo "compiler.  Here is the path where I found the netcdf library:"
+	echo "     $NETCDF_LDFLAGS"
+	echo "You must use the same compiler for ncview as was used to build the netcdf library!"
+	echo " "
+	echo "There are two possible ways to fix this."
+	echo " "
+	echo "1) Download the netcdf library and compile it with the $CC compiler,"
+	echo "install it, and try again to build ncview.  NOTE that if you do this,"
+	echo "you might have more than one version of the netcdf library on your system,"
+	echo "built with differnt compilers, which can get confusing.  If you do this,"
+	echo "you will have to specify the path to the (new) version of nc-config"
+	echo "that was compiled using the $CC compiler by configuring ncview in a "
+	echo "way similar to this:"
+	echo " "
+	echo "   ./configure --with-nc-config=/path/to/newly/compiled/nc-config"
+	echo " "
+	echo "2) Configure ncview to use the $NETCDF_CC compiler."
+	echo "To do this, set environmental variable CC to $NETCDF_CC"
+	echo "and run ./configure again"
+	echo "==================================================================="
+	exit -1
+fi
+
+#----------------------------------------------------------------------------------
+# Construct our RPATH flags.  Idea here is that we have LDFLAGS that might look,
+# for example, something like this:
+#	LIBS="-L/usr/local/lib -lnetcdf -L/home/pierce/lib -ludunits"
+# We want to convert this to -rpath flags suitable for the compiler, which would
+# have this format:
+#	"-Wl,-rpath,/usr/local/lib -Wl,-rpath,/home/pierce/lib"
+#
+# As a safety check, I only do this for the GNU compiler, as I don't know if this
+# is anything like correct syntax for other compilers.  Note that this *does* work
+# for the Intel icc compiler, but also that the icc compiler sets $ac_compiler_gnu
+# to "yes".  Go figure.
+#----------------------------------------------------------------------------------
+echo "ac_computer_gnu: $ac_compiler_gnu"
+if test x$ac_compiler_gnu = xyes; then
+	RPATH_FLAGS=""
+	for word in $UDUNITS2_LDFLAGS $NETCDF_LDFLAGS; do
+		if test `expr $word : -L/` -eq 3; then
+			#RPDIR=`expr substr $word 3 999`;
+			RPDIR=${word:2}
+			RPATH_FLAGS="$RPATH_FLAGS -Wl,-rpath,$RPDIR"
+		fi
+	done
+	AC_SUBST(RPATH_FLAGS)
+fi
+
+AC_CONFIG_FILES([Makefile src/Makefile])
+AC_OUTPUT
+
+
+echo " "
+echo "----------- Configure Summary ----------"
+echo "Compiler:"
+echo "        CC                 = $CC"
+echo "        Runtime path flags = $RPATH_FLAGS"
+echo " "
+echo "UDUNITS:"
+if test $do_udunits2 = true; then
+echo "        UDUNITS2_LIBS     = $UDUNITS2_LIBS"
+echo "        UDUNITS2_CPPFLAGS = $UDUNITS2_CPPFLAGS"
+echo "        UDUNITS2_LDFLAGS  = $UDUNITS2_LDFLAGS"
+echo " "
+else
+echo "        not found. Specify --with-udunits2_incdir=... and --with-udunits2_libdir=... flags to enable"
+fi
+
+echo " "
+echo "NETCDF:"
+echo "        VERSION          = $NETCDF_VERSION"
+echo "        COMPILER USED    = $NETCDF_CC"
+echo "        NETCDF_CPPFLAGS  = $NETCDF_CPPFLAGS"
+echo "        NETCDF_LDFLAGS   = $NETCDF_LDFLAGS"
+echo "        NETCDF_V4        = $NETCDF_V4"
+echo " "
+echo "X:"
+echo "        X_CFLAGS         = $X_CFLAGS"
+echo "        X11_LIBS         = $X11_LIBS"
+echo "        XAW_LIBS         = $XAW_LIBS"
+echo "        X_PRE_LIBS       = $X_PRE_LIBS"
+echo "        X_LIBS           = $X_LIBS"
+echo "        X_EXTRA_LIBS     = $X_EXTRA_LIBS"
+echo " "
+echo "PNG:"
+if test $do_png = true; then
+echo "        PNG_LIBS         = $PNG_LIBS"
+echo "        PNG_CPPFLAGS     = $PNG_CPPFLAGS"
+echo "        PNG_LDFLAGS      = $PNG_LDFLAGS"
+echo " "
+else
+echo "        not found. Install libpng, or specify --with-png_incdir=... and --with-png_libdir=... flags to enable"
+fi
+


=====================================
configure.in
=====================================
@@ -36,7 +36,7 @@ AC_HEADER_STDC
 
 
 AC_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE([ncview],[ncview_version])
+AM_INIT_AUTOMAKE
 
 AC_PATH_X
 if test "x$no_x" == "xyes"; then


=====================================
data/ncview.1.sed
=====================================
@@ -3,7 +3,7 @@
 ncview \- graphically display netCDF files under X windows
 .SH SYNOPSIS
 .B ncview
-[-beep] [-copying] [-frames] [-warranty] [-private] [-ncolors XX] [-extrainfo] [-mtitle "title"] [-minmax fast | med | slow | all] datafiles ...
+[\-beep] [\-copying] [\-frames] [\-warranty] [\-private] [\-ncolors XX] [\-extrainfo] [\-mtitle "title"] [\-minmax fast | med | slow | all] datafiles ...
 .PP
 .SH DESCRIPTION
 .I Ncview
@@ -305,7 +305,7 @@ the name of a directory which contains additional colormap
 files.
 If that is not defined, then colormaps are sought in
 the user's home directory, and in the directory which
-.i ncview
+.I ncview
 was run from.
 
 Colormap files have 256 lines, each consisting of


=====================================
src/file.c
=====================================
@@ -84,7 +84,7 @@ fi_initialize( char *name, int nfiles )
 
 	if( file_type == FILE_TYPE_NETCDF ) {
 		if( options.debug ) 
-			fprintf( stderr, "Initializing file %s\n", name );
+			printf( "Initializing file %s\n", name );
 		id = netcdf_fi_initialize( name );
 		}
 	else
@@ -95,12 +95,12 @@ fi_initialize( char *name, int nfiles )
 		}
 
 	if( options.debug ) 
-		fprintf( stderr, "Getting list of variables for file %s\n", name );
+		printf( "Getting list of variables for file %s\n", name );
 	var_list = fi_list_vars( id );
 	add_vars_to_list( var_list, id, name, nfiles );
 	
 	if( options.debug ) 
-		fprintf( stderr, "Done initializing file %s\n", name );
+		printf( "Done initializing file %s\n", name );
 
 	return( id );
 }	


=====================================
src/file_netcdf.c
=====================================
@@ -34,14 +34,15 @@
 extern	NCVar   *variables;
 extern  Options options;
 
-void warn_about_char_dims();
-int safe_ncdimid( int fileid, char *dim_name1 );
-int netcdf_dimvar_id( int fileid, char *dim_name );
-int netcdf_get_att_util( int id, int varid, char *var_name, char *att_name, int expected_len, void *value );
-int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid );
-void varname_no_groups( char *varname, char *varname_sans_groups );
-char *ncview_groupname( int gid );
-char *ncview_varname( int gid, int varid );
+void 	warn_about_char_dims();
+int 	safe_ncdimid( int fileid, char *dim_name1 );
+int 	netcdf_dimvar_id( int fileid, char *dim_name, int *dimvar_gid );
+int 	netcdf_get_att_util( int id, int varid, char *var_name, char *att_name, int expected_len, void *value );
+int 	nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid );
+char 	*ncview_groupname( int gid );
+char 	*ncview_varname( int gid, int varid );
+void 	nc_print_group_structure( int fileid );
+int 	nc_root_id_from_group_id( int gid );
 
 char *nc_type_to_string( nc_type type );
 
@@ -307,7 +308,7 @@ Stringlist *netcdf_scannable_dims( int fileid, char *var_name )
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	err = nc_inq_var( gid, var_id, var_name_ng, &var_type, &n_dims, dim, &n_atts );
 	if( err != NC_NOERR ) {
@@ -357,7 +358,7 @@ int netcdf_fi_n_dims( int fileid, char *var_name )
 		}
 
 	/* Strip off leading group names */
-	varname_no_groups( var_name, var_name_nogroups );
+	varname_no_groups( var_name, var_name_nogroups, NULL );
 
 	err = nc_inq_var( groupid, varid, var_name_nogroups, &var_type, &n_dims, dim, &n_atts );
 	if( err != NC_NOERR ) {
@@ -409,7 +410,7 @@ size_t * netcdf_fi_var_size( int fileid, char *var_name )
 		}
 
 	/* Strip off leading group names */
-	varname_no_groups( var_name, var_name_nogroups );
+	varname_no_groups( var_name, var_name_nogroups, NULL );
 
 	err = nc_inq_var( groupid, varid, var_name_nogroups, &var_type, &n_dims, dim, &n_atts );
 	if( err != NC_NOERR ) {
@@ -429,12 +430,15 @@ size_t * netcdf_fi_var_size( int fileid, char *var_name )
 	return( ret_val );
 }
 
-/*******************************************************************************************/
+/*******************************************************************************************
+ * for the given variable, which has N dims, return the fully qualified name of the 
+ * "dim_id"'th dim (dim_id is an index from 0 to 1-NDIMS(var_name))
+ */
 char *netcdf_dim_id_to_name( int fileid, char *var_name, int dim_id )
 {
 	int	netcdf_dim_id, netcdf_var_id, gid;
 	int	n_dims, *dim, err, n_atts;
-	char	*dim_name, var_name_ng[MAX_NC_NAME];
+	char	*dim_name, var_name_ng[MAX_NC_NAME], groupname[MAX_NC_NAME], *fq_dim_name;
 	nc_type	var_type;
 
 	/* see notes under "netcdf_dim_name_to_id".  "dim_id" is NOT
@@ -448,7 +452,15 @@ char *netcdf_dim_id_to_name( int fileid, char *var_name, int dim_id )
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	/* At this point fully qualified var name "var_name" lives in group "gid" with varid "netcdf_var_id" */
+
+	varname_no_groups( var_name, var_name_ng, groupname );
+	/*
+	printf( "VVVV %s %d netcdf_dim_id_to_name for dim var_name: >%s< var_name_ng: >%s< groupname: >%s<\n", 
+		__FILE__, __LINE__, 
+		var_name, var_name_ng, groupname );
+	*/
+
 
 	n_dims = fi_n_dims( gid, var_name_ng );
 	dim    = (int *)malloc( n_dims * sizeof( int ));
@@ -461,14 +473,39 @@ char *netcdf_dim_id_to_name( int fileid, char *var_name, int dim_id )
 		}
 
 	netcdf_dim_id = *(dim+dim_id);
-	dim_name = (char *)malloc( MAX_NC_NAME ); /* defined in netcdf.h */
+	dim_name    = (char *)malloc( MAX_NC_NAME ); /* defined in netcdf.h */
+	fq_dim_name = (char *)malloc( MAX_NC_NAME ); /* defined in netcdf.h */
 	err      = nc_inq_dimname( gid, netcdf_dim_id, dim_name );
 	if( err != NC_NOERR ) {
 		fprintf( stderr, "ncview: netcdf_dim_id_to_name: error on ");
 		fprintf( stderr, "nc_inq_dimname call.  Variable=%s\n", var_name );
 		exit( -1 );
 		}
-	return( dim_name );
+	/*
+	printf( "VVVV %s %d netcdf_dim_id_to_name for netcdf_dim_id=%d here is dim_name:>%s<\n", 
+		__FILE__, __LINE__, 
+		netcdf_dim_id, dim_name );
+	*/
+
+	/* 2024-11-05: return fully qualified dim name, not short version */
+	/* return( dim_name ); */
+
+	if( (groupname == NULL) || (groupname[0] == '\0') ) 
+		strcpy( fq_dim_name, dim_name );
+	else
+		{
+		strcpy( fq_dim_name, groupname );
+		strcat( fq_dim_name, "/" );
+		strcat( fq_dim_name, dim_name );
+		}
+
+	/*
+	printf( "VVVV %s %d netcdf_dim_id_to_name for dim >%s< here is full varname, varname_ng: >%s< >%s< FULLY QUAL DIM NAME: >%s<\n", 
+		__FILE__, __LINE__, 
+		dim_name, var_name, var_name_ng, fq_dim_name );
+	*/
+
+	return( fq_dim_name );
 }
 
 /*******************************************************************************************
@@ -513,7 +550,7 @@ int netcdf_dim_name_to_id( int fileid, char *var_name, char *dim_name )
 			ncview_varname(gid, netcdf_var_id) );
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	if( debug == 1 ) printf( "netcdf_dim_name_to_id: group_id=%d var_name_no_groups=%s\n", 
 		gid, var_name_ng );
@@ -564,7 +601,7 @@ void netcdf_fi_get_data( int fileid, char *var_name, size_t *start_pos,
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	tot_size = 1L;
 	n_dims = netcdf_fi_n_dims( gid, var_name_ng );
@@ -689,39 +726,13 @@ void netcdf_fi_close( int fileid )
 /* netCDF utility routines.  Analogs are not required for each data file format.	*/
 /****************************************************************************************/
 
-/*******************************************************************************************
- * Given a varname string of format: groupname0/groupname1/groupnameN/varname
- * this returns ONLY the trailing groupname
- */
-void varname_no_groups( char *varname, char *varname_sans_groups )
-{
-	int	i, i0, i1, idx_slash[MAX_NC_NAME], nslash;
-	char	ts[MAX_NC_NAME];
-
-	/* Get indices of the slashes */
-	nslash = 0;
-	for( i=0; i<strlen(varname); i++ ) {
-		if( varname[i] == '/' ) {
-			idx_slash[nslash] = i;
-			nslash++;
-			}
-		}
-
-	if( nslash == 0 ) {
-		strcpy( varname_sans_groups, varname );
-		return;
-		}
-
-	strcpy( varname_sans_groups, varname+idx_slash[nslash-1]+1 );
-}
-
 /*******************************************************************************************
  * A version of 'nc_inq_varid' that has been enhanced to return a groupid/varid pair
  * given a var name of form "groupname/varname" (NOTE: *NO* leading slash!!)
  */
 int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 {
-	int	ns, ig, gid, ierr, group_depth, cur_gid, debug, retval;
+	int	ns, ig, gid, ierr, group_depth, cur_gid, debug, retval, ncid2use;
 	char	groupname[MAX_NC_NAME], varname_sans_groups[MAX_NC_NAME], cur_gid_groupname[MAX_NC_NAME];
 
 	debug = 0;
@@ -729,6 +740,15 @@ int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 	if( debug ) printf( "nc_inq_varid_grp: entering with ncid=%d (%s) varname=>%s<\n", 
 		ncid, ncview_groupname(ncid), varname );
 
+	/* Since we are generally called with a fully qualified varname, we need
+	 * to start at the root ID, not the group id, which can be passed in 'ncid'
+	 */
+	/* ncid2use = nc_root_id_from_group_id( ncid ); */
+	ncid2use = ncid;
+
+	if( debug ) printf( "nc_inq_varid_grp: original ncid=%d (%s) ncid2use=%d (%s)\n", 
+		ncid, ncview_groupname(ncid), ncid2use, ncview_groupname(ncid2use) );
+
 	if( varname[0] == '/' ) {
 		fprintf( stderr, "Internal error, called nc_inq_varid_grp with a varname that starts with a slash: >%s<\n",
 			varname );
@@ -739,7 +759,7 @@ int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 	if( debug ) printf( "nc_inq_varid_grp: number of slashes in varname: %d\n", ns );
 
 	if( ns > 0 ) {
-		cur_gid = ncid;
+		cur_gid = ncid2use;
 		group_depth = ns;
 
 		/* Traverse to the LAST group in the chain of groups, that's where
@@ -757,11 +777,22 @@ int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 			if( debug ) printf( "nc_inq_varid_grp: looking for subgroup >%s< in root group >%s<\n",
 				groupname, cur_gid_groupname );
 
+			if( strcmp( groupname, cur_gid_groupname ) == 0 ) {
+				/* It is possible for this routine to be called with a groupname ID
+				 * instead of a root file id. In that case, we might have the case
+				 * that the groupname is ALREADY the current gid groupname, and
+				 * we don't need to proceed further
+				 */
+				break;
+				}
+
 			ierr = nc_inq_ncid( cur_gid, groupname, &gid );
 			if( ierr != NC_NOERR ) {
-				fprintf( stderr, "nc_inq_varid_grp: Error, did not find group named >%s< in base group >%s<\n",
+				fprintf( stderr, "%s %d nc_inq_varid_grp: Error, did not find group named >%s< in base group >%s<\n",
+					__FILE__, __LINE__, 
 					groupname, cur_gid_groupname );
-				fprintf( stderr, "nc_inq_varid_grp was called with id=%d (%s) varname=>%s<\n", ncid, cur_gid_groupname, varname );
+				fprintf( stderr, "nc_inq_varid_grp was called with id=%d (%s) ncid2use=%d varname=>%s<\n", 
+					ncid, cur_gid_groupname, ncid2use, varname );
 				exit(-1);
 				return(-1);
 				}
@@ -774,8 +805,8 @@ int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 		*groupid = cur_gid;
 		if( debug ) printf( "nc_inq_varid_grp: should now be on the LAST group, here is groupname: >%s<\n", ncview_groupname( cur_gid ));
 
-		varname_no_groups( varname, varname_sans_groups );
-		if( debug ) printf( "nc_inq_varid_grp: calling regular nc_inq_varid with group %d (%s) and varname_sans_gruops >%s<\n",
+		varname_no_groups( varname, varname_sans_groups, NULL );
+		if( debug ) printf( "nc_inq_varid_grp: calling regular nc_inq_varid with group %d (%s) and varname_sans_groups >%s<\n",
 			cur_gid, ncview_groupname(cur_gid), varname_sans_groups );
 		retval = nc_inq_varid( cur_gid, varname_sans_groups, varid );
 
@@ -785,8 +816,8 @@ int nc_inq_varid_grp( int ncid, char *varname, int *varid, int *groupid )
 		}
 	else
 		{
-		*groupid = ncid;
-		return( nc_inq_varid( ncid, varname, varid ));
+		*groupid = ncid2use;
+		return( nc_inq_varid( ncid2use, varname, varid ));
 		}
 }
 
@@ -917,7 +948,7 @@ int netcdf_att_id( int fileid, int varid, char *name )
 /*******************************************************************************************/
 char * netcdf_title( int fileid )
 {
-	int	err, attid;
+	int	err, attid, max_title_len;
 	char	*ret_val;
 	nc_type	type;
 	size_t	title_len;
@@ -943,6 +974,22 @@ char * netcdf_title( int fileid )
 
 	if( *(ret_val+title_len-1) != '\0' )
 		*(ret_val + title_len) = '\0';
+
+	/* Get rid of trailing spaces / blanks. This is necessary if
+	 * title is too long, which seems to give X a core dump
+	 */
+	for( int kk=title_len-1; kk>0; kk-- ) {
+		if( ret_val[kk] == ' ' )
+			ret_val[kk] = '\0';
+		else
+			break;
+		}
+
+	/* Protection from X windows crash if title is too long */
+	max_title_len = 100;
+	if( strlen( ret_val ) > max_title_len )
+		ret_val[ max_title_len-1 ] = '\0';
+
 	return( ret_val );
 }
 
@@ -972,7 +1019,7 @@ char *netcdf_get_char_att( int fileid, char *var_name, char *att_name )
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	if( netcdf_att_id( gid, varid, att_name ) < 0 )
 		return( NULL );
@@ -1013,50 +1060,113 @@ char *netcdf_var_units( int fileid, char *var_name )
 /*******************************************************************************************/
 char *netcdf_dim_calendar( int fileid, char *dim_name )
 {
-	int	dimvar_id;
+	int	dimvar_id, dimvar_gid;
 
-	dimvar_id = netcdf_dimvar_id( fileid, dim_name );
+	dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 
 	if( dimvar_id < 0 )
 		return( NULL );
 
-	return( netcdf_get_char_att( fileid, dim_name, "calendar" ));
+	return( netcdf_get_char_att( dimvar_gid, dim_name, "calendar" ));
 }
 
 /*******************************************************************************************/
 char *netcdf_dim_units( int fileid, char *dim_name )
 {
-	int	dimvar_id;
+	int	dimvar_id, dimvar_gid;
 
-	dimvar_id = netcdf_dimvar_id( fileid, dim_name );
+	dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 
 	if( dimvar_id < 0 )
 		return( NULL );
 
-	return( netcdf_var_units( fileid, dim_name ));
+	return( netcdf_var_units( dimvar_gid, dim_name ));
 }
 
-/*******************************************************************************************/
-int netcdf_dimvar_id( int fileid, char *dim_name )
+/*******************************************************************************************
+ * Given the (fully qualified) name of a dim, such as "group_obs_fine/time", returns
+ * the id of the associated dimvar, or -1 if no associted dimvar is found
+ *
+ * Group update: this tends to be called with the root fileid, but sometimes the
+ * dimvar is in a group (i.e., NOT the root fileid). If returned parameter
+ * dimvar_gid == -1, then this is not an issue and just go ahead and use the
+ * passed fileid. If dimvar_gid is NOT equal to -1, you must access the dimvar
+ * using the returned dimvar_gid, NOT the originally passed fileid!
+ */
+int netcdf_dimvar_id( int fileid, char *dim_name, int *dimvar_gid )
 {
-	int	i, err, n_dims, n_vars, rec_dim;
-	char	var_name[256];
+	int	i, err, n_dims, n_vars, rec_dim, gid, fileid2use;
+	char	var_name[256], dim_name_ng[MAX_NC_NAME], groupname[MAX_NC_NAME], gn_slash[MAX_NC_NAME];
+	char	dim_name_2use[ MAX_NC_NAME ];
 	nc_type	var_type;
 	int	n_atts, dim[MAX_VAR_DIMS];
+int parent_id;
+int id1, id2, id3;
+
+	*dimvar_gid	= fileid;
+	fileid2use 	= fileid;
+	strcpy( dim_name_2use, dim_name );
+
+	/* If we enter with a fully qualified dim name, such as group_obs_fine/time,
+	 * make sure we proceed with the fileid corresponding to that group. Note that
+	 * the netcdf library preceeds all group names with a slash
+	 */
+	 /* First see if there is a slash in dim_name; if so, it is fully qualified */
+	 if( count_nslashes( dim_name_2use ) > 0 ) {
 
-	err = nc_inq( fileid, &n_dims, &n_vars, &n_atts, &rec_dim );
+	 	/* Get group name */
+		varname_no_groups( dim_name_2use, dim_name_ng, groupname );
+
+		/* I have to admit I don't understand the netcdf library
+		 * at this point. Since it returns group names with a 
+		 * leading slash it only makes sense it should accept/require
+		 * group names with a leading slash. Yet it seems to require
+		 * NO leading slashes to find the group!
+		 */
+		/*strcpy( gn_slash, "/" );*/
+		/*strcat( gn_slash, groupname );*/
+		/* err = nc_inq_grp_ncid( fileid, gn_slash, &gid ); */
+
+		err = nc_inq_grp_ncid( fileid, groupname, &gid );
+
+		/* If we were called with a group ID to begin with, try agian
+		 * with the root ID
+		 */
+		if( err = NC_ENOGRP ) 
+			err = nc_inq_grp_ncid( nc_root_id_from_group_id(fileid), groupname, &gid );
+
+		if( err != NC_NOERR ) {
+			fprintf( stderr, "%s line %d : Error: nc_inq_grp_ncid failed in routine netcdf_dimvar_id:\n",
+				__FILE__, __LINE__ );
+			fprintf( stderr, "%s\n", nc_strerror( err ) );
+			exit(-1);
+			}
+
+		/* Found a group ID to use instead of the passed fileid */
+		fileid2use = gid;
+
+		/* For the rest of the code, the dim name to use is the
+		 * UNqualifed dim name
+		 */
+		strcpy( dim_name_2use, dim_name_ng );
+	 	}
+
+	err = nc_inq( fileid2use, &n_dims, &n_vars, &n_atts, &rec_dim );
 	if( err != NC_NOERR )
 		return( -1 );
 
 	for( i=0; i<n_vars; i++ ) {
-		err = nc_inq_var( fileid, i, var_name, &var_type, &n_dims, dim, &n_atts );
+		err = nc_inq_var( fileid2use, i, var_name, &var_type, &n_dims, dim, &n_atts );
 		if( err != NC_NOERR )
 			return( -1 );
-		if( strcmp( dim_name, var_name ) == 0 ) {
+		if( strcmp( dim_name_2use, var_name ) == 0 ) {
 			if( (var_type == NC_CHAR) && (options.no_char_dims) )
 				return( -1 );
 			else
+				{
+				*dimvar_gid = fileid2use;
 				return( i );
+				}
 			}
 		}
 
@@ -1066,24 +1176,24 @@ int netcdf_dimvar_id( int fileid, char *dim_name )
 /*******************************************************************************************/
 char *netcdf_dim_longname( int fileid, char *dim_name )
 {
-	int	dimvar_id, err;
+	int	dimvar_id, err, dimvar_gid;
 	size_t	len;
 	nc_type	att_type;
 	char	*dim_longname;
 
-	dimvar_id = netcdf_dimvar_id( fileid, dim_name );
+	dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 	if( dimvar_id < 0 )
 		return( dim_name );
 
-	if( netcdf_att_id( fileid, dimvar_id, "long_name" ) < 0 )
+	if( netcdf_att_id( dimvar_gid, dimvar_id, "long_name" ) < 0 )
 		return( dim_name );
 
-	err = nc_inq_att( fileid, dimvar_id, "long_name", &att_type, &len );
+	err = nc_inq_att( dimvar_gid, dimvar_id, "long_name", &att_type, &len );
 	if( (err != NC_NOERR) || (att_type != NC_CHAR))
 		return( dim_name );
 
 	dim_longname = (char *)malloc( len+1 );
-	err = nc_get_att_text( fileid, dimvar_id, "long_name", dim_longname );
+	err = nc_get_att_text( dimvar_gid, dimvar_id, "long_name", dim_longname );
 	if( err < 0 )
 		return( dim_name );
 	else	
@@ -1100,9 +1210,10 @@ char *netcdf_dim_longname( int fileid, char *dim_name )
  */
 int netcdf_has_dim_values( int fileid, char *dim_name )
 {
-	int	dimvar_id;
+	int	dimvar_id, dimvar_gid;
+
+	dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 
-	dimvar_id = netcdf_dimvar_id( fileid, dim_name );
 	if( dimvar_id < 0 )
 		return( FALSE );
 	else
@@ -1119,7 +1230,7 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 		double *ret_val_double, char *ret_val_char, size_t virt_place, 
 		int *return_has_bounds, double *return_bounds_min, double *return_bounds_max )
 {
-	int	err, dimvar_id, nvertices;
+	int	err, dimvar_id, nvertices, dimvar_gid;
 	char	var_name[MAX_NC_NAME];
 	nc_type type, ret_type;
 	size_t	limit;
@@ -1130,7 +1241,7 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 
 	debug = 0;
 
-	if( debug ) printf( "netcdf_dim_value: entering with dim=%s place=%ld\n", dim_name, place );
+	if( debug ) printf( "netcdf_dim_value: entering with dim_name=>%s< place=%ld\n", dim_name, place );
 
 	if( ! netcdf_has_dim_values( fileid, dim_name ) ) {
 		*ret_val_double = (double)virt_place;
@@ -1138,14 +1249,14 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 		return( NC_DOUBLE );
 		}
 
-	dimvar_id = netcdf_dimvar_id( fileid, dim_name );
+	dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 	if( dimvar_id < 0 ) {
 		*ret_val_double = (double)virt_place;
 		*return_has_bounds = 0;
 		return( NC_DOUBLE );
 		}
 
-	err = nc_inq_var( fileid, dimvar_id, var_name, &type, &n_dims, dim, &n_atts );
+	err = nc_inq_var( dimvar_gid, dimvar_id, var_name, &type, &n_dims, dim, &n_atts );
 	if( err != NC_NOERR ) {
 		fprintf( stderr, "netcdf_dim_value: failed on nc_inq_var call!\n" );
 		exit(-1);
@@ -1163,14 +1274,14 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 			warn_about_char_dims();
 			ret_type = NC_CHAR;
 			if( n_dims == 2 ) 
-				limit = netcdf_dim_size( fileid, dim[1] );
+				limit = netcdf_dim_size( dimvar_gid, dim[1] );
 			else
 				limit = 1024;
 			i = 0L;
 			char_place[0] = place;
 			do	{
 				char_place[1] = i;
-				err = nc_get_var1_uchar( fileid, dimvar_id, char_place, (((unsigned char *)(ret_val_char))+i));
+				err = nc_get_var1_uchar( dimvar_gid, dimvar_id, char_place, (((unsigned char *)(ret_val_char))+i));
 				i++;
 				}
 			while
@@ -1191,11 +1302,11 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 			 * centered between the boundaries.  Some files have the dim value NOT
 			 * centered between the boundaries, which isn't so useful.
 			 */
-			dimvar_bounds_id = netcdf_dimvar_bounds_id( fileid, dim_name, &nvertices );
+			dimvar_bounds_id = netcdf_dimvar_bounds_id( dimvar_gid, dim_name, &nvertices );
 			if( dimvar_bounds_id < 0 ) { 
 
 				*return_has_bounds = 0;
-				err = nc_get_var1_double( fileid, dimvar_id, &place, ret_val_double );
+				err = nc_get_var1_double( dimvar_gid, dimvar_id, &place, ret_val_double );
 #ifdef ELIM_DENORMS
 				/* Eliminate denormalized numbers */
 				c = (unsigned char *)ret_val_double;
@@ -1222,7 +1333,7 @@ nc_type netcdf_dim_value( int fileid, char *dim_name, size_t place,
 				bstart[1] = 0L;
 				bcount[0] = 1L;
 				bcount[1] = nvertices;
-				err = nc_get_vara_double( fileid, dimvar_bounds_id, bstart, bcount, boundvals );
+				err = nc_get_vara_double( dimvar_gid, dimvar_bounds_id, bstart, bcount, boundvals );
 				if( err != NC_NOERR ) {	
 					fprintf( stderr, "Error reading boundary dim values from file!\n" );
 					fprintf( stderr, "%s\n", nc_strerror( err ) );
@@ -1283,7 +1394,7 @@ void netcdf_fill_aux_data( int id, char *var_name, FDBlist *fdb )
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	/* Record the recdim units in this file
 	 */
@@ -1578,8 +1689,7 @@ void netcdf_fill_value( int file_id, char *var_name, float *v, NetCDFOptions *au
 	nc_type	vartype;
 
 	if( options.debug ) 
-		fprintf( stderr, "Checking %s for a missing value...\n",
-				var_name );
+		printf( "Checking %s for a missing value...\n", var_name );
 
 	foundit = FALSE;
 	err = nc_inq_varid_grp( file_id, var_name, &varid, &gid );
@@ -1589,18 +1699,18 @@ void netcdf_fill_value( int file_id, char *var_name, float *v, NetCDFOptions *au
 		exit(-1);
 		}
 
-	varname_no_groups( var_name, var_name_ng );
+	varname_no_groups( var_name, var_name_ng, NULL );
 
 	if( netcdf_get_att_util( gid, varid, var_name_ng, "missing_value", 1, v ) ) {
 		if( options.debug )
-			fprintf( stderr, "found a \"missing_value\" attribute=%g\n",
+			printf( "found a \"missing_value\" attribute=%g\n",
 				*v );
 		foundit = TRUE;
 		}
 
 	if( netcdf_get_att_util( gid, varid, var_name_ng, "_FillValue", 1, v ) ) {
 		if( options.debug )
-			fprintf( stderr, "found a \"_FillValue\" attribute=%g\n",
+			printf( "found a \"_FillValue\" attribute=%g\n",
 				*v );
 		foundit = TRUE;
 		}
@@ -1608,7 +1718,7 @@ void netcdf_fill_value( int file_id, char *var_name, float *v, NetCDFOptions *au
 	/* Is there a global missing value? */
 	if( netcdf_get_att_util( gid, NC_GLOBAL, var_name_ng, "missing_value", 1, v ) ) {
 		if( options.debug )
-			fprintf( stderr, "found a \"missing_value\" attribute=%g\n",
+			printf( "found a \"missing_value\" attribute=%g\n",
 				*v );
 		foundit = TRUE;
 		}
@@ -1656,8 +1766,7 @@ void netcdf_fill_value( int file_id, char *var_name, float *v, NetCDFOptions *au
 		}
 
 	if( options.debug )
-		fprintf( stderr, "setting fillvalue to default for var type=%g\n",
-			*v );
+		printf( "setting fillvalue to default for var type=%g\n", *v );
 }
 
 /*******************************************************************************************/
@@ -1927,7 +2036,8 @@ void warn_about_char_dims()
  */
 int netcdf_dimvar_bounds_id( int fileid, char *dim_name, int *nvertices )
 {
-	int	reg_dimvar_id, bounds_dimvar_id, dimvar_ndims, err, name_length, debug;
+	int	reg_dimvar_id, bounds_dimvar_id, dimvar_ndims, err, name_length, debug, 
+		dimvar_gid;
 	char	*attname = "bounds";
 	char 	*bounds_dimvarname;
 	nc_type	type;
@@ -1941,21 +2051,21 @@ int netcdf_dimvar_bounds_id( int fileid, char *dim_name, int *nvertices )
 	/* First get the regular dimvar for this dim, then see if that dimvar
 	 * has an attribute named "bounds".
 	 */
-	reg_dimvar_id = netcdf_dimvar_id( fileid, dim_name );
+	reg_dimvar_id = netcdf_dimvar_id( fileid, dim_name, &dimvar_gid );
 	if( reg_dimvar_id < 0 ) {
 		if( debug ) printf( "netcdf_dimvar_bounds_id: dim %s does NOT have a regular dimvar, returning -1\n", dim_name );
 		return( -1 );
 		}
 
-	if( netcdf_att_id( fileid, reg_dimvar_id, attname ) < 0 )
+	if( netcdf_att_id( dimvar_gid, reg_dimvar_id, attname ) < 0 )
 		return( -1 );
 
-	err = ncattinq( fileid, reg_dimvar_id, attname, &type, &name_length );
+	err = ncattinq( dimvar_gid, reg_dimvar_id, attname, &type, &name_length );
 	if( (err < 0) || (type != NC_CHAR))
 		return( -1 );
 
 	bounds_dimvarname = (char *)malloc( name_length+1 );
-	err = ncattget( fileid, reg_dimvar_id, attname, bounds_dimvarname );
+	err = ncattget( dimvar_gid, reg_dimvar_id, attname, bounds_dimvarname );
 	if( err < 0 ) {
 		free( bounds_dimvarname );
 		return( -1 );
@@ -1964,14 +2074,14 @@ int netcdf_dimvar_bounds_id( int fileid, char *dim_name, int *nvertices )
 	if( *(bounds_dimvarname+name_length-1) != '\0' )
 		*(bounds_dimvarname + name_length) = '\0';
 
-	err = nc_inq_varid( fileid, bounds_dimvarname, &bounds_dimvar_id );
+	err = nc_inq_varid( dimvar_gid, bounds_dimvarname, &bounds_dimvar_id );
 	if( err != 0 ) {
 		free( bounds_dimvarname );
 		return( -1 );
 		}
 
 	/* Currently only know how to handle 2-d bounds variables */
-	err = nc_inq_varndims( fileid, bounds_dimvar_id, &dimvar_ndims );
+	err = nc_inq_varndims( dimvar_gid, bounds_dimvar_id, &dimvar_ndims );
 	if( (err != NC_NOERR) || (dimvar_ndims != 2)) {
 		fprintf( stderr, "Currently can only handle bounds dims with ndims=2; bounds var %s has ndims=%d.  Ignoring!\n", 
 				bounds_dimvarname, dimvar_ndims );
@@ -1982,13 +2092,13 @@ int netcdf_dimvar_bounds_id( int fileid, char *dim_name, int *nvertices )
 	/* Get the dim ids of the bounds var so we can get the length of the trailing
 	 * one, which is the number of vertices 
 	 */
-	err = nc_inq_vardimid( fileid, bounds_dimvar_id, dimids );
+	err = nc_inq_vardimid( dimvar_gid, bounds_dimvar_id, dimids );
 	if( err != NC_NOERR ) {
 		fprintf( stderr, "Error reading bounds info for boundary variable %s.  Ignoring!\n", bounds_dimvarname );
 		free( bounds_dimvarname );
 		return( -1 );
 		}
-	err = nc_inq_dimlen( fileid, dimids[1], &st_nvertices );
+	err = nc_inq_dimlen( dimvar_gid, dimids[1], &st_nvertices );
 	if( err != NC_NOERR ) {
 		fprintf( stderr, "Error reading nvertices info for boundary variable %s.  Ignoring!\n", bounds_dimvarname );
 		free( bounds_dimvarname );
@@ -2027,3 +2137,81 @@ char *ncview_varname( int gid, int varid )
 	return( &(buffer[0]) );
 }
 
+/*****************************************************************************************************
+ * Given a ncid (file id) which may or may not be the root id, prints the entire group structure
+ * of the file. Useful for debugging
+ */
+void nc_print_group_structure( int fileid )
+{
+	int 	rootid, cursor, parent;
+	int	*gid, ig, ndims, nvars, natts, unlimdimid;
+	int	ierr, ng;
+	size_t	gnl;
+	char	*group_name;
+
+	/* Get root */
+	cursor = fileid;
+	while( nc_inq_grp_parent( cursor, &parent ) == 0 ) {
+		cursor = parent;
+		}
+	rootid = cursor;
+
+	printf( "nc_print_group_structure: fileid=%d rootid=%d\n", fileid, rootid );
+	ierr = nc_inq_grps( rootid, &ng, NULL );	/* first call to get num groups */
+
+	if( ng == 0 ) {
+		printf("nc_print_group_structure: no groups in this file\n" );
+		return;
+		}
+
+	gid = (int *)malloc( sizeof(int) * ng );     
+	ierr = nc_inq_grps( rootid, &ng, gid );	
+	printf( "nc_print_group_structure: fileid=%d rootid=%d has %d groups:\n", fileid, rootid, ng );
+
+	for( ig=0; ig<ng; ig++ ) {
+
+		/* Get group name */
+		ierr = nc_inq_grpname_len( gid[ig], &gnl );
+		group_name = malloc( sizeof(char) * (gnl+2) );
+		ierr = nc_inq_grpname_full( gid[ig], &gnl, group_name );
+
+		/* find info about this group: number of dims, vars, atts */
+		ierr = nc_inq( gid[ig], &ndims, &nvars, &natts, &unlimdimid );
+
+		printf( "   group %d: id=%d >%s<\n", 
+			ig, gid[ig], group_name );
+
+		printf( "       ndims:%d nvars:%d natts:%d unlimdimid:%d\n", 
+			ndims, nvars, natts, unlimdimid );
+
+		free( group_name );
+		}
+}
+
+/*****************************************************************************************************
+ * Given a fileid, which may be a root ID or a group ID, returns the root group ID
+ */
+int nc_root_id_from_group_id( int gid ) 
+{
+	int	err, cursor, parentid;
+
+	cursor = gid;
+
+	/* It is usually the case that the passed gid is the root id, so short circuit */
+	if( nc_inq_grp_parent( gid, &parentid ) == NC_ENOGRP )
+		return( gid );
+
+	cursor = gid;
+	while( (err = nc_inq_grp_parent( cursor, &parentid )) == 0 ) 
+		cursor = parentid;
+		
+
+	if( err == NC_ENOGRP ) 
+		return( cursor );	/* at the root of the chain */
+
+	fprintf( stderr, "%s line %d : nc_root_id_from_group_id failed with error %d : %s\n",
+		__FILE__, __LINE__, 
+		err, nc_strerror(err) );
+	exit(0);
+}
+


=====================================
src/interface/dataedit.c
=====================================
@@ -209,7 +209,7 @@ XtPointer call_data;
 	index = (size_t)list->list_index;
 	in_change_dat( index, new_val );
 	strcpy( *(list_text+list->list_index), line );
-	XawListChange( dataedit_list_widget, (const char **)list_text, 0, 0, True );
+	XawListChange( dataedit_list_widget, (_Xconst char **)list_text, 0, 0, True );
 	XawListHighlight( dataedit_list_widget, list->list_index );
 }
 


=====================================
src/interface/filesel.c
=====================================
@@ -241,7 +241,7 @@ fs_double_click(Widget w, XButtonEvent *e, String *p, Cardinal *n )
 			fprintf( stderr, "Error when trying to chdir to %s\n", highlited_entry->string );
 		fs_get_file_dir_list( &files_and_dirs );
 		XawListChange( fs_list_widget, 
-			(const char **)stringlist_to_Xawlist( files_and_dirs ),
+			(_Xconst char **)stringlist_to_Xawlist( files_and_dirs ),
 			0, 0, False );
 		XtVaSetValues( fs_pathname_text_widget, 
 			XtNstring, fs_cwd(), NULL );


=====================================
src/interface/x_interface.c
=====================================
@@ -1332,16 +1332,16 @@ void x_init_widgets_varsel_menu_grp( Widget menu_box, Widget *varsel_menu_widget
 			 * the group named "/"
 			 */
 			if( (count_nslashes( var_cursor->name )==0) && (strncmp( "/", group_cursor->string, 1)==0)) {
-printf( "root check: putting var %s in gruop %s\n", var_cursor->name, group_cursor->string );
+printf( "root check: putting var %s in group %s\n", var_cursor->name, group_cursor->string );
 				my_grp_num[i] = igrp;
 				break;
 				}
 			/* Var has at least one slash in its name */
 			else if( strncmp( var_cursor->name, group_cursor->string, strlen(group_cursor->string) ) == 0 ) {
-printf( "non root check: putting var %s in gruop %s\n", var_cursor->name, group_cursor->string );
-				/* At this point a var with a group name that STARTS with another gruop name,
+/* printf( "non root check: putting var %s in group %s\n", var_cursor->name, group_cursor->string ); */
+				/* At this point a var with a group name that STARTS with another group name,
 				 * but is longer, will match. So we check to see if the var's name actually
-				 * ends with a slash where it should, if this is the right gruop. If it does
+				 * ends with a slash where it should, if this is the right group. If it does
 				 * end with a slash, then it's the right group name
 				 */
 				if( var_cursor->name[ strlen(group_cursor->string) ] == '/' ) {
@@ -1500,7 +1500,7 @@ void x_init_widgets_varsel_list( Widget parent )
 		if( var == NULL ) 
 			{
 			fprintf( stderr, "ncview: x_init_widgets: internal ");
-			fprintf( stderr, "inconsistancy -- empty variable list\n" );
+			fprintf( stderr, "inconsistency -- empty variable list\n" );
 			exit( -1 );
 			}
 		if( i == 0 ) {
@@ -2558,6 +2558,9 @@ void x_indicate_active_dim( int dimension, char *dim_name )
 	String	label;
 	int	i = 0;
 	char	new_label[ 132 ];
+	char	dim_name_ng[ MAX_NC_NAME ];
+
+	varname_no_groups( dim_name, dim_name_ng, NULL );
 
 	if( dimension == DIMENSION_X )
 		snprintf( new_label, 130, "X:" );
@@ -2578,7 +2581,7 @@ void x_indicate_active_dim( int dimension, char *dim_name )
 	w = diminfo_name_widget;
 	while( *w != NULL ) {
 		XtVaGetValues( *w, XtNlabel, &label, NULL );
-		if( strcmp( label, dim_name ) == 0 ) {
+		if( strcmp( label, dim_name_ng ) == 0 ) {
 			XtVaSetValues( *(diminfo_dim_widget+i), 
 					XtNlabel, new_label,
 					XtNwidth, app_data.dimlabel_width, NULL);
@@ -2589,7 +2592,7 @@ void x_indicate_active_dim( int dimension, char *dim_name )
 
 	fprintf( stderr, "ncview: x_indicate_active_dim: cannot find " );
 	fprintf( stderr, "widget for dimension %d, named %s\n", 
-							dimension, dim_name );
+							dimension, dim_name_ng );
 	exit( -1 );
 }
 
@@ -3092,12 +3095,16 @@ void x_fill_dim_info( NCDim *d, int please_flip )
 	String	widget_name;
 	int	i;
 	char	temp_label[132];
+	char 	dimname_ng[ MAX_NC_NAME ];
+
+	/* Get the dimname sans group */
+	varname_no_groups( d->name, dimname_ng, NULL );
 
 	/* first, find the row we want */
 	i = 0;
 	while( (w = diminfo_name_widget + i) != NULL ) {
 		XtVaGetValues( *w, XtNlabel, &widget_name, NULL );
-		if( strcmp( widget_name, d->name ) == 0 ) {
+		if( strcmp( widget_name, dimname_ng ) == 0 ) {
 
 			if( please_flip )
 				snprintf( temp_label, 130, "%g", d->max );
@@ -3134,7 +3141,7 @@ void x_fill_dim_info( NCDim *d, int please_flip )
 		}
 
 	fprintf( stderr, "ncview: x_fill_dim_info: error, can't find " );
-	fprintf( stderr, "dim info widget named \"%s\"\n", d->name );
+	fprintf( stderr, "dim info widget named \"%s\"\n", dimname_ng );
 	exit( -1 );
 }
 
@@ -3144,11 +3151,14 @@ void x_set_cur_dim_value( char *dim_name, char *string )
 	int	i;
 	Widget	*w;
 	String	label;
+	char	dim_name_ng[ MAX_NC_NAME ];
+
+	varname_no_groups( dim_name, dim_name_ng, NULL );
 
 	i = 0;
 	while( (w = diminfo_name_widget+i) != NULL ) {
 		XtVaGetValues( *w, XtNlabel, &label, NULL );
-		if( strcmp( label, dim_name ) == 0 ) {
+		if( strcmp( label, dim_name_ng ) == 0 ) {
 			XtVaSetValues( *(diminfo_cur_widget+i), 
 				XtNlabel, string, NULL );
 			return;
@@ -3156,7 +3166,7 @@ void x_set_cur_dim_value( char *dim_name, char *string )
 		i++;
 		}
 	fprintf( stderr, "ncview: x_set_cur_dim: error; widget for dimension ");
-	fprintf( stderr, "named \"%s\" not found.\n", dim_name );
+	fprintf( stderr, "named \"%s\" not found.\n", dim_name_ng );
 	exit( -1 );
 }
 


=====================================
src/ncview.c
=====================================
@@ -495,7 +495,7 @@ get_cmaps_from_dir( char *dir_name )
 	int		n_colormaps = 0, n_suffix;
 
 	if( options.debug ) 
-		fprintf( stderr, "Getting colormaps from dir >%s<\n", dir_name );
+		printf( "Getting colormaps from dir >%s<\n", dir_name );
 
 	ncdir     = opendir( dir_name );
 	if( ncdir == NULL ) 
@@ -558,7 +558,7 @@ init_cmap_from_data( char *colormap_name, int *data )
 	unsigned char r[256], g[256], b[256];
 
 	if( options.debug ) 
-		fprintf( stderr, "    ... initting cmap >%s< from supplied data\n", colormap_name );
+		printf( "    ... initting cmap >%s< from supplied data\n", colormap_name );
 
 	for( i=0; i<256; i++ ) {
 		r[i] = (unsigned char)data[i*3+0];
@@ -581,7 +581,7 @@ init_cmap_from_file( char *dir_name, char *file_name, int n_suffix )
 	size_t	slen;
 
 	if( options.debug ) 
-		fprintf( stderr, "    ... initting cmap >%s<\n", file_name );
+		printf( "    ... initting cmap >%s<\n", file_name );
 
 	/* Colormap name is the file name without the '.ncmap' or '.ncm' extension */
 	colormap_name = (char *)malloc( strlen(file_name)-(n_suffix-1) );
@@ -660,7 +660,7 @@ initialize_file_interface( Stringlist *input_files )
 	NCVar	*var;
 
 	if( options.debug ) 
-		fprintf( stderr, "Initializing file interface...\n" );
+		printf( "Initializing file interface...\n" );
 
 	nfiles = stringlist_len( input_files );
 
@@ -669,7 +669,7 @@ initialize_file_interface( Stringlist *input_files )
 		input_files = input_files->next;
 		}
 	if( options.debug ) 
-		fprintf( stderr, "...calculating dim min & maxes...\n" );
+		printf( "...calculating dim min & maxes...\n" );
 	calc_dim_minmaxes();
 
 	/* Get the effective dimensionality of all the vars.
@@ -685,12 +685,12 @@ initialize_file_interface( Stringlist *input_files )
 			if( *(var->size + idim) > 1 )
 				var->effective_dimensionality++;
 			if( options.debug ) 
-				fprintf( stderr, "var %s has %d dims, dim %d: >%s< len %ld\n",
+				printf( "var %s has %d dims, dim %d: >%s< len %ld\n",
 					var->name, var->n_dims, idim, 
 					var->dim[idim]->name, var->dim[idim]->size );
 			}
 		if( options.debug ) {
-			fprintf( stderr, "variable %s had effective_dimensionality of %d\n",
+			printf( "variable %s had effective_dimensionality of %d\n",
 				var->name, var->effective_dimensionality );
 			}
 		var = var->next;
@@ -706,7 +706,7 @@ initialize_file_interface( Stringlist *input_files )
 		options.varsel_style = VARSEL_MENU;
 
 	if( options.debug ) 
-		fprintf( stderr, "Done initializing file interface...\n" );
+		printf( "Done initializing file interface...\n" );
 }
 
 /***********************************************************************************************/
@@ -799,7 +799,7 @@ fprintf( stderr, "		(\"-minmax slow\"), or all entries (\"-minmax all\").\n" );
 fprintf( stderr, "	-frames: Dump out PNG images (to make a movie, for instance)\n" );
 fprintf( stderr, "	-nc: 	Specify number of colors to use.\n" );
 fprintf( stderr, "	-no1d: 	Do NOT allow 1-D variables to be displayed.\n" );
-fprintf( stderr, "	-repl: 	Set default blowup type to replicate rathern than bilinear.\n" );
+fprintf( stderr, "	-repl: 	Set default blowup type to replicate rather than bilinear.\n" );
 fprintf( stderr, "	-calendar: Specify time calendar to use, overriding value in file. Known: noleap standard gregorian 365_day 360_day.\n" );
 fprintf( stderr, "	-private: Use a private colormap.\n" );
 fprintf( stderr, "	-debug: Print lots of debugging info.\n" );


=====================================
src/ncview.defines.h
=====================================
@@ -29,8 +29,8 @@
 #include <udunits2.h>
 #endif
 
-#define PROGRAM_ID		"Ncview 2.1.10 David W. Pierce 7 February 2024"
-#define PROGRAM_VERSION_STRING	"2.1.10"
+#define PROGRAM_ID		"Ncview 2.1.11 David W. Pierce 7 November 2024"
+#define PROGRAM_VERSION_STRING	"2.1.11"
 #define APP_RES_VERSION 	1.93
 
 #ifndef TRUE


=====================================
src/ncview.protos.h
=====================================
@@ -143,6 +143,7 @@ int 	unpack_groupname( char *varname, int ig, char *groupname );
 void 	cache_scalar_coord_info( NCVar *vars );
 int 	count_nslashes	    ( char *s );
 Stringlist *get_group_list  ( NCVar *vars );
+void 	varname_no_groups   ( char *varname, char *varname_sans_groups, char *groupname );
 
 /******************************************************************************
  * in interface.c 


=====================================
src/stringlist.c
=====================================
@@ -44,7 +44,7 @@ stringlist_match_string_exact( Stringlist *list, char *str )
 }
 
 /**************************************************************************************
- * Adds the given string and auxilliary data to the list.
+ * Adds the given string and auxiliary data to the list.
  * The first time this is called, assuming you want to make a new stringlist, pass
  * with *list == NULL. This will make a new stringlist with the passed string (and 
  * aux info) as the first element of the new string.
@@ -163,7 +163,7 @@ stringlist_add_string_ordered( Stringlist **list, char *new_string, void *aux, i
 }
 		
 /**************************************************************************************
- * Allocates space in the stringlist element for the auxilliary data, and copies it over
+ * Allocates space in the stringlist element for the auxiliary data, and copies it over
  * Returns 0 on success, -1 on error (usually inability to allocate memory)
  */
 	static int
@@ -493,7 +493,7 @@ stringlist_check_args( Stringlist **list, char *new_string, void *aux, int sltyp
 		}
 
 	if( (sltype == SLTYPE_STRING) && (strlen( (char *)aux ) > STRINGLIST_MAX_LEN) ) {
-		fprintf( stderr, "stringlist_check_args: error, trying to add auxilliary string data to a stringlist element and that string is longer than allowed max of %d\n",
+		fprintf( stderr, "stringlist_check_args: error, trying to add auxiliary string data to a stringlist element and that string is longer than allowed max of %d\n",
 			STRINGLIST_MAX_LEN );
 		return( -68 );
 		}


=====================================
src/stringlist.h
=====================================
@@ -39,7 +39,7 @@ typedef struct {
 	char	*string;
 	void	*next, *prev;
 	int	index;		/* initialized to position in list */
-	void	*aux;		/* auxilliary data */
+	void	*aux;		/* auxiliary data */
 	int	sltype;		/* one of the defined SLTYPEs, indicating type of aux */
 } Stringlist;
 


=====================================
src/util.c
=====================================
@@ -401,16 +401,16 @@ add_vars_to_list( Stringlist *var_list, int id, char *filename, int nfiles )
 	Stringlist *var;
 
 	if( options.debug )
-		fprintf( stderr, "add_vars_to_list: entering, adding vars to list for file %s\n", filename );
+		printf( "add_vars_to_list: entering, adding vars to list for file %s\n", filename );
 	var = var_list;
 	while( var != NULL ) {
 		if( options.debug ) 
-			fprintf( stderr, "adding variable %s to list\n", var->string );
+			printf( "adding variable %s to list\n", var->string );
 		add_var_to_list( var->string, id, filename, nfiles );
 		var = var->next;
 		}
 	if( options.debug ) 
-		fprintf( stderr, "done adding vars for file %s\n", filename );
+		printf( "done adding vars for file %s\n", filename );
 }
 
 /******************************************************************************
@@ -435,7 +435,7 @@ add_var_to_list( char *var_name, int file_id, char *filename, int nfiles )
 		}
 	strcpy( new_fdb->filename, filename );
 
-	/* fill out auxilliary (data-file format dependent) information
+	/* fill out auxiliary (data-file format dependent) information
 	 * for the new fdb.
 	 */
 	fi_fill_aux_data( file_id, var_name, new_fdb );
@@ -452,7 +452,7 @@ add_var_to_list( char *var_name, int file_id, char *filename, int nfiles )
 		n_dims              = fi_n_dims( file_id, var_name );
 		new_var->n_dims     = n_dims;
 		if( options.debug )
-			fprintf( stderr, "adding variable %s with %d dimensions\n",
+			printf( "adding variable %s with %d dimensions\n",
 				var_name, n_dims );
 		new_var->first_file = new_fdb;
 		new_var->last_file  = new_fdb;
@@ -491,11 +491,11 @@ add_var_to_list( char *var_name, int file_id, char *filename, int nfiles )
 		{
 		/* Go to the end of the file list and add it there */
 		if( options.debug )
-			fprintf( stderr, "adding another file with variable %s in it\n",
+			printf( "adding another file with variable %s in it\n",
 				var_name );
 		if( var->last_file == NULL ) {
 			fprintf( stderr, "ncview: add_var_to_list: internal ");
-			fprintf( stderr, "inconsistancy; var has no last_file\n" );
+			fprintf( stderr, "inconsistency; var has no last_file\n" );
 			exit( -1 );
 			}
 		fdb = var->first_file;
@@ -1152,9 +1152,9 @@ handle_dim_mapping_2d( NCVar *v, char *coord_var_name, char *coord_att, size_t *
 	must_be_left_of = v->n_dims;	/* Start out by setting all the way to right edge */
 	for( i=map_info->coord_var_ndims-1; i>=0; i--) {/* Want to find a dim in v that matches size of coord_var dim number i... */
 		/*
-		fprintf( stderr, "Searching for a dim in var %s that matches dim number %d in %s, which is of size %d\n",
+		printf( "Searching for a dim in var %s that matches dim number %d in %s, which is of size %d\n",
 			v->name, i, s, coord_var_eff_size[i] );
-		fprintf( stderr, "the match must be to the left of %d\n", must_be_left_of );
+		printf( "the match must be to the left of %d\n", must_be_left_of );
 		*/
 		for( j=must_be_left_of-1; j>=0; j-- ) {	/* ...subject to constraint that match be left of (have lower numerical value then) j */
 			if( coord_var_eff_size[i] == v->size[j] ) {
@@ -1340,14 +1340,14 @@ fill_dim_structs( NCVar *v )
 			d->global_id 	= ++global_id;
 			handle_time_dim( fileid, v, i );
 			if( options.debug ) 
-				fprintf( stderr, "adding scannable dim to var %s: dimname: %s dimsize: %ld\n", v->name, dim_name, d->size );
+				printf( "adding scannable dim to var %s: dimname: %s dimsize: %ld\n", v->name, dim_name, d->size );
 			}
 		else
 			{
 			/* Indicate non-scannable dimensions by a NULL */
 			*(v->dim + i) = NULL;
 			if( options.debug ) 
-				fprintf( stderr, "adding non-scannable dim to var %s: dim name: %s size: %ld\n", 
+				printf( "adding non-scannable dim to var %s: dim name: %s size: %ld\n", 
 					v->name, fi_dim_id_to_name( fileid, v->name, i), *(v->size+i) );
 			}
 		}
@@ -1513,8 +1513,11 @@ copy_info_to_identical_dims( NCVar *vsrc, NCDim *dsrc, size_t dim_len )
 				dims_are_same = (strcmp( dsrc->name, d->name ) == 0 ) &&
 						equivalent_FDBs( vsrc, v );
 				if( dims_are_same ) {
-					if( options.debug ) 
-						fprintf( stderr, "Dim %s (%d) is same as dim %s (%d), copying min&max from former to latter...\n", dsrc->name, dsrc->global_id, d->name, d->global_id );
+					if( options.debug ) {
+						printf( "Dim %s (%d) is same as dim %s (%d), copying min&max from former to latter... min=%f max=%f\n", 
+							dsrc->name, dsrc->global_id, d->name, d->global_id,
+							dsrc->min, dsrc->max );
+						}
 					d->min = dsrc->min;
 					d->max = dsrc->max;
 					d->have_calc_minmax = 1;
@@ -1554,7 +1557,8 @@ calc_dim_minmaxes( void )
 			d = *(v->dim+i);
 			if( (d != NULL) && (d->have_calc_minmax == 0)) {
 				if( options.debug ) 
-					fprintf( stderr, "...min & maxes for dim %s (%d)...\n", d->name, d->global_id );
+					printf( "%s %d ...min & maxes for dim d->name=>%s< (d->global_id=%d)...\n", 
+						__FILE__, __LINE__, d->name, d->global_id );
 				dim_len = *(v->size+i);
 				d->values = (float *)malloc(dim_len*sizeof(float));
 
@@ -1575,7 +1579,7 @@ calc_dim_minmaxes( void )
 				else
 					{
 					if( options.debug ) 
-						fprintf( stderr, "**Note: non-float dim found; i=%d\n", i );
+						printf( "**Note: non-float dim found; i=%d\n", i );
 					d->min  = 1.0;
 					d->max  = (float)dim_len;
 					for( j=0; j<dim_len; j++ )
@@ -2427,3 +2431,43 @@ int unpack_groupname( char *varname, int ig, char *groupname )
 	return( 0 );
 }
 
+/*******************************************************************************************
+ * Given a varname string of format: groupname0/groupname1/groupnameN/varname
+ * this returns ONLY the trailing varname in "varname_sans_groups", and ONLY the
+ * groupname with no leading or trailing slash ( "root/groupa" ) in "groupname"
+ */
+void varname_no_groups( char *varname, char *varname_sans_groups, char *groupname )
+{
+	int	i, i0, i1, idx_slash[MAX_NC_NAME], nslash;
+	char	ts[MAX_NC_NAME];
+
+	/* Get indices of the slashes */
+	nslash = 0;
+	for( i=0; i<strlen(varname); i++ ) {
+		if( varname[i] == '/' ) {
+			idx_slash[nslash] = i;
+			nslash++;
+			}
+		}
+
+	if( nslash == 0 ) {
+		strcpy( varname_sans_groups, varname );
+		if( groupname != NULL )
+			groupname[0] = '\0';
+		return;
+		}
+
+	strcpy( varname_sans_groups, varname+idx_slash[nslash-1]+1 );
+	if( groupname != NULL ) {
+		strncpy( groupname, varname, idx_slash[nslash-1] );
+		groupname[ idx_slash[nslash-1] ] = '\0';
+		}
+
+	/*
+	printf( "UUUU varname_no_groups, varname: >%s< varname_sans_groups: >%s< groupname: >%s<\n", 
+		varname,
+		varname_sans_groups,
+		((groupname == NULL) ? "NULL" : groupname));
+	*/
+}
+


=====================================
src/view.c
=====================================
@@ -194,7 +194,7 @@ set_scan_variable( NCVar *var )
 		 * the previous scan place.
 		 */
 		if( options.debug )
-			fprintf( stderr, "...determing scan axes (PREVIOUS)\n" );
+			fprintf( stderr, "...determining scan axes (PREVIOUS)\n" );
 		determine_scan_axes( new_view, var, old_view );
 		if( var->effective_dimensionality == 1 ) {
 			view = new_view;
@@ -1961,7 +1961,7 @@ calculate_blowup( View *view, NCVar *var, int val_to_set_to )
 draw_file_info( NCVar *var )
 {
 	char	*title, *units, *var_long_name;
-	char	range_label[256], temp_label[256];
+	char	range_label[256], temp_label[600];
 
 	title = fi_title( var->first_file->id );
 	if( title == NULL )
@@ -1997,7 +1997,7 @@ draw_file_info( NCVar *var )
 					var->global_max,
 					limit_string(units) );
 		}
-	snprintf( temp_label, 255, "displayed range: %s", range_label );
+	snprintf( temp_label, 599, "displayed range: %s", range_label );
 	in_set_label( LABEL_DATA_EXTREMA, temp_label );
 
 	var_long_name = fi_long_var_name( view->variable->first_file->id, 
@@ -2006,17 +2006,17 @@ draw_file_info( NCVar *var )
 		snprintf( temp_label, 255, "variable=%s", limit_string(view->variable->name) );
 		in_set_label( LABEL_SCANVAR_NAME, temp_label );
 		if( options.want_extra_info ) {
-			snprintf( temp_label, 255, "%s (%s)", limit_string(view->variable->name), 
+			snprintf( temp_label, 599, "%s (%s)", limit_string(view->variable->name), 
 								range_label );
 			in_set_label( LABEL_CCINFO_1, temp_label );
 			}
 		}
 	else
 		{
-		snprintf( temp_label, 255, "displaying %s", limit_string(var_long_name) );
+		snprintf( temp_label, 599, "displaying %s", limit_string(var_long_name) );
 		in_set_label( LABEL_SCANVAR_NAME, temp_label );
 		if( options.want_extra_info ) {
-			snprintf( temp_label, 255, "%s (%s)",  limit_string(var_long_name), range_label );
+			snprintf( temp_label, 599, "%s (%s)",  limit_string(var_long_name), range_label );
 			in_set_label( LABEL_CCINFO_1, temp_label );
 			}
 		}
@@ -2142,7 +2142,7 @@ view_report_position( int x, int y, unsigned int button_mask )
 	int	type, has_bounds, i, x_is_mapped, y_is_mapped;
 	float	val;
 	double	new_dimval, bound_min, bound_max;
-	char	current_value_label[80], temp_string[1024];
+	char	current_value_label[500], temp_string[1024];
 	char	xdim_str[80], ydim_str[80];
 	NCDim	*xdim, *ydim;
 	size_t	virt_cursor_pos[MAX_NC_DIMS];
@@ -2224,7 +2224,7 @@ view_report_position( int x, int y, unsigned int button_mask )
 	else
 		strncpy( ydim_str, temp_string, 80 );
 
-	snprintf( current_value_label, 79, "Current: (i=%1ld, j=%1ld) %g (x=%s, y=%s)\n", 
+	snprintf( current_value_label, 499, "Current: (i=%1ld, j=%1ld) %g (x=%s, y=%s)\n", 
 				data_x, data_y, val, xdim_str, ydim_str );
 	in_set_label( LABEL_DATA_VALUE, current_value_label );
 }
@@ -2313,7 +2313,7 @@ view_construct_scalar_coord_str( char *str, int slen )
 	void
 view_report_position_vals( float xval, float yval, int plot_index )
 {
-	char	current_value_label[80], temp[80];
+	char	current_value_label[200], temp[80];
 	NCDim	*dim;
 
 	dim = plot_XY_dim[plot_index];
@@ -2321,7 +2321,7 @@ view_report_position_vals( float xval, float yval, int plot_index )
 	/* If the X dimension is timelike, consider formatting that value */
 	if( (dim != NULL) && dim->timelike && options.t_conv ) {
 		fmt_time( temp, 79, xval, dim, 1 );
-		snprintf( current_value_label, 79, "Current: x=%s, y=%g",
+		snprintf( current_value_label, 199, "Current: x=%s, y=%g",
 		                temp, yval );
 		}
 	else


=====================================
t.patch
=====================================
@@ -0,0 +1,39 @@
+Description: Modernize autotools for clean autoreconf.
+ The issues in question:
+ .
+ configure.in:39: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
+ configure.in:39: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
+ configure.in:33: installing './compile'
+ src/Makefile.am:21: warning: source file 'interface/interface.c' is in a subdirectory,
+ src/Makefile.am:21: but option 'subdir-objects' is disabled
+ automake: warning: possible forward-incompatibility.
+ automake: At least a source file is in a subdirectory, but the 'subdir-objects'
+ automake: automake option hasn't been enabled.  For now, the corresponding output
+ automake: object file(s) will be placed in the top-level directory.  However,
+ automake: this behaviour will change in future Automake versions: they will
+ automake: unconditionally cause object files to be placed in the same subdirectory
+ automake: of the corresponding sources.
+ automake: You are advised to start using 'subdir-objects' option throughout your
+ automake: project, to avoid future incompatibilities.
+Author: Bas Couwenberg <sebastic at debian.org>
+Forwarded: yes, mailto:dpierce at ucsd.edu
+
+--- a/configure.in
++++ b/configure.in
+@@ -36,7 +36,7 @@ AC_HEADER_STDC
+ 
+ 
+ AC_CONFIG_HEADER(config.h)
+-AM_INIT_AUTOMAKE([ncview],[ncview_version])
++AM_INIT_AUTOMAKE
+ 
+ AC_PATH_X
+ if test "x$no_x" == "xyes"; then
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,3 +1,5 @@
++AUTOMAKE_OPTIONS = subdir-objects
++
+ bin_PROGRAMS=ncview
+ noinst_PROGRAMS=geteuid
+ geteuid_SOURCES=geteuid.c



View it on GitLab: https://salsa.debian.org/debian-gis-team/ncview/-/commit/e46db18ee568e007a4fbc6bd38f1700ee105e439

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/ncview/-/commit/e46db18ee568e007a4fbc6bd38f1700ee105e439
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20241127/ddf94e2a/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list