[grads] 01/06: Imported Upstream version 2.0.2

Alastair McKinstry mckinstry at moszumanska.debian.org
Fri Aug 28 10:42:57 UTC 2015


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch master
in repository grads.

commit d7732c72203630dc260d4d2bc53291ec45dc4781
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Mon Jul 6 14:31:16 2015 +0100

    Imported Upstream version 2.0.2
---
 COPYRIGHT                            |   374 +
 INSTALL                              |    53 +
 Makefile.am                          |    66 +
 Makefile.in                          |   702 +
 acinclude.m4                         |    98 +
 aclocal.m4                           |   629 +
 bootstrap                            |     8 +
 configure                            | 23192 +++++++++++++++++++++++++++++++++
 configure.ac                         |  1007 ++
 doc/16colors.html                    |    60 +
 doc/GrADS.css                        |    19 +
 doc/SDFdescriptorfile.html           |     1 +
 doc/Tutorial_Espanol.doc             |   Bin 0 -> 171008 bytes
 doc/about.html                       |    55 +
 doc/aboutgriddeddata.html            |     1 +
 doc/aboutstationdata.html            |   378 +
 doc/advdisplay.html                  |   189 +
 doc/advhardcopy.html                 |     3 +
 doc/animation.html                   |    76 +
 doc/basic.html                       |     1 +
 doc/bufr.sample.data                 |    75 +
 doc/bufr.sample.headers              |   188 +
 doc/bufrdescriptorfile.html          |   223 +
 doc/bufrformat.html                  |   224 +
 doc/clab_default.png                 |   Bin 0 -> 24606 bytes
 doc/clab_masked.png                  |   Bin 0 -> 25078 bytes
 doc/colorcontrol.html                |   287 +
 doc/commandline.html                 |   103 +
 doc/commands.html                    |     1 +
 doc/commandsatt.html                 |     1 +
 doc/compression.html                 |     1 +
 doc/coordinate.html                  |   144 +
 doc/descriptorfile.html              |  1804 +++
 doc/dimenv.html                      |     1 +
 doc/display.html                     |   129 +
 doc/edemo1.png                       |   Bin 0 -> 6973 bytes
 doc/edemo2.png                       |   Bin 0 -> 21321 bytes
 doc/edemo3.png                       |   Bin 0 -> 8822 bytes
 doc/edemo4.png                       |   Bin 0 -> 9985 bytes
 doc/edemo5.png                       |   Bin 0 -> 9190 bytes
 doc/edemo6.png                       |   Bin 0 -> 11942 bytes
 doc/edemo7.png                       |   Bin 0 -> 6328 bytes
 doc/ensembles.html                   |     1 +
 doc/expressions.html                 |     1 +
 doc/font.html                        |     1 +
 doc/fontcontrol.html                 |     1 +
 doc/footnote1.html                   |     6 +
 doc/functions.html                   |    77 +
 doc/functionsatt.html                |   112 +
 doc/gadoc.html                       |   160 +
 doc/gadoc_files.tar.gz               |   Bin 0 -> 5278845 bytes
 doc/gadocindex.html                  |    27 +
 doc/gfs.ctl                          |   176 +
 doc/gfsens.ctl                       |    79 +
 doc/gradcomdclear.html               |     1 +
 doc/gradcomdclose.html               |     7 +
 doc/gradcomdcollect.html             |    48 +
 doc/gradcomdddrawline.html           |    10 +
 doc/gradcomddefine.html              |    36 +
 doc/gradcomddisablefwrite.html       |     6 +
 doc/gradcomddisableprint.html        |     1 +
 doc/gradcomddisplay.html             |    41 +
 doc/gradcomddrawbutton.html          |     1 +
 doc/gradcomddrawdropmenu.html        |   122 +
 doc/gradcomddrawline.html            |    12 +
 doc/gradcomddrawmap.html             |     8 +
 doc/gradcomddrawmark.html            |     1 +
 doc/gradcomddrawpolyf.html           |    11 +
 doc/gradcomddrawrec.html             |    10 +
 doc/gradcomddrawrecf.html            |     9 +
 doc/gradcomddrawshp.html             |     1 +
 doc/gradcomddrawstring.html          |    13 +
 doc/gradcomddrawtitle.html           |     8 +
 doc/gradcomddrawwxsym.html           |    37 +
 doc/gradcomddrawxlab.html            |     8 +
 doc/gradcomddrawylab.html            |     8 +
 doc/gradcomdenableprint.html         |    29 +
 doc/gradcomdexec.html                |    12 +
 doc/gradcomdflush.html               |     1 +
 doc/gradcomdgrads.html               |     1 +
 doc/gradcomdhelp.html                |     7 +
 doc/gradcomdmodify.html              |    37 +
 doc/gradcomdopen.html                |    47 +
 doc/gradcomdoutxwd.html              |     1 +
 doc/gradcomdprint.html               |     1 +
 doc/gradcomdprintim.html             |     1 +
 doc/gradcomdqattr.html               |   122 +
 doc/gradcomdqdbf.html                |     1 +
 doc/gradcomdqdialog.html             |    80 +
 doc/gradcomdqens.html                |     1 +
 doc/gradcomdqfile.html               |    91 +
 doc/gradcomdqfwrite.html             |     1 +
 doc/gradcomdqpos.html                |     1 +
 doc/gradcomdqsdfwrite.html           |     1 +
 doc/gradcomdqshades.html             |     1 +
 doc/gradcomdqshp.html                |     1 +
 doc/gradcomdqshpopts.html            |     1 +
 doc/gradcomdquery.html               |     1 +
 doc/gradcomdquit.html                |     4 +
 doc/gradcomdredrawbutton.html        |     1 +
 doc/gradcomdreinit.html              |    27 +
 doc/gradcomdreset.html               |    55 +
 doc/gradcomdrun.html                 |    34 +
 doc/gradcomdscreen.html              |     1 +
 doc/gradcomdsdfopen.html             |     1 +
 doc/gradcomdsdfwrite.html            |     1 +
 doc/gradcomdsetannot.html            |     1 +
 doc/gradcomdsetarrlab.html           |    55 +
 doc/gradcomdsetarrowhead.html        |    11 +
 doc/gradcomdsetarrscl.html           |    20 +
 doc/gradcomdsetbackground.html       |     7 +
 doc/gradcomdsetbarbase.html          |    10 +
 doc/gradcomdsetbargap.html           |    10 +
 doc/gradcomdsetbaropts.html          |    13 +
 doc/gradcomdsetblack.html            |     8 +
 doc/gradcomdsetbutton.html           |    60 +
 doc/gradcomdsetcachesf.html          |     1 +
 doc/gradcomdsetccolor.html           |    63 +
 doc/gradcomdsetccols.html            |    44 +
 doc/gradcomdsetchunksize.html        |     1 +
 doc/gradcomdsetcint.html             |     8 +
 doc/gradcomdsetclab.html             |     1 +
 doc/gradcomdsetclevs.html            |    37 +
 doc/gradcomdsetclip.html             |    44 +
 doc/gradcomdsetclopts.html           |     1 +
 doc/gradcomdsetclskip.html           |     1 +
 doc/gradcomdsetcmark.html            |    45 +
 doc/gradcomdsetcmax.html             |     8 +
 doc/gradcomdsetcmin.html             |     8 +
 doc/gradcomdsetcoslat.html           |    19 +
 doc/gradcomdsetcsmooth.html          |    14 +
 doc/gradcomdsetcstyle.html           |    49 +
 doc/gradcomdsetcterp.html            |    12 +
 doc/gradcomdsetcthick.html           |    10 +
 doc/gradcomdsetdatawarn.html         |    25 +
 doc/gradcomdsetdbuff.html            |     9 +
 doc/gradcomdsetdefval.html           |   107 +
 doc/gradcomdsetdfile.html            |     7 +
 doc/gradcomdsetdialog.html           |    55 +
 doc/gradcomdsetdignum.html           |     7 +
 doc/gradcomdsetdigsize.html          |     9 +
 doc/gradcomdsetdisplay.html          |    23 +
 doc/gradcomdsetdropmenu.html         |    76 +
 doc/gradcomdsetfgvals.html           |    10 +
 doc/gradcomdsetfont.html             |     1 +
 doc/gradcomdsetframe.html            |    18 +
 doc/gradcomdsetfwrite.html           |     1 +
 doc/gradcomdsetgeotiff.html          |     1 +
 doc/gradcomdsetgrads.html            |    29 +
 doc/gradcomdsetgrid.html             |    72 +
 doc/gradcomdsetgridln.html           |    46 +
 doc/gradcomdsetgxout.html            |   178 +
 doc/gradcomdsethempref.html          |    46 +
 doc/gradcomdsetimprun.html           |    33 +
 doc/gradcomdsetkml.html              |     1 +
 doc/gradcomdsetlatlonlevtimeens.html |     1 +
 doc/gradcomdsetlats.html             |    64 +
 doc/gradcomdsetlfcols.html           |    10 +
 doc/gradcomdsetline.html             |    41 +
 doc/gradcomdsetlog1d.html            |     1 +
 doc/gradcomdsetloopdim.html          |     1 +
 doc/gradcomdsetloopincr.html         |     7 +
 doc/gradcomdsetlooping.html          |    13 +
 doc/gradcomdsetmap.html              |    16 +
 doc/gradcomdsetmdlopts.html          |     7 +
 doc/gradcomdsetmissconn.html         |    13 +
 doc/gradcomdsetmpdraw.html           |     9 +
 doc/gradcomdsetmpdset.html           |    10 +
 doc/gradcomdsetmproj.html            |    46 +
 doc/gradcomdsetmpt.html              |    50 +
 doc/gradcomdsetmpvals.html           |    15 +
 doc/gradcomdsetparea.html            |    29 +
 doc/gradcomdsetpoli.html             |    10 +
 doc/gradcomdsetprnopts.html          |    59 +
 doc/gradcomdsetrband.html            |    57 +
 doc/gradcomdsetrbcols.html           |    39 +
 doc/gradcomdsetrbrange.html          |    10 +
 doc/gradcomdsetrgb.html              |     1 +
 doc/gradcomdsetsdfattr.html          |     1 +
 doc/gradcomdsetsdfwrite.html         |     1 +
 doc/gradcomdsetshp.html              |     1 +
 doc/gradcomdsetshpattr.html          |     1 +
 doc/gradcomdsetshpopts.html          |     1 +
 doc/gradcomdsetstat.html             |    74 +
 doc/gradcomdsetstid.html             |     8 +
 doc/gradcomdsetstnprint.html         |    27 +
 doc/gradcomdsetstring.html           |     1 +
 doc/gradcomdsetstrmden.html          |     8 +
 doc/gradcomdsetstrsiz.html           |     1 +
 doc/gradcomdsettimelab.html          |    29 +
 doc/gradcomdsettlsupp.html           |    30 +
 doc/gradcomdsetundef.html            |     1 +
 doc/gradcomdsetvpage.html            |    25 +
 doc/gradcomdsetvrange.html           |    30 +
 doc/gradcomdsetvrange2.html          |    16 +
 doc/gradcomdsetwarn.html             |    28 +
 doc/gradcomdsetwxcols.html           |    23 +
 doc/gradcomdsetwxopt.html            |     1 +
 doc/gradcomdsetxaxis.html            |    33 +
 doc/gradcomdsetxflip.html            |    10 +
 doc/gradcomdsetxlab.html             |    47 +
 doc/gradcomdsetxlabs.html            |     1 +
 doc/gradcomdsetxlevs.html            |    46 +
 doc/gradcomdsetxlint.html            |    54 +
 doc/gradcomdsetxlopts.html           |     1 +
 doc/gradcomdsetxlpos.html            |    14 +
 doc/gradcomdsetxsize.html            |     8 +
 doc/gradcomdsetxyrev.html            |    16 +
 doc/gradcomdsetxyzte.html            |     1 +
 doc/gradcomdsetyaxis.html            |    33 +
 doc/gradcomdsetyflip.html            |     9 +
 doc/gradcomdsetylab.html             |    48 +
 doc/gradcomdsetylabs.html            |     8 +
 doc/gradcomdsetylevs.html            |    45 +
 doc/gradcomdsetylint.html            |    54 +
 doc/gradcomdsetylopts.html           |     1 +
 doc/gradcomdsetylpos.html            |    15 +
 doc/gradcomdsetzlog.html             |    17 +
 doc/gradcomdshell.html               |    13 +
 doc/gradcomdstat.html                |    78 +
 doc/gradcomdswap.html                |     7 +
 doc/gradcomdtserbarb.html            |     8 +
 doc/gradcomdtserwx.html              |    10 +
 doc/gradcomdundefine.html            |     7 +
 doc/gradcomdwi.html                  |     1 +
 doc/gradcomdxdfopen.html             |     1 +
 doc/gradfuncaave.html                |   127 +
 doc/gradfuncabs.html                 |    11 +
 doc/gradfuncacos.html                |    12 +
 doc/gradfuncamax.html                |    78 +
 doc/gradfuncamaxlocx.html            |    54 +
 doc/gradfuncamaxlocy.html            |    54 +
 doc/gradfuncamean.html               |    31 +
 doc/gradfuncamin.html                |    77 +
 doc/gradfuncaminlocx.html            |    54 +
 doc/gradfuncaminlocy.html            |    54 +
 doc/gradfuncasin.html                |    12 +
 doc/gradfuncasum.html                |    73 +
 doc/gradfuncasumg.html               |    30 +
 doc/gradfuncatan2.html               |    29 +
 doc/gradfuncatot.html                |    46 +
 doc/gradfuncave.html                 |   141 +
 doc/gradfunccdiff.html               |    51 +
 doc/gradfunccoll2gr.html             |    69 +
 doc/gradfuncconst.html               |   104 +
 doc/gradfunccos.html                 |    10 +
 doc/gradfunceloop.html               |     1 +
 doc/gradfuncexp.html                 |    10 +
 doc/gradfuncfndlvl.html              |    57 +
 doc/gradfuncgint.html                |     1 +
 doc/gradfuncgr2stn.html              |     1 +
 doc/gradfunchcurl.html               |    48 +
 doc/gradfunchdivg.html               |    19 +
 doc/gradfunclog.html                 |    12 +
 doc/gradfunclog10.html               |    11 +
 doc/gradfunclterp.html               |    92 +
 doc/gradfuncmag.html                 |    12 +
 doc/gradfuncmaskout.html             |    45 +
 doc/gradfuncmax.html                 |    52 +
 doc/gradfuncmaxloc.html              |    46 +
 doc/gradfuncmean.html                |    32 +
 doc/gradfuncmin.html                 |    44 +
 doc/gradfuncminloc.html              |     1 +
 doc/gradfuncoabin.html               |    57 +
 doc/gradfuncoacres.html              |    84 +
 doc/gradfuncpow.html                 |    23 +
 doc/gradfuncs2g1d.html               |     1 +
 doc/gradfuncscorr.html               |    68 +
 doc/gradfuncsin.html                 |    12 +
 doc/gradfuncskip.html                |     1 +
 doc/gradfuncsmth9.html               |    28 +
 doc/gradfuncsqrt.html                |    13 +
 doc/gradfuncsregr.html               |   131 +
 doc/gradfuncstnave.html              |    55 +
 doc/gradfuncstnmax.html              |    11 +
 doc/gradfuncstnmin.html              |    11 +
 doc/gradfuncsum.html                 |   112 +
 doc/gradfuncsumg.html                |    30 +
 doc/gradfunctan.html                 |    11 +
 doc/gradfunctcorr.html               |    68 +
 doc/gradfunctloop.html               |    88 +
 doc/gradfunctmave.html               |   117 +
 doc/gradfunctregr.html               |   109 +
 doc/gradfunctvrh2q.html              |    52 +
 doc/gradfunctvrh2t.html              |    13 +
 doc/gradfuncvint.html                |     1 +
 doc/gradutilbufrscan.html            |    77 +
 doc/gradutilgrib2scan.html           |   133 +
 doc/gradutilgribmap.html             |     1 +
 doc/gradutilgribscan.html            |   247 +
 doc/gradutilgxeps.html               |     1 +
 doc/gradutilgxps.html                |     1 +
 doc/gradutilgxtran.html              |    51 +
 doc/gradutilncdump.html              |   184 +
 doc/gradutilncgen.html               |    73 +
 doc/gradutilstnmap.html              |    94 +
 doc/graphelem.html                   |    46 +
 doc/graphics.html                    |    48 +
 doc/grib.html                        |     1 +
 doc/grib_levels.html                 |   410 +
 doc/grib_parameters.html             |  1595 +++
 doc/gsf.html                         |   152 +
 doc/imageoutput.html                 |   143 +
 doc/images/dot_10.gif                |   Bin 0 -> 35 bytes
 doc/images/dot_11.gif                |   Bin 0 -> 35 bytes
 doc/images/dot_12.gif                |   Bin 0 -> 35 bytes
 doc/images/dot_13.gif                |   Bin 0 -> 35 bytes
 doc/images/dot_14.gif                |   Bin 0 -> 65 bytes
 doc/images/dot_15.gif                |   Bin 0 -> 35 bytes
 doc/images/dot_2.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_3.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_4.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_5.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_6.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_7.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_8.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_9.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_b.gif                 |   Bin 0 -> 35 bytes
 doc/images/dot_clear.gif             |   Bin 0 -> 43 bytes
 doc/images/dot_w.gif                 |   Bin 0 -> 35 bytes
 doc/images/key.gif                   |   Bin 0 -> 1342 bytes
 doc/images/logom2.gif                |   Bin 0 -> 4151 bytes
 doc/images/tutorial_fig1.gif         |   Bin 0 -> 12526 bytes
 doc/images/tutorial_fig2.gif         |   Bin 0 -> 4501 bytes
 doc/images/tutorial_fig3.gif         |   Bin 0 -> 12476 bytes
 doc/images/tutorial_fig4.gif         |   Bin 0 -> 13437 bytes
 doc/images/tutorial_fig5.gif         |   Bin 0 -> 12729 bytes
 doc/images/tutorial_fig6.gif         |   Bin 0 -> 15249 bytes
 doc/images/tutorial_fig7.gif         |   Bin 0 -> 11656 bytes
 doc/images/tutorial_fig8.gif         |   Bin 0 -> 11212 bytes
 doc/images/tutorial_fig9.gif         |   Bin 0 -> 13053 bytes
 doc/indexalpha.html                  |    48 +
 doc/indexlist.html                   |   770 ++
 doc/key.gif                          |   Bin 0 -> 1342 bytes
 doc/library.html                     |   314 +
 doc/map.html                         |  1044 ++
 doc/mathfunctions.html               |   195 +
 doc/ncdump.html                      |   189 +
 doc/ncgen.html                       |    52 +
 doc/offt.html                        |     1 +
 doc/offt_1D_t1.png                   |   Bin 0 -> 4183 bytes
 doc/offt_diag.png                    |   Bin 0 -> 6961 bytes
 doc/offtv_1D.png                     |   Bin 0 -> 4316 bytes
 doc/offtv_diag.png                   |   Bin 0 -> 6835 bytes
 doc/pagecontrol.html                 |   162 +
 doc/pages.html                       |    12 +
 doc/pdef.html                        |     1 +
 doc/pdsi.png                         |   Bin 0 -> 24354 bytes
 doc/preprojectedgrids.html           |   302 +
 doc/reference.html                   |    27 +
 doc/reference_card.pdf               |   Bin 0 -> 28542 bytes
 doc/reference_card_scl.pdf           |   Bin 0 -> 13462 bytes
 doc/reinitialization.html            |    62 +
 doc/sample.ctl                       |    15 +
 doc/sample.grib                      |   Bin 0 -> 1973098 bytes
 doc/sample.ncdump                    |   179 +
 doc/sample_sfc.ctl                   |    28 +
 doc/sample_tau.ctl                   |    24 +
 doc/sample_temp.ctl                  |    29 +
 doc/sample_uv.ctl                    |    26 +
 doc/sample_w.ctl                     |    28 +
 doc/scatterplot.html                 |    57 +
 doc/script.html                      |     1 +
 doc/shapefiles.html                  |    80 +
 doc/shp_demo1.png                    |   Bin 0 -> 55648 bytes
 doc/shp_demo2.png                    |   Bin 0 -> 43732 bytes
 doc/shp_demo3.png                    |   Bin 0 -> 77796 bytes
 doc/start.html                       |     1 +
 doc/stnmap.html                      |    72 +
 doc/supplibs.html                    |   628 +
 doc/templates.html                   |   187 +
 doc/tutorial.html                    |   374 +
 doc/tutorial_fig1.gif                |   Bin 0 -> 12526 bytes
 doc/tutorial_fig2.gif                |   Bin 0 -> 4501 bytes
 doc/tutorial_fig3.gif                |   Bin 0 -> 12476 bytes
 doc/tutorial_fig4.gif                |   Bin 0 -> 13437 bytes
 doc/tutorial_fig5.gif                |   Bin 0 -> 12729 bytes
 doc/tutorial_fig6.gif                |   Bin 0 -> 15249 bytes
 doc/tutorial_fig7.gif                |   Bin 0 -> 11656 bytes
 doc/tutorial_fig8.gif                |   Bin 0 -> 11212 bytes
 doc/tutorial_fig9.gif                |   Bin 0 -> 13053 bytes
 doc/udf.html                         |   433 +
 doc/users.html                       |     1 +
 doc/usingstationdata.html            |   285 +
 doc/utilities.html                   |     1 +
 doc/variable.html                    |     1 +
 doc/variableformats.html             |     1 +
 doc/wrf.ncdump                       |    90 +
 doc/wrfgrid.ctl                      |    12 +
 doc/wrfvars.ctl                      |    15 +
 doc/xdfsample1.txt                   |    36 +
 doc/xdfsample2.txt                   |    80 +
 doc/xsections.html                   |   130 +
 etc/compile                          |    99 +
 etc/config.guess                     |  1321 ++
 etc/config.sub                       |  1443 ++
 etc/install-sh                       |   251 +
 etc/missing                          |   336 +
 etc/mkinstalldirs                    |   101 +
 lib/emacs/README-emacs.txt           |     7 +
 lib/emacs/ctl-mode.el                |   111 +
 lib/emacs/gs-mode.el                 |   151 +
 m4/Xaw.m4                            |    81 +
 m4/ga_lib_readline.m4                |    98 +
 m4/gd.m4                             |    76 +
 m4/geotiff.m4                        |   169 +
 m4/grib2.m4                          |    26 +
 m4/gui.m4                            |    30 +
 m4/hdf4.m4                           |   251 +
 m4/hdf5.m4                           |   155 +
 m4/libdap.m4                         |   314 +
 m4/libnc-dap.m4                      |   265 +
 m4/libnc-dap_header.m4               |    97 +
 m4/libsx.m4                          |    84 +
 m4/netcdf.m4                         |   154 +
 m4/netcdf_header.m4                  |    92 +
 m4/pkg.m4                            |   157 +
 m4/udunits.m4                        |    20 +
 src/Makefile.am                      |   191 +
 src/Makefile.in                      |   757 ++
 src/VERSION                          |     1 +
 src/bitmaps.h                        |   237 +
 src/bufrscan.c                       |   106 +
 src/bufrstn.c                        |   550 +
 src/config.h.in                      |   188 +
 src/dodstn.c                         |   603 +
 src/gabufr.c                         |   948 ++
 src/gabufr.h                         |   137 +
 src/gabufrtbl.c                      |   610 +
 src/gacfg.c                          |   247 +
 src/gaddes.c                         |  3871 ++++++
 src/gaexpr.c                         |  1412 ++
 src/gafunc.c                         |  7236 ++++++++++
 src/gagmap.c                         |  2052 +++
 src/gagmap.h                         |   128 +
 src/gagui.c                          |  1258 ++
 src/gagui.h                          |    69 +
 src/gagx.c                           |  7349 +++++++++++
 src/gaio.c                           |  5148 ++++++++
 src/galloc.c                         |   236 +
 src/gamach.c                         |   482 +
 src/gasdf.c                          |  4138 ++++++
 src/gasdf.h                          |    58 +
 src/gasdf_std_time.h                 |   376 +
 src/gatxt.c                          |   189 +
 src/gatypes.h                        |    10 +
 src/gauser.c                         |  8104 ++++++++++++
 src/gautil.c                         |  2389 ++++
 src/grads.c                          |   600 +
 src/grads.h                          |  1289 ++
 src/grib2scan.c                      |   845 ++
 src/gribmap.c                        |   246 +
 src/gribscan.c                       |  1283 ++
 src/gs.h                             |   184 +
 src/gscrpt.c                         |  3641 ++++++
 src/gsgui.c                          |   834 ++
 src/gstmp.c                          |   237 +
 src/gvt.h                            |   267 +
 src/gx.h                             |   489 +
 src/gxX.c                            |  3165 +++++
 src/gxchpl.c                         |   310 +
 src/gxcntr.c                         |  1107 ++
 src/gxdxwd.c                         |   391 +
 src/gxeps.c                          |  1775 +++
 src/gxgif.c                          |  2683 ++++
 src/gxhpng.c                         |   437 +
 src/gxmap.h                          |    11 +
 src/gxmeta.c                         |   686 +
 src/gxps.c                           |   635 +
 src/gxshad.c                         |  1323 ++
 src/gxshad2.c                        |  1709 +++
 src/gxstrm.c                         |   336 +
 src/gxsubs.c                         |  1090 ++
 src/gxtran.c                         |   312 +
 src/gxwmap.c                         |  1309 ++
 src/mtables.c                        |   734 ++
 src/stnmap.c                         |   451 +
 src/wgrib.c                          | 13389 +++++++++++++++++++
 src/wx.h                             |   115 +
 479 files changed, 143212 insertions(+)

diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..9600039
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,374 @@
+    The Grid Analysis and Display System (GrADS) 
+
+    Copyright (C) 1988-2010 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+
+    The Center for Ocean-Land-Atmosphere Studies (COLA) is the center
+    within IGES where GrADS is developed and maintained.
+
+    The copyright holders cann be contacted at:
+
+         COLA/IGES
+         4041 Powder Mill Rd.  Suite 302
+         Calverton, MD  20705
+
+         Phone:  301 595 7000
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; using version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+==============================================================================
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..5386187
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,53 @@
+	       GrADS - Grid Analysis and Display System
+			     Version 2.0
+
+                      http://grads.iges.org/grads
+
+                       GrADS Executables for UNIX
+
+GrADS is distributed freely and is copyrighted under the GNU Public License. 
+Please read the COPYRIGHT file for more complete information. 
+For download information consult http://grads.iges.org/grads/downloads.html
+
+The executables contained in this tar file are typically placed in the
+directory /usr/local/bin. If you do not have write permission for your
+/usr/local/bin directory, you can put them in the ~/bin subdirectory of your home
+directory.
+
+     cd /usr/local/bin
+     gunzip tarfile.gz
+     tar xvf tarfile
+
+After unpacking the first tar file, you should have the following executables:
+
+     grads            GrADS - The basic package
+     gradsdap         GrADS enabled to read data remotely via OPeNDAP
+     gribmap          Creates an index file that "maps" a GRIB data set for a GrADS descriptor file
+     gribscan         Extracts grid info from a GRIB data set
+     grib2scan        Extracts grid info from a GRIB2 data set
+     bufrscan         Reads BUFR messages and prints out ascii values 
+     gxps             Converts GrADS metafiles to Postscript
+     gxeps            Converts GrADS metafiles to Encapsulated Postscript
+     gxtran           Displays metafiles
+     stnmap           Maps station data
+     wgrib            See http://www.cpc.ncep.noaa.gov/products/wesley/wgrib.html
+
+A second tar file (data.tar.Z) contains the GrADS fonts and maps data sets is 
+also necessary and can be downloaded from http://grads.iges.org/grads/downloads.html.
+
+The contents of data.tar are typically placed in the directory
+/usr/local/lib/grads, the default location for these files. If you do not have
+write permission for /usr/local/lib/grads, you can place the files elsewhere, but
+you must also change the environment variable GADDIR so the GrADS executables will
+know where to find these files.
+
+     cd dirname
+     uncompress data.tar.Z
+     tar xvf data.tar
+     setenv GADDIR dirname (If dirname is not /usr/local/lib/grads)
+
+
+Documentation and Additional Information
+----------------------------------------
+
+Consult the GrADS homepage http://grads.iges.org/grads
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..7486801
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,66 @@
+# Adding this will suppress the requirement for INSTALL, et c., files.
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4 
+
+##############################################################
+#
+# Subdirectories with Makefiles
+#
+
+SUBDIRS=src
+
+EXTRA_DIST=COPYRIGHT INSTALL
+
+BINDISTFILES=COPYRIGHT INSTALL
+
+DATADISTFILES=data
+
+DOCDISTFILES=doc
+
+# Indicate that these targets are not the names of files
+.PHONY: nobin-dists all-dists snapshot-dist bin-dist snapshot-bin-dist \
+	data-dist doc-dist
+
+dist-all: dist data-dist doc-dist
+
+bin-dist: all-am
+	$(MAKE) $(AM_MAKE_FLAGS) prefix=$(prefix)/$(distdir) install-exec; \
+	for file in $(BINDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-bin-$(host_triplet).tar.gz; \
+	$(am__remove_distdir)
+
+data-dist:
+	mkdir -p $(distdir); \
+	for file in $(DATADISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-data.tar.gz; \
+	$(am__remove_distdir)
+
+doc-dist:
+	mkdir -p $(distdir); \
+	for file in $(DOCDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-doc.tar.gz; \
+	$(am__remove_distdir)
+
+snapshot: distdir
+	date_str=`date '+%Y%m%d-%H%M'`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-snapshot-$${date_str}.tar.gz; \
+	$(am__remove_distdir)
+
+bin-snapshot: all-am
+	$(MAKE) $(AM_MAKE_FLAGS) prefix=$(prefix)/$(distdir) install-exec; \
+	for file in $(BINDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	date_str=`date '+%Y%m%d-%H%M'`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-bin-snapshot-$${date_str}.tar.gz; \
+	$(am__remove_distdir)
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..f8b8618
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,702 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(top_srcdir)/configure ChangeLog \
+	INSTALL etc/compile etc/config.guess etc/config.sub \
+	etc/install-sh etc/missing etc/mkinstalldirs
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/Xaw.m4 \
+	$(top_srcdir)/m4/ga_lib_readline.m4 $(top_srcdir)/m4/gd.m4 \
+	$(top_srcdir)/m4/geotiff.m4 $(top_srcdir)/m4/grib2.m4 \
+	$(top_srcdir)/m4/gui.m4 $(top_srcdir)/m4/hdf4.m4 \
+	$(top_srcdir)/m4/hdf5.m4 $(top_srcdir)/m4/libsx.m4 \
+	$(top_srcdir)/m4/netcdf.m4 $(top_srcdir)/m4/netcdf_header.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/udunits.m4 \
+	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/etc/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-exec-recursive install-info-recursive \
+	install-recursive installcheck-recursive installdirs-recursive \
+	pdf-recursive ps-recursive uninstall-info-recursive \
+	uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+G2_LIBS = @G2_LIBS@
+GA_LIBSX_LIBS = @GA_LIBSX_LIBS@
+GD_CFLAGS = @GD_CFLAGS@
+GD_CONFIG = @GD_CONFIG@
+GD_LDFLAGS = @GD_LDFLAGS@
+GD_LIBS = @GD_LIBS@
+GEOTIFF_CFLAGS = @GEOTIFF_CFLAGS@
+GEOTIFF_FALSE = @GEOTIFF_FALSE@
+GEOTIFF_LDFLAGS = @GEOTIFF_LDFLAGS@
+GEOTIFF_LIBS = @GEOTIFF_LIBS@
+GEOTIFF_TRUE = @GEOTIFF_TRUE@
+GXPNG_FALSE = @GXPNG_FALSE@
+GXPNG_TRUE = @GXPNG_TRUE@
+HDF4_CFLAGS = @HDF4_CFLAGS@
+HDF4_LDFLAGS = @HDF4_LDFLAGS@
+HDF4_LIBS = @HDF4_LIBS@
+HDF5_CFLAGS = @HDF5_CFLAGS@
+HDF5_LDFLAGS = @HDF5_LDFLAGS@
+HDF5_LIBS = @HDF5_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NC_CFLAGS = @NC_CFLAGS@
+NC_LDFLAGS = @NC_LDFLAGS@
+NC_LIBS = @NC_LIBS@
+NC_NETCDF_3_CPPFLAG = @NC_NETCDF_3_CPPFLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+READLINE_FALSE = @READLINE_FALSE@
+READLINE_TRUE = @READLINE_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUPPLIBS = @SUPPLIBS@
+UDUNITS_LIBS = @UDUNITS_LIBS@
+USEDAP_FALSE = @USEDAP_FALSE@
+USEDAP_TRUE = @USEDAP_TRUE@
+USEGADAP_FALSE = @USEGADAP_FALSE@
+USEGADAP_TRUE = @USEGADAP_TRUE@
+USEGUI_FALSE = @USEGUI_FALSE@
+USEGUI_TRUE = @USEGUI_TRUE@
+USEHDF_FALSE = @USEHDF_FALSE@
+USEHDF_TRUE = @USEHDF_TRUE@
+USESHP_FALSE = @USESHP_FALSE@
+USESHP_TRUE = @USESHP_TRUE@
+VERSION = @VERSION@
+XAW7_CFLAGS = @XAW7_CFLAGS@
+XAW7_LIBS = @XAW7_LIBS@
+XAW_CFLAGS = @XAW_CFLAGS@
+XAW_LIBS = @XAW_LIBS@
+XAW_XLIBS = @XAW_XLIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+dap_libs = @dap_libs@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+extra_utils = @extra_utils@
+gadap_inc = @gadap_inc@
+geotiff_inc = @geotiff_inc@
+geotiff_libs = @geotiff_libs@
+grads_xlibs = @grads_xlibs@
+grib2_inc = @grib2_inc@
+grib2_libs = @grib2_libs@
+gui_inc = @gui_inc@
+gui_libs = @gui_libs@
+hdf5_inc = @hdf5_inc@
+hdf5_libs = @hdf5_libs@
+hdf_inc = @hdf_inc@
+hdf_libs = @hdf_libs@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_ldadd = @host_ldadd@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nc_inc = @nc_inc@
+nc_libs = @nc_libs@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+printim_inc = @printim_inc@
+printim_libs = @printim_libs@
+program_transform_name = @program_transform_name@
+readline_inc = @readline_inc@
+readline_libs = @readline_libs@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+shp_inc = @shp_inc@
+shp_libs = @shp_libs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+# Adding this will suppress the requirement for INSTALL, et c., files.
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4 
+
+##############################################################
+#
+# Subdirectories with Makefiles
+#
+SUBDIRS = src
+EXTRA_DIST = COPYRIGHT INSTALL
+BINDISTFILES = COPYRIGHT INSTALL
+DATADISTFILES = data
+DOCDISTFILES = doc
+all: all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign  --ignore-deps'; \
+	      cd $(srcdir) && $(AUTOMAKE) --foreign  --ignore-deps \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  --ignore-deps Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  --ignore-deps Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	mkdir $(distdir)
+	$(mkdir_p) $(distdir)/etc $(distdir)/m4
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+	list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(mkdir_p) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	    distdir=`$(am__cd) $(distdir) && pwd`; \
+	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+	    (cd $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$top_distdir" \
+	        distdir="$$distdir/$$subdir" \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-find $(distdir) -type d ! -perm -755 -exec chmod a+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r $(distdir)
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && cd $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+	@cd $(distuninstallcheck_dir) \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+	check-am clean clean-generic clean-recursive ctags \
+	ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
+	dist-tarZ dist-zip distcheck distclean distclean-generic \
+	distclean-recursive distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am install-man \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	maintainer-clean-recursive mostlyclean mostlyclean-generic \
+	mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am uninstall-info-am
+
+
+# Indicate that these targets are not the names of files
+.PHONY: nobin-dists all-dists snapshot-dist bin-dist snapshot-bin-dist \
+	data-dist doc-dist
+
+dist-all: dist data-dist doc-dist
+
+bin-dist: all-am
+	$(MAKE) $(AM_MAKE_FLAGS) prefix=$(prefix)/$(distdir) install-exec; \
+	for file in $(BINDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-bin-$(host_triplet).tar.gz; \
+	$(am__remove_distdir)
+
+data-dist:
+	mkdir -p $(distdir); \
+	for file in $(DATADISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-data.tar.gz; \
+	$(am__remove_distdir)
+
+doc-dist:
+	mkdir -p $(distdir); \
+	for file in $(DOCDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-doc.tar.gz; \
+	$(am__remove_distdir)
+
+snapshot: distdir
+	date_str=`date '+%Y%m%d-%H%M'`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-snapshot-$${date_str}.tar.gz; \
+	$(am__remove_distdir)
+
+bin-snapshot: all-am
+	$(MAKE) $(AM_MAKE_FLAGS) prefix=$(prefix)/$(distdir) install-exec; \
+	for file in $(BINDISTFILES) ; do \
+	  cp -pR $$file $(distdir)/ ; \
+	done; \
+	rm -rf `find $(distdir) -name CVS`; \
+	date_str=`date '+%Y%m%d-%H%M'`; \
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir)-bin-snapshot-$${date_str}.tar.gz; \
+	$(am__remove_distdir)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..9cfa0fb
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,98 @@
+dnl acinclude.m4: 
+dnl
+dnl  This file contains custom M4 macro definitions for the GrADS build system.
+dnl  It is merged with automake-related macros in "aclocal.m4" by the "aclocal"
+dnl  program. The merged "aclocal.m4" file is in turn used by the "autoconf" 
+dnl  program to generate the "configure" script. 
+dnl
+
+dnl GA_SET_SUPPLIBS : Find a supplibs directory. 
+dnl		      If SUPPLIBS environment variable is not set, then 
+dnl  		      search for "supplibs" in the paths given in the args
+dnl args: paths-to-search (eg. [. ..])
+AC_DEFUN([GA_SET_SUPPLIBS],
+[ 
+  AC_MSG_CHECKING([for supplibs directory])
+  if test -n "${SUPPLIBS}" ; then
+    # Use present supplib name unmodified, assume it is absolute path
+    AC_MSG_RESULT([${SUPPLIBS}])
+    # This is the "official" variable name for use by other macros
+    ga_supplib_dir="${SUPPLIBS}"
+  else
+    # Look for "supplibs" directory in ${top_builddir}
+    for ga_supplib_prefix in $1 ; do 
+      SUPPLIBS="${ga_supplib_prefix}/supplibs"
+      if test -d "${SUPPLIBS}" ; then
+        AC_MSG_RESULT([${SUPPLIBS}])
+        break
+      fi 
+    done
+    if test ! -d "${SUPPLIBS}" ; then
+      AC_MSG_RESULT([not found])
+      SUPPLIBS=""
+    fi
+    # This is the "official" variable name for use by other macros
+    ga_supplib_dir=$SUPPLIBS
+    # Add prefix so that Makefiles in subdirectories can find it
+    SUPPLIBS='$(top_builddir)/'"$SUPPLIBS"
+  fi
+  AC_SUBST(SUPPLIBS)
+])
+
+dnl GA_SET_FLAGS : Sets the compile and link paths to supplibs, plus any extra
+dnl 		   compiler or linker flags given, and saves original settings
+dnl 		   for restoration by GA_UNSET_FLAGS
+dnl  args: 	   extra_supplib_inc_names, extra-CPP-flags, extra-LD-flags, 
+dnl                   extra-LIB-flags
+AC_DEFUN([GA_SET_FLAGS],
+[
+  # Use to make temporary changes to -I and -L paths 
+  # Just for use during tests, because configure and make may run 
+  # from different directories. 
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+  m4_if([$1], [], [:], [
+    for ga_inc_name in $1 ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+  ])
+  CPPFLAGS="$CPPFLAGS $2"
+  LDFLAGS="-L${ga_supplib_dir}/lib $3"
+  LIBS="$LIBS $4"
+])
+
+dnl GA_UNSET_FLAGS : Undoes changes to compiler and linker flags made by GA_SET_FLAGS.
+dnl  args:	     none
+AC_DEFUN([GA_UNSET_FLAGS],
+[
+  # Use to undo temporary changes to -I and -L paths 
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+])
+
+dnl GA_SET_LIB_VAR : Puts necessary linker options to link with libraries given into
+dnl                  a shell variable. They will have the form 'supplib_dir/libname.a'.
+dnl   args:	   : shell-variable-name, list-of-libraries (e.g. [readline termcap])
+AC_DEFUN([GA_SET_LIB_VAR],
+[
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in $2 ; do
+      $1="$$1 ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done  
+])
+
+dnl GA_SET_INCLUDE_VAR : Puts necessary options to compile with include directories 
+dnl                      given into a shell variable. 
+dnl   args:	   : shell-variable-name, list-of-directories 
+AC_DEFUN([GA_SET_INCLUDE_VAR],
+[
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in $2 ; do
+      $1="$$1 ${ga_include_prefix}/${ga_include_name}"
+  done  
+])
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..e457d2d
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,629 @@
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+	 [AM_AUTOMAKE_VERSION([1.9.6])])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 7
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+	      		     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake.  There are at least two reasons why we must not
+# use `-m 0755':
+#   - it causes special bits like SGID to be ignored,
+#   - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out.  Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/Xaw.m4])
+m4_include([m4/ga_lib_readline.m4])
+m4_include([m4/gd.m4])
+m4_include([m4/geotiff.m4])
+m4_include([m4/grib2.m4])
+m4_include([m4/gui.m4])
+m4_include([m4/hdf4.m4])
+m4_include([m4/hdf5.m4])
+m4_include([m4/libsx.m4])
+m4_include([m4/netcdf.m4])
+m4_include([m4/netcdf_header.m4])
+m4_include([m4/pkg.m4])
+m4_include([m4/udunits.m4])
+m4_include([acinclude.m4])
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..3da632c
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,8 @@
+#!/bin/sh
+mkdir -p etc
+aclocal
+autoheader
+touch config.h.in
+touch src/stamp-h
+automake -i --foreign --add-missing
+autoconf
diff --git a/configure b/configure
new file mode 100755
index 0000000..e72a4c0
--- /dev/null
+++ b/configure
@@ -0,0 +1,23192 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for GrADS 2.0.2.
+#
+# Report bugs to <jma at iges.org>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='GrADS'
+PACKAGE_TARNAME='grads'
+PACKAGE_VERSION='2.0.2'
+PACKAGE_STRING='GrADS 2.0.2'
+PACKAGE_BUGREPORT='jma at iges.org'
+
+ac_default_prefix=`pwd`
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INS [...]
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+ac_env_SUPPLIBS_set=${SUPPLIBS+set}
+ac_env_SUPPLIBS_value=$SUPPLIBS
+ac_cv_env_SUPPLIBS_set=${SUPPLIBS+set}
+ac_cv_env_SUPPLIBS_value=$SUPPLIBS
+ac_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_cv_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_cv_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_env_XAW7_CFLAGS_set=${XAW7_CFLAGS+set}
+ac_env_XAW7_CFLAGS_value=$XAW7_CFLAGS
+ac_cv_env_XAW7_CFLAGS_set=${XAW7_CFLAGS+set}
+ac_cv_env_XAW7_CFLAGS_value=$XAW7_CFLAGS
+ac_env_XAW7_LIBS_set=${XAW7_LIBS+set}
+ac_env_XAW7_LIBS_value=$XAW7_LIBS
+ac_cv_env_XAW7_LIBS_set=${XAW7_LIBS+set}
+ac_cv_env_XAW7_LIBS_value=$XAW7_LIBS
+ac_env_GD_CFLAGS_set=${GD_CFLAGS+set}
+ac_env_GD_CFLAGS_value=$GD_CFLAGS
+ac_cv_env_GD_CFLAGS_set=${GD_CFLAGS+set}
+ac_cv_env_GD_CFLAGS_value=$GD_CFLAGS
+ac_env_GD_LIBS_set=${GD_LIBS+set}
+ac_env_GD_LIBS_value=$GD_LIBS
+ac_cv_env_GD_LIBS_set=${GD_LIBS+set}
+ac_cv_env_GD_LIBS_value=$GD_LIBS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures GrADS 2.0.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+X features:
+  --x-includes=DIR    X include files are in DIR
+  --x-libraries=DIR   X library files are in DIR
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of GrADS 2.0.2:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer
+  --disable-largefile     omit support for large files
+  --enable-dyn-supplibs   Use dynamic system libraries to support optional features when
+                          required libs are not present in "supplibs" directory. [default=yes]
+  --disable-dyn-supplibs  Do not use system libraries; look only in GrADS "supplibs" directory.
+                          Use this option to maximize binary portability.
+
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-gui              Athena X11 widget-based GUI
+  --with-readline         command line editing
+  --with-printim          image output
+  --with-grib2            GRIB2 data format
+  --with-sdf              all self-describing formats
+                          (HDF4,HDF5,NetCDF,OPeNDAP)
+  --with-gadap            OPeNDAP for station data
+  --with-shp              shapefile format
+  --with-geotiff          geotiff output
+  --with-x                use the X Window System
+  --with-geotiff=ARG      geotiff directory
+  --with-geotiff-include=ARG
+                          geotiff include directory
+  --with-geotiff-libdir=ARG
+                          geotiff library directory
+  --with-hdf4=ARG         hdf4 directory
+  --with-hdf4-include=ARG hdf 4 include directory
+  --with-hdf4-libdir=ARG  hdf 4 library directory
+  --with-hdf5=ARG         hdf5 directory
+  --with-hdf5-include=ARG hdf5 include directory
+  --with-hdf5-libdir=ARG  hdf5 library directory
+  --with-netcdf=ARG       netcdf directory
+  --with-netcdf-include=ARG
+                          netcdf include directory
+  --with-netcdf-libdir=ARG
+                          netcdf library directory
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  SUPPLIBS    Custom path (must be absolute) to a GrADS supplib distribution
+  PKG_CONFIG  path to pkg-config utility
+  XAW7_CFLAGS C compiler flags for XAW7, overriding pkg-config
+  XAW7_LIBS   linker flags for XAW7, overriding pkg-config
+  GD_CFLAGS   C compiler flags for GD, overriding pkg-config
+  GD_LIBS     linker flags for GD, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <jma at iges.org>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+GrADS configure 2.0.2
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GrADS $as_me 2.0.2, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Require autoconf 2.52 (comes with Mac OS X 10.2) or newer
+
+
+# Supporting scripts are in etc/
+ac_aux_dir=
+for ac_dir in etc $srcdir/etc; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in etc $srcdir/etc" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in etc $srcdir/etc" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+# Require automake 1.6 (comes with Mac OS X 10.2) or newer,
+# don't #define PACKAGE and VERSION,
+# disable dependency checking
+am__api_version="1.9"
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='grads'
+ VERSION='2.0.2'
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers src/config.h"
+
+
+# The following macro prevents annoying interactions between CVS and
+# automake, which result in make attempting to invoke autotools
+# even when the configure script is up to date
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi;
+  echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+# binaries go to ./bin by default, rather than /usr/bin.
+
+
+# ----------------------------------------------------
+#  Additional arguments for the configure script
+# ----------------------------------------------------
+
+
+# Check whether --with-gui or --without-gui was given.
+if test "${with_gui+set}" = set; then
+  withval="$with_gui"
+
+fi;
+
+# Check whether --with-readline or --without-readline was given.
+if test "${with_readline+set}" = set; then
+  withval="$with_readline"
+
+fi;
+
+# Check whether --with-printim or --without-printim was given.
+if test "${with_printim+set}" = set; then
+  withval="$with_printim"
+
+fi;
+
+# Check whether --with-grib2 or --without-grib2 was given.
+if test "${with_grib2+set}" = set; then
+  withval="$with_grib2"
+
+fi;
+
+# Check whether --with-sdf or --without-sdf was given.
+if test "${with_sdf+set}" = set; then
+  withval="$with_sdf"
+
+fi;
+
+# Check whether --with-gadap or --without-gadap was given.
+if test "${with_gadap+set}" = set; then
+  withval="$with_gadap"
+
+fi;
+
+# Check whether --with-shp or --without-shp was given.
+if test "${with_shp+set}" = set; then
+  withval="$with_shp"
+
+fi;
+
+# Check whether --with-geotiff or --without-geotiff was given.
+if test "${with_geotiff+set}" = set; then
+  withval="$with_geotiff"
+
+fi;
+
+# ----------------------------------------------------
+# Checks for programs
+# ----------------------------------------------------
+
+echo
+echo "Checking for programs"
+echo "------------------"
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in xlc gcc cc
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in xlc gcc cc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC xlc++ g++ c++
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC xlc++ g++ c++
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo
+
+echo "Setting host specific options"
+echo "-------------------------"
+
+# ----------------------------------------------------
+# Get host platform
+# ----------------------------------------------------
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+# ----------------------------------------------------
+# Set host specific options
+# ----------------------------------------------------
+
+echo Host machine:   "$host"
+case "$host" in
+
+  alpha-*-osf*)
+    # Option needed for IEEE floating points
+    CFLAGS="$(CFLAGS) -ieee"
+  ;;
+
+  powerpc-ibm-aix*)
+    LDFLAGS="$LDFLAGS -Wl,-bbigtoc -Wl,-bexpall -Wl,-brtl"
+  ;;
+
+  i*86-pc-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  x86_64-*-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  ia64-*-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  *-freebsd*)
+    CFLAGS="$CFLAGS -export-dynamic"
+  ;;
+
+  sparc-sun-solaris*)
+    is_solaris="yes"
+    host_ldadd="-lsocket -lnsl -lw"
+  ;;
+
+  *-pc-cygwin)
+    host_ldadd="-lrpclib"
+
+  ;;
+
+  *darwin*)
+    is_darwin="yes"
+    LDFLAGS="$LDFLAGS -lSystemStubs"
+  ;;
+
+  cray-*-*)
+    is_cray="yes"
+  ;;
+
+  *-hpux11*)
+     is_hpux11="yes"
+  ;;
+
+esac
+
+if test is_cray!="yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_CRAY 0
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_CRAY 1
+_ACEOF
+
+fi
+
+if test is_hpux11!="yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_HP64 0
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_HP64 1
+_ACEOF
+
+fi
+
+# ----------------------------------------------------
+# Check for basic libraries.
+# ----------------------------------------------------
+
+echo
+echo "Checking system libraries, headers, and compiler features"
+echo "-----------------------------------------"
+
+
+
+echo "$as_me:$LINENO: checking for cos in -lm" >&5
+echo $ECHO_N "checking for cos in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_cos+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char cos ();
+int
+main ()
+{
+cos ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_cos=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_cos=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_cos" >&5
+echo "${ECHO_T}$ac_cv_lib_m_cos" >&6
+if test $ac_cv_lib_m_cos = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: Fatal: Math library not found" >&5
+echo "$as_me: error: Fatal: Math library not found" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for X" >&5
+echo $ECHO_N "checking for X... $ECHO_C" >&6
+
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+
+fi;
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+    if test "${ac_cv_have_x+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -fr conftest.dir
+if mkdir conftest.dir; then
+  cd conftest.dir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat >Imakefile <<'_ACEOF'
+acfindx:
+	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+_ACEOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+	 test -f $ac_im_libdir/libX11.$ac_extension; then
+	ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case $ac_im_incroot in
+	/usr/include) ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+    esac
+    case $ac_im_usrlibdir in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+  # Guess where to find include files, by looking for Xlib.h.
+  # First, try using that file with no special directory specified.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  for ac_dir in $ac_x_header_dirs; do
+  if test -r "$ac_dir/X11/Xlib.h"; then
+    ac_x_includes=$ac_dir
+    break
+  fi
+done
+fi
+rm -f conftest.err conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+  # Check for the libraries.
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS=$LIBS
+  LIBS="-lX11 $LIBS"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+LIBS=$ac_save_LIBS
+for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+  # Don't even attempt the hair of trying to link an X program!
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/libXt.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$as_me:$LINENO: result: $have_x" >&5
+echo "${ECHO_T}$have_x" >&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5
+echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+
+cat >>confdefs.h <<\_ACEOF
+#define X_DISPLAY_MISSING 1
+_ACEOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case `(uname -sr) 2>/dev/null` in
+    "SunOS 5"*)
+      echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5
+echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&6
+      ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_R_nospace=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_R_nospace=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+      if test $ac_R_nospace = yes; then
+	echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+	X_LIBS="$X_LIBS -R$x_libraries"
+      else
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_R_space=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_R_space=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+	if test $ac_R_space = yes; then
+	  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+	  X_LIBS="$X_LIBS -R $x_libraries"
+	else
+	  echo "$as_me:$LINENO: result: neither works" >&5
+echo "${ECHO_T}neither works" >&6
+	fi
+      fi
+      LIBS=$ac_xsave_LIBS
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn Johnson says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And Karl Berry says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char XOpenDisplay ();
+int
+main ()
+{
+XOpenDisplay ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6
+if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dnet_ntoa ();
+int
+main ()
+{
+dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dnet_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dnet_dnet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6
+if test $ac_cv_lib_dnet_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5
+echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6
+if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet_stub  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dnet_ntoa ();
+int
+main ()
+{
+dnet_ntoa ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dnet_stub_dnet_ntoa=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dnet_stub_dnet_ntoa=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6
+if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+fi
+
+    fi
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+    LIBS="$ac_xsave_LIBS"
+
+    # msh at cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to T.E. Dickey.
+    # The functions gethostbyname, getservbyname, and inet_addr are
+    # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+    echo "$as_me:$LINENO: checking for gethostbyname" >&5
+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
+if test "${ac_cv_func_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define gethostbyname innocuous_gethostbyname
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef gethostbyname
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+char (*f) () = gethostbyname;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gethostbyname;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+fi
+
+      if test $ac_cv_lib_nsl_gethostbyname = no; then
+	echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5
+echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6
+if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_bsd_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_bsd_gethostbyname=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6
+if test $ac_cv_lib_bsd_gethostbyname = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
+fi
+
+      fi
+    fi
+
+    # lieder at skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says Simon Leinen: it contains gethostby*
+    # variants that don't use the name server (or something).  -lsocket
+    # must be given before -lnsl if both are needed.  We assume that
+    # if connect needs -lnsl, so does gethostbyname.
+    echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define connect to an innocuous variant, in case <limits.h> declares connect.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define connect innocuous_connect
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef connect
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+
+    if test $ac_cv_func_connect = no; then
+      echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+int
+main ()
+{
+connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_connect=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+if test $ac_cv_lib_socket_connect = yes; then
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+fi
+
+    fi
+
+    # Guillermo Gomez says -lposix is necessary on A/UX.
+    echo "$as_me:$LINENO: checking for remove" >&5
+echo $ECHO_N "checking for remove... $ECHO_C" >&6
+if test "${ac_cv_func_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define remove to an innocuous variant, in case <limits.h> declares remove.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define remove innocuous_remove
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef remove
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char remove ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+char (*f) () = remove;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != remove;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_remove=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5
+echo "${ECHO_T}$ac_cv_func_remove" >&6
+
+    if test $ac_cv_func_remove = no; then
+      echo "$as_me:$LINENO: checking for remove in -lposix" >&5
+echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6
+if test "${ac_cv_lib_posix_remove+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char remove ();
+int
+main ()
+{
+remove ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_posix_remove=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_posix_remove=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5
+echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6
+if test $ac_cv_lib_posix_remove = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo "$as_me:$LINENO: checking for shmat" >&5
+echo $ECHO_N "checking for shmat... $ECHO_C" >&6
+if test "${ac_cv_func_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shmat to an innocuous variant, in case <limits.h> declares shmat.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shmat innocuous_shmat
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shmat
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shmat ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+char (*f) () = shmat;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shmat;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shmat=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5
+echo "${ECHO_T}$ac_cv_func_shmat" >&6
+
+    if test $ac_cv_func_shmat = no; then
+      echo "$as_me:$LINENO: checking for shmat in -lipc" >&5
+echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6
+if test "${ac_cv_lib_ipc_shmat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lipc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shmat ();
+int
+main ()
+{
+shmat ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ipc_shmat=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ipc_shmat=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5
+echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6
+if test $ac_cv_lib_ipc_shmat = yes; then
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS=$LDFLAGS
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  # John Interrante, Karl Berry
+  echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5
+echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6
+if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber ();
+int
+main ()
+{
+IceConnectionNumber ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ICE_IceConnectionNumber=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ICE_IceConnectionNumber=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6
+if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+fi
+
+  LDFLAGS=$ac_save_LDFLAGS
+
+fi
+
+
+echo
+
+# ----------------------------------------------------
+# Check for basic header files.
+# ----------------------------------------------------
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+for ac_header in malloc.h sys/file.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+echo
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+if test $ac_cv_c_bigendian = "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define BYTEORDER 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define BYTEORDER 0
+_ACEOF
+
+fi
+
+
+
+
+
+for ac_func in strtod
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval="$enable_largefile"
+
+fi;
+if test "$enable_largefile" != no; then
+
+  echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+     	 # IRIX 6.2 and later do not support large files by default,
+     	 # so use the C compiler's -n32 option if that helps.
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+     	 rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+     	 CC="$CC -n32"
+     	 rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_largefile_CC=' -n32'; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+	 break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  ac_cv_sys_file_offset_bits=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_file_offset_bits=64; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+
+fi
+rm -f conftest*
+  echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  ac_cv_sys_large_files=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_large_files=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+
+fi
+rm -f conftest*
+fi
+
+echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+echo $ECHO_N "checking for _LARGEFILE_SOURCE value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  ac_cv_sys_largefile_source=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+return !fseeko;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGEFILE_SOURCE 1
+#include <stdio.h>
+int
+main ()
+{
+return !fseeko;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sys_largefile_source=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6
+if test "$ac_cv_sys_largefile_source" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+
+fi
+rm -f conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+echo "$as_me:$LINENO: checking for fseeko" >&5
+echo $ECHO_N "checking for fseeko... $ECHO_C" >&6
+if test "${ac_cv_func_fseeko+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+return fseeko && fseeko (stdin, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_fseeko=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_fseeko=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_fseeko" >&5
+echo "${ECHO_T}$ac_cv_func_fseeko" >&6
+if test $ac_cv_func_fseeko = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FSEEKO 1
+_ACEOF
+
+fi
+
+
+# ----------------------------------------------------
+# Check for optional feature support
+# ----------------------------------------------------
+
+echo
+echo Checking for optional feature support
+echo ------------------------------------
+
+
+# ----------------------------------------------------
+# Set supplibs directory name
+# ----------------------------------------------------
+
+
+  echo "$as_me:$LINENO: checking for supplibs directory" >&5
+echo $ECHO_N "checking for supplibs directory... $ECHO_C" >&6
+  if test -n "${SUPPLIBS}" ; then
+    # Use present supplib name unmodified, assume it is absolute path
+    echo "$as_me:$LINENO: result: ${SUPPLIBS}" >&5
+echo "${ECHO_T}${SUPPLIBS}" >&6
+    # This is the "official" variable name for use by other macros
+    ga_supplib_dir="${SUPPLIBS}"
+  else
+    # Look for "supplibs" directory in ${top_builddir}
+    for ga_supplib_prefix in . .. ; do
+      SUPPLIBS="${ga_supplib_prefix}/supplibs"
+      if test -d "${SUPPLIBS}" ; then
+        echo "$as_me:$LINENO: result: ${SUPPLIBS}" >&5
+echo "${ECHO_T}${SUPPLIBS}" >&6
+        break
+      fi
+    done
+    if test ! -d "${SUPPLIBS}" ; then
+      echo "$as_me:$LINENO: result: not found" >&5
+echo "${ECHO_T}not found" >&6
+      SUPPLIBS=""
+    fi
+    # This is the "official" variable name for use by other macros
+    ga_supplib_dir=$SUPPLIBS
+    # Add prefix so that Makefiles in subdirectories can find it
+    SUPPLIBS='$(top_builddir)/'"$SUPPLIBS"
+  fi
+
+
+
+
+# Check whether --enable-dyn-supplibs or --disable-dyn-supplibs was given.
+if test "${enable_dyn_supplibs+set}" = set; then
+  enableval="$enable_dyn_supplibs"
+
+else
+  enableval=yes
+fi;
+case "${enableval}" in
+  yes)
+    ga_dyn_supplibs=yes
+  ;;
+  no)
+    ga_dyn_supplibs=no
+  ;;
+esac
+
+
+echo "$as_me:$LINENO: checking whether to use dynamic linking" >&5
+echo $ECHO_N "checking whether to use dynamic linking... $ECHO_C" >&6
+if test "$ga_dyn_supplibs" = "yes" ; then
+   echo "$as_me:$LINENO: result: yes (Warning: binaries may not be suitable for distribution)" >&5
+echo "${ECHO_T}yes (Warning: binaries may not be suitable for distribution)" >&6
+else
+   echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+
+
+
+# ----------------------------------------------------
+# Check for optional feature support
+# ----------------------------------------------------
+
+use_gui=no
+use_freq=no
+use_xaw_xlibs=no
+use_readline=no
+have_tiff=no
+use_geotiff=no
+have_zlib=no
+have_libpng=no
+have_jpeg=no
+use_printim=no
+use_grib2=no
+have_udunits=no
+use_hdf=no
+use_hdf5=no
+use_nc=no
+use_nc4=no
+use_dap=no
+use_gadap=no
+
+# look for libraries to support gui interface
+echo
+if test "$with_gui" != "no" ; then
+  echo "Checking for libraries to support GUI interface ..."
+
+  # Check libs and headers for GUI widgets
+  ga_check_gui="no"
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in X11/neXtaw libsx ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+  LDFLAGS="-L${ga_supplib_dir}/lib $X_LIBS"
+  LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+
+  echo "$as_me:$LINENO: checking for main in -lXext" >&5
+echo $ECHO_N "checking for main in -lXext... $ECHO_C" >&6
+if test "${ac_cv_lib_Xext_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXext  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xext_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xext_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xext_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xext_main" >&6
+if test $ac_cv_lib_Xext_main = yes; then
+  gui_libs_Xext="-lXext"
+fi
+
+  echo "$as_me:$LINENO: checking for main in -lXt" >&5
+echo $ECHO_N "checking for main in -lXt... $ECHO_C" >&6
+if test "${ac_cv_lib_Xt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xt_main" >&6
+if test $ac_cv_lib_Xt_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lXmu" >&5
+echo $ECHO_N "checking for main in -lXmu... $ECHO_C" >&6
+if test "${ac_cv_lib_Xmu_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXmu  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xmu_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xmu_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xmu_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xmu_main" >&6
+if test $ac_cv_lib_Xmu_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lXpm" >&5
+echo $ECHO_N "checking for main in -lXpm... $ECHO_C" >&6
+if test "${ac_cv_lib_Xpm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXpm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xpm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xpm_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xpm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xpm_main" >&6
+if test $ac_cv_lib_Xpm_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lXaw" >&5
+echo $ECHO_N "checking for main in -lXaw... $ECHO_C" >&6
+if test "${ac_cv_lib_Xaw_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXaw  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xaw_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xaw_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xaw_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xaw_main" >&6
+if test $ac_cv_lib_Xaw_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lsx" >&5
+echo $ECHO_N "checking for main in -lsx... $ECHO_C" >&6
+if test "${ac_cv_lib_sx_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsx  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sx_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sx_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sx_main" >&5
+echo "${ECHO_T}$ac_cv_lib_sx_main" >&6
+if test $ac_cv_lib_sx_main = yes; then
+   ga_check_gui="yes"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+  if test $ga_check_gui = "yes" ; then
+
+    use_gui=yes
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in sx ; do
+      gui_libs="$gui_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+    if test z"$gui_libs_Xext" != 'z'; then
+      gui_libs="$gui_libs -lXext"
+    fi
+    gui_libs="$gui_libs -lXaw -lXpm -lXmu -lXt"
+
+    true #dummy command
+  else
+
+    true #dummy command
+  fi
+
+
+  if test $use_gui != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+
+if test -n "$PKG_CONFIG"; then
+  echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
+echo "${ECHO_T}$PKG_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+
+if test -n "$ac_pt_PKG_CONFIG"; then
+  echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5
+echo "${ECHO_T}$ac_pt_PKG_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  PKG_CONFIG=$ac_pt_PKG_CONFIG
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5
+echo $ECHO_N "checking pkg-config is at least version $_pkg_min_version... $ECHO_C" >&6
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+	else
+		echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+		PKG_CONFIG=""
+	fi
+
+fi
+
+# Check libs and headers for GUI widgets
+  GA_LIBSX_LIBS=
+  ac_save_LDFLAGS=$LDFLAGS
+  ac_save_LIBS=$LIBS
+  ac_save_CFLAGS=$CFLAGS
+
+
+
+
+  XAW_LIBS=
+  XAW_XLIBS=
+  XAW_CFLAGS=
+  ac_pkgconfig_xaw=no
+
+  ac_pkgconfig_xaw7=yes
+
+pkg_failed=no
+echo "$as_me:$LINENO: checking for XAW7" >&5
+echo $ECHO_N "checking for XAW7... $ECHO_C" >&6
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$XAW7_CFLAGS"; then
+        pkg_cv_XAW7_CFLAGS="$XAW7_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"xaw7\"") >&5
+  ($PKG_CONFIG --exists --print-errors "xaw7") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_XAW7_CFLAGS=`$PKG_CONFIG --cflags "xaw7" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$XAW7_LIBS"; then
+        pkg_cv_XAW7_LIBS="$XAW7_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"xaw7\"") >&5
+  ($PKG_CONFIG --exists --print-errors "xaw7") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_XAW7_LIBS=`$PKG_CONFIG --libs "xaw7" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        XAW7_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "xaw7"`
+        else
+	        XAW7_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "xaw7"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$XAW7_PKG_ERRORS" >&5
+
+	echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+                ac_pkgconfig_xaw7=no
+elif test $pkg_failed = untried; then
+	ac_pkgconfig_xaw7=no
+else
+	XAW7_CFLAGS=$pkg_cv_XAW7_CFLAGS
+	XAW7_LIBS=$pkg_cv_XAW7_LIBS
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+	:
+fi
+  ac_save_LDFLAGS=$LDFLAGS
+  ac_save_LIBS=$LIBS
+  ac_save_CFLAGS=$CFLAGS
+  LDFLAGS="$LDFLAGS $X_LIBS"
+  LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+  CFLAGS="$CFLAGS $X_CFLAGS"
+  ga_xaw_flag=''
+  ga_xaw_libs='-lXmu -lXt'
+  echo "$as_me:$LINENO: checking for main in -lXt" >&5
+echo $ECHO_N "checking for main in -lXt... $ECHO_C" >&6
+if test "${ac_cv_lib_Xt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xt_main" >&6
+if test $ac_cv_lib_Xt_main = yes; then
+
+    echo "$as_me:$LINENO: checking for main in -lXmu" >&5
+echo $ECHO_N "checking for main in -lXmu... $ECHO_C" >&6
+if test "${ac_cv_lib_Xmu_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXmu  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xmu_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xmu_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xmu_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xmu_main" >&6
+if test $ac_cv_lib_Xmu_main = yes; then
+
+      # we add Xext if found. Not sure which platform needs it
+      echo "$as_me:$LINENO: checking for main in -lXext" >&5
+echo $ECHO_N "checking for main in -lXext... $ECHO_C" >&6
+if test "${ac_cv_lib_Xext_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXext  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xext_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xext_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xext_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xext_main" >&6
+if test $ac_cv_lib_Xext_main = yes; then
+
+         ga_xaw_libs="$ga_xaw_libs -lXext"
+
+fi
+
+      # we add Xpm if found, and we don't check for neXtaw if no Xpm
+      echo "$as_me:$LINENO: checking for main in -lXpm" >&5
+echo $ECHO_N "checking for main in -lXpm... $ECHO_C" >&6
+if test "${ac_cv_lib_Xpm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXpm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xpm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xpm_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xpm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xpm_main" >&6
+if test $ac_cv_lib_Xpm_main = yes; then
+
+        ga_xaw_libs="$ga_xaw_libs -lXpm"
+        echo "$as_me:$LINENO: checking for main in -lneXtaw" >&5
+echo $ECHO_N "checking for main in -lneXtaw... $ECHO_C" >&6
+if test "${ac_cv_lib_neXtaw_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lneXtaw  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_neXtaw_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_neXtaw_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_neXtaw_main" >&5
+echo "${ECHO_T}$ac_cv_lib_neXtaw_main" >&6
+if test $ac_cv_lib_neXtaw_main = yes; then
+   ga_xaw_flag='-lneXtaw'
+fi
+
+
+fi
+
+      if test z"$ga_xaw_flag" = 'z'; then
+        echo "$as_me:$LINENO: checking for main in -lXaw3d" >&5
+echo $ECHO_N "checking for main in -lXaw3d... $ECHO_C" >&6
+if test "${ac_cv_lib_Xaw3d_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXaw3d  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xaw3d_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xaw3d_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xaw3d_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xaw3d_main" >&6
+if test $ac_cv_lib_Xaw3d_main = yes; then
+    ga_xaw_flag='-lXaw3d'
+fi
+
+      fi
+      if test z"$ga_xaw_flag" = 'z'; then
+        if test $ac_pkgconfig_xaw7 = 'yes'; then
+          ac_pkgconfig_xaw=xaw7
+          ga_use_xaw=yes
+          XAW_LIBS=$XAW7_LIBS
+          XAW_CFLAGS=$XAW7_CFLAGS
+          XAW_XLIBS=
+        else
+          echo "$as_me:$LINENO: checking for main in -lXaw" >&5
+echo $ECHO_N "checking for main in -lXaw... $ECHO_C" >&6
+if test "${ac_cv_lib_Xaw_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXaw $ga_xaw_libs $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_Xaw_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_Xaw_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_Xaw_main" >&5
+echo "${ECHO_T}$ac_cv_lib_Xaw_main" >&6
+if test $ac_cv_lib_Xaw_main = yes; then
+    ga_xaw_flag='-lXaw'
+fi
+
+        fi
+      fi
+      if test z"$ga_xaw_flag" != 'z'; then
+        XAW_LIBS="$ga_xaw_flag $ga_xaw_libs"
+        XAW_XLIBS="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+        ga_use_xaw=yes
+      fi
+
+
+fi
+
+
+fi
+
+
+  CFLAGS=$ac_save_CFLAGS
+  LIBS=$ac_save_LIBS
+  LDFLAGS=$ac_save_LDFLAGS
+  if test "z$ga_use_xaw" = "zyes"; then
+     ga_xaw_found='yes'
+  else
+     ga_xaw_found='no'
+  fi
+
+
+
+
+
+  LDFLAGS="$LDFLAGS -L$ga_supplib_dir/lib $X_LIBS"
+  CFLAGS="$CFLAGS -I$ga_supplib_dir/include/libsx"
+  ga_use_libsx='no'
+  ga_libsx_header='no'
+  ga_libsx_freq_header='no'
+
+  if test "z$ga_xaw_found" = "zyes"; then
+    LIBS="$LIBS $XAW_LIBS $XAW_XLIBS"
+    CFLAGS="$CFLAGS $X_CFLAGS $XAW_CFLAGS"
+
+    if test "${ac_cv_header_libsx_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for libsx.h" >&5
+echo $ECHO_N "checking for libsx.h... $ECHO_C" >&6
+if test "${ac_cv_header_libsx_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libsx_h" >&5
+echo "${ECHO_T}$ac_cv_header_libsx_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking libsx.h usability" >&5
+echo $ECHO_N "checking libsx.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <libsx.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking libsx.h presence" >&5
+echo $ECHO_N "checking libsx.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <libsx.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: libsx.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libsx.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libsx.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: libsx.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libsx.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libsx.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libsx.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libsx.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libsx.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libsx.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libsx.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for libsx.h" >&5
+echo $ECHO_N "checking for libsx.h... $ECHO_C" >&6
+if test "${ac_cv_header_libsx_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_libsx_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_libsx_h" >&5
+echo "${ECHO_T}$ac_cv_header_libsx_h" >&6
+
+fi
+if test $ac_cv_header_libsx_h = yes; then
+   if test "${ac_cv_header_freq_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for freq.h" >&5
+echo $ECHO_N "checking for freq.h... $ECHO_C" >&6
+if test "${ac_cv_header_freq_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_freq_h" >&5
+echo "${ECHO_T}$ac_cv_header_freq_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking freq.h usability" >&5
+echo $ECHO_N "checking freq.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <freq.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking freq.h presence" >&5
+echo $ECHO_N "checking freq.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <freq.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: freq.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: freq.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: freq.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: freq.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: freq.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: freq.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: freq.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: freq.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: freq.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: freq.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: freq.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for freq.h" >&5
+echo $ECHO_N "checking for freq.h... $ECHO_C" >&6
+if test "${ac_cv_header_freq_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_freq_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_freq_h" >&5
+echo "${ECHO_T}$ac_cv_header_freq_h" >&6
+
+fi
+if test $ac_cv_header_freq_h = yes; then
+
+         ga_libsx_freq_header='yes'
+
+fi
+
+
+      ga_libsx_header='yes'
+
+fi
+
+
+
+    if test "z$ga_libsx_header" = "zyes"; then
+      if test "z$ga_libsx_freq_header" = "zyes"; then
+        echo "$as_me:$LINENO: checking for main in -lfreq" >&5
+echo $ECHO_N "checking for main in -lfreq... $ECHO_C" >&6
+if test "${ac_cv_lib_freq_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfreq  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_freq_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_freq_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_freq_main" >&5
+echo "${ECHO_T}$ac_cv_lib_freq_main" >&6
+if test $ac_cv_lib_freq_main = yes; then
+   echo "$as_me:$LINENO: checking for GetFile in -lsx" >&5
+echo $ECHO_N "checking for GetFile in -lsx... $ECHO_C" >&6
+if test "${ac_cv_lib_sx_GetFile+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsx  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char GetFile ();
+int
+main ()
+{
+GetFile ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sx_GetFile=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sx_GetFile=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sx_GetFile" >&5
+echo "${ECHO_T}$ac_cv_lib_sx_GetFile" >&6
+if test $ac_cv_lib_sx_GetFile = yes; then
+   ga_use_libsx='freq'
+            GA_LIBSX_LIBS="-lsx -lfreq $XAW_LIBS"
+
+fi
+
+
+fi
+
+      fi
+      if test "z$ga_use_libsx" = "zno"; then
+         echo "$as_me:$LINENO: checking for GetFile in -lsx" >&5
+echo $ECHO_N "checking for GetFile in -lsx... $ECHO_C" >&6
+if test "${ac_cv_lib_sx_GetFile+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsx  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char GetFile ();
+int
+main ()
+{
+GetFile ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sx_GetFile=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sx_GetFile=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sx_GetFile" >&5
+echo "${ECHO_T}$ac_cv_lib_sx_GetFile" >&6
+if test $ac_cv_lib_sx_GetFile = yes; then
+    ga_use_libsx='yes'
+            GA_LIBSX_LIBS="-lsx $XAW_LIBS"
+
+fi
+
+      fi
+      if test "z$ga_use_libsx" != "zno"; then
+
+for ac_func in SimpleGetFile
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+         ga_getfile_short_prototype=no
+         echo "$as_me:$LINENO: checking if GetFile has a short prototype" >&5
+echo $ECHO_N "checking if GetFile has a short prototype... $ECHO_C" >&6
+         ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+         if test "z$ga_use_libsx" = "zfreq"; then
+            cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <libsx.h>
+#include <freq.h>
+int
+main ()
+{
+GetFile("/path/to/file")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ga_getfile_short_prototype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+         else
+            cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <libsx.h>
+int
+main ()
+{
+GetFile("/path/to/file")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ga_getfile_short_prototype=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+         fi
+         if test $ga_getfile_short_prototype = 'yes'; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GETFILE_SHORT_PROTOTYPE
+_ACEOF
+
+           echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+         else
+           echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+         fi
+         ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+      fi
+    fi
+  fi
+
+  if test "z$ga_use_libsx" = "zfreq" ; then
+      use_gui=yes;use_freq=yes
+  else
+      if test "z$ga_use_libsx" = "zyes" ; then
+         use_gui=yes;use_freq=no
+      else
+         :
+      fi
+  fi
+
+  CFLAGS=$ac_save_CFLAGS
+  LIBS=$ac_save_LIBS
+  LDFLAGS=$ac_save_LDFLAGS
+
+    gui_libs="$GA_LIBSX_LIBS"
+    grads_xlibs="$XAW_XLIBS"
+    use_xaw_xlibs=yes
+  fi
+fi
+if test $use_gui = "yes" ; then
+# if the gui is built, we use the X flags from Xaw.
+  if test "$use_xaw_xlibs" != 'yes'; then
+    grads_xlibs="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+
+  fi
+  if test $use_freq = 'yes'; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USEFREQ 1
+_ACEOF
+
+  else
+
+cat >>confdefs.h <<\_ACEOF
+#define USEFREQ 0
+_ACEOF
+
+  fi
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in libsx ; do
+      gui_inc="$gui_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USEGUI 1
+_ACEOF
+
+  echo "+ GUI enabled"
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define USEGUI 0
+_ACEOF
+
+  echo  "- GUI disabled"
+fi
+
+# look for libraries to support command line editing
+echo
+if test "$with_readline" != "no" ; then
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support command line editing ..."
+    readline_libadd=""
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in " " readline ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+    if test "${ac_cv_header_readline_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for readline.h" >&5
+echo $ECHO_N "checking for readline.h... $ECHO_C" >&6
+if test "${ac_cv_header_readline_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5
+echo "${ECHO_T}$ac_cv_header_readline_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking readline.h usability" >&5
+echo $ECHO_N "checking readline.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <readline.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking readline.h presence" >&5
+echo $ECHO_N "checking readline.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <readline.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: readline.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: readline.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: readline.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: readline.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: readline.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: readline.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: readline.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: readline.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: readline.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for readline.h" >&5
+echo $ECHO_N "checking for readline.h... $ECHO_C" >&6
+if test "${ac_cv_header_readline_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_readline_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_readline_h" >&5
+echo "${ECHO_T}$ac_cv_header_readline_h" >&6
+
+fi
+if test $ac_cv_header_readline_h = yes; then
+   if test "${ac_cv_header_history_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for history.h" >&5
+echo $ECHO_N "checking for history.h... $ECHO_C" >&6
+if test "${ac_cv_header_history_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_history_h" >&5
+echo "${ECHO_T}$ac_cv_header_history_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking history.h usability" >&5
+echo $ECHO_N "checking history.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <history.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking history.h presence" >&5
+echo $ECHO_N "checking history.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <history.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: history.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: history.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: history.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: history.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: history.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: history.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: history.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: history.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: history.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: history.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: history.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for history.h" >&5
+echo $ECHO_N "checking for history.h... $ECHO_C" >&6
+if test "${ac_cv_header_history_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_history_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_history_h" >&5
+echo "${ECHO_T}$ac_cv_header_history_h" >&6
+
+fi
+if test $ac_cv_header_history_h = yes; then
+   echo "$as_me:$LINENO: checking for tgetent in -lreadline" >&5
+echo $ECHO_N "checking for tgetent in -lreadline... $ECHO_C" >&6
+if test "${ac_cv_lib_readline_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_readline_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_readline_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_tgetent" >&6
+if test $ac_cv_lib_readline_tgetent = yes; then
+   use_readline=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in "" ; do
+      readline_inc="$readline_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in readline ; do
+      readline_libs="$readline_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+else
+   echo "$as_me:$LINENO: checking for tgetent in -lncurses" >&5
+echo $ECHO_N "checking for tgetent in -lncurses... $ECHO_C" >&6
+if test "${ac_cv_lib_ncurses_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ncurses_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ncurses_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_tgetent" >&6
+if test $ac_cv_lib_ncurses_tgetent = yes; then
+   use_readline=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in "" ; do
+      readline_inc="$readline_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in readline ncurses ; do
+      readline_libs="$readline_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+else
+   echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_termcap_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+   use_readline=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in "" ; do
+      readline_inc="$readline_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in readline ; do
+      readline_libs="$readline_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+              readline_libadd=" -ltermcap"
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+  fi
+  if test $use_readline = "yes" ; then
+    readline_libs="$readline_libs $readline_libadd"
+  else
+    if test "$ga_dyn_supplibs" = "yes" ; then
+      echo
+      echo "Checking in system locations for libraries to support command line editing ..."
+
+  echo "$as_me:$LINENO: checking for a readline compatible library" >&5
+echo $ECHO_N "checking for a readline compatible library... $ECHO_C" >&6
+if test "${vl_cv_lib_readline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    ORIG_LIBS="$LIBS"
+    for readline_lib in readline edit editline; do
+      for termcap_lib in "" termcap curses ncurses; do
+        if test -z "$termcap_lib"; then
+          TRY_LIB="-l$readline_lib"
+        else
+          TRY_LIB="-l$readline_lib -l$termcap_lib"
+        fi
+        LIBS="$ORIG_LIBS $TRY_LIB"
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char readline ();
+int
+main ()
+{
+readline ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  vl_cv_lib_readline="$TRY_LIB"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+        if test -n "$vl_cv_lib_readline"; then
+          break
+        fi
+      done
+      if test -n "$vl_cv_lib_readline"; then
+        break
+      fi
+    done
+    if test -z "$vl_cv_lib_readline"; then
+      vl_cv_lib_readline="no"
+      LIBS="$ORIG_LIBS"
+    fi
+
+fi
+echo "$as_me:$LINENO: result: $vl_cv_lib_readline" >&5
+echo "${ECHO_T}$vl_cv_lib_readline" >&6
+
+  if test "$vl_cv_lib_readline" != "no"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+
+
+for ac_header in readline.h readline/readline.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+    echo "$as_me:$LINENO: checking whether readline supports history" >&5
+echo $ECHO_N "checking whether readline supports history... $ECHO_C" >&6
+if test "${vl_cv_lib_readline_history+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+      vl_cv_lib_readline_history="no"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char add_history ();
+int
+main ()
+{
+add_history ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  vl_cv_lib_readline_history="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $vl_cv_lib_readline_history" >&5
+echo "${ECHO_T}$vl_cv_lib_readline_history" >&6
+    if test "$vl_cv_lib_readline_history" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_READLINE_HISTORY 1
+_ACEOF
+
+
+
+for ac_header in history.h readline/history.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+      use_readline=yes readline_libs=""
+    else
+      :
+    fi
+  fi
+
+    fi
+  fi
+fi
+if test $use_readline = "yes" ; then
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define READLINE 1
+_ACEOF
+
+  echo "+ Command line editing enabled"
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define READLINE 0
+_ACEOF
+
+  echo "- Command line editing disabled"
+fi
+
+# look for libraries to support geotiff
+echo
+if test "$with_geotiff" != "no" ; then
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support geotiff ..."
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in tiff ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+
+for ac_header in tiff.h tiffio.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for main in -ltiff" >&5
+echo $ECHO_N "checking for main in -ltiff... $ECHO_C" >&6
+if test "${ac_cv_lib_tiff_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_tiff_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_tiff_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_tiff_main" >&5
+echo "${ECHO_T}$ac_cv_lib_tiff_main" >&6
+if test $ac_cv_lib_tiff_main = yes; then
+   have_tiff=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    if test "$have_tiff" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in geotiff ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      if test "${ac_cv_header_geotiffio_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for geotiffio.h" >&5
+echo $ECHO_N "checking for geotiffio.h... $ECHO_C" >&6
+if test "${ac_cv_header_geotiffio_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_geotiffio_h" >&5
+echo "${ECHO_T}$ac_cv_header_geotiffio_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking geotiffio.h usability" >&5
+echo $ECHO_N "checking geotiffio.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <geotiffio.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking geotiffio.h presence" >&5
+echo $ECHO_N "checking geotiffio.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <geotiffio.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: geotiffio.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: geotiffio.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: geotiffio.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: geotiffio.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: geotiffio.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: geotiffio.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: geotiffio.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: geotiffio.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: geotiffio.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for geotiffio.h" >&5
+echo $ECHO_N "checking for geotiffio.h... $ECHO_C" >&6
+if test "${ac_cv_header_geotiffio_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_geotiffio_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_geotiffio_h" >&5
+echo "${ECHO_T}$ac_cv_header_geotiffio_h" >&6
+
+fi
+if test $ac_cv_header_geotiffio_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lgeotiff" >&5
+echo $ECHO_N "checking for main in -lgeotiff... $ECHO_C" >&6
+if test "${ac_cv_lib_geotiff_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgeotiff  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_geotiff_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_geotiff_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_geotiff_main" >&5
+echo "${ECHO_T}$ac_cv_lib_geotiff_main" >&6
+if test $ac_cv_lib_geotiff_main = yes; then
+   use_geotiff=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in tiff geotiff ; do
+      geotiff_inc="$geotiff_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in tiff geotiff ; do
+      geotiff_libs="$geotiff_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for geotiff
+  if test "$use_geotiff" != "yes"  -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support geotiff ..."
+
+
+# Check whether --with-geotiff or --without-geotiff was given.
+if test "${with_geotiff+set}" = set; then
+  withval="$with_geotiff"
+  GEOTIFF_PATH=$withval
+else
+  GEOTIFF_PATH=""
+fi;
+
+
+# Check whether --with-geotiff_include or --without-geotiff_include was given.
+if test "${with_geotiff_include+set}" = set; then
+  withval="$with_geotiff_include"
+  GEOTIFF_PATH_INC=$withval
+else
+  GEOTIFF_PATH_INC=""
+fi;
+
+
+# Check whether --with-geotiff_libdir or --without-geotiff_libdir was given.
+if test "${with_geotiff_libdir+set}" = set; then
+  withval="$with_geotiff_libdir"
+  GEOTIFF_PATH_LIBDIR=$withval
+else
+  GEOTIFF_PATH_LIBDIR=""
+fi;
+
+
+  if test "z$GEOTIFF_PATH" != "z"; then
+
+    if test "z$GEOTIFF_PATH_LIBDIR" = "z"; then
+  GEOTIFF_PATH_LIBDIR="$GEOTIFF_PATH/lib"
+fi
+
+    if test "z$GEOTIFF_PATH_INC" = "z"; then
+  GEOTIFF_PATH_INC="$GEOTIFF_PATH/include"
+fi
+
+
+fi
+
+
+
+  ac_geotiff_lib_ok='no'
+  ac_geotiff_save_LDFLAGS=$LDFLAGS
+  GEOTIFF_LIBS=
+  if test -d "$GEOTIFF_PATH_LIBDIR"; then
+
+      GEOTIFF_LDFLAGS="-L$GEOTIFF_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS"
+
+  GEOTIFF_LIBS=
+  ac_geotiff_lib='no'
+  ac_geotiff_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_tiff_main='no'
+  ac_check_lib_nocache_tiff_main_LIBS=$LIBS
+  LIBS="-ltiff  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -ltiff" >&5
+echo $ECHO_N "checking for main in -ltiff... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_tiff_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_tiff_main_LIBS
+  if test $ac_check_lib_nocache_ok_tiff_main = 'yes'; then
+
+  ac_check_lib_nocache_ok_geotiff_main='no'
+  ac_check_lib_nocache_geotiff_main_LIBS=$LIBS
+  LIBS="-lgeotiff -ltiff $LIBS"
+  echo "$as_me:$LINENO: checking for main in -lgeotiff" >&5
+echo $ECHO_N "checking for main in -lgeotiff... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_geotiff_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_geotiff_main_LIBS
+  if test $ac_check_lib_nocache_ok_geotiff_main = 'yes'; then
+   ac_geotiff_lib="yes"
+      GEOTIFF_LIBS="-lgeotiff -ltiff $GEOTIFF_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_geotiff_save_LIBS
+
+  if test "$ac_geotiff_lib" = 'yes'; then
+  ac_geotiff_lib_ok='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_geotiff_libdir in "" /usr/geotiff/lib64 /usr/local/lib64/geotiff \
+       /usr/libgeotiff/lib64 /usr/local/lib64/libgeotiff \
+       /opt/lib64/geotiff /opt/lib64/libgeotiff \
+       /opt/geotiff/lib64 /usr/lib64/geotiff /usr/local/geotiff/lib64 \
+       /opt/libgeotiff/lib64 /usr/lib64/libgeotiff /usr/local/libgeotiff/lib64 \
+       /usr/local/geotiff/lib /opt/geotiff/lib \
+       /usr/local/libgeotiff/lib /opt/libgeotiff/lib \
+       /usr/geotiff/lib /usr/local/lib/geotiff /opt/lib/geotiff \
+       /usr/libgeotiff/lib /usr/local/lib/libgeotiff /opt/lib/libgeotiff \
+       /usr/lib/geotiff /usr/lib/libgeotiff ; do
+        if test ! -d "$ac_geotiff_libdir"; then
+  GEOTIFF_LDFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching geotiff libraries in $ac_geotiff_libdir" >&5
+echo "$as_me: searching geotiff libraries in $ac_geotiff_libdir" >&6;}
+             GEOTIFF_LDFLAGS="-L$ac_geotiff_libdir"
+
+fi
+
+        LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS"
+
+  GEOTIFF_LIBS=
+  ac_geotiff_lib='no'
+  ac_geotiff_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_tiff_main='no'
+  ac_check_lib_nocache_tiff_main_LIBS=$LIBS
+  LIBS="-ltiff  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -ltiff" >&5
+echo $ECHO_N "checking for main in -ltiff... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_tiff_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_tiff_main_LIBS
+  if test $ac_check_lib_nocache_ok_tiff_main = 'yes'; then
+
+  ac_check_lib_nocache_ok_geotiff_main='no'
+  ac_check_lib_nocache_geotiff_main_LIBS=$LIBS
+  LIBS="-lgeotiff -ltiff $LIBS"
+  echo "$as_me:$LINENO: checking for main in -lgeotiff" >&5
+echo $ECHO_N "checking for main in -lgeotiff... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_geotiff_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_geotiff_main_LIBS
+  if test $ac_check_lib_nocache_ok_geotiff_main = 'yes'; then
+   ac_geotiff_lib="yes"
+      GEOTIFF_LIBS="-lgeotiff -ltiff $GEOTIFF_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_geotiff_save_LIBS
+
+  if test "$ac_geotiff_lib" = 'yes'; then
+  ac_geotiff_lib_ok='yes'
+else
+  :
+fi
+
+
+        if test $ac_geotiff_lib_ok = 'yes'; then
+  break
+fi
+
+        LDFLAGS=$ac_geotiff_save_LDFLAGS
+      done
+
+fi
+
+  LDFLAGS=$ac_geotiff_save_LDFLAGS
+
+  ac_geotiff_h='no'
+  GEOTIFF_CFLAGS=
+  ac_geotiff_save_CPPFLAGS=$CPPFLAGS
+  if test -d "$GEOTIFF_PATH_INC"; then
+
+       GEOTIFF_CFLAGS="-I$GEOTIFF_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $GEOTIFF_CFLAGS"
+
+  ac_check_header_nocache_compile_geotiffio_h='no'
+  ac_check_header_nocache_preproc_geotiffio_h='no'
+  echo "$as_me:$LINENO: checking for geotiffio.h with compiler" >&5
+echo $ECHO_N "checking for geotiffio.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <geotiffio.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_geotiffio_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  echo "$as_me:$LINENO: checking for geotiffio.h with preprocessor" >&5
+echo $ECHO_N "checking for geotiffio.h with preprocessor... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <geotiffio.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_preproc_geotiffio_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      if test "$ac_check_header_nocache_compile_geotiffio_h" = 'yes'; then
+  { echo "$as_me:$LINENO: WARNING: trusting compiler result, ignoring preprocessor error" >&5
+echo "$as_me: WARNING: trusting compiler result, ignoring preprocessor error" >&2;}
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_geotiffio_h" = 'yes'; then
+  ac_geotiff_h='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_geotiff_incdir in /usr/include \
+       /usr/local/geotiff/include /opt/geotiff/include \
+       /usr/geotiff/include /usr/local/include/geotiff \
+       /opt/include/geotiff /usr/include/geotiff /usr/local/libgeotiff/include \
+       /opt/libgeotiff/include /usr/libgeotiff/include /usr/local/include/libgeotiff \
+       /opt/include/libgeotiff /usr/include/libgeotiff ; do
+        if test ! -d "$ac_geotiff_incdir"; then
+  GEOTIFF_CFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching geotiff includes in $ac_geotiff_incdir" >&5
+echo "$as_me: searching geotiff includes in $ac_geotiff_incdir" >&6;}
+             GEOTIFF_CFLAGS="-I$ac_geotiff_incdir"
+             CPPFLAGS="$CPPFLAGS $GEOTIFF_CFLAGS"
+
+  ac_check_header_nocache_compile_geotiffio_h='no'
+  ac_check_header_nocache_preproc_geotiffio_h='no'
+  echo "$as_me:$LINENO: checking for geotiffio.h with compiler" >&5
+echo $ECHO_N "checking for geotiffio.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <geotiffio.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_geotiffio_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  echo "$as_me:$LINENO: checking for geotiffio.h with preprocessor" >&5
+echo $ECHO_N "checking for geotiffio.h with preprocessor... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <geotiffio.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_preproc_geotiffio_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      if test "$ac_check_header_nocache_compile_geotiffio_h" = 'yes'; then
+  { echo "$as_me:$LINENO: WARNING: trusting compiler result, ignoring preprocessor error" >&5
+echo "$as_me: WARNING: trusting compiler result, ignoring preprocessor error" >&2;}
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_geotiffio_h" = 'yes'; then
+  ac_geotiff_h='yes'
+else
+  :
+fi
+
+
+             if test $ac_geotiff_h = 'yes'; then
+  break
+fi
+
+             CPPFLAGS=$ac_geotiff_save_CPPFLAGS
+
+fi
+
+      done
+
+fi
+
+  CPPFLAGS=$ac_geotiff_save_CPPFLAGS
+
+  if test "$ac_geotiff_h" = 'yes' -a "$ac_geotiff_lib_ok" = 'yes'; then
+
+      LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS"
+      geotiff_libs="$GEOTIFF_LIBS"
+      geotiff_inc=$GEOTIFF_CFLAGS
+      use_geotiff='yes'
+
+else
+  :
+fi
+
+
+
+
+
+
+  fi
+fi
+if test "$use_geotiff" != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GEOTIFF 0
+_ACEOF
+
+  echo "- geotiff disabled"
+else
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define GEOTIFF 1
+_ACEOF
+
+  echo "+ geotiff enabled"
+fi
+
+# look for libraries to support shapefiles
+echo
+if test "$with_shp" != "no" ; then
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support shapefiles ..."
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in shapelib shp ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in shapefil.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for main in -lshp" >&5
+echo $ECHO_N "checking for main in -lshp... $ECHO_C" >&6
+if test "${ac_cv_lib_shp_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lshp  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_shp_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_shp_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_shp_main" >&5
+echo "${ECHO_T}$ac_cv_lib_shp_main" >&6
+if test $ac_cv_lib_shp_main = yes; then
+   use_shp=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in shapelib shp ; do
+      shp_inc="$shp_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in shp ; do
+      shp_libs="$shp_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+  fi
+  # here's where we could add a macro to look outside supplibs for shapelib
+fi
+if test "$use_shp" != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USESHP 0
+_ACEOF
+
+  echo "- shapefile disabled"
+else
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USESHP 1
+_ACEOF
+
+  echo "+ shapefile enabled"
+fi
+
+
+# look for libraries to support printim
+echo
+if test "$with_printim" != "no" ; then
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support printim ..."
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in zlib ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in zlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6
+if test $ac_cv_lib_z_compress = yes; then
+   have_zlib=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in libpng12 ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+    echo "$as_me:$LINENO: checking for main in -lpng12" >&5
+echo $ECHO_N "checking for main in -lpng12... $ECHO_C" >&6
+if test "${ac_cv_lib_png12_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng12  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png12_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png12_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png12_main" >&5
+echo "${ECHO_T}$ac_cv_lib_png12_main" >&6
+if test $ac_cv_lib_png12_main = yes; then
+   have_libpng=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+  :
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+    echo "$as_me:$LINENO: checking for main in -ljpeg" >&5
+echo $ECHO_N "checking for main in -ljpeg... $ECHO_C" >&6
+if test "${ac_cv_lib_jpeg_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jpeg_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jpeg_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_main" >&5
+echo "${ECHO_T}$ac_cv_lib_jpeg_main" >&6
+if test $ac_cv_lib_jpeg_main = yes; then
+   have_jpeg=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    if test "$have_zlib" = "yes" -a "$have_libpng" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in gd ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      if test "${ac_cv_header_gd_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gd.h usability" >&5
+echo $ECHO_N "checking gd.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gd.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gd.h presence" >&5
+echo $ECHO_N "checking gd.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gd.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: gd.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gd.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gd.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: gd.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: gd.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gd_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+
+fi
+if test $ac_cv_header_gd_h = yes; then
+   echo "$as_me:$LINENO: checking for gdImageCreate in -lgd" >&5
+echo $ECHO_N "checking for gdImageCreate in -lgd... $ECHO_C" >&6
+if test "${ac_cv_lib_gd_gdImageCreate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdImageCreate ();
+int
+main ()
+{
+gdImageCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gd_gdImageCreate=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gd_gdImageCreate=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gd_gdImageCreate" >&5
+echo "${ECHO_T}$ac_cv_lib_gd_gdImageCreate" >&6
+if test $ac_cv_lib_gd_gdImageCreate = yes; then
+   use_printim=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in gd ; do
+      printim_inc="$printim_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+	  if test "$have_jpeg" = "yes" ; then
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in gd png12 z jpeg ; do
+      printim_libs="$printim_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+	  else
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in gd png12 z ; do
+      printim_libs="$printim_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+          fi
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs
+  if test "$use_printim" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support printim ..."
+
+  ga_check_gd="no"
+  GD_LIBS=
+  GD_CFLAGS=
+  GD_LDFLAGS=
+
+  ga_pkgconfig_gd=yes
+
+pkg_failed=no
+echo "$as_me:$LINENO: checking for GD" >&5
+echo $ECHO_N "checking for GD... $ECHO_C" >&6
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GD_CFLAGS"; then
+        pkg_cv_GD_CFLAGS="$GD_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gdlib\"") >&5
+  ($PKG_CONFIG --exists --print-errors "gdlib") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_GD_CFLAGS=`$PKG_CONFIG --cflags "gdlib" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$GD_LIBS"; then
+        pkg_cv_GD_LIBS="$GD_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"gdlib\"") >&5
+  ($PKG_CONFIG --exists --print-errors "gdlib") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_GD_LIBS=`$PKG_CONFIG --libs "gdlib" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        GD_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "gdlib"`
+        else
+	        GD_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "gdlib"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$GD_PKG_ERRORS" >&5
+
+	echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+                ga_pkgconfig_gd=no
+elif test $pkg_failed = untried; then
+	ga_pkgconfig_gd=no
+else
+	GD_CFLAGS=$pkg_cv_GD_CFLAGS
+	GD_LIBS=$pkg_cv_GD_LIBS
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+	:
+fi
+  ac_save_LIBS="$LIBS"
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  ac_save_LDFLAGS="$LDFLAGS"
+
+  ga_config_gd=no
+  if test $ga_pkgconfig_gd != 'yes'; then
+    # Extract the first word of "gdlib-config", so it can be a program name with args.
+set dummy gdlib-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GD_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GD_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GD_CONFIG="$GD_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_GD_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_GD_CONFIG" && ac_cv_path_GD_CONFIG="no"
+  ;;
+esac
+fi
+GD_CONFIG=$ac_cv_path_GD_CONFIG
+
+if test -n "$GD_CONFIG"; then
+  echo "$as_me:$LINENO: result: $GD_CONFIG" >&5
+echo "${ECHO_T}$GD_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    if test "$GD_CONFIG" != "no"; then
+      GD_LIBS=`$GD_CONFIG --libs`
+      GD_CFLAGS=`$GD_CONFIG --cflags`
+      GD_LDFLAGS=`$GD_CONFIG --ldflags`
+      ga_config_gd=yes
+    fi
+  fi
+
+  if test $ga_pkgconfig_gd = 'yes' -o $ga_config_gd = 'yes'; then
+     LDFLAGS="$LDFLAGS $GD_LDFLAGS"
+     LIBS="$LIBS $GD_LIBS"
+     if test "${ac_cv_header_gd_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gd.h usability" >&5
+echo $ECHO_N "checking gd.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gd.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gd.h presence" >&5
+echo $ECHO_N "checking gd.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gd.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: gd.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gd.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gd.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: gd.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: gd.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gd_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+
+fi
+if test $ac_cv_header_gd_h = yes; then
+    echo "$as_me:$LINENO: checking for gdImageCreate in -lgd" >&5
+echo $ECHO_N "checking for gdImageCreate in -lgd... $ECHO_C" >&6
+if test "${ac_cv_lib_gd_gdImageCreate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdImageCreate ();
+int
+main ()
+{
+gdImageCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gd_gdImageCreate=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gd_gdImageCreate=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gd_gdImageCreate" >&5
+echo "${ECHO_T}$ac_cv_lib_gd_gdImageCreate" >&6
+if test $ac_cv_lib_gd_gdImageCreate = yes; then
+    ga_check_gd=yes
+           GD_LIBS="-lgd $GD_LIBS"
+
+for ac_func in gdCompareInt
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+else
+
+           GD_LDFLAGS=
+           GD_LIBS=
+           LIBS="$ac_save_LIBS"
+           LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+else
+
+       GD_CFLAGS=
+       CPPFLAGS="$ac_save_CPPFLAGS"
+
+fi
+
+
+  fi
+  if test $ga_check_gd = 'no'; then
+     if test "${ac_cv_header_gd_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gd.h usability" >&5
+echo $ECHO_N "checking gd.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gd.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gd.h presence" >&5
+echo $ECHO_N "checking gd.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gd.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gd.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: gd.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gd.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gd.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: gd.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: gd.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gd.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gd.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: gd.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gd.h" >&5
+echo $ECHO_N "checking for gd.h... $ECHO_C" >&6
+if test "${ac_cv_header_gd_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gd_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gd_h" >&5
+echo "${ECHO_T}$ac_cv_header_gd_h" >&6
+
+fi
+if test $ac_cv_header_gd_h = yes; then
+   echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6
+if test $ac_cv_lib_z_compress = yes; then
+   echo "$as_me:$LINENO: checking for main in -lpng" >&5
+echo $ECHO_N "checking for main in -lpng... $ECHO_C" >&6
+if test "${ac_cv_lib_png_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png_main" >&5
+echo "${ECHO_T}$ac_cv_lib_png_main" >&6
+if test $ac_cv_lib_png_main = yes; then
+   echo "$as_me:$LINENO: checking for gdImageCreate in -lgd" >&5
+echo $ECHO_N "checking for gdImageCreate in -lgd... $ECHO_C" >&6
+if test "${ac_cv_lib_gd_gdImageCreate+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgd  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdImageCreate ();
+int
+main ()
+{
+gdImageCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gd_gdImageCreate=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gd_gdImageCreate=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gd_gdImageCreate" >&5
+echo "${ECHO_T}$ac_cv_lib_gd_gdImageCreate" >&6
+if test $ac_cv_lib_gd_gdImageCreate = yes; then
+   ga_check_gd=yes
+
+for ac_func in gdCompareInt
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+              GD_LIBS='-lgd -lpng -lz'
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+  fi
+
+  LIBS="$ac_save_LIBS"
+  CPPFLAGS="$ac_save_CPPFLAGS"
+  LDFLAGS="$ac_save_LDFLAGS"
+
+  if test $ga_check_gd = 'yes'; then
+      use_printim=yes
+      printim_libs=$GD_LIBS
+      printim_inc=$GD_CFLAGS
+
+  else
+     :
+  fi
+
+
+
+
+
+  fi
+fi
+if test "$use_printim" != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GXPNG 0
+_ACEOF
+
+  echo "- printim disabled (Warning: gxtran will not be built)"
+else
+  extra_utils="$extra_utils gxtran"
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define GXPNG 1
+_ACEOF
+
+  echo "+ printim enabled"
+fi
+
+# look for libraries to support grib2
+echo
+if test "$with_grib2" != "no" ; then
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support grib2 ..."
+    if test "$have_zlib" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in zlib ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in zlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6
+if test $ac_cv_lib_z_compress = yes; then
+   have_zlib=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    if test "$have_libpng" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in libpng12 ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -lpng12" >&5
+echo $ECHO_N "checking for main in -lpng12... $ECHO_C" >&6
+if test "${ac_cv_lib_png12_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng12  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png12_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png12_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png12_main" >&5
+echo "${ECHO_T}$ac_cv_lib_png12_main" >&6
+if test $ac_cv_lib_png12_main = yes; then
+   have_libpng=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    if test "$have_zlib" = "yes" -a "$have_libpng" = "yes" ; then
+      have_libjasper=no
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+  :
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -ljasper" >&5
+echo $ECHO_N "checking for main in -ljasper... $ECHO_C" >&6
+if test "${ac_cv_lib_jasper_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljasper  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jasper_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jasper_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jasper_main" >&5
+echo "${ECHO_T}$ac_cv_lib_jasper_main" >&6
+if test $ac_cv_lib_jasper_main = yes; then
+   have_libjasper=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+      if test "$have_libjasper" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in grib2c ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+        if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for grib2.h" >&5
+echo $ECHO_N "checking for grib2.h... $ECHO_C" >&6
+if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_grib2_h" >&5
+echo "${ECHO_T}$ac_cv_header_grib2_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking grib2.h usability" >&5
+echo $ECHO_N "checking grib2.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <grib2.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking grib2.h presence" >&5
+echo $ECHO_N "checking grib2.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <grib2.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: grib2.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: grib2.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: grib2.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: grib2.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: grib2.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: grib2.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: grib2.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: grib2.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: grib2.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: grib2.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for grib2.h" >&5
+echo $ECHO_N "checking for grib2.h... $ECHO_C" >&6
+if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_grib2_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_grib2_h" >&5
+echo "${ECHO_T}$ac_cv_header_grib2_h" >&6
+
+fi
+if test $ac_cv_header_grib2_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lgrib2c" >&5
+echo $ECHO_N "checking for main in -lgrib2c... $ECHO_C" >&6
+if test "${ac_cv_lib_grib2c_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgrib2c  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_grib2c_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_grib2c_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_grib2c_main" >&5
+echo "${ECHO_T}$ac_cv_lib_grib2c_main" >&6
+if test $ac_cv_lib_grib2c_main = yes; then
+   use_grib2=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in grib2c ; do
+      grib2_inc="$grib2_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in grib2c jasper png12 z ; do
+      grib2_libs="$grib2_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+      fi
+    fi
+  fi
+    # if we haven't got what we need, look outside supplibs for grib2
+  if test "$use_grib2" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for grib2 libraries ..."
+
+  ga_check_grib2="no"
+  if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for grib2.h" >&5
+echo $ECHO_N "checking for grib2.h... $ECHO_C" >&6
+if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_grib2_h" >&5
+echo "${ECHO_T}$ac_cv_header_grib2_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking grib2.h usability" >&5
+echo $ECHO_N "checking grib2.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <grib2.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking grib2.h presence" >&5
+echo $ECHO_N "checking grib2.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <grib2.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: grib2.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: grib2.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: grib2.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: grib2.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: grib2.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: grib2.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: grib2.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: grib2.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: grib2.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: grib2.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: grib2.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for grib2.h" >&5
+echo $ECHO_N "checking for grib2.h... $ECHO_C" >&6
+if test "${ac_cv_header_grib2_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_grib2_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_grib2_h" >&5
+echo "${ECHO_T}$ac_cv_header_grib2_h" >&6
+
+fi
+if test $ac_cv_header_grib2_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lgrib2c" >&5
+echo $ECHO_N "checking for main in -lgrib2c... $ECHO_C" >&6
+if test "${ac_cv_lib_grib2c_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgrib2c  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_grib2c_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_grib2c_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_grib2c_main" >&5
+echo "${ECHO_T}$ac_cv_lib_grib2c_main" >&6
+if test $ac_cv_lib_grib2c_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lpng12" >&5
+echo $ECHO_N "checking for main in -lpng12... $ECHO_C" >&6
+if test "${ac_cv_lib_png12_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng12  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_png12_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_png12_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_png12_main" >&5
+echo "${ECHO_T}$ac_cv_lib_png12_main" >&6
+if test $ac_cv_lib_png12_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lz" >&5
+echo $ECHO_N "checking for main in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_main" >&5
+echo "${ECHO_T}$ac_cv_lib_z_main" >&6
+if test $ac_cv_lib_z_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -ljasper" >&5
+echo $ECHO_N "checking for main in -ljasper... $ECHO_C" >&6
+if test "${ac_cv_lib_jasper_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljasper  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jasper_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jasper_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jasper_main" >&5
+echo "${ECHO_T}$ac_cv_lib_jasper_main" >&6
+if test $ac_cv_lib_jasper_main = yes; then
+   ga_check_grib2="yes"
+            G2_LIBS='-lgrib2c -ljasper -lpng -lz'
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+  if test $ga_check_grib2 = "yes" ; then
+      use_grib2=yes
+      grib2_libs=$G2_LIBS
+
+  else
+     :
+  fi
+
+
+
+  fi
+fi
+if test "$use_grib2" != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GRIB2 0
+_ACEOF
+
+  echo "- grib2 disabled "
+else
+  extra_utils="$extra_utils grib2scan"
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define GRIB2 1
+_ACEOF
+
+  echo "+ grib2 enabled"
+fi
+
+# check if user wants support for self-describing files?
+echo
+if test "$with_sdf" = "no" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USENETCDF 0
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USEHDF 0
+_ACEOF
+
+  echo No support for self-describing files:
+  echo "- hdf4 disabled"
+  echo "- hdf5 disabled"
+  echo "- netcdf disabled"
+  echo "- OPeNDAP disabled"
+else
+  # look for libraries to support hdf4
+  # check if supplibs directory exists
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support hdf4 ..."
+    # look for zlib
+    if test "$have_zlib" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in zlib ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in zlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6
+if test $ac_cv_lib_z_compress = yes; then
+   have_zlib=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    # look for udunits
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in udunits ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in udunits.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+   have_udunits=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    # look for jpeg
+    if test "$have_jpeg" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+  :
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -ljpeg" >&5
+echo $ECHO_N "checking for main in -ljpeg... $ECHO_C" >&6
+if test "${ac_cv_lib_jpeg_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jpeg_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jpeg_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_main" >&5
+echo "${ECHO_T}$ac_cv_lib_jpeg_main" >&6
+if test $ac_cv_lib_jpeg_main = yes; then
+   have_jpeg=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    if test "$have_zlib" = "yes" -a "$have_udunits" = "yes" -a "$have_jpeg" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in hdf ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -lsz" >&5
+echo $ECHO_N "checking for main in -lsz... $ECHO_C" >&6
+if test "${ac_cv_lib_sz_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sz_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sz_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sz_main" >&5
+echo "${ECHO_T}$ac_cv_lib_sz_main" >&6
+if test $ac_cv_lib_sz_main = yes; then
+   if test "${ac_cv_header_mfhdf_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for mfhdf.h" >&5
+echo $ECHO_N "checking for mfhdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_mfhdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_mfhdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_mfhdf_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking mfhdf.h usability" >&5
+echo $ECHO_N "checking mfhdf.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <mfhdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking mfhdf.h presence" >&5
+echo $ECHO_N "checking mfhdf.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <mfhdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: mfhdf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: mfhdf.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: mfhdf.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: mfhdf.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: mfhdf.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: mfhdf.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: mfhdf.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: mfhdf.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: mfhdf.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for mfhdf.h" >&5
+echo $ECHO_N "checking for mfhdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_mfhdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_mfhdf_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_mfhdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_mfhdf_h" >&6
+
+fi
+if test $ac_cv_header_mfhdf_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -ldf" >&5
+echo $ECHO_N "checking for main in -ldf... $ECHO_C" >&6
+if test "${ac_cv_lib_df_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_df_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_df_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_df_main" >&5
+echo "${ECHO_T}$ac_cv_lib_df_main" >&6
+if test $ac_cv_lib_df_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lmfhdf" >&5
+echo $ECHO_N "checking for main in -lmfhdf... $ECHO_C" >&6
+if test "${ac_cv_lib_mfhdf_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmfhdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_mfhdf_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mfhdf_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mfhdf_main" >&5
+echo "${ECHO_T}$ac_cv_lib_mfhdf_main" >&6
+if test $ac_cv_lib_mfhdf_main = yes; then
+   use_hdf=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in hdf udunits ; do
+      hdf_inc="$hdf_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in mfhdf df udunits sz jpeg z ; do
+      hdf_libs="$hdf_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for hdf4
+  if test $use_hdf != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support hdf4 ..."
+
+  ga_use_udunits='no'
+  if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking udunits.h usability" >&5
+echo $ECHO_N "checking udunits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <udunits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking udunits.h presence" >&5
+echo $ECHO_N "checking udunits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <udunits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: udunits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: udunits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: udunits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: udunits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_udunits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+
+fi
+if test $ac_cv_header_udunits_h = yes; then
+    echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+    ga_use_udunits='yes'
+        UDUNITS_LIBS='-ludunits'
+
+fi
+
+
+fi
+
+
+
+  if test "z$ga_use_udunits" = "zyes" ; then
+
+  ac_hdf4_netcdf_lib='no'
+  ac_hdf4_sd_netcdf_lib='no'
+  ac_hdf4_netcdf_h='no'
+
+
+# Check whether --with-hdf4 or --without-hdf4 was given.
+if test "${with_hdf4+set}" = set; then
+  withval="$with_hdf4"
+  HDF4_PATH=$withval
+else
+  HDF4_PATH=""
+fi;
+
+
+# Check whether --with-hdf4_include or --without-hdf4_include was given.
+if test "${with_hdf4_include+set}" = set; then
+  withval="$with_hdf4_include"
+  HDF4_PATH_INC=$withval
+else
+  HDF4_PATH_INC=""
+fi;
+
+
+# Check whether --with-hdf4_libdir or --without-hdf4_libdir was given.
+if test "${with_hdf4_libdir+set}" = set; then
+  withval="$with_hdf4_libdir"
+  HDF4_PATH_LIBDIR=$withval
+else
+  HDF4_PATH_LIBDIR=""
+fi;
+
+
+  if test "z$HDF4_PATH" != "z"; then
+
+    if test "z$HDF4_PATH_LIBDIR" = "z"; then
+  HDF4_PATH_LIBDIR="$HDF4_PATH/lib"
+fi
+
+    if test "z$HDF4_PATH_INC" = "z"; then
+  HDF4_PATH_INC="$HDF4_PATH/include"
+fi
+
+
+fi
+
+
+
+  ac_hdf4_lib_ok='no'
+  ac_hdf4_save_LDFLAGS=$LDFLAGS
+  HDF4_LIBS=
+  if test "z$HDF4_PATH_LIBDIR" != "z"; then
+
+      HDF4_LDFLAGS="-L$HDF4_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+
+  HDF4_LIBS=
+  ac_hdf4_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress='no'
+  ac_check_lib_nocache_sz_SZ_BufftoBuffCompress_LIBS=$LIBS
+  LIBS="-lsz  $LIBS"
+  echo "$as_me:$LINENO: checking for SZ_BufftoBuffCompress in -lsz" >&5
+echo $ECHO_N "checking for SZ_BufftoBuffCompress in -lsz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SZ_BufftoBuffCompress ();
+int
+main ()
+{
+SZ_BufftoBuffCompress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_sz_SZ_BufftoBuffCompress_LIBS
+  if test $ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress = 'yes'; then
+
+      LIBS="$LIBS -lsz"
+      HDF4_LIBS='-lsz'
+
+else
+  :
+fi
+
+
+
+  ac_hdf4_lib='no'
+
+  ac_check_lib_nocache_ok_z_deflate='no'
+  ac_check_lib_nocache_z_deflate_LIBS=$LIBS
+  LIBS="-lz  $LIBS"
+  echo "$as_me:$LINENO: checking for deflate in -lz" >&5
+echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char deflate ();
+int
+main ()
+{
+deflate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_z_deflate='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_z_deflate_LIBS
+  if test $ac_check_lib_nocache_ok_z_deflate = 'yes'; then
+
+  ac_check_lib_nocache_ok_jpeg_jpeg_start_compress='no'
+  ac_check_lib_nocache_jpeg_jpeg_start_compress_LIBS=$LIBS
+  LIBS="-ljpeg  $LIBS"
+  echo "$as_me:$LINENO: checking for jpeg_start_compress in -ljpeg" >&5
+echo $ECHO_N "checking for jpeg_start_compress in -ljpeg... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char jpeg_start_compress ();
+int
+main ()
+{
+jpeg_start_compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_jpeg_jpeg_start_compress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_jpeg_jpeg_start_compress_LIBS
+  if test $ac_check_lib_nocache_ok_jpeg_jpeg_start_compress = 'yes'; then
+
+  ac_check_lib_nocache_ok_df_Hopen='no'
+  ac_check_lib_nocache_df_Hopen_LIBS=$LIBS
+  LIBS="-ldf -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for Hopen in -ldf" >&5
+echo $ECHO_N "checking for Hopen in -ldf... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char Hopen ();
+int
+main ()
+{
+Hopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_df_Hopen='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_df_Hopen_LIBS
+  if test $ac_check_lib_nocache_ok_df_Hopen = 'yes'; then
+
+  ac_check_lib_nocache_ok_mfhdf_SDstart='no'
+  ac_check_lib_nocache_mfhdf_SDstart_LIBS=$LIBS
+  LIBS="-lmfhdf -ldf -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for SDstart in -lmfhdf" >&5
+echo $ECHO_N "checking for SDstart in -lmfhdf... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SDstart ();
+int
+main ()
+{
+SDstart ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_mfhdf_SDstart='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_mfhdf_SDstart_LIBS
+  if test $ac_check_lib_nocache_ok_mfhdf_SDstart = 'yes'; then
+   ac_hdf4_lib="yes"
+          HDF4_LIBS="-lmfhdf -ldf -ljpeg -lz $HDF4_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_hdf4_save_LIBS
+
+  if test "$ac_hdf4_lib" = 'yes'; then
+  ac_hdf4_lib_ok='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_hdf4_libdir in "" /usr/local/hdf4.2r1/lib64 /opt/hdf4.2r1/lib64 \
+       /usr/hdf4.2r1/lib64 /usr/local/lib64/hdf4.2r1 /opt/lib64/hdf4.2r1 \
+       /usr/lib64/hdf4.2r1 /usr/local/hdf/lib64/ /opt/hdf/lib64 /usr/hdf/lib64 \
+       /usr/local/lib64/hdf /opt/lib64/hdf /usr/lib64/hdf \
+       /usr/local/hdf4.2r1/lib /opt/hdf4.2r1/lib \
+       /usr/hdf4.2r1/lib /usr/local/lib/hdf4.2r1 /opt/lib/hdf4.2r1 \
+       /usr/lib/hdf4.2r1 /usr/local/hdf/lib/ /opt/hdf/lib /usr/hdf/lib \
+       /usr/local/lib/hdf /opt/lib/hdf /usr/lib/hdf ; do
+        if test "z$ac_hdf4_libdir" = 'z'; then
+  HDF4_LDFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching hdf libraries in $ac_hdf4_libdir" >&5
+echo "$as_me: searching hdf libraries in $ac_hdf4_libdir" >&6;}
+             HDF4_LDFLAGS="-L$ac_hdf4_libdir"
+
+fi
+
+        LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+
+  HDF4_LIBS=
+  ac_hdf4_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress='no'
+  ac_check_lib_nocache_sz_SZ_BufftoBuffCompress_LIBS=$LIBS
+  LIBS="-lsz  $LIBS"
+  echo "$as_me:$LINENO: checking for SZ_BufftoBuffCompress in -lsz" >&5
+echo $ECHO_N "checking for SZ_BufftoBuffCompress in -lsz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SZ_BufftoBuffCompress ();
+int
+main ()
+{
+SZ_BufftoBuffCompress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_sz_SZ_BufftoBuffCompress_LIBS
+  if test $ac_check_lib_nocache_ok_sz_SZ_BufftoBuffCompress = 'yes'; then
+
+      LIBS="$LIBS -lsz"
+      HDF4_LIBS='-lsz'
+
+else
+  :
+fi
+
+
+
+  ac_hdf4_lib='no'
+
+  ac_check_lib_nocache_ok_z_deflate='no'
+  ac_check_lib_nocache_z_deflate_LIBS=$LIBS
+  LIBS="-lz  $LIBS"
+  echo "$as_me:$LINENO: checking for deflate in -lz" >&5
+echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char deflate ();
+int
+main ()
+{
+deflate ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_z_deflate='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_z_deflate_LIBS
+  if test $ac_check_lib_nocache_ok_z_deflate = 'yes'; then
+
+  ac_check_lib_nocache_ok_jpeg_jpeg_start_compress='no'
+  ac_check_lib_nocache_jpeg_jpeg_start_compress_LIBS=$LIBS
+  LIBS="-ljpeg  $LIBS"
+  echo "$as_me:$LINENO: checking for jpeg_start_compress in -ljpeg" >&5
+echo $ECHO_N "checking for jpeg_start_compress in -ljpeg... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char jpeg_start_compress ();
+int
+main ()
+{
+jpeg_start_compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_jpeg_jpeg_start_compress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_jpeg_jpeg_start_compress_LIBS
+  if test $ac_check_lib_nocache_ok_jpeg_jpeg_start_compress = 'yes'; then
+
+  ac_check_lib_nocache_ok_df_Hopen='no'
+  ac_check_lib_nocache_df_Hopen_LIBS=$LIBS
+  LIBS="-ldf -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for Hopen in -ldf" >&5
+echo $ECHO_N "checking for Hopen in -ldf... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char Hopen ();
+int
+main ()
+{
+Hopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_df_Hopen='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_df_Hopen_LIBS
+  if test $ac_check_lib_nocache_ok_df_Hopen = 'yes'; then
+
+  ac_check_lib_nocache_ok_mfhdf_SDstart='no'
+  ac_check_lib_nocache_mfhdf_SDstart_LIBS=$LIBS
+  LIBS="-lmfhdf -ldf -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for SDstart in -lmfhdf" >&5
+echo $ECHO_N "checking for SDstart in -lmfhdf... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char SDstart ();
+int
+main ()
+{
+SDstart ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_mfhdf_SDstart='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_mfhdf_SDstart_LIBS
+  if test $ac_check_lib_nocache_ok_mfhdf_SDstart = 'yes'; then
+   ac_hdf4_lib="yes"
+          HDF4_LIBS="-lmfhdf -ldf -ljpeg -lz $HDF4_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_hdf4_save_LIBS
+
+  if test "$ac_hdf4_lib" = 'yes'; then
+  ac_hdf4_lib_ok='yes'
+else
+  :
+fi
+
+
+        if test $ac_hdf4_lib_ok = 'yes'; then
+  break
+fi
+
+        LDFLAGS=$ac_hdf4_save_LDFLAGS
+      done
+
+fi
+
+  LDFLAGS=$ac_hdf4_save_LDFLAGS
+
+  ac_hdf4_h='no'
+  HDF4_CFLAGS=
+  ac_hdf4_save_CPPFLAGS=$CPPFLAGS
+  if test "z$HDF4_PATH_INC" != "z"; then
+
+       HDF4_CFLAGS="-I$HDF4_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS"
+
+  ac_check_header_nocache_compile_mfhdf_h='no'
+  ac_check_header_nocache_preproc_mfhdf_h='no'
+  echo "$as_me:$LINENO: checking for mfhdf.h with compiler" >&5
+echo $ECHO_N "checking for mfhdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <mfhdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_mfhdf_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  echo "$as_me:$LINENO: checking for mfhdf.h with preprocessor" >&5
+echo $ECHO_N "checking for mfhdf.h with preprocessor... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <mfhdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_preproc_mfhdf_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      if test "$ac_check_header_nocache_compile_mfhdf_h" = 'yes'; then
+  { echo "$as_me:$LINENO: WARNING: trusting compiler result, ignoring preprocessor error" >&5
+echo "$as_me: WARNING: trusting compiler result, ignoring preprocessor error" >&2;}
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_mfhdf_h" = 'yes'; then
+  ac_hdf4_h='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_hdf4_incdir in "" /usr/local/hdf4.2r1/include /opt/hdf4.2r1/include \
+       /usr/hdf4.2r1/include /usr/local/include/hdf4.2r1 \
+       /opt/include/hdf4.2r1 /usr/include/hdf4.2r1 /usr/local/hdf/include \
+       /opt/hdf/include /usr/hdf/include /usr/local/include/hdf \
+       /opt/include/hdf /usr/include/hdf ; do
+        if test "z$ac_hdf4_incdir" = 'z'; then
+  HDF4_CFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching hdf includes in $ac_hdf4_incdir" >&5
+echo "$as_me: searching hdf includes in $ac_hdf4_incdir" >&6;}
+             HDF4_CFLAGS="-I$ac_hdf4_incdir"
+
+fi
+
+        CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS"
+
+  ac_check_header_nocache_compile_mfhdf_h='no'
+  ac_check_header_nocache_preproc_mfhdf_h='no'
+  echo "$as_me:$LINENO: checking for mfhdf.h with compiler" >&5
+echo $ECHO_N "checking for mfhdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <mfhdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_mfhdf_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  echo "$as_me:$LINENO: checking for mfhdf.h with preprocessor" >&5
+echo $ECHO_N "checking for mfhdf.h with preprocessor... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <mfhdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_preproc_mfhdf_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      if test "$ac_check_header_nocache_compile_mfhdf_h" = 'yes'; then
+  { echo "$as_me:$LINENO: WARNING: trusting compiler result, ignoring preprocessor error" >&5
+echo "$as_me: WARNING: trusting compiler result, ignoring preprocessor error" >&2;}
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_mfhdf_h" = 'yes'; then
+  ac_hdf4_h='yes'
+else
+  :
+fi
+
+
+        if test $ac_hdf4_h = 'yes'; then
+  break
+fi
+
+        CPPFLAGS=$ac_hdf4_save_CPPFLAGS
+      done
+
+fi
+
+  CPPFLAGS=$ac_hdf4_save_CPPFLAGS
+
+  if test "$ac_hdf4_h" = 'yes' -a "$ac_hdf4_lib_ok" = 'yes'; then
+
+    ac_hdf4_netcdf_save_LDFLAGS=$LDFLAGS
+    ac_hdf4_netcdf_save_LIBS=$LIBS
+    LIBS="$LIBS $HDF4_LIBS"
+    LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+    echo "$as_me:$LINENO: checking for sd_ncopen" >&5
+echo $ECHO_N "checking for sd_ncopen... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sd_ncopen ();
+int
+main ()
+{
+sd_ncopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+        ac_hdf4_sd_netcdf_lib='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+        echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+        ac_hdf4_sd_netcdf_lib='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+    if test "$ac_hdf4_sd_netcdf_lib" = 'no'; then
+
+      echo "$as_me:$LINENO: checking for ncopen with hdf link flags" >&5
+echo $ECHO_N "checking for ncopen with hdf link flags... $ECHO_C" >&6
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ncopen ();
+int
+main ()
+{
+ncopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+        ac_hdf4_netcdf_lib='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+        echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+        ac_hdf4_netcdf_lib='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+    LDFLAGS=$ac_hdf4_netcdf_save_LDFLAGS
+    LIBS=$ac_hdf4_netcdf_save_LIBS
+
+    ac_hdf4_netcdf_save_CPPFLAGS=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS"
+
+for ac_header in hdf4_netcdf.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ ac_hdf4_netcdf_h='yes'
+fi
+
+done
+
+
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  :
+  :
+  echo "$as_me:$LINENO: checking for netcdf.h with compiler" >&5
+echo $ECHO_N "checking for netcdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_compile='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_compile='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for netcdf.h with preprocessor" >&5
+echo $ECHO_N "checking for netcdf.h with preprocessor... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_preproc='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_preproc='no'
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  if test $ac_netcdf_h_compile = 'yes'; then
+  ac_netcdf_h='yes'
+    if test "z$ac_nc_header_interface" = 'z3'; then
+
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  echo "$as_me:$LINENO: checking for netcdf 3 interface" >&5
+echo $ECHO_N "checking for netcdf 3 interface... $ECHO_C" >&6
+  :
+  if test "z$ac_check_netcdf_3_include" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"
+fi
+
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+int
+main ()
+{
+int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      if test "z$ac_check_netcdf_3_include" != "z"; then
+  NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"
+fi
+
+      ac_check_netcdf_3_header='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_check_netcdf_3_header='no'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  if test "$ac_check_netcdf_3_header" = 'yes'; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h='yes'
+
+else
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h='no'
+
+fi
+
+
+
+
+fi
+
+
+fi
+
+
+  if test "$ac_netcdf_h" = 'yes'; then
+
+      ac_hdf4_netcdf_h='yes'
+
+else
+  :
+fi
+
+
+    CPPFLAGS=$ac_hdf4_netcdf_save_CPPFLAGS
+
+else
+  :
+fi
+
+
+
+
+
+
+
+
+
+  if test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_sd_netcdf_lib = 'yes'; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HDF_HAVE_NETCDF
+_ACEOF
+
+     cat >>confdefs.h <<\_ACEOF
+#define HDF_NETCDF_NAME(name) sd_ ## name
+_ACEOF
+
+     use_hdf=yes
+
+else
+
+    cat >>confdefs.h <<\_ACEOF
+#define HDF_NETCDF_NAME(name) name
+_ACEOF
+
+    if test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_netcdf_lib = 'yes'; then
+  use_hdf=yes
+else
+  :
+fi
+
+
+fi
+
+
+      if test "$use_hdf" = 'yes'; then
+        LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+        hdf_libs="$HDF4_LIBS $UDUNITS_LIBS"
+      fi
+
+  else
+      :
+  fi
+
+
+  fi
+
+  if test $use_hdf != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USEHDF 0
+_ACEOF
+
+    echo "- hdf4 disabled"
+  else
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USEHDF 1
+_ACEOF
+
+    echo "+ hdf4 enabled"
+  fi
+
+  # look for libraries to support hdf5
+  # check if supplibs directory exists
+  echo
+  if test "Z$ga_supplib_dir" != "Z" ; then
+    echo "Checking in supplibs for libraries to support hdf5 ..."
+    # look for zlib
+    if test "$have_zlib" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in zlib ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in zlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_compress+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_z_compress=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_compress=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5
+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6
+if test $ac_cv_lib_z_compress = yes; then
+   have_zlib=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    # look for jpeg
+    if test "$have_jpeg" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+  :
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -ljpeg" >&5
+echo $ECHO_N "checking for main in -ljpeg... $ECHO_C" >&6
+if test "${ac_cv_lib_jpeg_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_jpeg_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_jpeg_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_main" >&5
+echo "${ECHO_T}$ac_cv_lib_jpeg_main" >&6
+if test $ac_cv_lib_jpeg_main = yes; then
+   have_jpeg=yes
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    if test "$have_zlib" = "yes" -a "$have_jpeg" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in hdf5 ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      echo "$as_me:$LINENO: checking for main in -lsz" >&5
+echo $ECHO_N "checking for main in -lsz... $ECHO_C" >&6
+if test "${ac_cv_lib_sz_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sz_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sz_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sz_main" >&5
+echo "${ECHO_T}$ac_cv_lib_sz_main" >&6
+if test $ac_cv_lib_sz_main = yes; then
+   if test "${ac_cv_header_hdf5_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for hdf5.h" >&5
+echo $ECHO_N "checking for hdf5.h... $ECHO_C" >&6
+if test "${ac_cv_header_hdf5_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_hdf5_h" >&5
+echo "${ECHO_T}$ac_cv_header_hdf5_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking hdf5.h usability" >&5
+echo $ECHO_N "checking hdf5.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <hdf5.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking hdf5.h presence" >&5
+echo $ECHO_N "checking hdf5.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <hdf5.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: hdf5.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: hdf5.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: hdf5.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: hdf5.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: hdf5.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: hdf5.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: hdf5.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: hdf5.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: hdf5.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for hdf5.h" >&5
+echo $ECHO_N "checking for hdf5.h... $ECHO_C" >&6
+if test "${ac_cv_header_hdf5_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_hdf5_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_hdf5_h" >&5
+echo "${ECHO_T}$ac_cv_header_hdf5_h" >&6
+
+fi
+if test $ac_cv_header_hdf5_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lhdf5" >&5
+echo $ECHO_N "checking for main in -lhdf5... $ECHO_C" >&6
+if test "${ac_cv_lib_hdf5_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lhdf5  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_hdf5_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_hdf5_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_hdf5_main" >&5
+echo "${ECHO_T}$ac_cv_lib_hdf5_main" >&6
+if test $ac_cv_lib_hdf5_main = yes; then
+   use_hdf5=yes
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in hdf5 ; do
+      hdf5_inc="$hdf5_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in hdf5 sz z ; do
+      hdf5_libs="$hdf5_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+
+fi
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for hdf5
+  if test "$use_hdf5" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support hdf5 ..."
+
+
+# Check whether --with-hdf5 or --without-hdf5 was given.
+if test "${with_hdf5+set}" = set; then
+  withval="$with_hdf5"
+  HDF5_PATH=$withval
+else
+  HDF5_PATH=""
+fi;
+
+
+# Check whether --with-hdf5_include or --without-hdf5_include was given.
+if test "${with_hdf5_include+set}" = set; then
+  withval="$with_hdf5_include"
+  HDF5_PATH_INC=$withval
+else
+  HDF5_PATH_INC=""
+fi;
+
+
+# Check whether --with-hdf5_libdir or --without-hdf5_libdir was given.
+if test "${with_hdf5_libdir+set}" = set; then
+  withval="$with_hdf5_libdir"
+  HDF5_PATH_LIBDIR=$withval
+else
+  HDF5_PATH_LIBDIR=""
+fi;
+
+  if test "z$HDF5_PATH" != "z"; then
+
+    if test "z$HDF5_PATH_LIBDIR" = "z"; then
+  HDF5_PATH_LIBDIR="$HDF5_PATH/lib"
+fi
+
+    if test "z$HDF5_PATH_INC" = "z"; then
+  HDF5_PATH_INC="$HDF5_PATH/include"
+fi
+
+
+fi
+
+
+
+  ac_hdf5_lib_ok='no'
+  ac_hdf5_save_LDFLAGS=$LDFLAGS
+  HDF5_LIBS=
+  if test "z$HDF5_PATH_LIBDIR" != "z"; then
+
+      HDF5_LDFLAGS="-L$HDF5_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $HDF5_LDFLAGS"
+
+  HDF5_LIBS=
+  ac_hdf5_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_sz_main='no'
+  ac_check_lib_nocache_sz_main_LIBS=$LIBS
+  LIBS="-lsz  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -lsz" >&5
+echo $ECHO_N "checking for main in -lsz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_sz_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_sz_main_LIBS
+  if test $ac_check_lib_nocache_ok_sz_main = 'yes'; then
+
+      LIBS="$LIBS -lsz"
+      HDF5_LIBS='-lsz'
+
+else
+  :
+fi
+
+
+
+  ac_hdf5_lib='no'
+
+  ac_check_lib_nocache_ok_z_compress='no'
+  ac_check_lib_nocache_z_compress_LIBS=$LIBS
+  LIBS="-lz  $LIBS"
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_z_compress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_z_compress_LIBS
+  if test $ac_check_lib_nocache_ok_z_compress = 'yes'; then
+
+  ac_check_lib_nocache_ok_jpeg_main='no'
+  ac_check_lib_nocache_jpeg_main_LIBS=$LIBS
+  LIBS="-ljpeg  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -ljpeg" >&5
+echo $ECHO_N "checking for main in -ljpeg... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_jpeg_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_jpeg_main_LIBS
+  if test $ac_check_lib_nocache_ok_jpeg_main = 'yes'; then
+
+  ac_check_lib_nocache_ok_hdf5_H5Fopen='no'
+  ac_check_lib_nocache_hdf5_H5Fopen_LIBS=$LIBS
+  LIBS="-lhdf5 -lhdf5 -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for H5Fopen in -lhdf5" >&5
+echo $ECHO_N "checking for H5Fopen in -lhdf5... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char H5Fopen ();
+int
+main ()
+{
+H5Fopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_hdf5_H5Fopen='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_hdf5_H5Fopen_LIBS
+  if test $ac_check_lib_nocache_ok_hdf5_H5Fopen = 'yes'; then
+   ac_hdf5_lib="yes"
+          HDF5_LIBS="-lhdf5 -ljpeg -lz $HDF5_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_hdf5_save_LIBS
+
+  if test "$ac_hdf5_lib" = 'yes'; then
+  ac_hdf5_lib_ok='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_hdf5_libdir in "" /usr/local/hdf5/lib64/ /opt/hdf5/lib64 /usr/hdf5/lib64 \
+       /usr/local/lib64/hdf5 /opt/lib64/hdf5 /usr/lib64/hdf5 /usr/lib64 \
+       /usr/local/hdf5/lib/ /opt/hdf5/lib /usr/hdf5/lib \
+       /usr/local/lib/hdf5 /opt/lib/hdf5 /usr/lib/hdf5 /usr/lib ; do
+        if test "z$ac_hdf5_libdir" = 'z'; then
+  HDF5_LDFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching hdf5 libraries in $ac_hdf5_libdir" >&5
+echo "$as_me: searching hdf5 libraries in $ac_hdf5_libdir" >&6;}
+             HDF5_LDFLAGS="-L$ac_hdf5_libdir"
+
+fi
+
+        LDFLAGS="$LDFLAGS $HDF5_LDFLAGS"
+
+  HDF5_LIBS=
+  ac_hdf5_save_LIBS=$LIBS
+
+  ac_check_lib_nocache_ok_sz_main='no'
+  ac_check_lib_nocache_sz_main_LIBS=$LIBS
+  LIBS="-lsz  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -lsz" >&5
+echo $ECHO_N "checking for main in -lsz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_sz_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_sz_main_LIBS
+  if test $ac_check_lib_nocache_ok_sz_main = 'yes'; then
+
+      LIBS="$LIBS -lsz"
+      HDF5_LIBS='-lsz'
+
+else
+  :
+fi
+
+
+
+  ac_hdf5_lib='no'
+
+  ac_check_lib_nocache_ok_z_compress='no'
+  ac_check_lib_nocache_z_compress_LIBS=$LIBS
+  LIBS="-lz  $LIBS"
+  echo "$as_me:$LINENO: checking for compress in -lz" >&5
+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char compress ();
+int
+main ()
+{
+compress ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_z_compress='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_z_compress_LIBS
+  if test $ac_check_lib_nocache_ok_z_compress = 'yes'; then
+
+  ac_check_lib_nocache_ok_jpeg_main='no'
+  ac_check_lib_nocache_jpeg_main_LIBS=$LIBS
+  LIBS="-ljpeg  $LIBS"
+  echo "$as_me:$LINENO: checking for main in -ljpeg" >&5
+echo $ECHO_N "checking for main in -ljpeg... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_jpeg_main='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_jpeg_main_LIBS
+  if test $ac_check_lib_nocache_ok_jpeg_main = 'yes'; then
+
+  ac_check_lib_nocache_ok_hdf5_H5Fopen='no'
+  ac_check_lib_nocache_hdf5_H5Fopen_LIBS=$LIBS
+  LIBS="-lhdf5 -lhdf5 -ljpeg -lz $LIBS"
+  echo "$as_me:$LINENO: checking for H5Fopen in -lhdf5" >&5
+echo $ECHO_N "checking for H5Fopen in -lhdf5... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char H5Fopen ();
+int
+main ()
+{
+H5Fopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+    ac_check_lib_nocache_ok_hdf5_H5Fopen='yes'
+    echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LIBS=$ac_check_lib_nocache_hdf5_H5Fopen_LIBS
+  if test $ac_check_lib_nocache_ok_hdf5_H5Fopen = 'yes'; then
+   ac_hdf5_lib="yes"
+          HDF5_LIBS="-lhdf5 -ljpeg -lz $HDF5_LIBS"
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+
+else
+  :
+fi
+
+
+  LIBS=$ac_hdf5_save_LIBS
+
+  if test "$ac_hdf5_lib" = 'yes'; then
+  ac_hdf5_lib_ok='yes'
+else
+  :
+fi
+
+
+        if test $ac_hdf5_lib_ok = 'yes'; then
+  break
+fi
+
+        LDFLAGS=$ac_hdf5_save_LDFLAGS
+      done
+
+fi
+
+  LDFLAGS=$ac_hdf5_save_LDFLAGS
+
+  ac_hdf5_h='no'
+  HDF5_CFLAGS=
+  ac_hdf5_save_CPPFLAGS=$CPPFLAGS
+  if test "z$HDF5_PATH_INC" != "z"; then
+
+       HDF5_CFLAGS="-I$HDF5_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $HDF5_CFLAGS"
+
+  ac_check_header_nocache_compile_hdf5_h='no'
+  echo "$as_me:$LINENO: checking for hdf5.h with compiler" >&5
+echo $ECHO_N "checking for hdf5.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <hdf5.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_hdf5_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_hdf5_h" = 'yes'; then
+  ac_hdf5_h='yes'
+else
+  :
+fi
+
+
+
+else
+
+      for ac_hdf5_incdir in "" /usr/include /usr/local/hdf5/include \
+       /opt/hdf5/include /usr/hdf5/include /usr/local/include/hdf5 \
+       /opt/include/hdf5 /usr/include/hdf5 ; do
+        if test "z$ac_hdf5_incdir" = 'z'; then
+  HDF5_CFLAGS=
+else
+
+             { echo "$as_me:$LINENO: searching hdf5 includes in $ac_hdf5_incdir" >&5
+echo "$as_me: searching hdf5 includes in $ac_hdf5_incdir" >&6;}
+             HDF5_CFLAGS="-I$ac_hdf5_incdir"
+
+fi
+
+        CPPFLAGS="$CPPFLAGS $HDF5_CFLAGS"
+
+  ac_check_header_nocache_compile_hdf5_h='no'
+  echo "$as_me:$LINENO: checking for hdf5.h with compiler" >&5
+echo $ECHO_N "checking for hdf5.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <hdf5.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_check_header_nocache_compile_hdf5_h='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  if test "$ac_check_header_nocache_compile_hdf5_h" = 'yes'; then
+  ac_hdf5_h='yes'
+else
+  :
+fi
+
+
+        if test $ac_hdf5_h = 'yes'; then
+  break
+fi
+
+        CPPFLAGS=$ac_hdf5_save_CPPFLAGS
+      done
+
+fi
+
+  CPPFLAGS=$ac_hdf5_save_CPPFLAGS
+
+  if test "$ac_hdf5_h" = 'yes' -a "$ac_hdf5_lib_ok" = 'yes'; then
+
+      LDFLAGS="$LDFLAGS $HDF5_LDFLAGS"
+      hdf5_libs="$HDF5_LIBS"
+      hdf5_inc=$HDF5_CFLAGS
+      use_hdf5='yes'
+
+else
+  :
+fi
+
+
+
+
+
+
+  fi
+
+  if test $use_hdf5 != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USEHDF5 0
+_ACEOF
+
+    echo "- hdf5 disabled"
+  else
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USEHDF5 1
+_ACEOF
+
+    echo "+ hdf5 enabled"
+
+    # now that we have hdf5, look for libraries to support netcdf-4
+    # check if supplibs directory exists
+    echo
+    if test "Z$ga_supplib_dir" != "Z" ; then
+      echo "Checking in supplibs for libraries to support netcdf-4 ..."
+      if test "$have_udunits" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in udunits ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in udunits.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+   have_udunits=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+      fi
+      if test "$have_udunits" = "yes" ; then
+        # look for netcdf4
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in netcdf ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+        if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for netcdf.h" >&5
+echo $ECHO_N "checking for netcdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_netcdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_netcdf_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking netcdf.h usability" >&5
+echo $ECHO_N "checking netcdf.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking netcdf.h presence" >&5
+echo $ECHO_N "checking netcdf.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: netcdf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: netcdf.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: netcdf.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: netcdf.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: netcdf.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: netcdf.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: netcdf.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: netcdf.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for netcdf.h" >&5
+echo $ECHO_N "checking for netcdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_netcdf_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_netcdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_netcdf_h" >&6
+
+fi
+if test $ac_cv_header_netcdf_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lnetcdf" >&5
+echo $ECHO_N "checking for main in -lnetcdf... $ECHO_C" >&6
+if test "${ac_cv_lib_netcdf_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetcdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_netcdf_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_netcdf_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_netcdf_main" >&5
+echo "${ECHO_T}$ac_cv_lib_netcdf_main" >&6
+if test $ac_cv_lib_netcdf_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lhdf5_hl" >&5
+echo $ECHO_N "checking for main in -lhdf5_hl... $ECHO_C" >&6
+if test "${ac_cv_lib_hdf5_hl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lhdf5_hl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_hdf5_hl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_hdf5_hl_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_hdf5_hl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_hdf5_hl_main" >&6
+if test $ac_cv_lib_hdf5_hl_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lcurl" >&5
+echo $ECHO_N "checking for main in -lcurl... $ECHO_C" >&6
+if test "${ac_cv_lib_curl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_curl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_curl_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_curl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_curl_main" >&6
+if test $ac_cv_lib_curl_main = yes; then
+   use_nc4="yes"
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in udunits netcdf ; do
+      nc_inc="$nc_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in udunits netcdf hdf5_hl hdf5 z sz curl ; do
+      nc_libs="$nc_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+	# set these before calling the macros to look outside of supplibs
+
+
+        NC_CONFIG=${ga_supplib_dir}/bin/nc-config
+      fi
+    fi
+    #  if we haven't got what we need, look outside supplibs for netcdf-4
+    if test "$use_nc4" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+
+  ga_use_udunits='no'
+  if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking udunits.h usability" >&5
+echo $ECHO_N "checking udunits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <udunits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking udunits.h presence" >&5
+echo $ECHO_N "checking udunits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <udunits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: udunits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: udunits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: udunits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: udunits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_udunits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+
+fi
+if test $ac_cv_header_udunits_h = yes; then
+    echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+    ga_use_udunits='yes'
+        UDUNITS_LIBS='-ludunits'
+
+fi
+
+
+fi
+
+
+
+  if test "z$ga_use_udunits" = "zyes" ; then
+
+
+# Check whether --with-netcdf or --without-netcdf was given.
+if test "${with_netcdf+set}" = set; then
+  withval="$with_netcdf"
+  NC_PATH=$withval
+else
+  NC_PATH=""
+fi;
+
+
+# Check whether --with-netcdf_include or --without-netcdf_include was given.
+if test "${with_netcdf_include+set}" = set; then
+  withval="$with_netcdf_include"
+  NC_PATH_INC=$withval
+else
+  NC_PATH_INC=""
+fi;
+
+
+# Check whether --with-netcdf_libdir or --without-netcdf_libdir was given.
+if test "${with_netcdf_libdir+set}" = set; then
+  withval="$with_netcdf_libdir"
+  NC_PATH_LIBDIR=$withval
+else
+  NC_PATH_LIBDIR=""
+fi;
+
+  if test "z$NC_PATH" != "z"; then
+
+    if test "z$NC_PATH_LIBDIR" = "z"; then
+  NC_PATH_LIBDIR="$NC_PATH/lib"
+fi
+
+    if test "z$NC_PATH_INC" = "z"; then
+  NC_PATH_INC="$NC_PATH/include"
+fi
+
+
+fi
+
+
+  ac_netcdf_ok='no'
+  NC_LIBS=
+  NC_LDFLAGS=
+  ac_nc_save_LDFLAGS=$LDFLAGS
+  ac_nc_save_LIBS=$LIBS
+  ac_check_nc_func_checked='ncopen'
+  ac_check_nc_interface=
+  ac_check_nc_interface=2
+  if test "z$ac_check_nc_interface" = 'z3'; then
+  ac_check_nc_func_checked='nc_open'
+fi
+
+  if test "z$NC_PATH_LIBDIR" != "z"; then
+
+      NC_LDFLAGS="-L$NC_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+      as_ac_Lib=`echo "ac_cv_lib_netcdf_$ac_check_nc_func_checked" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_check_nc_func_checked in -lnetcdf" >&5
+echo $ECHO_N "checking for $ac_check_nc_func_checked in -lnetcdf... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Lib+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetcdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_check_nc_func_checked ();
+int
+main ()
+{
+$ac_check_nc_func_checked ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Lib=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Lib=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Lib'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Lib'}'`" >&6
+if test `eval echo '${'$as_ac_Lib'}'` = yes; then
+
+          NC_LIBS='-lnetcdf'
+          ac_netcdf_ok='yes'
+
+fi
+
+
+else
+
+      for ac_netcdf_libdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib64 \
+       /opt/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/local/lib64/netcdf-${ac_check_nc_interface} \
+       /opt/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib64 /opt/netcdf/lib64 \
+       /usr/netcdf/lib64 /usr/local/lib64/netcdf /opt/lib64/netcdf \
+       /usr/lib64/netcdf \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib \
+       /opt/netcdf-${ac_check_nc_interface}/lib \
+       /usr/netcdf-${ac_check_nc_interface}/lib \
+       /usr/local/lib/netcdf-${ac_check_nc_interface} \
+       /opt/lib/netcdf-${ac_check_nc_interface} \
+       /usr/lib/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib /opt/netcdf/lib \
+       /usr/netcdf/lib /usr/local/lib/netcdf /opt/lib/netcdf \
+       /usr/lib/netcdf ; do
+        if test "z$ac_netcdf_libdir" = 'z'; then
+  NC_LDFLAGS=
+else
+
+            echo "$as_me:$LINENO: checking for netcdf libraries in $ac_netcdf_libdir" >&5
+echo $ECHO_N "checking for netcdf libraries in $ac_netcdf_libdir... $ECHO_C" >&6
+            NC_LDFLAGS="-L$ac_netcdf_libdir"
+
+fi
+
+        LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+        LIBS="$LIBS -lnetcdf"
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_check_nc_func_checked ();
+int
+main ()
+{
+$ac_check_nc_func_checked ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+            NC_LIBS='-lnetcdf'
+            ac_netcdf_ok='yes'
+            if test "z$ac_netcdf_libdir" != 'z'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi
+
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+            if test "z$ac_netcdf_libdir" != 'z'; then
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+        if test $ac_netcdf_ok = 'yes'; then
+  break
+fi
+
+        LDFLAGS=$ac_nc_save_LDFLAGS
+        LIBS=$ac_nc_save_LIBS
+      done
+
+fi
+
+  LDFLAGS=$ac_nc_save_LDFLAGS
+  LIBS=$ac_nc_save_LIBS
+
+
+
+  ac_netcdf_header='no'
+
+  NC_CFLAGS=
+  if test "z$NC_PATH_INC" != "z"; then
+
+
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+
+    ac_nc_include_dir="$NC_PATH_INC"
+    if test "z$ac_nc_include_dir" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"
+fi
+
+
+  ac_nc_header_interface=$ac_check_nc_interface
+  echo "$as_me:$LINENO: checking for netcdf.h with compiler" >&5
+echo $ECHO_N "checking for netcdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_compile='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_compile='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for netcdf.h with preprocessor" >&5
+echo $ECHO_N "checking for netcdf.h with preprocessor... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_preproc='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_preproc='no'
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  if test $ac_netcdf_h_compile = 'yes'; then
+  ac_netcdf_h='yes'
+    if test "z$ac_nc_header_interface" = 'z3'; then
+
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  echo "$as_me:$LINENO: checking for netcdf 3 interface" >&5
+echo $ECHO_N "checking for netcdf 3 interface... $ECHO_C" >&6
+
+    ac_check_netcdf_3_include="$NC_PATH_INC"
+
+  if test "z$ac_check_netcdf_3_include" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"
+fi
+
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+int
+main ()
+{
+int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      if test "z$ac_check_netcdf_3_include" != "z"; then
+  NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"
+fi
+
+      ac_check_netcdf_3_header='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_check_netcdf_3_header='no'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  if test "$ac_check_netcdf_3_header" = 'yes'; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h='yes'
+
+else
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h='no'
+
+fi
+
+
+
+
+fi
+
+
+fi
+
+
+  if test "$ac_netcdf_h" = 'yes'; then
+
+      ac_netcdf_header='yes'
+
+else
+  ac_netcdf_header='no'
+fi
+
+
+
+else
+
+      for ac_netcdf_incdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/include \
+       /opt/netcdf-${ac_check_nc_interface}/include \
+       /usr/netcdf-${ac_check_nc_interface}/include \
+       /usr/local/include/netcdf-${ac_check_nc_interface} \
+       /opt/include/netcdf-${ac_check_nc_interface} \
+       /usr/include/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/include \
+       /opt/netcdf/include /usr/netcdf/include /usr/local/include/netcdf \
+       /opt/include/netcdf /usr/include/netcdf ; do
+        { echo "$as_me:$LINENO: searching netcdf includes in $ac_netcdf_incdir" >&5
+echo "$as_me: searching netcdf includes in $ac_netcdf_incdir" >&6;}
+
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+
+    ac_nc_include_dir="$ac_netcdf_incdir"
+    if test "z$ac_nc_include_dir" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"
+fi
+
+
+  ac_nc_header_interface=$ac_check_nc_interface
+  echo "$as_me:$LINENO: checking for netcdf.h with compiler" >&5
+echo $ECHO_N "checking for netcdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_compile='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_compile='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for netcdf.h with preprocessor" >&5
+echo $ECHO_N "checking for netcdf.h with preprocessor... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_preproc='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_preproc='no'
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  if test $ac_netcdf_h_compile = 'yes'; then
+  ac_netcdf_h='yes'
+    if test "z$ac_nc_header_interface" = 'z3'; then
+
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  echo "$as_me:$LINENO: checking for netcdf 3 interface" >&5
+echo $ECHO_N "checking for netcdf 3 interface... $ECHO_C" >&6
+
+    ac_check_netcdf_3_include="$ac_netcdf_incdir"
+
+  if test "z$ac_check_netcdf_3_include" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"
+fi
+
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+int
+main ()
+{
+int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      if test "z$ac_check_netcdf_3_include" != "z"; then
+  NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"
+fi
+
+      ac_check_netcdf_3_header='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_check_netcdf_3_header='no'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  if test "$ac_check_netcdf_3_header" = 'yes'; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h='yes'
+
+else
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h='no'
+
+fi
+
+
+
+
+fi
+
+
+fi
+
+
+  if test "$ac_netcdf_h" = 'yes'; then
+
+      ac_netcdf_header='yes'
+
+else
+  ac_netcdf_header='no'
+fi
+
+
+        if test $ac_netcdf_header = 'yes'; then
+
+           if test "z$ac_netcdf_incdir" != "z"; then
+  NC_CFLAGS="-I$ac_nc_include_dir"
+fi
+
+           break
+
+fi
+
+      done
+
+fi
+
+
+
+  if test "$ac_netcdf_ok" = 'no' -o "$ac_netcdf_header" = 'no'; then
+  :
+else
+   use_nc4=yes
+            LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+            nc_libs="$NC_LIBS $UDUNITS_LIBS"
+            nc_inc="$NC_CFLAGS $UDUNITS_CFLAGS"
+
+fi
+
+
+
+  else
+      :
+  fi
+
+
+       NC_CONFIG="`pkg-config --variable=prefix netcdf`/bin/nc-config"
+    fi
+    if test $use_nc4 != "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USENETCDF 0
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVENETCDF4 0
+_ACEOF
+
+      echo "- netcdf-4 disabled"
+    else
+
+cat >>confdefs.h <<\_ACEOF
+#define USENETCDF 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVENETCDF4 1
+_ACEOF
+
+      echo "+ netcdf-4 enabled"
+      # find out if it is dap-enabled
+      use_dap=`$NC_CONFIG --has-dap`
+      if test $use_dap = "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USEDAP 1
+_ACEOF
+
+      fi
+    fi
+  fi
+
+  # look for libraries to support netcdf
+  # check if we've already enabled netcdf-4
+  echo
+  if test $use_nc4 != "yes" ; then
+    # check if supplibs directory exists
+    if test "Z$ga_supplib_dir" != "Z" ; then
+      if test $use_nc != "yes" ; then
+        echo "Checking in supplibs for libraries to support netcdf-3 ..."
+        if test "$have_udunits" = "no" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in udunits ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+
+for ac_header in udunits.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+  echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+   have_udunits=yes
+
+fi
+
+
+fi
+
+done
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+        fi
+        if test "$have_udunits" = "yes" ; then
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in netcdf ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+          if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for netcdf.h" >&5
+echo $ECHO_N "checking for netcdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_netcdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_netcdf_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking netcdf.h usability" >&5
+echo $ECHO_N "checking netcdf.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking netcdf.h presence" >&5
+echo $ECHO_N "checking netcdf.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: netcdf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: netcdf.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: netcdf.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: netcdf.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: netcdf.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: netcdf.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: netcdf.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: netcdf.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: netcdf.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for netcdf.h" >&5
+echo $ECHO_N "checking for netcdf.h... $ECHO_C" >&6
+if test "${ac_cv_header_netcdf_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_netcdf_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_netcdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_netcdf_h" >&6
+
+fi
+if test $ac_cv_header_netcdf_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lnetcdf" >&5
+echo $ECHO_N "checking for main in -lnetcdf... $ECHO_C" >&6
+if test "${ac_cv_lib_netcdf_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetcdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_netcdf_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_netcdf_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_netcdf_main" >&5
+echo "${ECHO_T}$ac_cv_lib_netcdf_main" >&6
+if test $ac_cv_lib_netcdf_main = yes; then
+   use_nc="yes"
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in udunits netcdf ; do
+      nc_inc="$nc_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in netcdf udunits ; do
+      nc_libs="$nc_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+        fi
+      fi
+      # if we haven't got what we need, look outside supplibs
+      if test $use_nc != "yes"  -a "$ga_dyn_supplibs" = "yes" ; then
+        echo
+        echo "Checking in system locations for libraries to support netcdf-3 ..."
+        # check for netcdf 3
+
+  ga_use_udunits='no'
+  if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking udunits.h usability" >&5
+echo $ECHO_N "checking udunits.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <udunits.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking udunits.h presence" >&5
+echo $ECHO_N "checking udunits.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <udunits.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: udunits.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: udunits.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: udunits.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: udunits.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: udunits.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: udunits.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: udunits.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: udunits.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: udunits.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for udunits.h" >&5
+echo $ECHO_N "checking for udunits.h... $ECHO_C" >&6
+if test "${ac_cv_header_udunits_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_udunits_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_udunits_h" >&5
+echo "${ECHO_T}$ac_cv_header_udunits_h" >&6
+
+fi
+if test $ac_cv_header_udunits_h = yes; then
+    echo "$as_me:$LINENO: checking for utInit in -ludunits" >&5
+echo $ECHO_N "checking for utInit in -ludunits... $ECHO_C" >&6
+if test "${ac_cv_lib_udunits_utInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludunits  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char utInit ();
+int
+main ()
+{
+utInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_udunits_utInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_udunits_utInit=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_udunits_utInit" >&5
+echo "${ECHO_T}$ac_cv_lib_udunits_utInit" >&6
+if test $ac_cv_lib_udunits_utInit = yes; then
+    ga_use_udunits='yes'
+        UDUNITS_LIBS='-ludunits'
+
+fi
+
+
+fi
+
+
+
+  if test "z$ga_use_udunits" = "zyes" ; then
+
+
+# Check whether --with-netcdf or --without-netcdf was given.
+if test "${with_netcdf+set}" = set; then
+  withval="$with_netcdf"
+  NC_PATH=$withval
+else
+  NC_PATH=""
+fi;
+
+
+# Check whether --with-netcdf_include or --without-netcdf_include was given.
+if test "${with_netcdf_include+set}" = set; then
+  withval="$with_netcdf_include"
+  NC_PATH_INC=$withval
+else
+  NC_PATH_INC=""
+fi;
+
+
+# Check whether --with-netcdf_libdir or --without-netcdf_libdir was given.
+if test "${with_netcdf_libdir+set}" = set; then
+  withval="$with_netcdf_libdir"
+  NC_PATH_LIBDIR=$withval
+else
+  NC_PATH_LIBDIR=""
+fi;
+
+  if test "z$NC_PATH" != "z"; then
+
+    if test "z$NC_PATH_LIBDIR" = "z"; then
+  NC_PATH_LIBDIR="$NC_PATH/lib"
+fi
+
+    if test "z$NC_PATH_INC" = "z"; then
+  NC_PATH_INC="$NC_PATH/include"
+fi
+
+
+fi
+
+
+  ac_netcdf_ok='no'
+  NC_LIBS=
+  NC_LDFLAGS=
+  ac_nc_save_LDFLAGS=$LDFLAGS
+  ac_nc_save_LIBS=$LIBS
+  ac_check_nc_func_checked='ncopen'
+  ac_check_nc_interface=
+  ac_check_nc_interface=3
+  if test "z$ac_check_nc_interface" = 'z3'; then
+  ac_check_nc_func_checked='nc_open'
+fi
+
+  if test "z$NC_PATH_LIBDIR" != "z"; then
+
+      NC_LDFLAGS="-L$NC_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+      as_ac_Lib=`echo "ac_cv_lib_netcdf_$ac_check_nc_func_checked" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_check_nc_func_checked in -lnetcdf" >&5
+echo $ECHO_N "checking for $ac_check_nc_func_checked in -lnetcdf... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Lib+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetcdf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_check_nc_func_checked ();
+int
+main ()
+{
+$ac_check_nc_func_checked ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Lib=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Lib=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Lib'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Lib'}'`" >&6
+if test `eval echo '${'$as_ac_Lib'}'` = yes; then
+
+          NC_LIBS='-lnetcdf'
+          ac_netcdf_ok='yes'
+
+fi
+
+
+else
+
+      for ac_netcdf_libdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib64 \
+       /opt/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/local/lib64/netcdf-${ac_check_nc_interface} \
+       /opt/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib64 /opt/netcdf/lib64 \
+       /usr/netcdf/lib64 /usr/local/lib64/netcdf /opt/lib64/netcdf \
+       /usr/lib64/netcdf \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib \
+       /opt/netcdf-${ac_check_nc_interface}/lib \
+       /usr/netcdf-${ac_check_nc_interface}/lib \
+       /usr/local/lib/netcdf-${ac_check_nc_interface} \
+       /opt/lib/netcdf-${ac_check_nc_interface} \
+       /usr/lib/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib /opt/netcdf/lib \
+       /usr/netcdf/lib /usr/local/lib/netcdf /opt/lib/netcdf \
+       /usr/lib/netcdf ; do
+        if test "z$ac_netcdf_libdir" = 'z'; then
+  NC_LDFLAGS=
+else
+
+            echo "$as_me:$LINENO: checking for netcdf libraries in $ac_netcdf_libdir" >&5
+echo $ECHO_N "checking for netcdf libraries in $ac_netcdf_libdir... $ECHO_C" >&6
+            NC_LDFLAGS="-L$ac_netcdf_libdir"
+
+fi
+
+        LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+        LIBS="$LIBS -lnetcdf"
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_check_nc_func_checked ();
+int
+main ()
+{
+$ac_check_nc_func_checked ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+            NC_LIBS='-lnetcdf'
+            ac_netcdf_ok='yes'
+            if test "z$ac_netcdf_libdir" != 'z'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi
+
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+            if test "z$ac_netcdf_libdir" != 'z'; then
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+        if test $ac_netcdf_ok = 'yes'; then
+  break
+fi
+
+        LDFLAGS=$ac_nc_save_LDFLAGS
+        LIBS=$ac_nc_save_LIBS
+      done
+
+fi
+
+  LDFLAGS=$ac_nc_save_LDFLAGS
+  LIBS=$ac_nc_save_LIBS
+
+
+
+  ac_netcdf_header='no'
+
+  NC_CFLAGS=
+  if test "z$NC_PATH_INC" != "z"; then
+
+
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+
+    ac_nc_include_dir="$NC_PATH_INC"
+    if test "z$ac_nc_include_dir" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"
+fi
+
+
+  ac_nc_header_interface=$ac_check_nc_interface
+  echo "$as_me:$LINENO: checking for netcdf.h with compiler" >&5
+echo $ECHO_N "checking for netcdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_compile='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_compile='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for netcdf.h with preprocessor" >&5
+echo $ECHO_N "checking for netcdf.h with preprocessor... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_preproc='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_preproc='no'
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  if test $ac_netcdf_h_compile = 'yes'; then
+  ac_netcdf_h='yes'
+    if test "z$ac_nc_header_interface" = 'z3'; then
+
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  echo "$as_me:$LINENO: checking for netcdf 3 interface" >&5
+echo $ECHO_N "checking for netcdf 3 interface... $ECHO_C" >&6
+
+    ac_check_netcdf_3_include="$NC_PATH_INC"
+
+  if test "z$ac_check_netcdf_3_include" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"
+fi
+
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+int
+main ()
+{
+int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      if test "z$ac_check_netcdf_3_include" != "z"; then
+  NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"
+fi
+
+      ac_check_netcdf_3_header='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_check_netcdf_3_header='no'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  if test "$ac_check_netcdf_3_header" = 'yes'; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h='yes'
+
+else
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h='no'
+
+fi
+
+
+
+
+fi
+
+
+fi
+
+
+  if test "$ac_netcdf_h" = 'yes'; then
+
+      ac_netcdf_header='yes'
+
+else
+  ac_netcdf_header='no'
+fi
+
+
+
+else
+
+      for ac_netcdf_incdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/include \
+       /opt/netcdf-${ac_check_nc_interface}/include \
+       /usr/netcdf-${ac_check_nc_interface}/include \
+       /usr/local/include/netcdf-${ac_check_nc_interface} \
+       /opt/include/netcdf-${ac_check_nc_interface} \
+       /usr/include/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/include \
+       /opt/netcdf/include /usr/netcdf/include /usr/local/include/netcdf \
+       /opt/include/netcdf /usr/include/netcdf ; do
+        { echo "$as_me:$LINENO: searching netcdf includes in $ac_netcdf_incdir" >&5
+echo "$as_me: searching netcdf includes in $ac_netcdf_incdir" >&6;}
+
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+
+    ac_nc_include_dir="$ac_netcdf_incdir"
+    if test "z$ac_nc_include_dir" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"
+fi
+
+
+  ac_nc_header_interface=$ac_check_nc_interface
+  echo "$as_me:$LINENO: checking for netcdf.h with compiler" >&5
+echo $ECHO_N "checking for netcdf.h with compiler... $ECHO_C" >&6
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_compile='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_compile='no'
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for netcdf.h with preprocessor" >&5
+echo $ECHO_N "checking for netcdf.h with preprocessor... $ECHO_C" >&6
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h_preproc='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h_preproc='no'
+
+fi
+rm -f conftest.err conftest.$ac_ext
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  if test $ac_netcdf_h_compile = 'yes'; then
+  ac_netcdf_h='yes'
+    if test "z$ac_nc_header_interface" = 'z3'; then
+
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  echo "$as_me:$LINENO: checking for netcdf 3 interface" >&5
+echo $ECHO_N "checking for netcdf 3 interface... $ECHO_C" >&6
+
+    ac_check_netcdf_3_include="$ac_netcdf_incdir"
+
+  if test "z$ac_check_netcdf_3_include" != "z"; then
+  CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"
+fi
+
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netcdf.h>
+int
+main ()
+{
+int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+      if test "z$ac_check_netcdf_3_include" != "z"; then
+  NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"
+fi
+
+      ac_check_netcdf_3_header='yes'
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_check_netcdf_3_header='no'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  if test "$ac_check_netcdf_3_header" = 'yes'; then
+
+      echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+      ac_netcdf_h='yes'
+
+else
+
+      echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+      ac_netcdf_h='no'
+
+fi
+
+
+
+
+fi
+
+
+fi
+
+
+  if test "$ac_netcdf_h" = 'yes'; then
+
+      ac_netcdf_header='yes'
+
+else
+  ac_netcdf_header='no'
+fi
+
+
+        if test $ac_netcdf_header = 'yes'; then
+
+           if test "z$ac_netcdf_incdir" != "z"; then
+  NC_CFLAGS="-I$ac_nc_include_dir"
+fi
+
+           break
+
+fi
+
+      done
+
+fi
+
+
+
+  if test "$ac_netcdf_ok" = 'no' -o "$ac_netcdf_header" = 'no'; then
+  :
+else
+   use_nc=yes
+            LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+            nc_libs="$NC_LIBS $UDUNITS_LIBS"
+
+fi
+
+
+
+  else
+      :
+  fi
+
+
+      fi
+    fi
+    if test $use_nc = "yes" ; then
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USENETCDF 1
+_ACEOF
+
+      echo "+ netcdf enabled"
+    else
+
+cat >>confdefs.h <<\_ACEOF
+#define USENETCDF 0
+_ACEOF
+
+      echo "- netcdf disabled"
+    fi
+  fi
+
+  # look for libraries to support OPeNDAP station data interface
+  # check if supplibs directory exists
+  echo
+  if test "$with_gadap" = "no" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USEGADAP 0
+_ACEOF
+
+    echo "- OPeNDAP for station data disabled"
+  else
+    if test "Z$ga_supplib_dir" != "Z" ; then
+      echo "Checking in supplibs for libraries to support OPeNDAP station data access ..."
+
+  # Use to make temporary changes to -I and -L paths
+  # Just for use during tests, because configure and make may run
+  # from different directories.
+  ga_saved_cppflags=$CPPFLAGS
+  ga_saved_ldflags=$LDFLAGS
+  ga_saved_libs=$LIBS
+  CPPFLAGS=""
+
+    for ga_inc_name in gadap ; do
+      CPPFLAGS="$CPPFLAGS -I${ga_supplib_dir}/include/${ga_inc_name}"
+    done
+
+  CPPFLAGS="$CPPFLAGS "
+  LDFLAGS="-L${ga_supplib_dir}/lib "
+  LIBS="$LIBS "
+
+      if test "${ac_cv_header_gadap_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gadap.h" >&5
+echo $ECHO_N "checking for gadap.h... $ECHO_C" >&6
+if test "${ac_cv_header_gadap_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gadap_h" >&5
+echo "${ECHO_T}$ac_cv_header_gadap_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gadap.h usability" >&5
+echo $ECHO_N "checking gadap.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gadap.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gadap.h presence" >&5
+echo $ECHO_N "checking gadap.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gadap.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: gadap.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gadap.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: gadap.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: gadap.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gadap.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gadap.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: gadap.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: gadap.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gadap.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gadap.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: gadap.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------- ##
+## Report this to jma at iges.org ##
+## --------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gadap.h" >&5
+echo $ECHO_N "checking for gadap.h... $ECHO_C" >&6
+if test "${ac_cv_header_gadap_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gadap_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gadap_h" >&5
+echo "${ECHO_T}$ac_cv_header_gadap_h" >&6
+
+fi
+if test $ac_cv_header_gadap_h = yes; then
+   echo "$as_me:$LINENO: checking for main in -lgadap" >&5
+echo $ECHO_N "checking for main in -lgadap... $ECHO_C" >&6
+if test "${ac_cv_lib_gadap_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgadap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gadap_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gadap_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gadap_main" >&5
+echo "${ECHO_T}$ac_cv_lib_gadap_main" >&6
+if test $ac_cv_lib_gadap_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -ldap" >&5
+echo $ECHO_N "checking for main in -ldap... $ECHO_C" >&6
+if test "${ac_cv_lib_dap_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dap_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dap_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dap_main" >&5
+echo "${ECHO_T}$ac_cv_lib_dap_main" >&6
+if test $ac_cv_lib_dap_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -ldapclient" >&5
+echo $ECHO_N "checking for main in -ldapclient... $ECHO_C" >&6
+if test "${ac_cv_lib_dapclient_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldapclient  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dapclient_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dapclient_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dapclient_main" >&5
+echo "${ECHO_T}$ac_cv_lib_dapclient_main" >&6
+if test $ac_cv_lib_dapclient_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lxml2" >&5
+echo $ECHO_N "checking for main in -lxml2... $ECHO_C" >&6
+if test "${ac_cv_lib_xml2_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxml2  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_xml2_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_xml2_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_xml2_main" >&5
+echo "${ECHO_T}$ac_cv_lib_xml2_main" >&6
+if test $ac_cv_lib_xml2_main = yes; then
+   echo "$as_me:$LINENO: checking for main in -lcurl" >&5
+echo $ECHO_N "checking for main in -lcurl... $ECHO_C" >&6
+if test "${ac_cv_lib_curl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_curl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_curl_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_curl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_curl_main" >&6
+if test $ac_cv_lib_curl_main = yes; then
+   use_gadap="yes"
+
+  ga_include_prefix='-I$(supp_include_dir)'
+
+  for ga_include_name in gadap ; do
+      gadap_inc="$gadap_inc ${ga_include_prefix}/${ga_include_name}"
+  done
+
+
+  ga_lib_prefix='$(supp_lib_dir)/lib'
+  ga_lib_suffix='.a'
+  for ga_lib_name in gadap dapclient dap curl xml2 z ; do
+      gadap_libs="$gadap_libs ${ga_lib_prefix}${ga_lib_name}${ga_lib_suffix}"
+  done
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+  # Use to undo temporary changes to -I and -L paths
+  CPPFLAGS=$ga_saved_cppflags
+  LDFLAGS=$ga_saved_ldflags
+  LIBS=$ga_saved_libs
+
+    fi
+    #  here's where you would add code for looking outside of supplibs
+    if test $use_gadap = "yes" ; then
+      # add linking options
+      if test "$is_darwin" = "yes" ; then
+        dap_extra_libs="-lpthread -lm -liconv"
+      else
+        dap_extra_libs="-lpthread -lm -ldl -lrt"
+      fi
+      # merge gadap and extras
+      dap_libs="$gadap_libs $dap_extra_libs"
+      #
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define USEGADAP 1
+_ACEOF
+
+      echo "+ OPeNDAP for station data enabled"
+    else
+
+cat >>confdefs.h <<\_ACEOF
+#define USEGADAP 0
+_ACEOF
+
+      echo "- OPeNDAP for station data disabled"
+    fi
+  fi
+fi
+# end of if $with_sdf test
+echo
+
+#  ----------------------------------------------------
+# Send test results to makefile and config.h
+# ----------------------------------------------------
+
+# Some non-configuration-dependent GrADS macros
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_VERSION "2.0.2"
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define GRADS_DESC
+_ACEOF
+
+
+# These are used to add the necessary source files to Makefile targets
+
+
+if  test "$use_readline"  = "yes"  ; then
+  READLINE_TRUE=
+  READLINE_FALSE='#'
+else
+  READLINE_TRUE='#'
+  READLINE_FALSE=
+fi
+
+
+
+if  test "$use_gui"  = "yes"  ; then
+  USEGUI_TRUE=
+  USEGUI_FALSE='#'
+else
+  USEGUI_TRUE='#'
+  USEGUI_FALSE=
+fi
+
+
+
+if  test "$use_printim"  = "yes"  ; then
+  GXPNG_TRUE=
+  GXPNG_FALSE='#'
+else
+  GXPNG_TRUE='#'
+  GXPNG_FALSE=
+fi
+
+
+
+if  test "$use_geotiff"  = "yes"  ; then
+  GEOTIFF_TRUE=
+  GEOTIFF_FALSE='#'
+else
+  GEOTIFF_TRUE='#'
+  GEOTIFF_FALSE=
+fi
+
+
+
+if  test "$use_shp"  = "yes"  ; then
+  USESHP_TRUE=
+  USESHP_FALSE='#'
+else
+  USESHP_TRUE='#'
+  USESHP_FALSE=
+fi
+
+
+
+if  test "$use_gadap" = "yes"  ; then
+  USEGADAP_TRUE=
+  USEGADAP_FALSE='#'
+else
+  USEGADAP_TRUE='#'
+  USEGADAP_FALSE=
+fi
+
+
+
+if  test "$use_dap" = "yes"  ; then
+  USEDAP_TRUE=
+  USEDAP_FALSE='#'
+else
+  USEDAP_TRUE='#'
+  USEDAP_FALSE=
+fi
+
+
+
+if  test "$use_hdf" = "yes"  ; then
+  USEHDF_TRUE=
+  USEHDF_FALSE='#'
+else
+  USEHDF_TRUE='#'
+  USEHDF_FALSE=
+fi
+
+
+
+# Host specific linker flags
+
+
+
+
+build_date=`date +%D`
+build_host=`uname -sr`
+build_info="Built `date` for ${host}"
+
+   echo \
+"  +=========================================================================+"
+   echo "   GrADS "2.0.2 ":" $build_info
+   echo \
+"  +=========================================================================+"
+   echo
+   echo "  +-------------------------------+"
+   echo "  |                               |"
+   echo "  |  GrADS will be built with:    |"
+   echo "  |                               |"
+if test "$use_gui" = "yes" ; then
+   echo "  |  + GUI enabled                |"
+else
+   echo "  |  - GUI disabled               |"
+fi
+if test "$use_readline" = "yes" ; then
+   echo "  |  + readline enabled           |"
+else
+   echo "  |  - readline disabled          |"
+fi
+if test "$use_geotiff" = "yes" ; then
+   echo "  |  + geotiff enabled            |"
+else
+   echo "  |  - geotiff disabled           |"
+fi
+if test "$use_shp" = "yes" ; then
+   echo "  |  + shapefile enabled          |"
+else
+   echo "  |  - shapefile disabled         |"
+fi
+if test "$use_printim" = "yes" ; then
+   echo "  |  + printim enabled            |"
+else
+   echo "  |  - printim disabled           |"
+fi
+if test "$use_grib2" = "yes" ; then
+   echo "  |  + grib2 enabled              |"
+else
+   echo "  |  - grib2 disabled             |"
+fi
+if test "$use_hdf" = "yes" ; then
+   echo "  |  + hdf4 enabled               |"
+else
+   echo "  |  - hdf4 disabled              |"
+fi
+if test "$use_hdf5" = "yes" ; then
+   echo "  |  + hdf5 enabled               |"
+else
+   echo "  |  - hdf5 disabled              |"
+fi
+if test "$use_nc4" = "yes" ; then
+   echo "  |  + netcdf-4 enabled           |"
+else
+  if test "$use_nc" = "yes" ; then
+     echo "  |  + netcdf-3 enabled           |"
+  else
+     echo "  |  - netcdf disabled            |"
+  fi
+fi
+
+
+if test "$use_gadap" = "yes" -o "$use_dap" = "yes" ; then
+  echo "  |  + OPeNDAP enabled            |"
+  if test "$use_gadap" = "yes" -a "$use_dap" = "yes" ; then
+    echo "  |     for grids and stn data    |"
+  else
+    if test "$use_gadap" = "yes" ; then
+      echo "  |     for stn data only         |"
+    else
+      echo "  |     for grids only            |"
+    fi
+  fi
+else
+  echo "  |  - OPeNDAP disabled           |"
+fi
+if test "$use_printim" != "yes" ; then
+   echo "  |                               |"
+   echo "  |  gxtran will not be built     |"
+fi
+if test "$use_grib2" != "yes" ; then
+   echo "  |  grib2scan will not be built  |"
+fi
+   echo "  |                               |"
+   echo "  +-------------------------------+"
+
+echo "configure: creating src/VERSION"
+echo 2.0.2 > src/VERSION
+
+echo "configure: creating src/buildinfo.h"
+mkdir -p src
+echo "static char *buildinfo = \"${build_info}\";" > src/buildinfo.h
+
+                    ac_config_files="$ac_config_files Makefile src/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${READLINE_TRUE}" && test -z "${READLINE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"READLINE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"READLINE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${USEGUI_TRUE}" && test -z "${USEGUI_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USEGUI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USEGUI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${GXPNG_TRUE}" && test -z "${GXPNG_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"GXPNG\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"GXPNG\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${GEOTIFF_TRUE}" && test -z "${GEOTIFF_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"GEOTIFF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"GEOTIFF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${USESHP_TRUE}" && test -z "${USESHP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USESHP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USESHP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${USEGADAP_TRUE}" && test -z "${USEGADAP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USEGADAP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USEGADAP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${USEDAP_TRUE}" && test -z "${USEDAP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USEDAP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USEDAP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${USEHDF_TRUE}" && test -z "${USEHDF_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"USEHDF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USEHDF\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by GrADS $as_me 2.0.2, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf at gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+GrADS config.status 2.0.2
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+  "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s, at SHELL@,$SHELL,;t t
+s, at PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s, at PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s, at PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s, at PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s, at PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s, at PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s, at exec_prefix@,$exec_prefix,;t t
+s, at prefix@,$prefix,;t t
+s, at program_transform_name@,$program_transform_name,;t t
+s, at bindir@,$bindir,;t t
+s, at sbindir@,$sbindir,;t t
+s, at libexecdir@,$libexecdir,;t t
+s, at datadir@,$datadir,;t t
+s, at sysconfdir@,$sysconfdir,;t t
+s, at sharedstatedir@,$sharedstatedir,;t t
+s, at localstatedir@,$localstatedir,;t t
+s, at libdir@,$libdir,;t t
+s, at includedir@,$includedir,;t t
+s, at oldincludedir@,$oldincludedir,;t t
+s, at infodir@,$infodir,;t t
+s, at mandir@,$mandir,;t t
+s, at build_alias@,$build_alias,;t t
+s, at host_alias@,$host_alias,;t t
+s, at target_alias@,$target_alias,;t t
+s, at DEFS@,$DEFS,;t t
+s, at ECHO_C@,$ECHO_C,;t t
+s, at ECHO_N@,$ECHO_N,;t t
+s, at ECHO_T@,$ECHO_T,;t t
+s, at LIBS@,$LIBS,;t t
+s, at INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s, at INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s, at INSTALL_DATA@,$INSTALL_DATA,;t t
+s, at CYGPATH_W@,$CYGPATH_W,;t t
+s, at PACKAGE@,$PACKAGE,;t t
+s, at VERSION@,$VERSION,;t t
+s, at ACLOCAL@,$ACLOCAL,;t t
+s, at AUTOCONF@,$AUTOCONF,;t t
+s, at AUTOMAKE@,$AUTOMAKE,;t t
+s, at AUTOHEADER@,$AUTOHEADER,;t t
+s, at MAKEINFO@,$MAKEINFO,;t t
+s, at install_sh@,$install_sh,;t t
+s, at STRIP@,$STRIP,;t t
+s, at ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s, at INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s, at mkdir_p@,$mkdir_p,;t t
+s, at AWK@,$AWK,;t t
+s, at SET_MAKE@,$SET_MAKE,;t t
+s, at am__leading_dot@,$am__leading_dot,;t t
+s, at AMTAR@,$AMTAR,;t t
+s, at am__tar@,$am__tar,;t t
+s, at am__untar@,$am__untar,;t t
+s, at MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
+s, at MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
+s, at MAINT@,$MAINT,;t t
+s, at CC@,$CC,;t t
+s, at CFLAGS@,$CFLAGS,;t t
+s, at LDFLAGS@,$LDFLAGS,;t t
+s, at CPPFLAGS@,$CPPFLAGS,;t t
+s, at ac_ct_CC@,$ac_ct_CC,;t t
+s, at EXEEXT@,$EXEEXT,;t t
+s, at OBJEXT@,$OBJEXT,;t t
+s, at CXX@,$CXX,;t t
+s, at CXXFLAGS@,$CXXFLAGS,;t t
+s, at ac_ct_CXX@,$ac_ct_CXX,;t t
+s, at LN_S@,$LN_S,;t t
+s, at build@,$build,;t t
+s, at build_cpu@,$build_cpu,;t t
+s, at build_vendor@,$build_vendor,;t t
+s, at build_os@,$build_os,;t t
+s, at host@,$host,;t t
+s, at host_cpu@,$host_cpu,;t t
+s, at host_vendor@,$host_vendor,;t t
+s, at host_os@,$host_os,;t t
+s, at host_ldadd@,$host_ldadd,;t t
+s, at CPP@,$CPP,;t t
+s, at X_CFLAGS@,$X_CFLAGS,;t t
+s, at X_PRE_LIBS@,$X_PRE_LIBS,;t t
+s, at X_LIBS@,$X_LIBS,;t t
+s, at X_EXTRA_LIBS@,$X_EXTRA_LIBS,;t t
+s, at EGREP@,$EGREP,;t t
+s, at SUPPLIBS@,$SUPPLIBS,;t t
+s, at PKG_CONFIG@,$PKG_CONFIG,;t t
+s, at ac_pt_PKG_CONFIG@,$ac_pt_PKG_CONFIG,;t t
+s, at XAW7_CFLAGS@,$XAW7_CFLAGS,;t t
+s, at XAW7_LIBS@,$XAW7_LIBS,;t t
+s, at XAW_LIBS@,$XAW_LIBS,;t t
+s, at XAW_XLIBS@,$XAW_XLIBS,;t t
+s, at XAW_CFLAGS@,$XAW_CFLAGS,;t t
+s, at GA_LIBSX_LIBS@,$GA_LIBSX_LIBS,;t t
+s, at grads_xlibs@,$grads_xlibs,;t t
+s, at gui_inc@,$gui_inc,;t t
+s, at gui_libs@,$gui_libs,;t t
+s, at readline_inc@,$readline_inc,;t t
+s, at readline_libs@,$readline_libs,;t t
+s, at GEOTIFF_LIBS@,$GEOTIFF_LIBS,;t t
+s, at GEOTIFF_CFLAGS@,$GEOTIFF_CFLAGS,;t t
+s, at GEOTIFF_LDFLAGS@,$GEOTIFF_LDFLAGS,;t t
+s, at geotiff_inc@,$geotiff_inc,;t t
+s, at geotiff_libs@,$geotiff_libs,;t t
+s, at shp_inc@,$shp_inc,;t t
+s, at shp_libs@,$shp_libs,;t t
+s, at GD_CFLAGS@,$GD_CFLAGS,;t t
+s, at GD_LIBS@,$GD_LIBS,;t t
+s, at GD_CONFIG@,$GD_CONFIG,;t t
+s, at GD_LDFLAGS@,$GD_LDFLAGS,;t t
+s, at printim_inc@,$printim_inc,;t t
+s, at printim_libs@,$printim_libs,;t t
+s, at G2_LIBS@,$G2_LIBS,;t t
+s, at grib2_inc@,$grib2_inc,;t t
+s, at grib2_libs@,$grib2_libs,;t t
+s, at NC_NETCDF_3_CPPFLAG@,$NC_NETCDF_3_CPPFLAG,;t t
+s, at HDF4_LIBS@,$HDF4_LIBS,;t t
+s, at HDF4_CFLAGS@,$HDF4_CFLAGS,;t t
+s, at HDF4_LDFLAGS@,$HDF4_LDFLAGS,;t t
+s, at UDUNITS_LIBS@,$UDUNITS_LIBS,;t t
+s, at hdf_inc@,$hdf_inc,;t t
+s, at hdf_libs@,$hdf_libs,;t t
+s, at HDF5_LIBS@,$HDF5_LIBS,;t t
+s, at HDF5_CFLAGS@,$HDF5_CFLAGS,;t t
+s, at HDF5_LDFLAGS@,$HDF5_LDFLAGS,;t t
+s, at hdf5_inc@,$hdf5_inc,;t t
+s, at hdf5_libs@,$hdf5_libs,;t t
+s, at nc_inc@,$nc_inc,;t t
+s, at nc_libs@,$nc_libs,;t t
+s, at NC_LDFLAGS@,$NC_LDFLAGS,;t t
+s, at NC_LIBS@,$NC_LIBS,;t t
+s, at NC_CFLAGS@,$NC_CFLAGS,;t t
+s, at gadap_inc@,$gadap_inc,;t t
+s, at dap_libs@,$dap_libs,;t t
+s, at READLINE_TRUE@,$READLINE_TRUE,;t t
+s, at READLINE_FALSE@,$READLINE_FALSE,;t t
+s, at USEGUI_TRUE@,$USEGUI_TRUE,;t t
+s, at USEGUI_FALSE@,$USEGUI_FALSE,;t t
+s, at GXPNG_TRUE@,$GXPNG_TRUE,;t t
+s, at GXPNG_FALSE@,$GXPNG_FALSE,;t t
+s, at GEOTIFF_TRUE@,$GEOTIFF_TRUE,;t t
+s, at GEOTIFF_FALSE@,$GEOTIFF_FALSE,;t t
+s, at USESHP_TRUE@,$USESHP_TRUE,;t t
+s, at USESHP_FALSE@,$USESHP_FALSE,;t t
+s, at USEGADAP_TRUE@,$USEGADAP_TRUE,;t t
+s, at USEGADAP_FALSE@,$USEGADAP_FALSE,;t t
+s, at USEDAP_TRUE@,$USEDAP_TRUE,;t t
+s, at USEDAP_FALSE@,$USEDAP_FALSE,;t t
+s, at USEHDF_TRUE@,$USEHDF_TRUE,;t t
+s, at USEHDF_FALSE@,$USEHDF_FALSE,;t t
+s, at extra_utils@,$extra_utils,;t t
+s, at LIBOBJS@,$LIBOBJS,;t t
+s, at LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s, at configure_input@,$configure_input,;t t
+s, at srcdir@,$ac_srcdir,;t t
+s, at abs_srcdir@,$ac_abs_srcdir,;t t
+s, at top_srcdir@,$ac_top_srcdir,;t t
+s, at abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s, at builddir@,$ac_builddir,;t t
+s, at abs_builddir@,$ac_abs_builddir,;t t
+s, at top_builddir@,$ac_top_builddir,;t t
+s, at abs_top_builddir@,$ac_abs_top_builddir,;t t
+s, at INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X$ac_file : 'X\(//\)[^/]' \| \
+	 X$ac_file : 'X\(//\)$' \| \
+	 X$ac_file : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+echo
+echo "Run 'make && make install' to build GrADS."
+echo "Executables will be installed" \
+     "to bin/ in current dir, unless prefix was specified."
+echo
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..e1f037f
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,1007 @@
+dnl
+dnl configure.ac: 
+dnl
+dnl  Source file for GrADS auto-configuration script. 
+dnl  Run autoreconf to generate a configure script from this file
+dnl  See acinclude.m4 for definitions of the GA_xxx macros   
+
+# The version number
+# below is the "master" version that will appear in all code, etc.
+AC_INIT(GrADS, [2.0.2], [jma at iges.org])
+
+# Require autoconf 2.52 (comes with Mac OS X 10.2) or newer
+AC_PREREQ(2.52) 
+
+# Supporting scripts are in etc/
+AC_CONFIG_AUX_DIR(etc)
+
+# Require automake 1.6 (comes with Mac OS X 10.2) or newer,
+# don't #define PACKAGE and VERSION,
+# disable dependency checking
+AM_INIT_AUTOMAKE([1.6 no-define no-dependencies])
+
+AM_CONFIG_HEADER([src/config.h])
+
+# The following macro prevents annoying interactions between CVS and 
+# automake, which result in make attempting to invoke autotools 
+# even when the configure script is up to date
+AM_MAINTAINER_MODE 
+
+# binaries go to ./bin by default, rather than /usr/bin. 
+AC_PREFIX_DEFAULT(`pwd`)
+
+# ----------------------------------------------------
+#  Additional arguments for the configure script
+# ----------------------------------------------------
+
+AC_ARG_WITH(gui,      [AC_HELP_STRING([--with-gui],
+                                      [Athena X11 widget-based GUI])])
+AC_ARG_WITH(readline, [AC_HELP_STRING([--with-readline],
+                                      [command line editing])])
+AC_ARG_WITH(printim,  [AC_HELP_STRING([--with-printim],
+                                      [image output])])
+AC_ARG_WITH(grib2,    [AC_HELP_STRING([--with-grib2],
+                                      [GRIB2 data format])])
+AC_ARG_WITH(sdf,      [AC_HELP_STRING([--with-sdf],
+                                      [all self-describing formats (HDF4,HDF5,NetCDF,OPeNDAP)])])
+AC_ARG_WITH(gadap,    [AC_HELP_STRING([--with-gadap],
+                                      [OPeNDAP for station data])])
+AC_ARG_WITH(shp,      [AC_HELP_STRING([--with-shp],
+                                      [shapefile format])])
+AC_ARG_WITH(geotiff,  [AC_HELP_STRING([--with-geotiff],
+                                      [geotiff output])])
+
+# ----------------------------------------------------
+# Checks for programs
+# ----------------------------------------------------
+
+echo
+echo "Checking for programs"
+echo "------------------"
+AC_PROG_AWK
+AC_PROG_CC(xlc gcc cc)
+AC_PROG_CXX(xlc++ g++ c++)
+AC_PROG_INSTALL
+AC_PROG_LN_S
+echo
+
+echo "Setting host specific options"
+echo "-------------------------"
+
+# ----------------------------------------------------
+# Get host platform
+# ----------------------------------------------------
+
+AC_CANONICAL_HOST()
+
+# ----------------------------------------------------
+# Set host specific options
+# ----------------------------------------------------
+
+echo Host machine:   "$host"
+case "$host" in 
+
+  alpha-*-osf*)
+    # Option needed for IEEE floating points
+    CFLAGS="$(CFLAGS) -ieee"
+  ;;
+
+  powerpc-ibm-aix*)
+    LDFLAGS="$LDFLAGS -Wl,-bbigtoc -Wl,-bexpall -Wl,-brtl"
+  ;;
+
+  i*86-pc-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  x86_64-*-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  ia64-*-linux-*)
+    CFLAGS="$CFLAGS -rdynamic"
+  ;;
+
+  *-freebsd*)
+    CFLAGS="$CFLAGS -export-dynamic"
+  ;;
+
+  sparc-sun-solaris*)
+    is_solaris="yes"
+dnl checked in AC_PATH_XTRA in X_PRE_LIBS
+    host_ldadd="-lsocket -lnsl -lw"
+dnl    guilibadd="-lSM -lICE"
+  ;;
+
+  *-pc-cygwin)
+    host_ldadd="-lrpclib"
+    AC_SUBST(host_ldadd)
+  ;;
+
+  *darwin*)
+    is_darwin="yes"
+    LDFLAGS="$LDFLAGS -lSystemStubs"
+  ;;
+
+  cray-*-*)
+    is_cray="yes"
+  ;;
+
+  *-hpux11*)
+     is_hpux11="yes"
+  ;;
+
+esac
+
+if test is_cray!="yes" ; then
+  AC_DEFINE(GRADS_CRAY, 0, [Machine is NOT a Cray])
+else
+  AC_DEFINE(GRADS_CRAY, 1, [Machine is a Cray])
+fi
+
+if test is_hpux11!="yes" ; then
+  AC_DEFINE(GRADS_HP64, 0, [Machine is NOT a 64-bit HP])
+else
+  AC_DEFINE(GRADS_HP64, 1, [Machine is 64-bit HP])
+fi
+
+# ----------------------------------------------------
+# Check for basic libraries.
+# ----------------------------------------------------
+
+echo
+echo "Checking system libraries, headers, and compiler features"
+echo "-----------------------------------------"
+
+AC_CHECK_LIB(m,cos,, AC_MSG_ERROR([Fatal: Math library not found]))
+AC_PATH_XTRA
+
+echo
+
+# ----------------------------------------------------
+# Check for basic header files.
+# ----------------------------------------------------
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(malloc.h sys/file.h unistd.h)
+echo
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+dnl joew - In autoconf 2.52, AC_C_BIGENDIAN seems to ignore its
+dnl parameters, so I test the internal variable that it sets.  Note
+dnl that AC_BIG_ENDIAN defines its own macro, WORDS_BIGENDIAN, so
+dnl really it would make most sense to replace the instances of
+dnl BYTEORDER in the GrADS source; but that might cause confusion
+dnl among longtime users.
+AC_C_BIGENDIAN
+if test $ac_cv_c_bigendian = "yes" ; then
+   AC_DEFINE(BYTEORDER,1,[BIG_ENDIAN machine])
+else
+   AC_DEFINE(BYTEORDER,0,[little_endian machine])
+fi
+
+dnl The following tests all check for functions and typedefs that are
+dnl required for GrADS, but 1) I don't think we support any platforms
+dnl where they fail, and 2) if they do, there is no backup plan
+dnl anyway. So I figure we might as well speed the script up a bit by
+dnl commenting them out, unless/until there is some actual handling
+dnl for failure.
+
+dnl AC_TYPE_SIZE_T AC_STRUCT_TM
+
+dnl Checks for library functions.
+dnl AC_TYPE_SIGNAL
+dnl AC_FUNC_STRFTIME
+dnl AC_FUNC_VPRINTF
+dnl AC_CHECK_FUNCS(strdup strstr strtod strtol)
+
+dnl In this case we do have an alternative - valprs()
+AC_CHECK_FUNCS(strtod)
+
+dnl Check for and set up large file support via fseeko()
+AC_TYPE_OFF_T
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+
+# ----------------------------------------------------
+# Check for optional feature support
+# ----------------------------------------------------
+
+echo
+echo Checking for optional feature support
+echo ------------------------------------
+
+
+# ----------------------------------------------------
+# Set supplibs directory name
+# ----------------------------------------------------
+
+GA_SET_SUPPLIBS([. ..])
+
+
+AC_ARG_ENABLE([dyn-supplibs], 
+[  --enable-dyn-supplibs   Use dynamic system libraries to support optional features when
+                          required libs are not present in "supplibs" directory. [[default=yes]] 
+  --disable-dyn-supplibs  Do not use system libraries; look only in GrADS "supplibs" directory.
+                          Use this option to maximize binary portability. 
+],, 
+[enableval=yes])
+case "${enableval}" in
+  yes)
+    ga_dyn_supplibs=yes
+  ;;
+  no)
+    ga_dyn_supplibs=no
+  ;;
+esac
+
+
+AC_MSG_CHECKING([whether to use dynamic linking])
+if test "$ga_dyn_supplibs" = "yes" ; then
+   AC_MSG_RESULT([yes (Warning: binaries may not be suitable for distribution)])
+else
+   AC_MSG_RESULT([no])
+fi
+
+
+AC_ARG_VAR(SUPPLIBS, 
+           [Custom path (must be absolute) to a GrADS supplib distribution])
+
+
+
+# ----------------------------------------------------
+# Check for optional feature support
+# ----------------------------------------------------
+
+use_gui=no
+use_freq=no
+use_xaw_xlibs=no
+use_readline=no
+have_tiff=no
+use_geotiff=no
+have_zlib=no
+have_libpng=no
+have_jpeg=no
+use_printim=no
+use_grib2=no
+have_udunits=no
+use_hdf=no
+use_hdf5=no
+use_nc=no
+use_nc4=no
+use_dap=no
+use_gadap=no
+
+# look for libraries to support gui interface
+echo
+if test "$with_gui" != "no" ; then
+  echo "Checking for libraries to support GUI interface ..."
+  GA_CHECK_GUI([
+    use_gui=yes
+    GA_SET_LIB_VAR(gui_libs, [sx])
+    if test z"$gui_libs_Xext" != 'z'; then
+      gui_libs="$gui_libs -lXext"
+    fi
+    gui_libs="$gui_libs -lXaw -lXpm -lXmu -lXt"
+  ])
+  if test $use_gui != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    GA_CHECK_LIBSX([use_gui=yes;use_freq=yes],[use_gui=yes;use_freq=no])
+    gui_libs="$GA_LIBSX_LIBS"
+    grads_xlibs="$XAW_XLIBS"
+    use_xaw_xlibs=yes
+  fi
+fi
+if test $use_gui = "yes" ; then
+# if the gui is built, we use the X flags from Xaw.
+  if test "$use_xaw_xlibs" != 'yes'; then
+    grads_xlibs="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+    AC_SUBST(grads_xlibs)
+  fi
+  if test $use_freq = 'yes'; then
+    AC_DEFINE(USEFREQ, 1, [Use GetFile from freq])
+  else
+    AC_DEFINE(USEFREQ, 0, [Use GetFile from freq])
+  fi
+  GA_SET_INCLUDE_VAR([gui_inc],[libsx]) 
+  AC_SUBST(gui_inc)
+  AC_SUBST(gui_libs)
+  AC_DEFINE(USEGUI, 1, [Enable GUI widgets]) 
+  echo "+ GUI enabled"
+else
+  AC_DEFINE(USEGUI, 0, [Enable GUI widgets]) 
+  echo  "- GUI disabled"
+fi
+
+# look for libraries to support command line editing
+echo
+if test "$with_readline" != "no" ; then
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support command line editing ..."
+    readline_libadd=""
+    GA_SET_FLAGS([" " readline])
+    AC_CHECK_HEADER(readline.h,
+    [ AC_CHECK_HEADER(history.h,
+      [ AC_CHECK_LIB(readline, tgetent, 
+        [ use_readline=yes
+          GA_SET_INCLUDE_VAR([readline_inc],[""])
+          GA_SET_LIB_VAR([readline_libs],[readline])
+        ],
+        [ AC_CHECK_LIB(ncurses, tgetent,
+          [ use_readline=yes
+            GA_SET_INCLUDE_VAR([readline_inc],[""])
+            GA_SET_LIB_VAR([readline_libs],[readline ncurses])
+          ],
+          [ AC_CHECK_LIB(termcap, tgetent,
+            [ use_readline=yes
+              GA_SET_INCLUDE_VAR([readline_inc],[""])
+              GA_SET_LIB_VAR([readline_libs],[readline])
+              readline_libadd=" -ltermcap"
+            ])
+          ])
+        ])
+      ])
+    ])
+    GA_UNSET_FLAGS
+  fi
+  if test $use_readline = "yes" ; then
+    readline_libs="$readline_libs $readline_libadd"
+  else
+    if test "$ga_dyn_supplibs" = "yes" ; then
+      echo
+      echo "Checking in system locations for libraries to support command line editing ..."
+      GA_LIB_READLINE([use_readline=yes readline_libs=""])
+    fi 
+  fi
+fi
+if test $use_readline = "yes" ; then
+  AC_SUBST(readline_inc)
+  AC_SUBST(readline_libs)
+  AC_DEFINE(READLINE, 1, [Enable command line editing]) 
+  echo "+ Command line editing enabled"
+else
+  AC_DEFINE(READLINE, 0, [Enable command line editing]) 
+  echo "- Command line editing disabled"
+fi
+
+# look for libraries to support geotiff
+echo
+if test "$with_geotiff" != "no" ; then
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support geotiff ..."
+    GA_SET_FLAGS([tiff])
+    AC_CHECK_HEADERS([tiff.h tiffio.h], 
+    [ AC_CHECK_LIB([tiff], [main], 
+      [ have_tiff=yes 
+      ])
+    ])
+    GA_UNSET_FLAGS
+    if test "$have_tiff" = "yes" ; then
+      GA_SET_FLAGS([geotiff])
+      AC_CHECK_HEADER(geotiffio.h,
+      [ AC_CHECK_LIB([geotiff], [main], 
+        [ use_geotiff=yes
+          GA_SET_INCLUDE_VAR([geotiff_inc], [tiff geotiff])
+          GA_SET_LIB_VAR([geotiff_libs], [tiff geotiff])
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for geotiff
+  if test "$use_geotiff" != "yes"  -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support geotiff ..."
+    AC_CHECK_GEOTIFF([
+      LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS"
+      geotiff_libs="$GEOTIFF_LIBS"
+      geotiff_inc=$GEOTIFF_CFLAGS
+      use_geotiff='yes'
+    ]) 
+  fi
+fi
+if test "$use_geotiff" != "yes" ; then
+  AC_DEFINE(GEOTIFF, 0, [Enable geotiff])
+  echo "- geotiff disabled" 
+else
+  AC_SUBST(geotiff_inc)
+  AC_SUBST(geotiff_libs)
+  AC_DEFINE(GEOTIFF, 1, [Enable geotiff])
+  echo "+ geotiff enabled" 
+fi
+
+# look for libraries to support shapefiles
+echo
+if test "$with_shp" != "no" ; then
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support shapefiles ..."
+    GA_SET_FLAGS([shapelib shp])
+    AC_CHECK_HEADERS([shapefil.h], 
+    [ AC_CHECK_LIB([shp], [main], 
+      [ use_shp=yes 
+        GA_SET_INCLUDE_VAR([shp_inc], [shapelib shp])
+        GA_SET_LIB_VAR([shp_libs], [shp])
+      ])
+    ])    
+    GA_UNSET_FLAGS
+  fi
+  # here's where we could add a macro to look outside supplibs for shapelib
+fi
+if test "$use_shp" != "yes" ; then
+  AC_DEFINE(USESHP, 0, [Enable shapefile])
+  echo "- shapefile disabled" 
+else
+  AC_SUBST(shp_inc)
+  AC_SUBST(shp_libs)
+  AC_DEFINE(USESHP, 1, [Enable shapefile])
+  echo "+ shapefile enabled" 
+fi
+
+
+# look for libraries to support printim
+echo
+if test "$with_printim" != "no" ; then
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support printim ..."
+    GA_SET_FLAGS([zlib])
+    AC_CHECK_HEADERS([zlib.h], 
+    [ AC_CHECK_LIB([z], [compress], 
+      [ have_zlib=yes 
+      ])
+    ])
+    GA_UNSET_FLAGS
+    GA_SET_FLAGS([libpng12])
+    AC_CHECK_LIB([png12], [main], 
+    [ have_libpng=yes 
+    ])
+    GA_UNSET_FLAGS
+    GA_SET_FLAGS([])
+    AC_CHECK_LIB([jpeg], [main], 
+    [ have_jpeg=yes 
+    ])
+    GA_UNSET_FLAGS
+    if test "$have_zlib" = "yes" -a "$have_libpng" = "yes" ; then
+      GA_SET_FLAGS([gd])
+      AC_CHECK_HEADER(gd.h,
+      [ AC_CHECK_LIB([gd], [gdImageCreate], 
+        [ use_printim=yes
+          GA_SET_INCLUDE_VAR([printim_inc], [gd])
+	  if test "$have_jpeg" = "yes" ; then
+	    GA_SET_LIB_VAR([printim_libs], [gd png12 z jpeg])
+	  else
+  	    GA_SET_LIB_VAR([printim_libs], [gd png12 z])
+          fi
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs
+  if test "$use_printim" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support printim ..."
+    GA_CHECK_LIB_GD(
+    [ use_printim=yes 
+      printim_libs=$GD_LIBS
+      printim_inc=$GD_CFLAGS
+    ])
+  fi
+fi
+if test "$use_printim" != "yes" ; then
+  AC_DEFINE(GXPNG, 0, [Enable printim using zlib, libpng, and libgd])
+  echo "- printim disabled (Warning: gxtran will not be built)" 
+else
+  extra_utils="$extra_utils gxtran"
+  AC_SUBST(printim_inc)
+  AC_SUBST(printim_libs)
+  AC_DEFINE(GXPNG, 1, [Enable printim using zlib, libpng, and libgd])
+  echo "+ printim enabled" 
+fi
+
+# look for libraries to support grib2
+echo
+if test "$with_grib2" != "no" ; then
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support grib2 ..."
+    if test "$have_zlib" = "no" ; then
+      GA_SET_FLAGS([zlib])
+      AC_CHECK_HEADERS([zlib.h], 
+      [ AC_CHECK_LIB([z], [compress], 
+        [ have_zlib=yes 
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+    if test "$have_libpng" = "no" ; then
+      GA_SET_FLAGS([libpng12])
+      AC_CHECK_LIB([png12], [main], 
+      [ have_libpng=yes 
+      ])
+      GA_UNSET_FLAGS
+    fi
+    if test "$have_zlib" = "yes" -a "$have_libpng" = "yes" ; then
+      have_libjasper=no
+      GA_SET_FLAGS([])
+      AC_CHECK_LIB([jasper], [main], 
+      [ have_libjasper=yes 
+      ])
+      GA_UNSET_FLAGS
+      if test "$have_libjasper" = "yes" ; then
+        GA_SET_FLAGS([grib2c])
+        AC_CHECK_HEADER(grib2.h,
+        [ AC_CHECK_LIB([grib2c], [main], 
+          [ use_grib2=yes 
+            GA_SET_INCLUDE_VAR([grib2_inc], [grib2c])
+            GA_SET_LIB_VAR([grib2_libs], [grib2c jasper png12 z])
+          ])
+        ])
+        GA_UNSET_FLAGS
+      fi
+    fi
+  fi
+    # if we haven't got what we need, look outside supplibs for grib2
+  if test "$use_grib2" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for grib2 libraries ..."
+    GA_CHECK_LIB_GRIB2(
+    [ use_grib2=yes 
+      grib2_libs=$G2_LIBS
+    ])
+  fi
+fi
+if test "$use_grib2" != "yes" ; then
+  AC_DEFINE(GRIB2, 0, [Enable grib2])
+  echo "- grib2 disabled " 
+else
+  extra_utils="$extra_utils grib2scan"
+  AC_SUBST(grib2_inc)
+  AC_SUBST(grib2_libs)
+  AC_DEFINE(GRIB2, 1, [Enable grib2])
+  echo "+ grib2 enabled" 
+fi
+
+# check if user wants support for self-describing files?
+echo
+if test "$with_sdf" = "no" ; then 
+  AC_DEFINE(USENETCDF, 0, [Enable netcdf])
+  AC_DEFINE(USEHDF, 0, [Enable hdf4])
+  echo No support for self-describing files:
+  echo "- hdf4 disabled"
+  echo "- hdf5 disabled"
+  echo "- netcdf disabled"
+  echo "- OPeNDAP disabled"
+else
+  # look for libraries to support hdf4
+  # check if supplibs directory exists 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support hdf4 ..."
+    # look for zlib
+    if test "$have_zlib" = "no" ; then
+      GA_SET_FLAGS([zlib])
+      AC_CHECK_HEADERS([zlib.h], 
+      [ AC_CHECK_LIB([z], [compress], 
+        [ have_zlib=yes 
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+    # look for udunits
+    GA_SET_FLAGS([udunits])
+    AC_CHECK_HEADERS([udunits.h], 
+    [ AC_CHECK_LIB([udunits], [utInit], 
+      [ have_udunits=yes 
+      ])
+    ])
+    GA_UNSET_FLAGS	
+    # look for jpeg
+    if test "$have_jpeg" = "no" ; then
+      GA_SET_FLAGS([])
+      AC_CHECK_LIB([jpeg], [main], 
+      [ have_jpeg=yes 
+      ])
+      GA_UNSET_FLAGS
+    fi
+    if test "$have_zlib" = "yes" -a "$have_udunits" = "yes" -a "$have_jpeg" = "yes" ; then
+      GA_SET_FLAGS([hdf])
+      AC_CHECK_LIB([sz], [main],
+      [ AC_CHECK_HEADER([mfhdf.h],
+        [ AC_CHECK_LIB([df], [main], 
+          [ AC_CHECK_LIB([mfhdf], [main],
+            [ use_hdf=yes 
+              GA_SET_INCLUDE_VAR([hdf_inc], [hdf udunits])
+              GA_SET_LIB_VAR([hdf_libs], [mfhdf df udunits sz jpeg z])
+            ])
+          ])
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for hdf4
+  if test $use_hdf != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support hdf4 ..."
+    GA_CHECK_UDUNITS(
+    [ AC_CHECK_HDF4_NETCDF([use_hdf=yes], [use_hdf=yes])
+      if test "$use_hdf" = 'yes'; then
+        LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+        hdf_libs="$HDF4_LIBS $UDUNITS_LIBS"
+      fi
+    ])
+  fi
+
+  if test $use_hdf != "yes" ; then
+    AC_DEFINE(USEHDF, 0, [Enable hdf4])
+    echo "- hdf4 disabled"  
+  else
+    AC_SUBST(hdf_inc)
+    AC_SUBST(hdf_libs)
+    AC_DEFINE(USEHDF, 1, [Enable hdf4])
+    echo "+ hdf4 enabled"
+  fi
+
+  # look for libraries to support hdf5
+  # check if supplibs directory exists 
+  echo 
+  if test "Z$ga_supplib_dir" != "Z" ; then 
+    echo "Checking in supplibs for libraries to support hdf5 ..."
+    # look for zlib
+    if test "$have_zlib" = "no" ; then
+      GA_SET_FLAGS([zlib])
+      AC_CHECK_HEADERS([zlib.h], 
+      [ AC_CHECK_LIB([z], [compress], 
+        [ have_zlib=yes 
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+    # look for jpeg
+    if test "$have_jpeg" = "no" ; then
+      GA_SET_FLAGS([])
+      AC_CHECK_LIB([jpeg], [main], 
+      [ have_jpeg=yes 
+      ])
+      GA_UNSET_FLAGS
+    fi
+    if test "$have_zlib" = "yes" -a "$have_jpeg" = "yes" ; then
+      GA_SET_FLAGS([hdf5])
+      AC_CHECK_LIB([sz], [main],
+      [ AC_CHECK_HEADER([hdf5.h],
+        [ AC_CHECK_LIB([hdf5], [main], 
+          [ use_hdf5=yes 
+            GA_SET_INCLUDE_VAR([hdf5_inc], [hdf5])
+            GA_SET_LIB_VAR([hdf5_libs], [hdf5 sz z])
+          ])
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+  fi
+  # if we haven't got what we need, look outside supplibs for hdf5
+  if test "$use_hdf5" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+    echo
+    echo "Checking in system locations for libraries to support hdf5 ..."
+    AC_CHECK_HDF5([
+      LDFLAGS="$LDFLAGS $HDF5_LDFLAGS"
+      hdf5_libs="$HDF5_LIBS"
+      hdf5_inc=$HDF5_CFLAGS
+      use_hdf5='yes'
+    ])
+  fi
+
+  if test $use_hdf5 != "yes" ; then
+    AC_DEFINE(USEHDF5, 0, [Enable hdf5])
+    echo "- hdf5 disabled"  
+  else
+    AC_SUBST(hdf5_inc)
+    AC_SUBST(hdf5_libs)
+    AC_DEFINE(USEHDF5, 1, [Enable hdf5])
+    echo "+ hdf5 enabled"
+
+    # now that we have hdf5, look for libraries to support netcdf-4
+    # check if supplibs directory exists 
+    echo 
+    if test "Z$ga_supplib_dir" != "Z" ; then 
+      echo "Checking in supplibs for libraries to support netcdf-4 ..."
+      if test "$have_udunits" = "no" ; then
+        GA_SET_FLAGS([udunits])
+        AC_CHECK_HEADERS([udunits.h], 
+        [ AC_CHECK_LIB([udunits], [utInit], 
+          [ have_udunits=yes 
+          ])
+        ])
+        GA_UNSET_FLAGS
+      fi
+      if test "$have_udunits" = "yes" ; then
+        # look for netcdf4
+        GA_SET_FLAGS([netcdf])
+        AC_CHECK_HEADER([netcdf.h],
+        [ AC_CHECK_LIB([netcdf], [main],
+          [ AC_CHECK_LIB([hdf5_hl], [main], 
+            [ AC_CHECK_LIB(curl,main,
+              [ use_nc4="yes"
+                GA_SET_INCLUDE_VAR(nc_inc, [udunits netcdf])
+                GA_SET_LIB_VAR(nc_libs, [udunits netcdf hdf5_hl hdf5 z sz curl])
+              ])
+            ])
+          ])
+        ])
+        GA_UNSET_FLAGS
+	# set these before calling the macros to look outside of supplibs
+ 	AC_SUBST(nc_inc)
+        AC_SUBST(nc_libs)
+        NC_CONFIG=${ga_supplib_dir}/bin/nc-config
+      fi
+    fi
+    #  if we haven't got what we need, look outside supplibs for netcdf-4
+    if test "$use_nc4" != "yes" -a "$ga_dyn_supplibs" = "yes" ; then
+        GA_CHECK_UDUNITS(
+        [ AC_CHECK_NETCDF(
+          [ use_nc4=yes 
+            LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+            nc_libs="$NC_LIBS $UDUNITS_LIBS"
+            nc_inc="$NC_CFLAGS $UDUNITS_CFLAGS"
+          ],,
+          [])
+        ])
+       NC_CONFIG="`pkg-config --variable=prefix netcdf`/bin/nc-config"
+    fi
+    if test $use_nc4 != "yes" ; then
+      AC_DEFINE(USENETCDF, 0, [Enable netcdf])
+      AC_DEFINE(HAVENETCDF4, 0, [Enable netcdf4])
+      echo "- netcdf-4 disabled"  
+    else
+      AC_DEFINE(USENETCDF, 1, [Enable netcdf])
+      AC_DEFINE(HAVENETCDF4, 1, [Enable netcdf4])
+      echo "+ netcdf-4 enabled"
+      # find out if it is dap-enabled
+      use_dap=`$NC_CONFIG --has-dap`
+      if test $use_dap = "yes" ; then
+        AC_DEFINE(USEDAP, 1, [Enable OPeNDAP for grids])
+      fi
+    fi
+  fi
+
+  # look for libraries to support netcdf
+  # check if we've already enabled netcdf-4
+  echo
+  if test $use_nc4 != "yes" ; then
+    # check if supplibs directory exists 
+    if test "Z$ga_supplib_dir" != "Z" ; then 
+      if test $use_nc != "yes" ; then
+        echo "Checking in supplibs for libraries to support netcdf-3 ..."
+        if test "$have_udunits" = "no" ; then
+          GA_SET_FLAGS([udunits])
+          AC_CHECK_HEADERS([udunits.h], 
+          [ AC_CHECK_LIB([udunits], [utInit], 
+            [ have_udunits=yes 
+            ])
+          ])
+          GA_UNSET_FLAGS
+        fi
+        if test "$have_udunits" = "yes" ; then
+          GA_SET_FLAGS([netcdf])
+          AC_CHECK_HEADER([netcdf.h],
+          [ AC_CHECK_LIB([netcdf], [main],
+            [ use_nc="yes"
+              GA_SET_INCLUDE_VAR(nc_inc, [udunits netcdf])
+              GA_SET_LIB_VAR(nc_libs, [netcdf udunits])
+            ])
+          ])
+          GA_UNSET_FLAGS
+        fi
+      fi
+      # if we haven't got what we need, look outside supplibs
+      if test $use_nc != "yes"  -a "$ga_dyn_supplibs" = "yes" ; then
+        echo
+        echo "Checking in system locations for libraries to support netcdf-3 ..."
+        # check for netcdf 3 
+        GA_CHECK_UDUNITS(
+        [ AC_CHECK_NETCDF(
+          [ use_nc=yes 
+            LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+            nc_libs="$NC_LIBS $UDUNITS_LIBS"
+          ],,
+          [3])
+        ])
+      fi
+    fi
+    if test $use_nc = "yes" ; then
+      AC_SUBST(nc_inc)
+      AC_SUBST(nc_libs)
+      AC_DEFINE(USENETCDF, 1, [Enable netcdf])
+      echo "+ netcdf enabled"
+    else
+      AC_DEFINE(USENETCDF, 0, [Enable netcdf])
+      echo "- netcdf disabled"
+    fi
+  fi
+
+  # look for libraries to support OPeNDAP station data interface
+  # check if supplibs directory exists 
+  echo
+  if test "$with_gadap" = "no" ; then 
+    AC_DEFINE(USEGADAP, 0, [Enable OPeNDAP for station data])
+    echo "- OPeNDAP for station data disabled"
+  else
+    if test "Z$ga_supplib_dir" != "Z" ; then 
+      echo "Checking in supplibs for libraries to support OPeNDAP station data access ..."
+      GA_SET_FLAGS([gadap])
+      AC_CHECK_HEADER(gadap.h,
+      [ AC_CHECK_LIB(gadap,main,
+        [ AC_CHECK_LIB(dap,main,
+          [ AC_CHECK_LIB(dapclient,main,
+            [ AC_CHECK_LIB(xml2,main,
+              [ AC_CHECK_LIB(curl,main,
+                [ use_gadap="yes"
+                  GA_SET_INCLUDE_VAR(gadap_inc, [gadap])
+                  GA_SET_LIB_VAR(gadap_libs, [gadap dapclient dap curl xml2 z])
+                ])
+              ])
+            ])
+          ])
+        ])
+      ])
+      GA_UNSET_FLAGS
+    fi
+    #  here's where you would add code for looking outside of supplibs
+    if test $use_gadap = "yes" ; then
+      # add linking options
+      if test "$is_darwin" = "yes" ; then 
+        dap_extra_libs="-lpthread -lm -liconv"
+      else
+        dap_extra_libs="-lpthread -lm -ldl -lrt"
+      fi
+      # merge gadap and extras
+      dap_libs="$gadap_libs $dap_extra_libs"
+      # 
+      AC_SUBST(gadap_inc)
+      AC_SUBST(dap_libs)
+      AC_DEFINE(USEGADAP, 1, [Enable OPeNDAP for station data])
+      echo "+ OPeNDAP for station data enabled"
+    else
+      AC_DEFINE(USEGADAP, 0, [Enable OPeNDAP for station data])
+      echo "- OPeNDAP for station data disabled"
+    fi
+  fi
+fi
+# end of if $with_sdf test
+echo
+
+#  ----------------------------------------------------
+# Send test results to makefile and config.h
+# ----------------------------------------------------
+
+# Some non-configuration-dependent GrADS macros
+AC_DEFINE(GRADS_VERSION, "AC_PACKAGE_VERSION", [GrADS version])
+AC_DEFINE(GRADS_DESC,, [Obsolete feature description string])
+
+# These are used to add the necessary source files to Makefile targets
+AM_CONDITIONAL(READLINE, [ test "$use_readline"  = "yes" ] )
+AM_CONDITIONAL(USEGUI,   [ test "$use_gui"  = "yes" ] )
+AM_CONDITIONAL(GXPNG,    [ test "$use_printim"  = "yes" ] )
+AM_CONDITIONAL(GEOTIFF,  [ test "$use_geotiff"  = "yes" ] )
+AM_CONDITIONAL(USESHP,   [ test "$use_shp"  = "yes" ] )
+AM_CONDITIONAL(USEGADAP, [ test "$use_gadap" = "yes" ] )
+AM_CONDITIONAL(USEDAP,   [ test "$use_dap" = "yes" ] )
+AM_CONDITIONAL(USEHDF,   [ test "$use_hdf" = "yes" ] )
+AC_SUBST(extra_utils)
+
+# Host specific linker flags
+AC_SUBST(host_ldadd)
+
+
+dnl ----------------------------------------------------
+dnl Print summary and write output files
+dnl ----------------------------------------------------
+
+build_date=`date +%D`
+build_host=`uname -sr`
+build_info="Built `date` for ${host}"
+
+   echo \
+"  +=========================================================================+"
+   echo "   GrADS "AC_PACKAGE_VERSION ":" $build_info
+   echo \
+"  +=========================================================================+"
+   echo     
+   echo "  +-------------------------------+"
+   echo "  |                               |"
+   echo "  |  GrADS will be built with:    |"
+   echo "  |                               |"
+if test "$use_gui" = "yes" ; then
+   echo "  |  + GUI enabled                |"
+else
+   echo "  |  - GUI disabled               |"
+fi 
+if test "$use_readline" = "yes" ; then
+   echo "  |  + readline enabled           |"
+else
+   echo "  |  - readline disabled          |"
+fi 
+if test "$use_geotiff" = "yes" ; then
+   echo "  |  + geotiff enabled            |"
+else
+   echo "  |  - geotiff disabled           |"
+fi 
+if test "$use_shp" = "yes" ; then
+   echo "  |  + shapefile enabled          |"
+else
+   echo "  |  - shapefile disabled         |"
+fi 
+if test "$use_printim" = "yes" ; then
+   echo "  |  + printim enabled            |"
+else
+   echo "  |  - printim disabled           |"
+fi 
+if test "$use_grib2" = "yes" ; then
+   echo "  |  + grib2 enabled              |"
+else
+   echo "  |  - grib2 disabled             |"
+fi 
+if test "$use_hdf" = "yes" ; then
+   echo "  |  + hdf4 enabled               |"
+else
+   echo "  |  - hdf4 disabled              |"
+fi 
+if test "$use_hdf5" = "yes" ; then
+   echo "  |  + hdf5 enabled               |"
+else
+   echo "  |  - hdf5 disabled              |"
+fi 
+if test "$use_nc4" = "yes" ; then
+   echo "  |  + netcdf-4 enabled           |"
+else
+  if test "$use_nc" = "yes" ; then
+     echo "  |  + netcdf-3 enabled           |"
+  else 
+     echo "  |  - netcdf disabled            |"
+  fi 
+fi 
+
+
+if test "$use_gadap" = "yes" -o "$use_dap" = "yes" ; then
+  echo "  |  + OPeNDAP enabled            |"
+  if test "$use_gadap" = "yes" -a "$use_dap" = "yes" ; then
+    echo "  |     for grids and stn data    |"
+  else
+    if test "$use_gadap" = "yes" ; then
+      echo "  |     for stn data only         |"
+    else
+      echo "  |     for grids only            |"
+    fi
+  fi
+else
+  echo "  |  - OPeNDAP disabled           |"
+fi
+if test "$use_printim" != "yes" ; then
+   echo "  |                               |"
+   echo "  |  gxtran will not be built     |"
+fi
+if test "$use_grib2" != "yes" ; then
+   echo "  |  grib2scan will not be built  |"
+fi
+   echo "  |                               |"
+   echo "  +-------------------------------+"
+
+echo "configure: creating src/VERSION"
+echo AC_PACKAGE_VERSION > src/VERSION
+
+echo "configure: creating src/buildinfo.h"
+mkdir -p src
+echo "static char *buildinfo = \"${build_info}\";" > src/buildinfo.h
+
+AC_CONFIG_FILES([Makefile src/Makefile])
+AC_OUTPUT
+
+echo
+echo "Run 'make && make install' to build GrADS."
+echo "Executables will be installed" \
+     "to bin/ in current dir, unless prefix was specified."
+echo
diff --git a/doc/16colors.html b/doc/16colors.html
new file mode 100644
index 0000000..52498ab
--- /dev/null
+++ b/doc/16colors.html
@@ -0,0 +1,60 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Default Colors</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2>The GrADS Default colors</h2>
+<p>
+<pre>
+Col#  Description   Sample    R   G   B 
+<br>
+  0   background    <img src="images/dot_b.gif"  width=50 height=12>   0   0   0 (black by default)<br>
+  1   foreground    <img src="images/dot_w.gif"  width=50 height=12> 255 255 255 (white by default)<br>
+  2   red           <img src="images/dot_2.gif"  width=50 height=12> 250  60  60 <br>
+  3   green         <img src="images/dot_3.gif"  width=50 height=12>   0 220   0 <br>
+  4   dark blue     <img src="images/dot_4.gif"  width=50 height=12>  30  60 255 <br>
+  5   light blue    <img src="images/dot_5.gif"  width=50 height=12>   0 200 200 <br>
+  6   magenta       <img src="images/dot_6.gif"  width=50 height=12> 240   0 130 <br>
+  7   yellow        <img src="images/dot_7.gif"  width=50 height=12> 230 220  50 <br>
+  8   orange        <img src="images/dot_8.gif"  width=50 height=12> 240 130  40 <br>
+  9   purple        <img src="images/dot_9.gif"  width=50 height=12> 160   0 200 <br>
+ 10   yellow/green  <img src="images/dot_10.gif" width=50 height=12> 160 230  50 <br>
+ 11   medium blue   <img src="images/dot_11.gif" width=50 height=12>   0 160 255 <br>
+ 12   dark yellow   <img src="images/dot_12.gif" width=50 height=12> 230 175  45 <br>
+ 13   aqua          <img src="images/dot_13.gif" width=50 height=12>   0 210 140 <br>
+ 14   dark purple   <img src="images/dot_14.gif" width=50 height=12> 130   0 220 <br>
+ 15   gray          <img src="images/dot_15.gif" width=50 height=12> 170 170 170 <br>
+</pre>
+
+<h2>The GrADS Default Rainbow Sequence</h2>
+<p>
+<pre>
+Col#  Description   Sample    R   G   B 
+<br>
+  9   purple        <img src="images/dot_9.gif"  width=50 height=12>  160   0 200 <br>
+ 14   dark purple   <img src="images/dot_14.gif" width=50 height=12>  110   0 220 <br>
+  4   dark blue     <img src="images/dot_4.gif"  width=50 height=12>   30  60 255 <br>
+ 11   medium blue   <img src="images/dot_11.gif" width=50 height=12>    0 160 255 <br>
+  5   light blue    <img src="images/dot_5.gif"  width=50 height=12>    0 200 200 <br>
+ 13   aqua          <img src="images/dot_13.gif" width=50 height=12>    0 210 140 <br>
+  3   green         <img src="images/dot_3.gif"  width=50 height=12>    0 220   0 <br>
+ 10   yellow/green  <img src="images/dot_10.gif" width=50 height=12>  160 230  50 <br>
+  7   yellow        <img src="images/dot_7.gif"  width=50 height=12>  230 220  50 <br>
+ 12   dark yellow   <img src="images/dot_12.gif" width=50 height=12>  230 175  45 <br>
+  8   orange        <img src="images/dot_8.gif"  width=50 height=12>  240 130  40 <br>
+  2   red           <img src="images/dot_2.gif"  width=50 height=12>  250  60  60 <br>
+  6   magenta       <img src="images/dot_6.gif"  width=50 height=12>  240   0 130 <br>
+</pre>
+
+<p>
+<font size=-1>Disclaimer: The color samples may not be displayed properly.</font>
+
+</body>
+</html>
+
+
+
+
diff --git a/doc/GrADS.css b/doc/GrADS.css
new file mode 100644
index 0000000..39cb790
--- /dev/null
+++ b/doc/GrADS.css
@@ -0,0 +1,19 @@
+.banner18 {  font-family: Arial, Helvetica, sans-serif; font-size: 18pt; font-style: normal; font-weight: bold; color: #333399}
+.banner24 { font-family: Arial, Helvetica, sans-serif; font-size: 24pt; font-style: normal; font-weight: bold; color: #333399 }
+.fineprint { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-style: normal; font-weight: normal; color: #000000}
+.item14 { font-family: Arial, Helvetica, sans-serif; font-size: 14pt; font-style: normal; font-weight: normal}
+.item16 { font-family: Arial, Helvetica, sans-serif; font-size: 16pt; font-style: normal; font-weight: normal; color: #000000}
+.item12 { font-family: Arial, Helvetica, sans-serif; font-size: 12pt; font-style: normal; font-weight: normal; color: #000000}
+.item10 { font-family: Arial, Helvetica, sans-serif; font-size: 10pt; font-style: normal; font-weight: normal; color: #000000}
+.plaintext { font-family: Arial, Helvetica, sans-serif; font-size: 10pt; font-style: normal; font-weight: normal}
+.plaintextbold { font-family: Arial, Helvetica, sans-serif; font-size: 10pt; font-style: normal; font-weight: bold}
+.item11 { font-family: Arial, Helvetica, sans-serif; font-size: 11pt; font-style: normal; font-weight: normal; color: #000000}
+.item10bold { font-family: Arial, Helvetica, sans-serif; font-size: 10pt; font-style: normal; font-weight: bold; color: #000000}
+.banner22 { font-family: Arial, Helvetica, sans-serif; font-size: 22pt; font-style: normal; font-weight: bold; color: #333399 }
+.banner20 { font-family: Arial, Helvetica, sans-serif; font-size: 20pt; font-style: normal; font-weight: bold; color: #333399 }
+.code {  font-family: "Courier New", Courier, mono; font-size: 10pt; font-style: normal; font-weight: normal}
+.codeitalic { font-family: "Courier New", Courier, mono; font-size: 10pt; font-style: italic; font-weight: normal }
+.item12bold { font-family: Arial, Helvetica, sans-serif; font-size: 12pt; font-style: normal; font-weight: bold; color: #000000}
+.fineprintbold { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-style: normal; font-weight: bold; color: #000000 }
+.headingnew { font-family: "Arial Narrow"; font-size: 22pt; font-style: normal; font-weight: bold; color: #000000 ; text-decoration: underline}
+.item9 { font-family: Arial, Helvetica, sans-serif; font-size: 9px; font-style: normal; font-weight: normal; color: #000000 }
diff --git a/doc/SDFdescriptorfile.html b/doc/SDFdescriptorfile.html
new file mode 100644
index 0000000..f0b08a7
--- /dev/null
+++ b/doc/SDFdescriptorfile.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>How to Generate NetCDF Descriptor Files</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="GrADS.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>

<body bgcolor="e0f0ff">
<p class="item16"><b>Reading NetCDF and HDF Files with GrADS</b></p>
<p class="plaintext">Data files in the NetCDF and HDF file formats are called 
  self-describing files (SDF) because the data and metadata are packaged together 
  in the same file. GrADS can read data NetCDF and HDF formatted files, as long as the data are on a regular grid. The HDF format is very general; the GrADS interface is limited to gridded data sets that fit into the internal 5-D  lon/lat/lev/time/ensemble grid space. GrADS handles HDF4  Scientific Data Sets and (as of <span class="style1">version 2.0.a7</span>)  some HDF5 files. In order to read the data in SDFs, GrADS needs a certain amount of  metadata in order to place the data 
  in the internal grid space. There are three ways 
  to do this: </p>
<ol>
  <li class="plaintext">Use the <a href="gradcomdsdfopen.html"><code>sdfopen</code></a> 
    command to open the file. This requires the least amount of effort for the 
    user -- simply provide the file name (or an OPeNDAP URL) and GrADS does the 
    rest. If you use the sdfopen command to open your SDF, then all the metadata 
    in the file that GrADS requires must conform to the 
	<a href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html" target="_parent">COARDS 
    conventions</a>. The 'sdfopen' interface does not support the HDF5 format. If sdfopen doesn't work, then ...<br>
    <br>
  </li>
  <li class="plaintext">Use the <code><a href="gradcomdxdfopen.html">xdfopen</a></code> 
    command to open the file. This requires a bit more effort for the user -- 
    you must write a data descriptor file to supplement or replace the existing 
    metadata so that GrADS can understand it. The syntax of the descriptor file 
    used with xdfopen is not exactly the same as that used in a descriptor file 
    for gridded binary data -- see the <a href="gradcomdxdfopen.html">documentation 
    page</a> for further details. The xdfopen command provides access to a greater 
    number of SDFs, including many that do not conform to any known standard. 
    The 'xdfopen' interface does not support the HDF5 format. If xdfopen doesn't work, then ... <br>
    <br>
  </li>
  <li class="plaintext">Use the <code><a href="gradcomdopen.html">open</a></code> 
    command to open the file. This requires the user to write a complete GrADS 
    descriptor file to override all the metadata in the file. Guidance for composing 
    a complete descriptor file for NetCDF, HDF-SDS, or HDF5 gridded data files is given below. 
    Please also see the reference page <a href="descriptorfile.html">Elements 
    of a Data Descriptor File</a>. The 'open' interface is recommended if you 
    are templating large numbers of data files together, the data are pre-projected 
    onto a non-lat/lon grid, the variables in the file have different undefined 
    values, or the variables in the file have been packed in a non-standard way. The 'open' interface is the only way to read HDF5 files. </li>
 </ol>
 
<span class="item16"><b>NetCDF and HDF-SDS Descriptor File Components</b> </span>
<p class="plaintext">The data descriptor file is free format, which means the 
  components of each record (line of text) are blank delimited and can appear 
  in any order. Leading blanks at the beginning of each record are removed before 
  parsing. Individual records may not be more than 255 characters long. Each record 
  begins with a specific entry name, followed by a number of arguments or keywords, 
  depending on the entry.</p>
<p class="plaintext">Descriptor file entries used for NetCDF, HDF-SDS, and HDF5 files 
  are: </p>
<table width="700" cellpadding="2" cellspacing="5" class="plaintext">
  <tr bgcolor="#b8d8dd"> 
    <td width="76" class="plaintext">DSET</td>
    <td width="609" class="plaintext">This entry points to the data file. See 
      the <a href="descriptorfile.html#DSET">reference page</a> for more details.</td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext">DTYPE </td>
    <td class="plaintext">This entry should have either the 'netcdf' or 'hdfsds' keywords. <br>
      (<span class="style1">GrADS version 2.0.a7+</span>) For HDF5, use the 'hdf5_grid' keyword.</td>
   </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext">TITLE</td>
    <td class="plaintext">It is good general practice to include a descriptive 
      title in every GrADS descriptor file. </td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext">UNDEF</td>
    <td><p class="plaintext">This entry specifies the undefined or missing data 
        value. An optional second argument is the name of the attribute in the 
        SDF that contains the undefined value. This should be used when individual 
        variables in the data file have different undefined values. After data 
        I/O, the missing values in the grid are converted from the variable undef 
        to the file-wide undef (the numerical value in the first argument of the 
        UNDEF record). Then it appears to GrADS that all variables have the same 
        undef value, even if they don't in the SDF. Attribute names are case sensitive, 
        and it is assumed that the name is identical for all variables in the 
        SDF. If the name given does not match any attributes, or if no name is 
        given, the file-wide undef value will be used. <br>
        Example: UNDEF -9.99e8 _FillValue</p></td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td> <span class="plaintext">UNPACK</span></td>
    <td >This 
      entry is used for data variables that are 'packed' -- i.e. non-float data 
      that need to be converted to float by applying the following formula: <br> 
	       y = x * <em>scale_factor</em> 
      + <em>add_offset</em><br>
      Only the attribute name for the scale factor is required. If your SDF does 
      not have an offset attribute, the 2nd argument may be omitted, and the offset 
      will be assigned the default value of 0.0. Attribute names are case sensitive, 
      and it is assumed that the names are identical for all variables in the 
      netcdf or hdfsds data file. If the names given do not match any attributes, 
      the scale factor will be assigned a value of 1.0 and the offset will be 
      assigned a value of 0.0. The transformation of packed data is done after 
      the undef test has been applied. <br>
      Examples: <br>
      UNPACK scale_factor add_offset<br>
      UNPACK Slope Intercept</td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext"> OPTIONS</td>
    <td class="plaintext">Valid keywords are 'yrev', 'zrev', 'template', and '365_day_calendar'.</td>
  </tr>
  <tr bgcolor="#b8d8dd">
    <td class="plaintext">CACHESIZE</td>
    <td class="plaintext">(<font color="#990000">GrADS version 2.0.a8+</font>) 
    This entry overrides the default size of the cache for reading HDF5 or NetCDF4 files. It is not relevant for other data types. It should not be necessary to set the cache size explicitly unless the data file has especially large chunks. Please see the documentation on <a href="compression.html">compression</a>. </td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext">PDEF</td>
    <td class="plaintext"> (<font color="#990000">GrADS version 1.9b4+</font>) 
      This is used when the SDF contains data on a native projection other than 
      lat/lon, such as a lambert conformal or polar stereographic grid. See the 
      <a href="pdef.html">PDEF documentation</a> for more information.</td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext"> XDEF<br>
      YDEF<br>
      ZDEF<br>
      TDEF<br>
      EDEF</td>
    <td class="plaintext">These entries are used to describe the coordinate dimensions 
      in the SDF. The syntax is the same as for binary files. See the <a href="descriptorfile.html#DSET">reference 
      page</a> for more details. You can use the output from ncdump with the -c 
      option to get information about the coordinate dimensions in the SDF. </td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext"> VECTORPAIRS</td>
    <td> <p class="plaintext">This entry is for explicity identifying vector component 
        pairs. The VECTORPAIRS entry is only necessary if the data are on a native 
        projection other than lat/lon (i.e. you are using <a href="pdef.html">PDEF</a>) 
        and if the winds have to be <a href="pdef.html#rotation">rotated</a> from 
        a grid-relative sense to an Earth-relative sense. (GrADS has to retrieve 
        both the u and v component in order to do the rotation calculation.)</p>
      <p class="plaintext"> The arguments are the <i>U-component</i> and <i>V-component 
        </i> variable names, separated by a comma, with no spaces. More than one 
        pair of components may be listed; in this case, the pairs should be separated 
        by a space. <br>
        Example:<br>
        VECTORPAIRS  u,v  u10,v10  uflx,vflx</p></td>
  </tr>
  <tr bgcolor="#b8d8dd"> 
    <td class="plaintext"> VARS<br>
      through <br>
      ENDVARS</td>
    <td><p class="plaintext">The variable declarations in a SDF descriptor file 
        have a few special features, described below. It is not necessary to include 
        a variable declaration for all the variables in the SDF, only those you 
        wish to read with GrADS.</p>
      <p class="plaintext">The <em>varname </em>field has the following syntax: 
        <br>
            <em>SDF_name</em>=><em>grads_name</em> <br>
        <em>SDF_name</em> must exactly match the data variable name in the SDF 
        -- it may contain uppercase letters and non-alpha-numeric characters. 
        The <em>grads_name</em> is an alias for <em>SDF_name</em> and must be 
        less than 16 characters, start with an alphabetic character, and cannot 
        contain any upper case letters or non-alpha-numeric characters. The aliasing 
        of variable names may be omitted (i.e., "<em>SDF_name</em>=>" 
        does not precede <em>grads_name</em>) if the <em>SDF_name</em> already 
        meets the criteria for GrADS variable names listed above. For dtype hdf5_grid, the <em>SDF_name</em> must contain the names of all the nested groups (separated by "/") to which the data set belongs (see example below).</p>
      <p class="plaintext">The<em> levs</em> field is an integer that specifies 
        the number of vertical levels the variable contains. Variables that do 
        not have a Z dimension should have a <i>levs</i> value of 0. Variables 
        that do have a Z dimension should have a <em>levs</em> value equal to 
        the <em>znum</em> value specified in the ZDEF statement.</p>
      <p class="plaintext">The <em>units</em> field is a comma-delimited list 
        of the varying dimensions of the variable. The dimensions are expressed 
        as x, y, z, t, and e and correspond to the five axes defined by XDEF, YDEF, 
        ZDEF, TDEF, and EDEF. The order of the dimensions listed in the <em>units</em> 
        field is important -- it must describe the shape of the variable as it 
        was written to the SDF data file. For NetCDf files, this information appears 
        in the output from ncdump next to the variable name. For HDF5 files, this information appears in the output from h5dump as the variable's dataspace.</p>
      <p class="plaintext">Examples:<br>
        Height=>hgt   17   t,z,y,x   Geopotential 
        Height (m) <br>
        /HDFEOS/GRIDS/ColumnAmountNO2/Data~Fields/CloudFraction=>cf  15  z,y,x  Cloud Fraction <br>
    </td>
  </tr>
</table>

    
<p class="item16"><strong>Usage Notes</strong> </p>
<ol>
  <li class="plaintext">The NetCDF data types that GrADS currently handles are 
    short, long, and float. The HDF-SDS data types that are handled are 8-bit 
    ints (int8 and uint8), shorts (int16 and uint16), ints (int32 and uint32) 
    and float. These are all converted to type float after the I/O is done.<br>
    <br>
  </li>
  <li class="plaintext"> The <a href="gradcomdsdfopen.html">sdfopen</a>/<a href="gradcomdxdfopen.html">xdfopen</a> 
    interface will automatically handle the unpacking of NetCDF data if the following 
    conditions are met:<br>
       a. The packed data type is "short" <br>
       b. The constants used for the transformation are data type 
    "float" <br>
       c. The attribute names are "scale_factor" or "slope" 
    and "add_offset" or "intercept"<br>
    If the packed data in your SDF does not fit this description, then you must 
    use the <a href="gradcomdopen.html">open</a> command with a complete descriptor 
    file, providing the attribute names in the <a href="#unpack">UNPACK</a> entry. 
    In this case, the attribute data type may be short, long, float, or double.<br>
    <br>
  </li>
  <li class="plaintext">If the data in the SDF are not floating-point numbers 
    and require a transformation using the attributes named in the <a href="#unpack">UNPACK</a> 
    entry, GrADS assumes the variable undef value corresponds to the data values 
    as they appear in the file, i.e., <em>before</em> they are transformed using 
    a scale factor and offset. Missing packed data values are assigned the file-wide 
    undef value and are never unpacked. <br>
    <br>
  </li>
 
  <li class="plaintext">If your data file contains a variable that varies in a non-world-coordinate 
  dimension (e.g. histogram interval, spectral band, ensemble number) then you 
  can put a non-negative integer in the list of varying dimensions that will become 
  the array index of the extra dimension. For example: 
<p class="plaintext"> VAR=>hist0   0   0,y,x   
  First historgram interval for VAR<br>
  VAR=>hist1   0   1,y,x   Second historgram 
  interval for VAR<br>
  VAR=>hist2   0   2,y,x   Third histogram interval 
  for VAR </p>
<p class="plaintext">Another option in this example would be to fill the unused 
  Z axis with the histogram intervals: </p>
<p class="plaintext"> ZDEF 3 linear 1 1<br>
  ... <br>
  VAR=>hist   3   z,y,x   VAR Histogram</p>
<p class="plaintext">In this case, it would appear to GrADS that variable 'hist' 
  varies in Z, but the user would have to remember that the Z levels correspond 
  to histogram intervals and not pressure levels. The latter technique makes it 
  easier to slice through the data, but is not the most accurate representation. 
  And if you don't have an unsued world-coordinate axis available, then you still 
  have a way to access all the dimensions of your data<em> </em>variable. </p>
</li>
 <li class="plaintext">Some SDFs have many more than four coordinate dimensions 
    -- staggered longitude and latitude axes are one example. In this case, it 
    is likely that there will be variables defined on different grids contained 
    in the same SDF. GrADS can only handle one 4D grid per data file -- all the 
    SDF variables listed in a descriptor file must share the same coordinate axes. 
    Multiple descriptor files must be written to describe the varibles defined 
    on different grids.<br>
    <br>
  </li></ol>

<p class="item16"><strong>Examples</strong></p>
<ol>
  <li class="plaintext"> Here is a <a href="sample.ncdump">sample output from 
    ncdump</a> for a file containing ocean model output. This file contains eight 
    coordinate dimensions and nine data variables, which are defined on different 
    combinations of coordinate axes. Five separate descriptor files are required 
    to describe all the variables: one for the velocity components <a href="sample_uv.ctl">u 
    and v</a>, another for velocity component <a href="sample_w.ctl">w</a>, a 
    third for <a href="sample_temp.ctl">potential temperature</a>, a fourth for 
    wind stress components <a href="sample_tau.ctl">taux and tauy</a>, and a fifth 
    for surface variables<a href="sample_sfc.ctl"> hflx, sflx, and eta</a>.<br>
    <br>
  </li>
  <li class="plaintext"> The <a href="http://www.wrf-model.org/" target="_parent">Weather Research 
    and Forecasting (WRF) Model</a> can generate NetCDF output on non-lat/lon 
    grids. GrADS can read these files in their native format using a complete 
    descriptor file with a <a href="pdef.html">PDEF</a> entry. To extract the 
    arguments for the PDEF entry, you can use the global attribute values, which 
    describe the native grid parameters, as well as the data variables which provide 
    the grid point lat/lon values. The WRF model uses staggered grids, just as 
    the ocean model does in the example above. For the sake of clarity, this <a href="wrf.ncdump">WRF 
    ncdump output</a> has been edited to show only the four coordinate axes that 
    are relevant for the data variables used in the example descriptor files. 
    There are many, many more data variables and coordinate dimensions in the 
    actual output files. First, here is a sample descriptor file to get the native 
    <a href="wrfgrid.ctl">grid point longitude and latitude</a> values -- note 
    that no PDEF statement is included and the XDEF and YDEF statements do not 
    map to longitude and latitude, they are simply used as abstract grid increments. 
    Any one of these grid points may be used as the reference point in the PDEF 
    entry, this example uses grid point (1,1) with values (-125.898, 26.9628). 
    Finally, here is the descriptor file for <a href="wrfvars.ctl">four data variables</a>. 
    The WRF model is highly configurable, and also under active development, so 
    this example should be used only as a guideline. </li>
</ol>
</body>
</html>
\ No newline at end of file
diff --git a/doc/Tutorial_Espanol.doc b/doc/Tutorial_Espanol.doc
new file mode 100644
index 0000000..7d1c923
Binary files /dev/null and b/doc/Tutorial_Espanol.doc differ
diff --git a/doc/about.html b/doc/about.html
new file mode 100644
index 0000000..92e3871
--- /dev/null
+++ b/doc/about.html
@@ -0,0 +1,55 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>About the GrADS Documentation</title>
+</head>
+<body text="#000000">
+
+<h1>About the GrADS Documentation</h1>
+<p>
+This html version of the GrADS documentation has become the standard
+base documentation for GrADS. If you would like to download a
+compressed tar file containing all the html source code, it is located
+in the GrADS anonymous FTP directory. The most recent version was
+posted on 1 May 2001:
+<p>
+<dd><a href="ftp://grads.iges.org/grads/gadoc_files.tar.Z">
+ftp://grads.iges.org/grads/gadoc_files.tar.Z</a>
+<p>
+<p>
+Although there are no immediate plans to produce a printed version of
+the GrADS documentation, a limited set of html tags were used so that
+a filter could be developed that would make it possible to create a
+printed document from the html source code.
+<p>
+<p>
+<h3>Tags Used</h3>
+
+<p>
+<a href> </a><br>
+<b> </b><br>  
+<body> </body><br>
+<br><br>
+<center> </center><br>
+<code> </code><br>
+<dd><br>
+<font size color> </font><br>
+<h1> </h1><br>
+<h2> </h2><br>
+<h3> </h3><br>
+<hr><br>
+<i> </i><br>
+<li><br>
+<ol> </ol><br>
+<p><br>
+<pre> </pre><br>
+<u> </u><br>
+<ul> </ul><br>
+&lt;<br>
+&gt;<br>
+&nbsp;<br>
+&amp;
+
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/aboutgriddeddata.html b/doc/aboutgriddeddata.html
new file mode 100644
index 0000000..5442d03
--- /dev/null
+++ b/doc/aboutgriddeddata.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Gridded Data</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h1>About GrADS Gridded Data Sets</h1>
<p>
This section describes GrADS gridded data sets -- their structure and
format, how to create them, and how to instruct GrADS to interpret
them properly.  Here are some quick links for skipping through this
section:
<ul>
<li><a href="aboutgriddeddata.html#introduction">Introduction</a>
<li><a href="aboutgriddeddata.html#descriptor">The Data Descriptor File</a>
<li><a href="aboutgriddeddata.html#structure">Structure of a Gridded Binary Data File</a>
<li><a href="aboutgriddeddata.html#formats">Binary Formats</a>
<li><a href="aboutgriddeddata.html#create">Creating Data Files</a>
</ul>

<hr>
<p>
<h2><a name="introduction">Introduction</a></h2>
<p>
In GrADS, the raw binary data and the meta data (information about the
binary data) are stored in separate files. The meta data file contains
a complete description of the binary data as well as instructions for
GrADS on where to find the data and how to read it. The binary data
file is purely data with no space or time identifiers. The meta data
file is the one you open in GrADS -- it is called the <b>data
descriptor file</b>. The data descriptor file has a default file extension of <code>.ctl</code>
 and is therefore also referred to as a <b>control file</b>.
<p>
<code>ga-> <a href="gradcomdopen.html">open</a> <i>filename</i>.ctl</code>


<h2><a name="descriptor">The Data Descriptor File</a></h2>

<p>
The data descriptor file contains a complete description of the binary
data as well as instructions for GrADS on where to find the data and
how to read it. The descriptor file is an ascii file that can be
created easily with a text editor. The general contents of a gridded
data descriptor file are as follows:
<ul>
<li>Filename for the binary data
<li>Missing or undefined data value
<li>Mapping between grid coordinates and world coordinates
<li>Description of variables in the binary data set
</ul>

<p>
The individual components of data descriptor files are discussed in
detail in the section <a href="descriptorfile.html">Elements of a Data
Descriptor File</a>.

<p> The data descriptor file is free format, which means the components of each 
  record (line of text) are blank delimited. Leading blanks at the beginning of 
  each record are removed before parsing. Comment records must start with an asterisk 
  (*). Individual records may not be more than 255 characters long. Here is an 
  example of a basic data descriptor file: 
<p>
<ul>
<pre>
<a href="descriptorfile.html#DSET">DSET</a>  ^gridded_data_sample.dat 
<a href="descriptorfile.html#TITLE">TITLE</a> Gridded Data Sample
<a href="descriptorfile.html#UNDEF">UNDEF</a> -9.99E33
<a href="descriptorfile.html#XDEF">XDEF</a> 180 LINEAR 0.0  2.0 
<a href="descriptorfile.html#YDEF">YDEF</a>  90 LINEAR -90  2.0 
<a href="descriptorfile.html#ZDEF">ZDEF</a>  10 LEVELS 1000 850 700 500 400 300 250 200 150 100 
<a href="descriptorfile.html#TDEF">TDEF</a>   4 LINEAR 0Z10apr1991 12hr 
<a href="descriptorfile.html#VARS">VARS</a>      4
slp     0  99  sea level pressure 
hgt    10  99  heights 
temp   10  99  temperature 
shum    6  99  specific humidity
<a href="descriptorfile.html#ENDVARS">ENDVARS</a>
</pre>
</ul>

<p>
In this example, the binary data set is named
<code>gridded_data_sample.dat</code> and is located in the same
directory as the descriptor file. This is specified by the caret (^) in
front of the data filename. The undefined or missing data value is
-9.99e33, there are 180 grid points in the X direction, 90 grid points
in the Y direction, 10 vertical levels, 4 time steps, and 4
variables. The variable "slp" is a surface variable -- it has no
vertical levels, but is assigned a default vertical coordinate of
Z=1. The variables "hgt" and "temp" have 10 vertical levels, and the
variable "shum" has 6 vertical levels (the first six listed, 1000 to
300).


<p>
<h2><a name="structure">Structure of a Gridded Binary Data File</a></h2>

<p>
The binary data file is purely data with no space or time
identifiers. The data descriptor specifies the data's grid dimensions,
but it is up to the user to make sure that the binary data have been
written to file in the proper order so GrADS will interpret them
correctly.

<p>
GrADS views gridded data sets as multi-dimensional arrays varying in
longitude, latitude, vertical level, variable, and time. In version 2.0, a <a href="ensembles.html">fifth grid dimension</a> was added. The fifth grid dimension is assumed to be used for ensembles, and so it is given the name E (or ens), but because it is generally implemented, it may be used for other grid dimensions such as EOFs. The default size of the E dimension is 1 -- if no E dimension exists, it is not necessary to explicity declare it the descriptor file. 
<p>It is helpful
  to think of a gridded binary data file as a sequence of "building
  blocks", where each building block is a horizonal grid of data varying
  in the X and Y dimensions.  The first dimension (X) always varies from
  west to east; the second dimension (Y) varies from south to north (by
  default).  One horizontal grid represents a particular variable at a
  particular height and time. Each horizontal grid in a GrADS binary data file must be the same
size.  If you have two variables with different horizontal grids,
you must create two separate data sets. 
<p>
The structure of a 3-D, 4-D, or 5-D data set is determined by the
order in which the horizonal grids are written to file. The building
blocks are stacked in a sequence according to dimension. The sequence
goes in the following order starting from the fastest varying
dimension to the slowest varying dimension: longitude (X), latitude
(Y), vertical level (Z), variable (VAR), time (T), and ensemble (E).
<p>
For example, suppose you want to create a 4-D binary data set
containing four variables. The horizonal grids would be written to the
data set in the following order:
<ul>
<pre>
Time 1, Variable 1, Each vertical level from bottom to top
Time 1, Variable 2, Each vertical level from bottom to top
Time 1, Variable 3, Each vertical level from bottom to top
Time 1, Variable 4, Each vertical level from bottom to top

Time 2, Variable 1, Each vertical level from bottom to top
Time 2, Variable 2, Each vertical level from bottom to top
Time 2, Variable 3, Each vertical level from bottom to top
Time 2, Variable 4, Each vertical level from bottom to top

etc.
</pre>
</ul>

<p>5-D ensemble data sets are created by concatenating 4-D data sets together -- the ensemble dimension varies outside of all the others. To extend the previous example, suppose you are creating a data set that has 3 ensembles (but only 2 variables) :
<ul>
<pre>
Ensemble 1, Time 1, Variable 1, Each vertical level from bottom to top
Ensemble 1, Time 1, Variable 2, Each vertical level from bottom to top
Ensemble 1, Time 2, Variable 1, Each vertical level from bottom to top
Ensemble 1, Time 2, Variable 2, Each vertical level from bottom to top
            <...>
Ensemble 1, Time N, Variable 1, Each vertical level from bottom to top
Ensemble 1, Time N, Variable 2, Each vertical level from bottom to top
Ensemble 2, Time 1, Variable 1, Each vertical level from bottom to top
Ensemble 2, Time 1, Variable 2, Each vertical level from bottom to top
Ensemble 2, Time 2, Variable 1, Each vertical level from bottom to top
Ensemble 2, Time 2, Variable 2, Each vertical level from bottom to top
            <...>
Ensemble 2, Time N, Variable 1, Each vertical level from bottom to top
Ensemble 2, Time N, Variable 2, Each vertical level from bottom to top
Ensemble 3, Time 1, Variable 1, Each vertical level from bottom to top
Ensemble 3, Time 1, Variable 2, Each vertical level from bottom to top
Ensemble 3, Time 2, Variable 1, Each vertical level from bottom to top
Ensemble 3, Time 2, Variable 2, Each vertical level from bottom to top
            <...>
Ensemble 3, Time N, Variable 1, Each vertical level from bottom to top
Ensemble 3, Time N, Variable 2, Each vertical level from bottom to top
</pre>
</ul>

<h2><a name="formats">Binary Formats</a></h2>

<p>
GrADS can read binary data that are formatted with or without
FORTRAN record length headers. Files containing record length headers
are called "sequential" and those without embedded record length
information are called "direct access" or "stream" files. Unless 
otherwise specified, GrADS will assume the data file does not contain 
the record length headers. 

<p>
GrADS can also directly read GRIB formatted data -- one of GrADS 
most powerful and unique features! See the section on 
<a href="grib2ctl.html">Creating Data Descriptor Files for GRIB 
Data</a> for more information.

<p>
A third category of data formats that GrADS can read are
"self-describing files" such as NetCDF or HDF-SDS. For more
information, see the references pages for <a
href="sdfdescriptorfile.html">reading NetCDF or HDF-SDS files</a>.
<p>
<h2><a name="create">Creating Data Files</a></h2>

<p>
The default format for GrADS gridded binary data files is "stream" or
"direct access". If you want to read FORTRAN "sequential" unformatted
binary data files, you must include the following additional record in
the data descriptor file:
<ul><code><a href="descriptorfile.html#OPTIONS">OPTIONS</a> sequential</code></ul>
<p>
Following are three examples of how to create gridded binary data
files with simple FORTRAN programs.
<p>
<ol>
<li>Suppose you have U and V wind components in 4-dimensions (X, Y, Z, and T)
and you want to write them out in so they can be viewed in GrADS. The
FORTRAN code might look something like this:
<p>
<pre>
parameter (ni=144,nj=91,nk=8,nt=4) 
dimension u(ni,nj,nk),v(ni,nj,nk),dum(ni,nj) 
do n=1,nk 
   call load(u,ni,nj,nk,n,dum)
   write(10) dum 
end do 
do n=1,nk 
   call load(v,ni,nj,nk,n,dum)
   write(10) dum 
end do 

subroutine load(a,ni,nj,nk,n,dum)
dimension a(ni,nj,nk),dum(ni,nj) 
do i=1,ni 
   do j=1,nj 
   dum(i,j)=a(i,j,n) 
end do 
end do 
return
</pre>

<p>
The data descriptor file would look something like:

<p>
<pre>
<a href="descriptorfile.html#DSET">DSET</a>      ^model.dat 
<a href="descriptorfile.html#TITLE">TITLE</a>     Sample Model Data 
<a href="descriptorfile.html#UNDEF">UNDEF</a>    0.10000E+16 
<a href="descriptorfile.html#XDEF">XDEF</a>     144 linear   0 2.5 
<a href="descriptorfile.html#YDEF">YDEF</a>      91 linear -90 2.0 
<a href="descriptorfile.html#ZDEF">ZDEF</a>       8 levels 1000 900 800 700 500 300 100 50
<a href="descriptorfile.html#TDEF">TDEF</a>       4 linear 00z01apr85 6hr
<a href="descriptorfile.html#VARS">VARS</a>      2 
   u 8 99 U component 
   v 8 99 V component 
<a href="descriptorfile.html#ENDVARS">ENDVARS</a>
</pre>


<p>
<li>This simple example write out one variable:
<p>
<pre>
   REAL  Z(72,46,16)
   ....
   OPEN(8,FILE='grads.dat',FORM='UNFORMATTED',
 & ACCESS='DIRECT',RECL=72*46)
   ....
   IREC=1 
   DO 10 I=1,16
     WRITE (8,REC=IREC) ((Z(J,K,I),J=1,72),K=1,46)
     IREC=IREC+1
10 CONTINUE
</pre>

<p>
<li>Another simple sample might be:
<p>
<pre>
   REAL X(100) 
   DO 10 I=1,100 
     X(I)=I  
10 CONTINUE 
   OPEN (8,FILE='samp.dat',FORM='UNFORMATTED',ACCESS='DIRECT',
  &RECL=100) 
   WRITE (8,REC=1) X 
   STOP 
   END
</pre>

<p>
The associated descriptor file:
<p>
<pre>
<a href="descriptorfile.html#DSET">DSET</a>      samp.dat 
<a href="descriptorfile.html#TITLE">TITLE</a>     Sample Data Set 
<a href="descriptorfile.html#UNDEF">UNDEF</a>    -9.99E33 
<a href="descriptorfile.html#XDEF">XDEF</a>     100 LINEAR 1 1 
<a href="descriptorfile.html#YDEF">YDEF</a>     1 LINEAR 1 1 
<a href="descriptorfile.html#ZDEF">ZDEF</a>      1 LINEAR 1 1 
<a href="descriptorfile.html#TDEF">TDEF</a>      1 LINEAR 1JAN2000 1DY 
<a href="descriptorfile.html#VARS">VARS</a>      1 
x  0  99  100 Data Points 
<a href="descriptorfile.html#ENDVARS">ENDVARS</a>
</pre>

<p>
Once created, you can use this data set to experiment with GrADS
data functions, such as:
<p>
<ul>
<code>
<a href="gradcomddisplay.html">display</a> 
<a href="gradfuncsin.html"> sin</a>(x/50)
</code>
</ul>
</ol>

</body>
</html>

\ No newline at end of file
diff --git a/doc/aboutstationdata.html b/doc/aboutstationdata.html
new file mode 100644
index 0000000..cc4c36f
--- /dev/null
+++ b/doc/aboutstationdata.html
@@ -0,0 +1,378 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>About GrADS Station Data</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h1>About GrADS Station Data</h1>
+<p>
+This section describes the structure of station data files, how to
+create them, and how to instruct GrADS to interpret them properly.
+Please refer to the companion section on <a
+href="usingstationdata.html">Using Station Data</a> for information
+about the GrADS commands and functions that are available for
+analyzing and displaying station data.
+
+Here are some quick links for skipping through this section:
+<ul>
+<li><a href="aboutstationdata.html#station">Structure of a Station Data File</a>
+<li><a href="aboutstationdata.html#create">Creating a Station Data File</a>
+<li><a href="aboutstationdata.html#descriptor">Station Data Descriptor File</a>
+<li><a href="aboutstationdata.html#stnmap">The STNMAP Utility</a>
+</ul>
+<hr>
+<p>
+<h2><a name="station">Structure of a Station Data File</a></h2>
+
+<p>
+Station data are written to a binary file one report at a time.
+Groups of station reports are ordered within the file according to the
+time interval. The time interval for a set of upper air soundings
+might be 12 hours, and the time interval for a set of surface
+observations might be 1 hour.
+
+<p>
+Variables within each report are split into two categories: surface
+and level-dependent. Surface variables are reported at most once per
+report, and level-dependent variable are reported at multiple
+pressure levels within each report.
+
+<p>
+Each station report in a binary station data file has the following structure:
+
+<ul>
+<li>A header which provides information about the location of the station
+<li>Surface variables, if any
+<li>Level dependent variables, if any
+</ul>
+
+<p>
+The header is described by the following C language data structure:
+
+<ul>
+<pre>
+struct reportheader {
+  char  id[8];    /* Station ID */
+  float lat;      /* Latitude of Station */
+  float lon;      /* Longitude of Station */ 
+  float t;        /* Time in grid-relative units */ 
+  int   nlev;	  /* Number of data groups following the header */ 
+  int   flag;     /* Level independent var set flag */ 
+};
+</pre>
+</ul>
+
+<p>
+A detailed description of each header entry follows:
+
+<p>
+<ul>
+
+<code>id</code> 
+<ul>The station ID uniquely identifies the station. It
+can be 1 to 7 characters long and may be assigned arbitrarily; ie. the
+stations could be numbered in some arbitrary order.</ul>
+
+<p>
+<code>lat, lon</code>
+<ul>The location of the station, given in world coordinates (latitude
+and longitude).</ul>
+
+<p>
+<code>t</code>
+<ul>The time of this report, in grid-relative units. This refers to
+the way the stations are grouped in time.  For example, if you are
+working with surface airways reports, you would probably have a time
+grouping interval of one hour. If you wanted to treat the report
+times of each report as being exactly on the hour, you would set t to
+0.0.  If the report was for 12:15pm, and you were writing the time
+group for 12pm, you would set t to be 0.25.  Thus, t would typically
+have the range of - 0.5 to 0.5. </ul>
+
+<p>
+<code>nlev</code>
+<ul>Number of data groups following the header. This is the count of
+the one surface group, if present, plus the number of level dependent
+groups.  Is set to zero to mark the end of a time group in the
+file. </ul>
+
+<p>
+<code>flag</code>
+<ul>If set to <code>0</code>, there are no surface variables following
+the header.  If set to <code>1</code>, then there are surface
+variables following the header.</ul>
+</ul>
+
+<p>
+The surface variable data (if present) are written to file following
+the header.  Surface variables are written out as floating point
+numbers in the order they are listed in the data descriptor file. Each
+of the surface variables must be written -- missing variables should
+contain the missing data value specified in the data descriptor file.
+The group of surface variable data must be the same size for each
+report in the file.
+
+<p>
+The level-dependent variables are written to file following the surface variables
+as follows:
+<ul>
+<code>level    </code>
+-- a floating point value giving the Z dimension in world coordinates for this level. 
+<br>
+<code>variables</code> 
+-- The level-dependent variables for this level.
+</ul>
+<p>
+Each level dependent group must have all the level dependent variables
+present, even if they are filled with the missing data value. The
+group of level dependent variable data must be the same size for all
+levels and all reports in the file.
+
+<p>
+After all the reports for one time grouping have been written, a
+special header (with no data groups -- <code>nlev</code> set to zero)
+is written to indicate the end of the time group. The next time group
+may then start immediately after.  A time group with no reports would
+still contain the time group terminator header record (ie, two
+terminators in a row).
+
+
+<p>
+<h2><a name="create">Creating a Station Data File</a></h2>
+
+<p>
+GrADS station data files must be written out in the structure outlined 
+in the previous section. Examples of C and FORTRAN programs to create station
+data sets are provided below. 
+
+<p>
+Let's say you have a data set with monthly rainfall:
+<p>
+<pre>
+Year   Month  Stid    Lat    Lon    Rainfall
+1980     1     QQQ    34.3  -85.5    123.3 
+1980     1     RRR    44.2  -84.5     87.1 
+1980     1     SSS    22.4  -83.5    412.8
+1980     1     TTT    33.4  -82.5     23.3 
+1980     2     QQQ    34.3  -85.5    145.1
+1980     2     RRR    44.2  -84.5    871.4
+1980     2     SSS    22.4  -83.5    223.1
+1980     2     TTT    33.4  -82.5     45.5
+</pre>
+
+<p>
+A sample DEC FORTRAN program to write this data set in GrADS format is
+given below. Note that the OPEN statement is set to write a stream
+data set. This option may not not available with every compiler. If 
+your program writes out data in sequential format, you must add an 
+<code>"OPTIONS sequential"</code> entry to your GrADS data descriptor file.
+
+<p>
+<pre>
+       CHARACTER*8 STID 
+       OPEN (8,NAME='rain.ch') 
+       OPEN (10,NAME='rain.dat',FORM='UNFORMATTED',RECORDTYPE='STREAM')
+       IFLAG = 0 
+C  Read and Write 
+10     READ (8,9000,END=90) IYEAR,IMONTH,STID,RLAT,RLON,RVAL 
+9000   FORMAT (I4,3X,I2,2X,A8,3F8.1) 
+       IF (IFLAG.EQ.0) THEN
+          IFLAG = 1 
+          IYROLD = IYEAR
+          IMNOLD = IMONTH 
+       ENDIF 
+C  If new time group, write time group terminator. 
+C  Assuming no empty time groups. 
+       IF (IYROLD.NE.IYEAR.OR.IMNOLD.NE.IMONTH) THEN 
+          NLEV = 0 
+          WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG 
+          ENDIF 
+          IYROLD = IYEAR 
+          IMNOLD = IMONTH 
+C  Write this report 
+       TIM = 0.0 
+       NLEV = 1 
+       NFLAG = 1
+       WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG 
+       WRITE (10) RVAL 
+       GO TO 10
+C  On end of file write last time group terminator. 
+90     CONTINUE 
+       NLEV = 0 
+       WRITE (10) STID,RLAT,RLON,TIM,NLEV,NFLAG 
+       STOP
+       END
+</pre>
+
+<p>
+An equivalent C program might be:
+
+<p>
+<pre> 
+#include <stdio.h>
+/* Structure that describes a report header in a stn file */ 
+struct rpthdr {
+  char  id[8];    /* Station ID */
+  float lat;      /* Latitude of Station */
+  float lon;      /* Longitude of Station */ 
+  float t;        /* Time in grid-relative units */ 
+  int   nlev;	  /* Number of levels following */ 
+  int   flag;     /* Level independent var set flag */ 
+} hdr;
+
+main () 
+{
+  FILE  *ifile, *ofile; 
+  char  rec[80]; 
+  int   flag,year,month,yrsav,mnsav,i; 
+  float val;
+
+/* Open files */ 
+  ifile = fopen ("rain.ch","r"); 
+  ofile = fopen ("rain.dat","wb"); 
+  if (ifile==NULL || ofile==NULL) { 
+    printf("Error opening files\n"); 
+    return; 
+  }
+
+/* Read, write loop */
+  flag = 1; 
+  while (fgets(rec,79,ifile)!=NULL) { 
+    /* Format conversion */ 
+    sscanf (rec,"%i %i",&year,&month); 
+    sscanf (rec+20," %g %g %g",&hdr.lat,&hdr.lon,&val); 
+    for (i=0; i<8; i++) hdr.id[i] = rec[i+11]; 
+    /* Time group terminator if needed */ 
+    if (flag) { 
+      yrsav = year; 
+      mnsav = month;
+      flag = 0; 
+    } 
+    if (yrsav!=year || mnsav!=month) { 
+      hdr.nlev = 0; 
+      fwrite(&hdr,sizeof(struct rpthdr), 1, ofile); 
+    } 
+    yrsav = year; 
+    mnsav = month;
+    /* Write this report */ 
+    hdr.nlev = 1;
+    hdr.flag = 1; 
+    hdr.t = 0.0;
+    fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
+    fwrite (&val,sizeof(float), 1, ofile); 
+  } 
+  hdr.nlev = 0; 
+  fwrite (&hdr,sizeof(struct rpthdr), 1, ofile); 
+}
+</pre>
+
+<p>
+<h2><a name="descriptor">Station Data Descriptor File</a></h2>
+
+<p>
+After creating a binary file containing your station data, you must
+write a station data descriptor file so GrADS knows how to interpret
+the binary data file. The format for the data descriptor file for
+station data is similar to the format for a gridded data set, but
+there are a few differences as well as additional entries that are
+unique to station data descriptor files. These differences are
+outlined below. For further information on all the entries of a
+descriptor file, consult the secion of the User's Guide on <a
+href="descriptorfile.html">Elements of a GrADS Data
+Descriptor File</a>.
+
+<p>
+Here is an example of a station data descriptor file. Remember that
+the variables must be listed in the same order as they were written to
+the binary file.
+<p>
+<ul>
+<pre>
+DSET   ^station_data_sample.dat
+DTYPE  station 
+STNMAP station_data_sample.map
+UNDEF  -999.0
+TITLE  Station Data Sample
+TDEF   10 linear 12z18jan1992 12hr
+VARS 11
+ps    0  99  Surface Pressure
+ts    0  99  Surface Temperature
+ds    0  99  Surface Dewpoint Temperature
+us    0  99  Surface U-Wind 
+vs    0  99  Surface V-Wind 
+elev  0  99  Elevation of Station
+z     1  99  Height
+t     1  99  Temperature
+d     1  99  Dewpoint Temperature
+u     1  99  U-Wind
+v     1  99  V-Wind 
+ENDVARS
+</code>
+</ul>
+
+<p>
+Note the following differences between this descriptor file and a gridded data 
+descriptor file:
+<ul>
+<p>
+<code>DTYPE station</code>
+<ul>This entry identifies the data file as station data.</ul>
+
+<p>
+<code>STNMAP <i>filename</i></code>
+<ul>This entry identifies the file name of the station map
+file created by the <a href="gradutilstnmap.html">
+<code>stnmap</code></a> utility.</ul>
+
+<p>
+<code>XDEF, YDEF, </code>and <code>ZDEF</code>
+<ul>These entries are not included in a station data control file.</ul>
+
+<p>
+<code>TDEF</code> 
+<ul>This entry gives the number of the time groups in the file, the
+time stamp for the first group, and the interval between time
+groups.</ul>
+
+<p>
+<code>VARS</code>
+<ul>The surface variables are listed first, and contain a "0" in the
+<code><i>levs</i></code> field. Level-dependent variables are listed
+after the surface variables, and contain a "1" in the
+<code><i>levs</i></code> field.</ul>
+</ul>
+
+<p>
+<a name="stnmap">
+<h3>STNMAP Utility</h3></a>
+<p>
+Once the station data set has been created and the descriptor file has
+been written, the final step is to create the station map file by
+running the <a href="gradutilstnmap.html"><code>stnmap</code></a>
+utility. This utility is executed externally from the command line,
+not from within GrADs. <a
+href="gradutilstnmap.html"><code>stnmap</code></a> writes out
+information that allows GrADS to access the station report data more
+efficiently. The output from <a
+href="gradutilstnmap.html"><code>stnmap</code></a> is called the
+station map file and its name is identified in the <code>STNMAP</code>
+entry of the data descriptor file. <a
+href="gradutilstnmap.html"><code>stnmap</code></a> will prompt the
+user for the name of the data descriptor file, or it can be specified
+as an input argument on the command line. Station map files must be
+created on the machine where they are to be used. Consult the <a
+href="gradutilstnmap.html">reference page</a> for more information.
+
+<p>
+If you change the station data file, perhaps by appending another time group,
+then you will also have to change the descriptor file to reflect the
+changes and then rerun the <a href="gradutilstnmap.html">
+<code>stnmap</code></a> utility.
+</ul>
+
+
+</body>
+</html>
+
diff --git a/doc/advdisplay.html b/doc/advdisplay.html
new file mode 100644
index 0000000..b759521
--- /dev/null
+++ b/doc/advdisplay.html
@@ -0,0 +1,189 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<font size=+2>Graphics Options</font><br>
+<ul><a name="1dgraphics">1-D Graphics</a><p>
+<ul>Line Graphs (gxout = line):<br>
+<a href="gradcomdsetccolor.html">set ccolor</a><br>
+<a href="gradcomdsetcthick.html">set cthick</a><br>
+<a href="gradcomdsetcstyle.html">set cstyle</a><br>
+<a href="gradcomdsetcmark.html">set cmark</a><br>  
+<a href="gradcomdsetmissconn.html">missconn</a><br>
+<a href="gradcomdsetmissconn.html">missconn</a><br>
+</ul><p>
+<ul>Bar Graphs (gxout = bar):<br>
+<a href="gradcomdsetbargap.html">bargap</a><br>
+<a href="gradcomdsetbarbase.html">barbase</a><br>
+<a href="gradcomdsetbaropts.html">baropts</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>  
+</ul><p>
+<ul>Error Bars(gxout = errbar):<br>
+<a href="gradcomdsetccolor.html">set ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>
+<a href="gradcomdsetbargap.html">bargap</a><br>
+<a href="gradcomdsetbarbase.html">barbase</a><br>
+</ul><p>
+<ul>Line Graph Shading (gxout = linefill):<br>
+<a href="gradcomdsetlfcols.html">lfcols</a><br>
+</ul><p>
+<a name="2dgraphics">2-D Gridded Graphics</a><p>
+<ul>Line Contour Plots (gxout = contour):<br>
+<a href="gradcomdsetccolor.html">set ccolor</a><br>
+<a href="gradcomdsetcthick.html">set cthick</a><br>
+<a href="gradcomdsetcstyle.html">set cstyle</a><br>
+<a href="gradcomdsetcterp.html">set cterp</a><br>  
+<a href="gradcomdsetcint.html">set cint</a><br>
+<a href="gradcomdsetcmin.html">set cmin</a><br>
+<a href="gradcomdsetcmax.html">set cmax</a><br>
+<a href="gradcomdsetblack.html">black</a><br>
+<a href="gradcomdsetclevs.html">clevs</a><br>  
+<a href="gradcomdsetccols.html">ccols</a><br>
+<a href="gradcomdsetrbrange.html">rbrange</a><br>
+<a href="gradcomdsetrbcols.html">rbcols</a><br>  
+<a href="gradcomdsetclopts.html">clopts</a><br>
+<a href="gradcomdsetcsmooth.html">csmooth</a><br>
+<a href="gradcomdsetclab.html">clab</a><br>
+<a href="gradcomdsetclskip.html">clskip</a><br>
+</ul><p>
+<ul>Shaded or Grid Fill Contour Plots (gxout = shaded or grfill):<br>
+<a href="gradcomdsetcint.html">cint</a><br>
+<a href="gradcomdsetcmin.html">cmin</a><br>   
+<a href="gradcomdsetcmax.html">cmax</a><br>
+<a href="gradcomdsetblack.html">black</a><br>
+<a href="gradcomdsetclevs.html">clevs</a><br>
+<a href="gradcomdsetccols.html">ccols</a><br>
+<a href="gradcomdsetrbrange.html">rbrange</a><br>  
+<a href="gradcomdsetrbcols.html">rbcols</a><br>
+<a href="gradcomdsetcsmooth.html">set csmooth</a><br>
+</ul><p>
+<ul>Grid Value Plot (gxout = grid):<br>
+<a href="gradcomdsetdignum.html">dignum</a><br>
+<a href="gradcomdsetdigsize.html">digsize</a><br>
+</ul><p>
+<ul>Vector Plot (gxout = vector):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>  
+<a href="gradcomdsetarrscl.html">arrscl</a><br>  
+<a href="gradcomdsetarrowhead.html">arrowhead</a><br>
+<a href="gradcomdsetcint.html">cint</a><br>
+<a href="gradcomdsetcmin.html">cmin</a><br>
+<a href="gradcomdsetcmax.html">cmax</a><br>
+<a href="gradcomdsetblack.html">black</a><br>
+<a href="gradcomdsetclevs.html">clevs</a><br>
+<a href="gradcomdsetccols.html">ccols</a><br>
+<a href="gradcomdsetrbrange.html">rbrange</a><br>
+<a href="gradcomdsetrbcols.html">rbcols</a><br>
+<a href="gradcomdsetarrlab.html">arrlab</a><br>
+</ul><p>
+<ul>Wind Bard Plot (gxout = barb):<br>
+?????????????????????????????????????????????
+</ul><p>
+<ul>Scatter Plot (gxout = scatter):<br>
+<a href="gradcomdsetcmark.html">cmark</a><br>
+<a href="gradcomdsetdigsize.html">digsize</a><br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+</ul><p>
+<ul>Specific Value Grid Fill Plot (gxout = fgrid):<br>
+<a href="gradcomdsetfgvals.html">fgvals</a><br>
+</ul><p>
+<ul>Streamline Plot (gxout = stream):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>  
+<a href="gradcomdsetcint.html">cint</a><br>
+<a href="gradcomdsetcmin.html">cmin</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>
+<a href="gradcomdsetcmax.html">cmax</a><br>
+<a href="gradcomdsetblack.html">black</a><br>
+<a href="gradcomdsetclevs.html">clevs</a><br>
+<a href="gradcomdsetccols.html">ccols</a><br>
+<a href="gradcomdsetrbrange.html">rbrange</a><br>
+<a href="gradcomdsetrbcols.html">rbcols</a><br>
+<a href="gradcomdsetstrmden.html">strmden</a><br>
+</ul><p>
+<a name="1dstation">1-D Station Graphics</a><p>
+<ul><a href="gradcomdtserbarb.html">Plot time series of wind barbs at a
+point   
+(gxout = tserbarb)</a></ul><p>
+<ul><a href="gradcomdtserwx.html">Plot time series of weather symbols
+at
+a point (gxout = tserwx)</a></ul><p>
+
+<a name="2dstation">2-D Station Graphics</a><p>
+<ul>Plot station values (gxout = value):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>
+<a href="gradcomdsetdigsize.html">digsiz</a><br>
+<a href="gradcomdsetstid.html">stid</a><br>
+</ul><p>
+<ul>Plot wind barb at station (gxout = barb):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>
+<a href="gradcomdsetdigsize.html">digsize</a><br>
+</ul><p>
+<ul>Plot weather symbol at station (gxout = wxsym):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>  
+<a href="gradcomdsetdigsize.html">digsize</a><br>
+<a href="gradcomdsetwxcols.html">wxcols</a><br>  
+</ul><p>
+<ul>Plot station model (gxout = model):<br>
+<a href="gradcomdsetccolor.html">ccolor</a><br>
+<a href="gradcomdsetcthick.html">cthick</a><br>
+<a href="gradcomdsetdigsize.html">digsize</a><br>
+<a href="gradcomdsetmdlopts.html">mdlopts</a><br>
+<a href="gradcomdsetwxcols.html">wxcols</a><br>
+</ul><p>
+<a name="other">Other Display Options</a><p>
+<ul><a href="script.html#scriptfindstn">Find closest station to x,y
+point (gxout = findstn)</a><p>
+<a href="gradcomdstat.html">Display information about data (gxout =
+stat)</a></ul><p>
+<a name="setcommands">Set Commands to Control Graphics Display</a><p>
+<ul>Set range for plotting 1-D or scatter plots:<br>
+<a href="gradcomdsetvrange.html">set vrange</a><br>
+<a href="gradcomdsetvrange2.html">set vrange2</a><br>
+</ul><p>
+<ul>To control log scaling when the Z dimension is plotted on any
+plot:<br>
+<a href="gradcomdsetxyrev.html">xyrev</a><br>  
+<a href="gradcomdsetxflip.html">xflip</a><br>    
+<a href="gradcomdsetyflip.html">yflip</a><br>
+</ul><p>
+<ul>To control axis labelling:<br>
+<a href="gradcomdsetxaxis.html">xaxis</a><br>
+<a href="gradcomdsetyaxis.html">yaxis</a><br>  
+<a href="gradcomdsetxlint.html">xlint</a><br>  
+<a href="gradcomdsetylint.html">ylint</a><br>
+<a href="gradcomdsetxlab.html">xlab</a><br>
+<a href="gradcomdsetylab.html">ylab</a><br>
+<a href="gradcomdsetxlevs.html">xlevs</a><br>
+<a href="gradcomdsetylevs.html">ylevs</a><br>
+<a href="gradcomdsetxlopts.html">xlopts</a><br>
+<a href="gradcomdsetylopts.html">ylopts</a><br>
+<a href="gradcomdsetxlpos.html">xlpos</a><br>
+<a href="gradcomdsetylpos.html">ylpos</a><br>
+</ul><p>
+<ul>To control displayed map projections:<br>
+<a href="gradcomdsetmproj.html">mproj</a><br>
+<a href="gradcomdsetmpvals.html">mpvals</a><br>
+</ul><p>
+<ul>To control map drawing:<br>
+<a href="gradcomdsetmpdset.html">mpdset</a><br>
+<a href="gradcomdsetpoli.html">poli</a><br>    
+<a href="gradcomdsetmap.html">map</a><br>
+<a href="gradcomdsetmpdraw.html">mpdraw</a><br>
+<a href="gradcomdsetgrid.html">grid</a><br>
+</ul><p>
+<ul>To control annotation:<br>
+<a href="gradcomdsetfont.html">font</a><br>    
+<a href="gradcomddrawtitle.html">title</a><br> 
+<a href="gradcomdsetannot.html">set annot</a><br>
+</ul><p>
+<ul>To control console display:<br>
+<a href="gradcomdsetdisplay.html">display</a><br>
+</ul><p>
+<ul>To control the frame:<br>
+<a href="gradcomdsetframe.html">frame</a><br>  
+</ul><p>
+<ul>To control logo display:<br>
+<a href="gradcomdsetgrads.html">grads</a><br>
+</ul></ul><p>
+
diff --git a/doc/advhardcopy.html b/doc/advhardcopy.html
new file mode 100644
index 0000000..1e3d61d
--- /dev/null
+++ b/doc/advhardcopy.html
@@ -0,0 +1,3 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+works
diff --git a/doc/animation.html b/doc/animation.html
new file mode 100644
index 0000000..127ef0f
--- /dev/null
+++ b/doc/animation.html
@@ -0,0 +1,76 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Animation</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2>Animation</h2>
+
+There are two different ways to animate images within GrADS.
+
+<ol>
+<li>
+Set the <a href="dimenv.html">dimension environment</a> to have three
+varying dimensions and then <a
+href="gradcomddisplay.html"><code>display</code></a> a variable. GrADS
+will return an <b>animation sequence</b>. By default, the animation
+dimension is time, but you may specify a different dimension to
+animate by using the following command:
+<p>
+<dd><a href="gradcomdsetloopdim.html"><code>set loopdim</a> x|y|z|t</code>
+<p>
+If you wish to animate a variable with fewer than three varying dimensions
+(i.e., animate a line graph), you can control animation by
+entering:
+<p>
+<dd><a href="gradcomdsetlooping.html"><code>set looping</a> on|off</code>
+<p>
+Remember to <a href="gradcomdsetlooping.html"><code>set looping
+off</code></a> when you are done animating, or you
+will get a surprise when you display your next expression!
+<p>
+<li>
+Use double buffering, which means you have
+two display windows, one of which is always in the
+background. Double buffering is invoked with the following command:
+<p>
+<dd><code><a href="gradcomdsetdbuff.html">set dbuff</a> on</code>
+<p>
+When you issue a display command after turning on double buffering,
+the image is drawn to the backgound buffer. Then you issue the 
+<a href="gradcomdswap.html"><code>swap</code></a>
+command, and GrADS swaps the background and foreground buffers so you can
+see what you've displayed. <a href="gradcomdswap.html"><code>swap</code></a>
+ works like <a href="gradcomdclear.html"><code>clear</code></a> in that it
+resets many graphics options.
+
+Here is a sample script demonstrating how to use double buffering:
+<p>
+<pre>
+'open model.ctl'
+'set dbuff on'
+t = 1
+'set gxout shaded'
+while (t <= 5)
+  'set t 't
+  'draw title Temperature'
+  'd t'  
+  'cbarn'
+  'swap'
+  t = t + 1
+endwhile
+</pre>
+<p>
+You may also control the speed of the animation by inserting a 
+<a href="gradcomdqpos.html"><code>q pos</code></a> following the 
+<a href="gradcomdswap.html"><code>swap</code></a> command -- then each
+click of the mouse would move to the next time step.
+
+
+
+
+</body>
+</html>
+
diff --git a/doc/basic.html b/doc/basic.html
new file mode 100644
index 0000000..4ae76d2
--- /dev/null
+++ b/doc/basic.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>Basic Concept of Operation</title><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<table width="700" border="0">
  <tr>
    <td><h1>Basic Concept of Operation</h1>
      When you have successfully installed and started GrADS, you'll be
confronted with two windows -- a terminal window with a
prompt (ga->), and a resizable
window (black background by default) where graphics are
displayed.
<p> GrADS commands are entered in the terminal window and the
  response from GrADS is either graphics in the graphics window or
  text in the terminal window.  The three fundamental GrADS
  commands: </p>
<ol>
  <li><code>open</code>       open or make available to GrADS a data file
    with
    either gridded or station data </li>
  <li><code>d</code>           display a GrADS
    "expression" (e.g., a slice of data) </li>
  <li><code>set</code>       manipulate the "what" "where" and
    "how" of data
    display</li>
</ol>
<p> The GrADS "expression," or what you want to look at, can be as
  simple as a variable in the data file that was opened, e.g., <code>d
    slp</code> or an arithmetic or GrADS function operation on the data,
  e.g., <code>d slp/100</code> or <code>d mag(u,v)</code> where mag is a GrADS intrinsic
  function.</p>
<p> The "where" of data display is called the "dimension environment"
  and defines which part, chunk or "hyperslab" of the 5-D 
  geophysical space (lon,lat,level,time,ens) is displayed.  The
  dimension environment is manipulated through the <a href="commands.html#setdimension">set</a> command and
  is controlled in either grid coordinates (x,y,z,t,e  indices) or <i>world</i> coordinates (<code>lon, lat, lev, time</code>, ens).</p>
<p> The "what" and "how" of display is also controlled by the  <a href="commands.html"><code>set</code></a> command and
  includes both graphics methods (e.g., contours, streamlines) and
  data (e.g., <code>d</code> to a file).</p>
<p> GrADS graphics can be written to a file (i.e., <code><a
href="gradcomdenableprint.html">enable print</a> <i>filename</i></code> and <a
href="gradcomdprint.html"><code>print</code></a>)
  and then converted to postscript for
  printing
  and/or conversion to other image formats.</p>
<p> In addition, GrADS includes graphic primitives (e.g., lines and
  circles) and basic labelling through the <a href="commands.html#draw"><code>draw
    command</code></a>.</p>
<p> The <code><a href="gradcomdquery.html">q</a></code> or <a href="gradcomdquery.html"><code>query</code></a> command is used to get information from GrADS
  such
  as which files are opened and even statistics. </p></td>
  </tr>
</table>
<h1> </h1>

\ No newline at end of file
diff --git a/doc/bufr.sample.data b/doc/bufr.sample.data
new file mode 100644
index 0000000..ee6257a
--- /dev/null
+++ b/doc/bufr.sample.data
@@ -0,0 +1,75 @@
+7 (0) [-001]    0-63-000     156
+7 (0) [-001]    0-04-001     2004
+7 (0) [-001]    0-04-002     4
+7 (0) [-001]    0-04-003     22
+7 (0) [-001]    0-04-004     15
+7 (0) [-001]    0-04-005     0
+7 (0) [-001]    0-01-198     [78062   ]
+7 (0) [-001]    0-01-001     78
+7 (0) [-001]    0-01-002     62
+7 (0) [-001]    0-05-002     26.55
+7 (0) [-001]    0-06-002     -78.7
+7 (0) [-001]    0-07-001     11
+7 (0) [-001]    0-33-215     0
+7 (0) [-001]    0-35-195     [369 ]
+7 (0) [-001]    0-35-021     [YYXX84]
+7 (0) [-001]    0-35-023     [KAWN]
+7 (0) [-001]    0-35-022     [221500]
+7 (0) [-001]    0-35-194     [RRB   ]
+7 (0) [-001]    0-08-202     0
+7 (0) [-001]    0-04-200     2004
+7 (0) [-001]    0-04-201     4
+7 (0) [-001]    0-04-202     22
+7 (0) [-001]    0-04-203     15
+7 (0) [-001]    0-04-204     0
+7 (0) [-001]    0-02-193     1
+7 (0) [-001]    0-02-001     1
+7 (0) [-001]    0-13-194     3
+7 (0) [-001]    0-20-001     28000
+7 (0) [-001]    0-02-002     12
+7 (0) [-001]    0-33-195     undef (15)
+7 (0) [-001]    0-11-001     160
+7 (0) [-001]    0-11-002     5.7
+7 (0) [-001]    0-33-193     undef (15)
+7 (0) [-001]    0-12-101     298.75
+7 (0) [-001]    0-33-194     undef (15)
+7 (0) [-001]    0-12-103     290.25
+7 (0) [-001]    0-02-038     undef (7)
+7 (0) [-001]    0-33-218     undef (15)
+7 (0) [-001]    0-22-043     undef (327.67)
+7 (0) [-001]    0-33-207     undef (15)
+7 (0) [-001]    0-10-004     undef (163830)
+7 (0) [-001]    0-10-051     102170
+7 (0) [-001]    0-10-063     undef (15)
+7 (0) [-001]    0-10-061     undef (5230)
+7 (0) [-001]    0-13-021     undef (1638.2)
+7 (0) [000]    0-13-019     undef (1638.2)
+7 (0) [000]    0-13-020     0
+7 (0) [000]    0-13-022     undef (1638.2)
+7 (0) [000]    0-13-023     undef (1638.2)
+7 (0) [-001]    0-20-010     50
+7 (0) [-001]    0-20-201     5
+7 (0) [000]    0-08-002     7
+7 (0) [000]    0-20-011     3
+7 (0) [000]    0-20-012     32
+7 (0) [000]    0-20-013     undef (20070)
+7 (0) [001]    0-08-002     8
+7 (0) [001]    0-20-011     undef (15)
+7 (0) [001]    0-20-012     20
+7 (0) [001]    0-20-013     undef (20070)
+7 (0) [002]    0-08-002     9
+7 (0) [002]    0-20-011     undef (15)
+7 (0) [002]    0-20-012     14
+7 (0) [002]    0-20-013     undef (20070)
+7 (0) [000]    0-58-008     [78062 32]
+7 (0) [001]    0-58-008     [578 4161]
+7 (0) [002]    0-58-008     [1 10256 ]
+7 (0) [003]    0-58-008     [20171 40]
+7 (0) [004]    0-58-008     [217 8320]
+7 (0) [005]    0-58-008     [4 83825 ]
+7 (0) [006]    0-58-008     [84075   ]
+7 (0) [000]    0-63-255     0
+7 (0) [001]    0-63-255     0
+7 (0) [002]    0-63-255     0
+7 (0) [003]    0-63-255     0
+
diff --git a/doc/bufr.sample.headers b/doc/bufr.sample.headers
new file mode 100644
index 0000000..a1f3b25
--- /dev/null
+++ b/doc/bufr.sample.headers
@@ -0,0 +1,188 @@
+>>> start of message
+0 63 000  (numeric) BYTCNT                                                          
+3 51 001  (sequence)
+  3 01 011  (sequence)
+    0 04 001  (numeric) YEAR     YEAR                                                   
+    0 04 002  (numeric) MNTH     MONTH                                                  
+    0 04 003  (numeric) DAYS     DAY                                                    
+  3 01 012  (sequence)
+    0 04 004  (numeric) HOUR     HOUR                                                   
+    0 04 005  (numeric) MINU     MINUTES                                                
+  0 01 198  (text) RPID     REPORT IDENTIFIER                                      
+  0 01 001  (numeric) WMOB     WMO BLOCK NUMBER                                       
+  0 01 002  (numeric) WMOS     WMO STATION NUMBER                                     
+  3 01 024  (sequence)
+    0 05 002  (numeric) CLAT     LATITUDE (COARSE ACCURACY)                             
+    0 06 002  (numeric) CLON     LONGITUDE (COARSE ACCURACY)                            
+    0 07 001  (numeric) SELV     HEIGHT OF STATION                                      
+  0 33 215  (numeric) CORN     CORRECTED REPORT INDICATOR                             
+  0 35 200  (numeric) RSRD     RESTRICTIONS ON REDISTRIBUTION                         
+  0 35 201  (numeric) EXPRSRD  EXPIRATION OF RESTRICTIONS ON REDISTRIBUTION           
+  3 63 001  (sequence)
+    0 35 195  (text) SEQNUM   CHANNEL SEQUENCE NUMBER                                
+    0 35 021  (text) BUHD     BULLETIN BEING MONITORED (TTAAii)                      
+    0 35 023  (text) BORG     BULLETIN BEING MONITORED (CCCC)                        
+    0 35 022  (text) BULTIM   BULLETIN BEING MONITORED (YYGGgg)                      
+    0 35 194  (text) BBB      BULLETIN BEING MONITORED (BBB)                         
+  3 63 003  (sequence)
+    0 08 202  (numeric) RCTS     RECEIPT TIME SIGNIFICANCE                              
+    0 04 200  (numeric) RCYR     YEAR   - TIME OF RECEIPT                               
+    0 04 201  (numeric) RCMO     MONTH  - TIME OF RECEIPT                               
+    0 04 202  (numeric) RCDY     DAY    - TIME OF RECEIPT                               
+    0 04 203  (numeric) RCHR     HOUR   - TIME OF RECEIPT                               
+    0 04 204  (numeric) RCMI     MINUTE - TIME OF RECEIPT                               
+  3 61 036  (sequence)
+    0 02 193  (numeric) ITSO     IND TYPE OF STN OPERATION PAST/P                       
+    0 02 001  (numeric) TOST     TYPE OF STATION                                        
+    0 13 194  (numeric) INPC     INDIC INCLUSION/OMISSION OF PREC                       
+    0 20 001  (numeric) HOVI     HORIZONTAL VISIBILITY                                  
+  3 61 042  (sequence)
+    0 02 002  (numeric) TIWM     TYPE OF INSTRUMENTATION FOR WIND MEASUREMENT           
+    0 33 195  (numeric) QMWN     SDMEDIT QUALITY MARK FOR WIND                          
+    0 11 001  (numeric) WDIR     WIND DIRECTION                                         
+    0 11 002  (numeric) WSPD     WIND SPEED                                             
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 043  (sequence)
+      0 04 032  (numeric) .DTM.... DUR OF TIME IN MINS RELATED TO FOLLOWING VALUE         
+      0 11 041  (numeric) MXGS     MAX WIND SPEED (GUSTS)                                 
+  3 61 037  (sequence)
+    0 33 193  (numeric) QMAT     SDMEDIT QUALITY MARK FOR TEMPERATURE                   
+    0 12 101  (numeric) TMDB     TEMPERATURE/DRY BULB TEMPERATURE                       
+    0 33 194  (numeric) QMDD     SDMEDIT QUALITY MARK FOR MOISTURE                      
+    0 12 103  (numeric) TMDP     DEW POINT TEMPERATURE                                  
+    0 02 038  (numeric) MSST     METHOD OF SEA SURFACE TEMPERATURE MEASUREMENT          
+    0 33 218  (numeric) QMST     SDMEDIT QUALITY MARK FOR SEA SURFACE TEMPERATURE       
+    0 22 043  (numeric) SST1     SEA TEMPERATURE                                        
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 038  (sequence)
+      0 02 039  (numeric) MWBT     METHOD OF WET BULB TEMPERATURE MEASUREMENT             
+      0 12 102  (numeric) TMWB     WET BULB TEMPERATURE                                   
+      0 13 003  (numeric) REHU     RELATIVE HUMIDITY                                      
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 039  (sequence)
+      0 04 031  (numeric) .DTH.... DUR OF TIME IN HOURS RELATED TO FOLLOWING VALUE        
+      0 12 111  (numeric) MXTM     MAXIMUM TEMPERATURE                                    
+      0 04 031  (numeric) .DTH.... DUR OF TIME IN HOURS RELATED TO FOLLOWING VALUE        
+      0 12 112  (numeric) MITM     MINIMUM TEMPERATURE                                    
+  3 61 045  (sequence)
+    0 33 207  (numeric) QMPR     SDMEDIT QUALITY MARK FOR PRESSURE                      
+    0 10 004  (numeric) PRES     PRESSURE                                               
+    0 10 051  (numeric) PMSL     PRESSURE REDUCED TO MSL                                
+    0 10 063  (numeric) CHPT     CHARACTERISTIC OF PRESSURE TENDE                       
+    0 10 061  (numeric) 3HPC     3 HOUR PRESSURE CHANGE                                 
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 046  (sequence)
+    0 07 004  (numeric) PRLC     PRESSURE                                               
+    0 10 008  (numeric) GP10     GEOPOTENTIAL                                           
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 047  (sequence)
+    0 10 062  (numeric) 24PC     24 HOUR PRESSURE CHANGE                                
+  3 61 048  (sequence)
+    0 13 021  (numeric) TP06     TOTAL PRECIPITATION PAST 6 HOURS                       
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 049  (sequence)
+      0 13 019  (numeric) TP01     TOTAL PRECIPITATION PAST 1 HOUR                        
+      0 13 020  (numeric) TP03     TOTAL PRECIPITATION PAST 3 HOURS                       
+      0 13 022  (numeric) TP12     TOTAL PRECIPITATION PAST 12 HOURS                      
+      0 13 023  (numeric) TP24     TOTAL PRECIPITATION PAST 24 HOURS                      
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 050  (sequence)
+      0 04 031  (numeric) .DTH.... DUR OF TIME IN HOURS RELATED TO FOLLOWING VALUE        
+      0 13 011  (numeric) TOPC     TOTAL PRECIPITATION/TOTAL WATER EQUIVALENT             
+  0 20 010  (numeric) TOCC     CLOUD COVER (TOTAL)                                    
+  0 20 201  (numeric) HBLCS    HEIGHT ABOVE SURFACE OF BASE OF LOWEST CLOUD SEEN      
+  3 60 002  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 001  (replication count)
+  3 61 041  (sequence)
+    0 08 002  (numeric) VSSO     VERT. SIGNIFICANCE (SFC OBSERVATION)                   
+    0 20 011  (numeric) CLAM     CLOUD AMOUNT                                           
+    0 20 012  (numeric) CLTP     CLOUD TYPE                                             
+    0 20 013  (numeric) HOCB     HEIGHT OF BASE OF CLOUD                                
+    3 60 004  (sequence)
+      1 01 000  (replicate next 1, not including replication count)
+      0 31 000  (replication count)
+    3 61 092  (sequence)
+      0 20 014  (numeric) HOCT     HEIGHT OF TOP OF CLOUD                                 
+      0 20 017  (numeric) CTDS     CLOUD TOP DESCRIPTION                                  
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 054  (sequence)
+    0 20 003  (numeric) PRWE     PRESENT WEATHER                                        
+    0 20 004  (numeric) PSW1     PAST WEATHER (1)                                       
+    0 20 005  (numeric) PSW2     PAST WEATHER (2)                                       
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 051  (sequence)
+    0 22 011  (numeric) POWV     PERIOD OF WAVES                                        
+    0 22 021  (numeric) HOWV     HEIGHT OF WAVES                                        
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 052  (sequence)
+    0 22 012  (numeric) POWW     PERIOD OF WIND WAVES                                   
+    0 22 022  (numeric) HOWW     HEIGHT OF WIND WAVES                                   
+  3 60 002  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 001  (replication count)
+  3 61 053  (sequence)
+    0 22 003  (numeric) DOSW     DIRECTION OF SWELL WAVES                               
+    0 22 013  (numeric) POSW     PERIOD OF SWELL WAVES                                  
+    0 22 023  (numeric) HOSW     HEIGHT OF SWELL WAVES                                  
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 055  (sequence)
+    0 04 031  (numeric) .DTH.... DUR OF TIME IN HOURS RELATED TO FOLLOWING VALUE        
+    0 13 012  (numeric) DOFS     DEPTH OF FRESH SNOW                                    
+    0 13 013  (numeric) TOSD     TOTAL SNOW DEPTH                                       
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 057  (sequence)
+    0 20 033  (numeric) COIA     CAUSE OF ICE ACCRETION                                 
+    0 20 031  (numeric) IDTH     ICE DEPOSIT (THICKNESS)                                
+    0 20 032  (numeric) ROIA     RATE OF ICE ACCRETION                                  
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 056  (sequence)
+    0 20 062  (numeric) SOGR     STATE OF THE GROUND                                    
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 040  (sequence)
+    0 12 193  (numeric) CTTP     CITY TEMPERATURE                                       
+    0 12 194  (numeric) CTMX     CITY MAXIMUM TEMPERATURE                               
+    0 12 195  (numeric) CTMN     CITY MINIMUM TEMPERATURE                               
+  3 60 004  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 000  (replication count)
+  3 61 089  (sequence)
+    0 20 002  (numeric) VTVI     VERTICAL VISIBILITY                                    
+  3 60 002  (sequence)
+    1 01 000  (replicate next 1, not including replication count)
+    0 31 001  (replication count)
+  3 63 002  (sequence)
+    0 58 008  (text) RRSTG    RAW REPORT STRING                                      
+1 02 000  (replicate next 2, not including replication count)
+0 31 001  (replication count)
+2 06 001  (operator)
+0 63 255  (numeric) BITPAD                                                          
+<<< end of message
diff --git a/doc/bufrdescriptorfile.html b/doc/bufrdescriptorfile.html
new file mode 100644
index 0000000..8925a20
--- /dev/null
+++ b/doc/bufrdescriptorfile.html
@@ -0,0 +1,223 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>How to Generate BUFR Descriptor Files</title>
+<link href="../../assets/NewIGES.css" rel="stylesheet" type="text/css">
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>How to Generate BUFR Descriptor Files</b></h2>
+
+<p> <span class="plaintext">BUFR (Binary Universal Form for the Representation 
+  of meteorological data) is a World Meteorological Organization (WMO) standard 
+  for storing observational data (aka sequence or in-situ data). BUFR is self-describing 
+  data format and can store a large amount of data and metadata in a small amount 
+  of disk space by using look-up tables and bit-by-bit packing. </span>
+<p class="plaintext">There is a GrADS interface for BUFR, which means that BUFR 
+  data can be read directly in their native format and are handled as a GrADS 
+  station data set with all the associated display an analysis capabilities. GrADS 
+  requires a specially-formatted descriptor file to read BUFR data; the output 
+  from <a href="gradutilbufrscan.html"><code>bufrscan</code></a>, an external 
+  GrADS utility, is used to compose the descriptor file. 
+<p class="plaintext">Individual elements of a BUFR message are uniquely described 
+  by three numbers: F, X, and Y. F is a type indicator and may be 0, 1, 2, or 
+  3. X is a class or category indicator and varies between 0 and 63. Y indicates 
+  an entry within an X class, and varies between 0 and 255. The F,X,Y trio provides 
+  the required unique table reference, so that a value may be retrieved for the 
+  BUFR element. 
+<p class="plaintext">To read BUFR with GrADS, the user needs to identify which 
+  F,X,Y trios are in the BUFR file and then organize that information in a descriptor 
+  file to give "shape" to the data by identifying the appropriate time 
+  axis, vertical dimension, and number of variables. The GrADS-relevant data in 
+  a BUFR message will always have an F value of 0. For this reason, it is only 
+  necessary to put the X,Y pairs that are associated with the data or metadata 
+  variables in the BUFR descriptor file. 
+<p class="plaintext">The GrADS station data interface requires a few pieces of 
+  metadata for each report: the location of the station (lat/lon), a station ID 
+  (a string no more than 8-characters long), a pressure level (if it is an upper 
+  air variable), and a time stamp. The BUFR descriptor file must provide the X,Y 
+  pairs for these metadata fields, plus a few other elements. 
+<p class="plaintext">Descriptor file entries used for BUFR files are: 
+<table width="600" cellpadding="2" cellspacing="5" class="plaintext">
+  <tr bgcolor="#b8d8dd"> 
+    <td>DSET</td>
+    <td>This entry points to the BUFR data file. It is not currently recommend 
+      to use templating with BUFR data. (See <a href="#templating">Note on Templating</a> 
+      below)</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>TITLE</td>
+    <td>It is good general practice to include a descriptive title in every GrADS 
+      descriptor file. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>UNDEF</td>
+    <td>This is required by GrADS, but not used for undef-testing in the BUFR 
+      interface. Place an arbitrary number here that is unlikely to be confused 
+      with a good data value.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td width="76">DTYPE </td>
+    <td width="609">This entry should have the 'bufr' keyword. This data type 
+      <em>must</em> be accompanied by the XVAR, YVAR, TVAR, and STID entries. 
+    </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> STID </td>
+    <td>This required entry provides the X,Y pair for the station ID. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> XVAR</td>
+    <td>This required entry provides the X,Y pair for the station's longitude.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>YVAR</td>
+    <td>This required entry provides the X,Y pair for the station's latitude.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> ZVAR</td>
+    <td>This optional entry provides the X,Y pair for the data's vertical coordinate 
+      (usually pressure). This is only required if there are level-dependent variables 
+      in the BUFR file. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> TVAR <br>
+      and <br>
+      TOFFVAR</td>
+    <td> 
+      <p>The time for any individual BUFR station report is the base time plus 
+        the offset time.The TVAR entry is required and provides the X,Y pairs 
+        for the base time coordinate variables. The TOFFVAR entry provides the 
+        X,Y pairs for the offset time. If the offset time is zero, the TOFFVAR 
+        entry is not required. Each time coordinate variable (year=yr, month=mo, 
+        day=dy, hour=hr, minute=mn, second=sc) is presented as a 2-letter abbreviation 
+        followed by the X,Y pair that goes with that time unit. All six base/offset 
+        time units are not required to appear in the TVAR/TOFFVAR record, only 
+        those that are in the data file.</p></td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>TDEF</td>
+    <td bgcolor="#b8d8dd">For BUFR station data, the time axis defined by the 
+      TDEF entry provides an evenly-spaced framework for the (sometimes) unevenly 
+      spaced BUFR station reports to fit into. Choose a TDEF that spans the time 
+      range of your BUFR data and has a time increment that matches the frequency 
+      of the BUFR reports. (See <a href="#tdef">Note on TDEF</a> below)</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> VARS<br>
+      through <br>
+      ENDVARS</td>
+    <td>The variable declarations in a BUFR descriptor file also have special 
+      features. The <em>varname </em>field may be any 15-character alphanumeric 
+      string that must start with an alphabetic character (a-z). It is not necessary 
+      for the varname in the descriptor to match the varname in the BUFR file. 
+      The <em>levs</em> field is 0 for surface variables, 1 for upper air variables. 
+      Exception to this rule: replicated surface variables (i.e. variables for 
+      which there may be more than one observation, such as present weather) are 
+      given a<em> levs</em> value of 2. The <em>units</em> field contains the 
+      X,Y pair for the named variable. </td>
+  </tr>
+</table>
+<p><br>
+  <span class="plaintext">The first step in generating a BUFR descriptor file 
+  is figuring out the X,Y values for the data and metadata variables that GrADS 
+  requires. Begin by perusing the header output from <a href="gradutilbufrscan.html"><code>bufrscan</code></a> 
+  looking primarily at the numeric elements. Here is a link to some <a href="bufr.sample.headers">example 
+  header output</a> -- a subset of this is given below. </span>
+<p class="plaintext">These lines give the base time for the report, the station 
+  identifier, the location and elevation of the station, plus some of the observed 
+  variables:<br>
+  0 04 001 (numeric) YEAR YEAR <br>
+  0 04 002 (numeric) MNTH MONTH <br>
+  0 04 003 (numeric) DAYS DAY <br>
+  0 04 004 (numeric) HOUR HOUR <br>
+  0 04 005 (numeric) MINU MINUTES<br>
+  0 01 198 (text) RPID REPORT IDENTIFIER <br>
+  0 06 002 (numeric) CLON LONGITUDE (COARSE ACCURACY) <br>
+  0 05 002 (numeric) CLAT LATITUDE (COARSE ACCURACY) <br>
+  0 07 001 (numeric) SELV HEIGHT OF STATION <br>
+  0 11 001 (numeric) WDIR WIND DIRECTION <br>
+  0 11 002 (numeric) WSPD WIND SPEED <br>
+  0 12 101 (numeric) TMDB TEMPERATURE/DRY BULB TEMPERATURE <br>
+  0 12 103 (numeric) TMDP DEW POINT TEMPERATURE <br>
+  0 10 051 (numeric) PMSL PRESSURE REDUCED TO MSL<br>
+  0 10 061 (numeric) 3HPC 3 HOUR PRESSURE CHANGE 
+<p class="plaintext">The corresponding descriptor file entries would look like 
+  this (N.B. This is not a complete descriptor file): <br>
+  TVAR yr 4,1 mo 4,2 dy 4,3 hr 4,4 mn 4,5 <br>
+  STID 1,198<br>
+  XVAR 6,2<br>
+  YVAR 5,2<br>
+  VARS 9<br>
+  slon 0 6,2 Station longitude<br>
+  slat 0 6,2 Station latitude<br>
+  selv 0 7,1 Station elevation<br>
+  wdir 0 11,001 Wind direction<br>
+  wspd 0 11,002 Wind speed<br>
+  temp 0 12,101 Temperature<br>
+  dewpt 0 12,103 Dew point temperature<br>
+  mslp 0 10,51 Mean sea level pressure<br>
+  dp 0 10,004 3-hour pressure change <br>
+  ENDVARS 
+<p class="plaintext"> The internal GrADS variables "lat", "lon", 
+  and "lev" do not exist for station data, so it's a good idea to put 
+  them in the variable list in case you need them for any calculations (BUFR variables 
+  can be both coordinate and data variables at the same time). Just be careful 
+  not to assign the names "lat", "lon" or "lev", 
+  as this will confuse GrADS and you'll get the message that the predefined variable 
+  is only for grid type files. 
+<p class="plaintext">The second step is to figure out what to use for a TDEF entry. 
+  You may be aware ahead of time that your BUFR file contains hourly data covering 
+  a known 6-hour period, in which case you are done (<code>TDEF 6 <em>start_of_period</em> 
+  1hr</code>). But if you have no idea what's in your BUFR file, then you need 
+  to examine the data output from <a href="gradutilbufrscan.html"><code>bufrscan</code></a> 
+  looking for the F-X-Y triplets that appear in your TVAR entry. Here is a link 
+  to some <a href="bufr.sample.data">example data output</a> -- a subset of this 
+  is given below. 
+<p class="plaintext">7 (0) [-001] 0-04-001 2004<br>
+  7 (0) [-001] 0-04-002 4<br>
+  7 (0) [-001] 0-04-003 22<br>
+  7 (0) [-001] 0-04-004 15<br>
+  7 (0) [-001] 0-04-005 0<br>
+<p class="plaintext">These lines indicate an appropriate TDEF might be:<br>
+  TDEF 1 linear 15z22apr2004 1hr
+<p class="plaintext">If you found more occurrences of 0-04-004 with values other 
+  than 15, change your TDEF:<br>
+  TDEF 24 linear 00z22apr2004 1hr
+<p class="plaintext">If you found occurrences of 0-04-003 with values equal to 
+  23 as well as 22, change your TDEF again:<br>
+  TDEF 48 linear 00z22apr2004 1hr
+<p class="plaintext"> 
+<p class="plaintext"><a name="tdef"></a><strong>Note on TDEF:</strong><br>
+  As mentioned above, the time axis you describe with TDEF provides an evenly-spaced 
+  framework for the station reports to fit into. A display request at a specific 
+  time will return all station reports whose time stamp is within a range of times 
+  equal to the specific time plus or minus one half of the time axis interval. 
+  Let's say you set TDEF to be hourly, set the time dimension to 12Z, and then 
+  do a display request. GrADS will sift through every report in the BUFR file 
+  and display only those which fall between 11:30Z and 12:30Z. If you change TDEF 
+  to be six-hourly, set the time dimension to12Z, and then do a display request, 
+  GrADS will show you all reports that fall between 09Z and 15Z. GrADS displays 
+  the reports that fit between the grid points based on the time axis and time 
+  dimension environment you describe. In BUFR, there's no reason to expect the 
+  messages to be ordered in terms of time or place, and there's no index file 
+  to help navigate the data file, so for each display request GrADS has to sift 
+  through the whole file. 
+<p class="plaintext"><strong><a name="templating"></a>Note on Templating: <br>
+  </strong>In GrADS, file templating (aggregation) is only done in the the time 
+  dimension. It's handled by matching substrings in the file names with time dimension 
+  values. After a display request, GrADS determines which data files need to be 
+  opened in order to get the data the user requested, based on the current dimension 
+  environment settings. Templating in this manner should be avoided with BUFR. 
+  Since there's no index file to help GrADS navigate the data file, a BUFR file 
+  containing 10 reports is treated exactly the same way as a BUFR file with 10,000 
+  -- the whole file is read into memory when the user submits the first display 
+  request. For each display request, GrADS sifts through the entire collection 
+  of reports to find the ones that match the current dimension environment. Since 
+  the memory usage is so extreme, it's better to keep BUFR files small and only 
+  access one at a time. When necessary and/or appropriate, it's possible to aggregate 
+  BUFR files by simply concatenating them together. 
+</body>
+</html>
+
diff --git a/doc/bufrformat.html b/doc/bufrformat.html
new file mode 100644
index 0000000..1117d5e
--- /dev/null
+++ b/doc/bufrformat.html
@@ -0,0 +1,224 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>How to Generate BUFR Descriptor Files</title>
+<link href="../../assets/NewIGES.css" rel="stylesheet" type="text/css">
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<p class="item16"><b>Reading BUFR Files with GrADS </b></p>
+
+<p> <span class="plaintext">BUFR (Binary Universal Form for the Representation 
+  of meteorological data) is a World Meteorological Organization (WMO) standard 
+  for storing observational data (aka sequence or in-situ data). BUFR is self-describing 
+  data format and can store a large amount of data and metadata in a small amount 
+  of disk space by using look-up tables and bit-by-bit packing. </span>
+<p class="plaintext">There is a GrADS interface for BUFR, which means that BUFR 
+  data can be read directly in their native format and are handled as a GrADS 
+  station data set with all the associated display an analysis capabilities. GrADS 
+  requires a specially-formatted descriptor file to read BUFR data; the output 
+  from <a href="gradutilbufrscan.html"><code>bufrscan</code></a>, an external 
+  GrADS utility, is used to compose the descriptor file. 
+<p class="plaintext">Individual elements of a BUFR message are uniquely described 
+  by three numbers: F, X, and Y. F is a type indicator and may be 0, 1, 2, or 
+  3. X is a class or category indicator and varies between 0 and 63. Y indicates 
+  an entry within an X class, and varies between 0 and 255. The F,X,Y trio provides 
+  the required unique table reference, so that a value may be retrieved for the 
+  BUFR element. 
+<p class="plaintext">To read BUFR with GrADS, the user needs to identify which 
+  F,X,Y trios are in the BUFR file and then organize that information in a descriptor 
+  file to give "shape" to the data by identifying the appropriate time 
+  axis, vertical dimension, and number of variables. The GrADS-relevant data in 
+  a BUFR message will always have an F value of 0. For this reason, it is only 
+  necessary to put the X,Y pairs that are associated with the data or metadata 
+  variables in the BUFR descriptor file. 
+
+<p class="item16"><b> BUFR Descriptor File Components</b>
+<p class="plaintext">The GrADS station data interface requires a few pieces of 
+  metadata for each report: the location of the station (lat/lon), a station ID 
+  (a string no more than 8-characters long), a pressure level (if it is an upper 
+  air variable), and a time stamp. The BUFR descriptor file must provide the X,Y 
+  pairs for these metadata fields, plus a few other elements. <p class="plaintext">Descriptor file entries used for BUFR files are: 
+<table width="600" cellpadding="2" cellspacing="5" class="plaintext">
+  <tr bgcolor="#b8d8dd"> 
+    <td>DSET</td>
+    <td>This entry points to the BUFR data file. It is not currently recommend 
+      to use templating with BUFR data. (See <a href="#templating">Note on Templating</a> 
+      below)</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>TITLE</td>
+    <td>It is good general practice to include a descriptive title in every GrADS 
+      descriptor file. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>UNDEF</td>
+    <td>This is required by GrADS, but not used for undef-testing in the BUFR 
+      interface. Place an arbitrary number here that is unlikely to be confused 
+      with a good data value.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td width="76">DTYPE </td>
+    <td width="609">This entry should have the 'bufr' keyword. This data type 
+      <em>must</em> be accompanied by the XVAR, YVAR, TVAR, and STID entries. 
+    </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> STID </td>
+    <td>This required entry provides the X,Y pair for the station ID. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> XVAR</td>
+    <td>This required entry provides the X,Y pair for the station's longitude.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>YVAR</td>
+    <td>This required entry provides the X,Y pair for the station's latitude.</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> ZVAR</td>
+    <td>This optional entry provides the X,Y pair for the data's vertical coordinate 
+      (usually pressure). This is only required if there are level-dependent variables 
+      in the BUFR file. </td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> TVAR <br>
+      and <br>
+      TOFFVAR</td>
+    <td> 
+      <p>The time for any individual BUFR station report is the base time plus 
+        the offset time.The TVAR entry is required and provides the X,Y pairs 
+        for the base time coordinate variables. The TOFFVAR entry provides the 
+        X,Y pairs for the offset time. If the offset time is zero, the TOFFVAR 
+        entry is not required. Each time coordinate variable (year=yr, month=mo, 
+        day=dy, hour=hr, minute=mn, second=sc) is presented as a 2-letter abbreviation 
+        followed by the X,Y pair that goes with that time unit. All six base/offset 
+        time units are not required to appear in the TVAR/TOFFVAR record, only 
+        those that are in the data file.</p></td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td>TDEF</td>
+    <td bgcolor="#b8d8dd">For BUFR station data, the time axis defined by the 
+      TDEF entry provides an evenly-spaced framework for the (sometimes) unevenly 
+      spaced BUFR station reports to fit into. Choose a TDEF that spans the time 
+      range of your BUFR data and has a time increment that matches the frequency 
+      of the BUFR reports. (See <a href="#tdef">Note on TDEF</a> below)</td>
+  </tr>
+  <tr bgcolor="#b8d8dd"> 
+    <td> VARS<br>
+      through <br>
+      ENDVARS</td>
+    <td>The variable declarations in a BUFR descriptor file also have special 
+      features. The <em>varname </em>field may be any 15-character alphanumeric 
+      string that must start with an alphabetic character (a-z). It is not necessary 
+      for the varname in the descriptor to match the varname in the BUFR file. 
+      The <em>levs</em> field is 0 for surface variables, 1 for upper air variables. 
+      Exception to this rule: replicated surface variables (i.e. variables for 
+      which there may be more than one observation, such as present weather) are 
+      given a<em> levs</em> value of 2. The <em>units</em> field contains the 
+      X,Y pair for the named variable. </td>
+  </tr>
+</table>
+<p><br>
+  <span class="plaintext">The first step in generating a BUFR descriptor file 
+  is figuring out the X,Y values for the data and metadata variables that GrADS 
+  requires. Begin by perusing the header output from <a href="gradutilbufrscan.html"><code>bufrscan</code></a> 
+  looking primarily at the numeric elements. Here is a link to some <a href="bufr.sample.headers">example 
+  header output</a> -- a subset of this is given below. </span>
+<p class="plaintext">These lines give the base time for the report, the station 
+  identifier, the location and elevation of the station, plus some of the observed 
+  variables:<br>
+  0 04 001 (numeric) YEAR YEAR <br>
+  0 04 002 (numeric) MNTH MONTH <br>
+  0 04 003 (numeric) DAYS DAY <br>
+  0 04 004 (numeric) HOUR HOUR <br>
+  0 04 005 (numeric) MINU MINUTES<br>
+  0 01 198 (text) RPID REPORT IDENTIFIER <br>
+  0 06 002 (numeric) CLON LONGITUDE (COARSE ACCURACY) <br>
+  0 05 002 (numeric) CLAT LATITUDE (COARSE ACCURACY) <br>
+  0 07 001 (numeric) SELV HEIGHT OF STATION <br>
+  0 11 001 (numeric) WDIR WIND DIRECTION <br>
+  0 11 002 (numeric) WSPD WIND SPEED <br>
+  0 12 101 (numeric) TMDB TEMPERATURE/DRY BULB TEMPERATURE <br>
+  0 12 103 (numeric) TMDP DEW POINT TEMPERATURE <br>
+  0 10 051 (numeric) PMSL PRESSURE REDUCED TO MSL<br>
+  0 10 061 (numeric) 3HPC 3 HOUR PRESSURE CHANGE 
+<p class="plaintext">The corresponding descriptor file entries would look like 
+  this (N.B. This is not a complete descriptor file): <br>
+  TVAR yr 4,1 mo 4,2 dy 4,3 hr 4,4 mn 4,5 <br>
+  STID 1,198<br>
+  XVAR 6,2<br>
+  YVAR 5,2<br>
+  VARS 9<br>
+  slon 0 6,2 Station longitude<br>
+  slat 0 6,2 Station latitude<br>
+  selv 0 7,1 Station elevation<br>
+  wdir 0 11,001 Wind direction<br>
+  wspd 0 11,002 Wind speed<br>
+  temp 0 12,101 Temperature<br>
+  dewpt 0 12,103 Dew point temperature<br>
+  mslp 0 10,51 Mean sea level pressure<br>
+  dp 0 10,004 3-hour pressure change <br>
+  ENDVARS 
+<p class="plaintext"> The internal GrADS variables "lat", "lon", 
+  and "lev" do not exist for station data, so it's a good idea to put 
+  them in the variable list in case you need them for any calculations (BUFR variables 
+  can be both coordinate and data variables at the same time). Just be careful 
+  not to assign the names "lat", "lon" or "lev", 
+  as this will confuse GrADS and you'll get the message that the predefined variable 
+  is only for grid type files. 
+<p class="plaintext">The second step is to figure out what to use for a TDEF entry. 
+  You may be aware ahead of time that your BUFR file contains hourly data covering 
+  a known 6-hour period, in which case you are done (<code>TDEF 6 <em>start_of_period</em> 
+  1hr</code>). But if you have no idea what's in your BUFR file, then you need 
+  to examine the data output from <a href="gradutilbufrscan.html"><code>bufrscan</code></a> 
+  looking for the F-X-Y triplets that appear in your TVAR entry. Here is a link 
+  to some <a href="bufr.sample.data">example data output</a> -- a subset of this 
+  is given below. 
+<p class="plaintext">7 (0) [-001] 0-04-001 2004<br>
+  7 (0) [-001] 0-04-002 4<br>
+  7 (0) [-001] 0-04-003 22<br>
+  7 (0) [-001] 0-04-004 15<br>
+  7 (0) [-001] 0-04-005 0<br>
+<p class="plaintext">These lines indicate an appropriate TDEF might be:<br>
+  TDEF 1 linear 15z22apr2004 1hr
+<p class="plaintext">If you found more occurrences of 0-04-004 with values other 
+  than 15, change your TDEF:<br>
+  TDEF 24 linear 00z22apr2004 1hr
+<p class="plaintext">If you found occurrences of 0-04-003 with values equal to 
+  23 as well as 22, change your TDEF again:<br>
+  TDEF 48 linear 00z22apr2004 1hr
+<p class="plaintext"> 
+<p class="plaintext"><a name="tdef"></a><strong>Note on TDEF:</strong><br>
+  As mentioned above, the time axis you describe with TDEF provides an evenly-spaced 
+  framework for the station reports to fit into. A display request at a specific 
+  time will return all station reports whose time stamp is within a range of times 
+  equal to the specific time plus or minus one half of the time axis interval. 
+  Let's say you set TDEF to be hourly, set the time dimension to 12Z, and then 
+  do a display request. GrADS will sift through every report in the BUFR file 
+  and display only those which fall between 11:30Z and 12:30Z. If you change TDEF 
+  to be six-hourly, set the time dimension to12Z, and then do a display request, 
+  GrADS will show you all reports that fall between 09Z and 15Z. GrADS displays 
+  the reports that fit between the grid points based on the time axis and time 
+  dimension environment you describe. In BUFR, there's no reason to expect the 
+  messages to be ordered in terms of time or place, and there's no index file 
+  to help navigate the data file, so for each display request GrADS has to sift 
+  through the whole file. 
+<p class="plaintext"><strong><a name="templating"></a>Note on Templating: <br>
+  </strong>In GrADS, file templating (aggregation) is only done in the the time 
+  dimension. It's handled by matching substrings in the file names with time dimension 
+  values. After a display request, GrADS determines which data files need to be 
+  opened in order to get the data the user requested, based on the current dimension 
+  environment settings. Templating in this manner should be avoided with BUFR. 
+  Since there's no index file to help GrADS navigate the data file, a BUFR file 
+  containing 10 reports is treated exactly the same way as a BUFR file with 10,000 
+  -- the whole file is read into memory when the user submits the first display 
+  request. For each display request, GrADS sifts through the entire collection 
+  of reports to find the ones that match the current dimension environment. Since 
+  the memory usage is so extreme, it's better to keep BUFR files small and only 
+  access one at a time. When necessary and/or appropriate, it's possible to aggregate 
+  BUFR files by simply concatenating them together. 
+</body>
+</html>
+
diff --git a/doc/clab_default.png b/doc/clab_default.png
new file mode 100644
index 0000000..d9a4c6c
Binary files /dev/null and b/doc/clab_default.png differ
diff --git a/doc/clab_masked.png b/doc/clab_masked.png
new file mode 100644
index 0000000..05e5cbe
Binary files /dev/null and b/doc/clab_masked.png differ
diff --git a/doc/colorcontrol.html b/doc/colorcontrol.html
new file mode 100644
index 0000000..4da4c76
--- /dev/null
+++ b/doc/colorcontrol.html
@@ -0,0 +1,287 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Controlling Colors in GrADS</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>Controlling Colors in GrADS</b></h2>
+<p>
+<font size=+1><b><i>The GrADS Default Colors</i></b></font>
+<p>
+GrADS is built with 16 default colors that are used in a variety of
+applications. Every color in GrADS has a unique <i>color number</i> that is used
+as an index to identify it in GrADS commands. Complete specifications
+of the default colors numbered 0 to 15 are given below:
+
+<p>
+<pre>
+Col#  Description   Sample    R   G   B 
+<br>
+  0   background    <img src="images/dot_b.gif"  width=50 height=12>   0   0   0  (black by default)<br>
+  1   foreground    <img src="images/dot_w.gif"  width=50 height=12> 255 255 255  (white by default)<br>
+  2   red           <img src="images/dot_2.gif"  width=50 height=12> 250  60  60  <br>
+  3   green         <img src="images/dot_3.gif"  width=50 height=12>   0 220   0  <br>
+  4   dark blue     <img src="images/dot_4.gif"  width=50 height=12>  30  60 255  <br>
+  5   light blue    <img src="images/dot_5.gif"  width=50 height=12>   0 200 200  <br>
+  6   magenta       <img src="images/dot_6.gif"  width=50 height=12> 240   0 130  <br>
+  7   yellow        <img src="images/dot_7.gif"  width=50 height=12> 230 220  50  <br>
+  8   orange        <img src="images/dot_8.gif"  width=50 height=12> 240 130  40  <br>
+  9   purple        <img src="images/dot_9.gif"  width=50 height=12> 160   0 200  <br>
+ 10   yellow/green  <img src="images/dot_10.gif" width=50 height=12> 160 230  50  <br>
+ 11   medium blue   <img src="images/dot_11.gif" width=50 height=12>   0 160 255  <br>
+ 12   dark yellow   <img src="images/dot_12.gif" width=50 height=12> 230 175  45  <br>
+ 13   aqua          <img src="images/dot_13.gif" width=50 height=12>   0 210 140  <br>
+ 14   dark purple   <img src="images/dot_14.gif" width=50 height=12> 130   0 220  <br>
+ 15   gray          <img src="images/dot_15.gif" width=50 height=12> 170 170 170  <br>
+</pre>
+<font size=-1>Disclaimer: The color samples may not be displayed properly.</font>
+
+<p>
+<font size=+1><b><i>The GrADS Default Rainbow Sequence</i></b></font>
+<p>
+GrADS creates a default rainbow palette using the following sequence of 13 built-in colors: 
+<table>
+<tr align=center>
+<td>9</td> 
+<td>14</td>
+<td>4</td>
+<td>11</td>
+<td>5</td>
+<td>13</td>
+<td>3</td>
+<td>10</td>
+<td>7</td>
+<td>12</td>
+<td>8</td>
+<td>2</td>
+<td>6</td>
+</tr>
+<tr>
+    <td><img src="images/dot_9.gif"  width=45 height=12></td>
+    <td><img src="images/dot_14.gif" width=45 height=12></td>
+    <td><img src="images/dot_4.gif"  width=45 height=12></td>
+    <td><img src="images/dot_11.gif" width=45 height=12></td>
+    <td><img src="images/dot_5.gif"  width=45 height=12></td>
+    <td><img src="images/dot_13.gif" width=45 height=12></td>
+    <td><img src="images/dot_3.gif"  width=45 height=12></td>
+    <td><img src="images/dot_10.gif" width=45 height=12></td>
+    <td><img src="images/dot_7.gif"  width=45 height=12></td>
+    <td><img src="images/dot_12.gif" width=45 height=12></td>
+    <td><img src="images/dot_8.gif"  width=45 height=12></td>
+    <td><img src="images/dot_2.gif"  width=45 height=12></td>
+    <td><img src="images/dot_6.gif"  width=45 height=12></td>
+</tr>
+</table>
+<p>
+When drawing contour plots, the default behaviour of GrADS is to color
+code the contours and select an appropriate contour interval so that
+each contour is a different color and the colors span the range of the
+default rainbow sequence. The same principle is behind the selection
+of default contour intervals for filled contours and shaded grid
+plots. 
+
+<p>
+The scripts <code>"cbar.gs"</code> and <code>"cbarn.gs"</code> will
+draw a color key alongside a plot of filled contours or shaded grid
+cells; the script uses the <a href="gradcomdquery.html"><code>query
+shades</code></a> command to get information about the contour levels
+and their color shades.
+
+<p>
+<font size=+1><b><i>Defining new colors</i></b></font>
+
+<p>
+For some types of displays, the 16 GrADS default colors may not be
+suitable or adequate. It is possible for the user to define new colors
+using the <a href="gradcomdsetrgb.html"><code>set rgb</code></a> command:
+
+<p>
+<ul>
+<code><a href="gradcomdsetrgb.html">set rgb</a> <i>color# R G B</i></code>
+</ul>
+
+<p>
+For example, let's create a palette of colors for
+plotting anomalies. We need to define new colors that will be shades
+of blue and red that range in intensity from fully saturated to very
+light. White will be the color in the center of the new anomaly
+palette.
+
+<p>
+<ul>
+<pre>
+* These are the BLUE shades
+<a href="gradcomdsetrgb.html">set rgb</a> 16   0   0 255
+<a href="gradcomdsetrgb.html">set rgb</a> 17  55  55 255
+<a href="gradcomdsetrgb.html">set rgb</a> 18 110 110 255
+<a href="gradcomdsetrgb.html">set rgb</a> 19 165 165 255
+<a href="gradcomdsetrgb.html">set rgb</a> 20 220 220 255
+* These are the RED shades
+<a href="gradcomdsetrgb.html">set rgb</a> 21 255 220 220
+<a href="gradcomdsetrgb.html">set rgb</a> 22 255 165 165
+<a href="gradcomdsetrgb.html">set rgb</a> 23 255 110 110
+<a href="gradcomdsetrgb.html">set rgb</a> 24 255  55  55
+<a href="gradcomdsetrgb.html">set rgb</a> 25 255   0   0
+</pre>
+</ul>
+
+
+
+<p>
+<font size=+1><b><i>Overriding the Defaults</i></b></font>
+
+<p>
+Now that we have a set of newly defined colors (numbered 16-25), we
+can override the defaults and specify our anomaly palette with exact
+contour levels and the colors that go with them. This is accomplished
+by using the following commands:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetclevs.html">set clevs</a> <i>lev1 lev2 lev3 ... levN</i><br>
+<a href="gradcomdsetccols.html">set ccols</a> <i>col1 col2 col3 ... colN</i><br>
+</code>
+</ul>
+
+<p>
+Contour levels and the colors that go with them are reset with every
+execution of <a href="gradcomdclear.html"><code>clear</code></a> or 
+<a href="gradcomddisplay.html"><code>display</code></a>. Thus, it may be
+easier to use these commands in a script to avoid typing them over and
+over again.
+
+<p>
+<b><i>Filled Contours or Shaded Grids:</i></b> If you are specifying
+the levels and colors for filled contours (<code><a
+href="gradcomdsetgxout.html">set gxout</a> shaded</code>) or shaded
+grid cells (<code><a href="gradcomdsetgxout.html">set gxout</a>
+grfill</code>), then the number of colors specified with <a
+href="gradcomdsetccols.html">set ccols</a> must be one larger than the
+number of contour levels specified with <a
+href="gradcomdsetclevs.html">set clevs</a>. Continuing with our
+example of creating an anomaly palette, the commands would have the
+following syntax:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetgxout.html">set gxout</a> shaded<br>
+<a href="gradcomdsetclevs.html">set clevs</a> -5 -4 -3 -2 -1 1 2 3 4 5<br>
+<a href="gradcomdsetccols.html">set ccols</a> 16 17 18 19 20 1 21 22 23 24 25<br>
+</code>
+</ul>
+
+<p>
+Note the "0" contour level has been omitted, but color number "1" is still in
+the palette. Drawing a plot with these specified <code>clevs</code>
+and <code>ccols</code> and then running the "cbarn.gs" script will
+result in the following color key:
+<p>
+<img src="key.gif">
+<p>
+Here is example using 6 colors and 5 contour levels that shows how the
+filled contours (or shaded grids) relate to the data values:
+<p>
+<ul>
+<pre>
+col1:         values <= lev1
+col2:  lev1 < values <= lev2
+col3:  lev2 < values <= lev3
+col4:  lev3 < values <= lev4
+col5:  lev4 < values <= lev5
+col6:  lev5 < values
+</pre>
+</ul>
+
+<p>
+<b><i>Line Contours:</i></b> If you are specifying the levels and
+colors for line contours (<code><a href="gradcomdsetgxout.html">set
+gxout</a> contour</code>), then the number of arguments to <a
+href="gradcomdsetclevs.html">set clevs</a> and <a
+href="gradcomdsetccols.html">set ccols</a> should be equal -- one
+color for each contour.
+
+<p>
+<font size=+1><b><i>Plotting Contours of Constant Color</i></b></font>
+
+<p>
+It is sometimes preferable to plot line contours without the rainbow
+coloring. An example might be a plot with sea level pressure contours
+in one color (red) and 500 mb height contours overlaid in another
+color (blue).  For drawing all the contours in the same color, use the
+<a href="gradcomdsetccolor.html"><code>set ccolor</code></a> command:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetgxout.html">set gxout</a> contour <br>
+<a href="gradcomdsetccolor.html">set ccolor</a> 2 <br>
+<a href="gradcomddisplay.html">d</a> slp <br>
+<a href="gradcomdsetccolor.html">set ccolor</a> 4 <br>
+<a href="gradcomddisplay.html">d</a> z(lev=500) <br>
+</code>
+</ul>
+
+<p>
+<font size=+1><b><i>Omitting Colors</i></b></font>
+
+<p>
+The default behavior of GrADS when plotting filled contours or shaded
+grid cells is to colorize all areas. To omit a particular color (or
+contour level) from the plot, simply assign the background color. For
+example:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetgxout.html">set gxout</a> shaded<br>
+<a href="gradcomdsetclevs.html">set clevs</a> -5 -4 -3 -2 -1 1 2 3 4 5<br>
+<a href="gradcomdsetccols.html">set ccols</a> 0 17 18 19 20 0 21 22 23 24 0<br>
+</code>
+</ul>
+
+<p>
+This example is similar to the one given above, but notice where some
+of the <code>ccols</code> have been set to "0" (the background
+color). The first, last, and middle colors have been omitted. These
+commands set up a plot that will only shade areas where the anomalies
+are between 1 and 5 and -1 and -5. The remaining areas will be black.
+
+
+<p>
+<font size=+1><b><i>Plotting Non-Continuous Index Grids </i></b></font>
+
+<p>
+Plotting grids with index values or non-continuous data (e.g. surface
+type classification) is simplified by using the graphics output type
+<code>fgrid</code> and the <a href="gradcomdsetfgvals.html"><code>set
+fgvals</code></a> command.
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetgxout.html">set gxout</a> fgrid <br>
+<a href="gradcomdsetfgvals.html">set fgvals</a> 1 15 2 5 3 1 <br>
+<a href="gradcomddisplay.html">d</a> sfctype <br>
+</code>
+</ul>
+
+<p>
+In this example, the variable <code>"sfctype"</code> has three values:
+<code>1</code> represents land, <code>2</code> represents oceans, and
+<code>3</code> represents sea ice. These commands would draw a plot
+with land grid cells filled with color number 15 (gray), ocean grid
+cells filled with color number 5 (light blue), and sea ice grid cells
+filled with color number 1 (white). If the first two arguments to <a
+href="gradcomdsetfgvals.html">set fgvals</a> were omitted, then the
+land grid cells would not be omitted and only ocean and sea ice grid
+cells would be colored.
+
+
+
+</body>
+</html>
+
diff --git a/doc/commandline.html b/doc/commandline.html
new file mode 100644
index 0000000..f8ccfbb
--- /dev/null
+++ b/doc/commandline.html
@@ -0,0 +1,103 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Command Line Editing</title>
+</head>
+<body text="#000000">
+
+
+<h2>Command line editing and history</h2>
+
+<p>
+If the <code>readline</code> library compiles on your system then the
+default prompt will be <code>ga-></code> as opposed to
+<code>ga></code>.  This indicates that command line editing is
+active. The library defaults to <code>emacs</code> mode but can be
+set up to run using <code>vi</code> syntax.
+
+<p>
+Here's a list of the commands which may typically be used:
+
+<p>
+<ul>
+<code>ctrl-a   </code>go to beginning of line <br>
+<code>ctrl-e   </code>go to end of line <br>
+<code>ctrl-f   </code>go forward one char <br>
+<code>ctrl-b   </code>go backward one char <br>
+<code>ctrl-d   </code>delete the char <br>
+<code>ctrl-p   </code>recall previous line<br>
+<code>ctrl-n   </code>recall next line<br>
+<code>ctrl-r   </code>reverse search<br>
+</ul>
+
+<p>
+You also get <code>file name completion</code> using the
+<code>tab</code> key. If there is more than one option, then
+<code>double tab</code> will list the available completions.
+
+<p>
+For example, suppose you are running grads on div40-2 at FNMOC
+and want to start looking for files to open...<p>
+
+Type <code>open /h</code> and get,<p>
+
+<dd><code>ga-> open /h</code>
+
+and hit two <code>tabs</code> and get:
+
+<dd><code>h      home   home1  home2</code><p>
+
+then type <code>ome1</code> and <code>tab tab</code> and get,<p>
+
+<ul>
+<code>
+ga-> open /home1/ <br>
+GCC         bogus603    gnu         iqpops      nmcobs      roesserd <br>
+GRIB cstrey grads      lost+found  pacek       tsai <br>
+Mosaic      dh          hamilton   
+mendhall    picardr     witt <br>
+NEWDBS      dolan       hout       
+nicholso    qcops</code></ul><p>
+
+then type <code>GR</code>, <code>tab</code> to go to GRIB dir, followed by <code>d</code>,
+<code>tab</code> to go
+to the dat dir and then <code>n</code>, <code>tab tab</code> gives,<p>
+
+<ul>
+<code>
+ga-> open /home1/GRIB/dat/nogaps.25. <br>
+nogaps.25.95021600.grb         nogaps.25.95021912.grb <br>
+nogaps.25.95021600.gribmap     nogaps.25.95021912.gribmap <br>
+nogaps.25.95021612.anal.grb    nogaps.25.anal.ctl <br>
+nogaps.25.95021612.ctl         nogaps.25.anal.gribmap <br>
+nogaps.25.95021612.grb         nogaps.25.ls.mask.ctl <br>
+nogaps.25.95021612.gribmap     nogaps.25.ls.mask.dat <br>
+nogaps.25.95021700.anal.grb    nogaps.25.95021700.ctl</code></ul><p>
+
+and type <code>950217</code> to get<p>
+
+<ul>
+<code>
+ga-> open /home1/GRIB/dat/nogaps.25.950217<br>
+nogaps.25.95021700.anal.grb     nogaps.25.95021712.ctl<br>
+nogaps.25.95021700.ctl          nogaps.25.95021712.grb<br>
+nogaps.25.95021700.grb          nogaps.25.95021712.gribmap<br>
+nogaps.25.95021700.gribmap    nogaps.25.95021712.anal.grb</code></ul><p>
+
+and finally open the <code>12Z</code> data with </code>12.c</code>, <code>tab</code>,
+return to open the
+file<p>
+
+<dd><code>nogaps.25.95021712.ctl</code>
+
+<p>
+<h3>WARNING</h3>
+<p>
+There is no guarantee that these <code>readline</code> routines will always
+work, so the <code>-h</code> option has been added to the invocation of GrADS
+to turn them off. 
+
+</body>
+</html>
+
diff --git a/doc/commands.html b/doc/commands.html
new file mode 100644
index 0000000..bcc23db
--- /dev/null
+++ b/doc/commands.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Commands</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<center><h3>GrADS Commands Sorted by Attribute</h3></center>

<p><font size=+1>Animation</font>
<br><code><a href="gradcomdsetloopdim.html">set loopdim</a>
    </code>
Sets dimension to animate
<br><code><a href="gradcomdsetloopincr.html">set loopincr</a>
   </code>
Sets looping increment
<br><code><a href="gradcomdsetlooping.html">set looping</a>
    </code> 
Turns on animation when fewer than three dimesions are varying
<br><code><a href="gradcomdsetdbuff.html">set dbuff</a>
      </code>
Turns on/off double buffer mode
<br><code><a href="gradcomdswap.html">swap</a>
           </code>
Swaps buffers when in double buffer mode


<p><font size=+1>Axis Labeling</font>
<br><code><a href="gradcomddrawxlab.html">draw xlab</a>
       </code>
Draws an X-axis label
<br><code><a href="gradcomddrawylab.html">draw ylab</a>
       </code>
Draws a Y-axis label
<br><code><a href="gradcomdsetvrange.html">set vrange</a>
     </code>
Sets the range of values for Y-axis scaling
<br><code><a href="gradcomdsetvrange2.html">set vrange2</a>
    </code>
Sets the range of values for X-axis scaling
<br><code><a href="gradcomdsetxaxis.html">set xaxis</a>
      </code>
Specifies where the labeled tick marks will be placed on the X-axis
<br><code><a href="gradcomdsetxflip.html">set xflip</a>
      </code>
Flips the order of the horizontal axis
<br><code><a href="gradcomdsetxlab.html">set xlab</a>
       </code>
Controls the format of X-axis tick mark labels
<br><code><a href="gradcomdsetxlabs.html">set xlabs</a>
      </code>
Gives specific text for X-axis labels
<br><code><a href="gradcomdsetxlevs.html">set xlevs</a>
      </code>
Specifies each individual labeled tick mark for the X-axis
<br><code><a href="gradcomdsetxlint.html">set xlint</a>
      </code>
Specifies the interval between labeled tick marks on the X-axis
<br><code><a href="gradcomdsetxlopts.html">set xlopts</a>
     </code>
Controls X-axis label options
<br><code><a href="gradcomdsetxlpos.html">set xlpos</a>
      </code>
Controls position of X-axis labels
<br><code><a href="gradcomdsetxyrev.html">set xyrev</a>
      </code>
Reverses the X and Y axes on a plot
<br><code><a href="gradcomdsetyaxis.html">set yaxis</a>
      </code>
Specifies where the labeled tick marks will be placed on the Y-axis
<br><code><a href="gradcomdsetyflip.html">set yflip</a>
      </code>
Flips the order of the vertical axis
<br><code><a href="gradcomdsetylab.html">set ylab</a>
       </code>
Controls the format of Y-axis tick mark labels
<br><code><a href="gradcomdsetylabs.html">set ylabs</a>
      </code>
Gives specific text for Y-axis labels
<br><code><a href="gradcomdsetylevs.html">set ylevs</a>
      </code>
Specifies each individual labeled tick mark for the Y-axis
<br><code><a href="gradcomdsetylint.html">set ylint</a>
      </code>
Specifies the interval between labeled tick marks on the Y-axis
<br><code><a href="gradcomdsetylopts.html">set ylopts</a>
     </code>
Controls Y-axis label options
<br><code><a href="gradcomdsetylpos.html">set ylpos</a>
      </code>
Controls position of Y-axis labels
<br><code><a href="gradcomdsetzlog.html">set zlog</a>
       </code>
Sets log scaling of the Z dimension


<p><font size=+1>Bar Graphs</font>
<br><code><a href="gradcomdsetbarbase.html">set barbase</a>
    </code>
Sets the reference point for bar graphs
<br><code><a href="gradcomdsetbargap.html">set bargap</a>
     </code>
Sets the gap between bars for bar graphs
<br><code><a href="gradcomdsetbaropts.html">set baropts</a>
    </code>
Sets characteristics of bars for bar graphs
<br><code><a href="gradcomdsetgxout.html">set gxout bar</a>
 </code>
Graphics output type for bar graphs
<br><code><a href="gradcomdsetgxout.html">set gxout errbar</a>
 </code>
Graphics output type to show error bars


<p><font size=+1>Color Control</font>
<br><code><a href="gradcomdsetfgvals.html">set fgvals</a>
     </code> 
Assigns a color to a particular value; used with <code>set gxout fgrid</code>
<br><code><a href="gradcomdsetlfcols.html">set lfcols</a>
     </code> 

<br><code><a href="gradcomdsetrbcols.html">set rbcols</a>
     </code>
Specifies a new rainbow color sequence
<br><code><a href="gradcomdsetrbrange.html">set rbrange</a>
    </code>
Assigns a range of values to rainbow colors
<br><code><a href="gradcomdsetrgb.html">set rgb</a>
        </code>
Defines a new color
<br><code><a href="gradcomdsetwxcols.html">set wxcols</a>
     </code>
Controls color of weather symbols


<p><font size=+1>Contour Settings</font>
<br><code><a href="gradcomdsetannot.html">set annot</a>
      </code>
Sets the color and thickness for the axis border, axis labels, and tickmarks.
<br><code><a href="gradcomdsetblack.html">set black</a>
      </code>
Specifies a range of values for which no contours will be drawn
<br><code><a href="gradcomdsetccolor.html">set ccolor</a>
     </code>
Specifies the color of the plotted contours
<br><code><a href="gradcomdsetccols.html">set ccols</a>
      </code>
Assigns specific colors for each contour level
<br><code><a href="gradcomdsetcint.html">set cint</a>
       </code> 
Sets the contour interval
<br><code><a href="gradcomdsetclab.html">set clab</a>
       </code>
Controls contour labels
<br><code><a href="gradcomdsetclevs.html">set clevs</a>
      </code>
Sets specific contour levels
<br><code><a href="gradcomdsetclopts.html">set clopts</a>
     </code>
Contour label options
<br><code><a href="gradcomdsetclskip.html">set clskip</a>
     </code>
Sets the number of contour lines to skip when labelling
<br><code><a href="gradcomdsetcmax.html">set cmax</a>
       </code>
Contours not drawn above this value
<br><code><a href="gradcomdsetcmin.html">set cmin</a>
       </code>
Contours not drawn below this value
<br><code><a href="gradcomdsetcsmooth.html">set csmooth</a>
    </code>
Interpolates the grid to a finer resolution before contouring
<br><code><a href="gradcomdsetcstyle.html">set cstyle</a>
     </code>
Sets the contour line style
<br><code><a href="gradcomdsetcterp.html">set cterp</a>
      </code>
Turns on/off spline smoothing
<br><code><a href="gradcomdsetcthick.html">set cthick</a>
     </code> 
Sets contour line thickness


<p><font size=+1>Display Controls</font>
<br><code><a href="gradcomdclear.html">clear</a>
          </code>
Clears the display window and resets many graphics options
<br><code><a href="gradcomddisplay.html">display</a>
        </code>
Draws a plot
<br><code><a href="gradcomdreset.html">reset</a>
          </code>   
Returns GrADS settings to default state with some exceptions
<br><code><a href="gradcomdsetbackground.html">set background</a>
 </code>
Sets background color
<br><code><a href="gradcomdsetclip.html">set clip</a>
       </code>
Sets the coordinates for clipping the plot area
<br><code><a href="gradcomdsetcmark.html">set cmark</a>
      </code>
Sets the type of line marker
<br><code><a href="gradcomdsetdisplay.html">set display</a>
    </code> 
Sets the mode of display
<br><code><a href="gradcomdsetframe.html">set frame</a>
      </code> 
Draws a frame around plot borders
<br><code><a href="gradcomdsetgridln.html">set gridln</a>
     </code>
Controls appearance of grid lines; used with <code>set gxout grid</code>
<br><code><a href="gradcomdsetgxout.html">set gxout</a>
      </code>  
Sets a graphics output type
<br><code><a href="gradcomdsetline.html">set line</a>
       </code>
Sets line attributes
<br><code><a href="gradcomdsetmissconn.html">set missconn</a>
   </code>
Connects plots lines over missing data
<br><code><a href="gradcomdsetparea.html">set parea</a>
      </code>
Specifies the area for plotting contour plots, maps, or line graphs
<br><code><a href="gradcomdsetvpage.html">set vpage</a>
      </code>
Sets dimensions of the virtual page
<br><code><a href="gradcomdsetxsize.html">set xsize</a>
      </code>
Resizes the graphics display window 


<p><font size=+1>Data and Image Output</font><br>
<br><code><a href="gradcomddisablefwrite.html">disable fwrite</a>
 </code>
Closes output file containing gridded data 
<br><code><a href="gradcomddisableprint.html">disable print</a>
  </code>
Closes output file containing images in metacode format 
<br><code><a href="gradcomdenableprint.html">enable print</a>
   </code>  
Opens output file containing images in metacode format
<br><code><a href="gradutilgxeps.html">gxeps</a>
          </code>
Converts GrADS metacode format image files into postscript
<br><code><a href="gradutilgxps.html">gxps</a>
           </code>
Converts GrADS metacode format image files into postscript
<br><code><a href="gradutilgxtran.html">gxtran</a>
         </code>
Displays GrADS metacode format image files
<br><code><a href="gradcomdoutxwd.html">outxwd</a>
         </code>
Copies the contents of the display window into a file in XWD format 
<br><code><a href="gradcomdprint.html">print</a>
          </code>
Copies the contents of display window to a file in a metacode format
<br><code><a href="gradcomdprintim.html">printim</a>
        </code>
Copies the contents of display window to a file in PNG or GIF format
<br><code><a href="gradcomdsetfwrite.html">set fwrite</a>
     </code>
Sets filename, byte ordering, and format for data output
<br><code><a href="gradcomdsetgxout.html">set gxout fwrite</a>
 </code>
Graphics output type for writing data to file
<br><code><a href="gradcomdwi.html">wi</a>
             </code>
Dumps the contents of the display window into a file in a variety of formats


<p><font size=+1><a name="setdimension"></a>Dimension Environment</font>
<br><code><a href="gradcomdsetxyzte.html">set x</a>
          </code>
Specifies the X-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set y</a>
          </code>
Specifies the Y-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set z</a>
          </code>
Specifies the Z-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set t</a>
          </code>
Specifies the T-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set e</a>
          </code>
Specifies the E-dimension in grid coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a>
        </code>
Specifies the X-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lat</a>
        </code>
Specifies the Y-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lev</a>
        </code>
Specifies the Z-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set time</a>
       </code>
Specifies the T-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set ens</a>
       </code>
Specifies the E-dimension in world coordinates
<p><font size=+1>File I/O</font>
<br><code><a href="gradcomdclose.html">close</a>
          </code>
Closes a GrADS data file
<br><code><a href="gradcomdopen.html">open</a>
           </code>
Opens a GrADS data file
<br><code><a href="gradcomdreinit.html">reinit</a>
         </code>   
Returns GrADS to its initial state
<br><code><a href="gradcomdexec.html">exec</a>
           </code>
Executes the list of GrADS commands contained in a file
<br><code><a href="gradcomdrun.html">run</a>
            </code> 
Runs a GrADS script
<br><code><a href="gradcomdsdfopen.html">sdfopen</a>
        </code>
Opens a NetCDF of HDF-SDS file that conforms to the COARDS conventions
<br><code><a href="gradcomdxdfopen.html">xdfopen</a>
        </code>
Opens a NetCDF of HDF-SDS file that does not conform to the COARDS conventions
<br><code><a href="gradcomdsetdfile.html">set dfile</a>
      </code>
Changes default file
<br><code><a href="gradcomdsetimprun.html">set imprun</a>
     </code>
Sets up automatic script execution before every display command


<p><font size=+1>GrADS-User Interface</font>
<br><code><a href="gradcomdgrads.html">grads</a>
          </code>
Starts the GrADS program
<br><code><a href="gradcomdhelp.html">help</a>
           </code>
Lists a few basic GrADS commands
<br><code><a href="gradcomdquery.html">query</a>
          </code>
Returns information about a variety of aspects of the current GrADS session
<br><code><a href="gradcomdquit.html">quit</a>
           </code>  
Quits GrADS
<br><code><a href="gradcomdsetdatawarn.html">set datawarn</a>
   </code>
Prints "Entire Grid Undefined" in display window if all data are missing
<br><code><a href="gradcomdsetstat.html">set stat</a>
       </code>
Turns on/off printing of statistical information for each display
<br><code><a href="gradcomdsetwarn.html">set warn</a>
       </code>
Turns on/off messages about the progress of certain mathematical operations
<br><code><a href="gradcomdshell.html">!shell</a>
         </code>
Sends a command to the shell


<p><font size=+1>Graphical Elements</font>
<br><code><a href="gradcomddrawline.html">draw line</a>
       </code>
Draws a line
<br><code><a href="gradcomddrawmark.html">draw mark</a>
       </code>
Draws a mark
<br><code><a href="gradcomddrawpolyf.html">draw polyf</a>
      </code>
Draws a filled polygon
<br><code><a href="gradcomddrawrec.html">draw rec</a>
        </code>
Draws a rectangle
<br><code><a href="gradcomddrawrecf.html">draw recf</a>
       </code>
Draws a filled rectangle
<br><code><a href="gradcomddrawwxsym.html">draw wxsym</a>
      </code>
Draws a weather symbol


<p><font size=+1>GRIB Utilities</font>
<br><code><a href="gradutilgribmap.html">gribmap</a>
        </code>
Creates a map of data sets in GRIB format
<br><code><a href="gradutilgribscan.html">gribscan</a>
       </code>
Extracts grid info from data sets in GRIB format


<p><font size=+1>Map Settings</font>
<br><code><a href="gradcomddrawmap.html">draw map</a>        </code>
Draws a map outline
<br><code><a href="gradcomdsetgrid.html">set grid</a>
       </code>
Sets characteristics of displayed grid lines
<br><code><a href="gradcomdsetmap.html">set map</a>
        </code>
Sets map background characteristics
<br><code><a href="gradcomdsetmpdraw.html">set mpdraw</a>
     </code>
Turns on/off drawing of map background
<br><code><a href="gradcomdsetmpdset.html">set mpdset</a>
     </code>
Sets the resolution of the coastal outline
<br><code><a href="gradcomdsetmproj.html">set mproj</a>
      </code>
Sets current map projection
<br><code><a href="gradcomdsetmpt.html">set mpt</a>
        </code>
Controls map background characteristics 
<br><code><a href="gradcomdsetmpvals.html">set mpvals</a>
     </code>
Sets reference longitudes and latitudes for polar stereographic plots
<br><code><a href="gradcomdsetpoli.html">set poli</a>
       </code>
Turns on/off the drawing of political boundaries


<p><font size=+1>Plot Annotation and Labeling</font>
<br><code><a href="gradcomddrawstring.html">draw string</a>
     </code>
Draws a string anywhere on the page
<br><code><a href="gradcomddrawtitle.html">draw title</a>
      </code>
Draws a title centered over a plot
<br><code><a href="gradcomdsetdignum.html">set dignum</a>
     </code> 
Sets the number of significant digits after the decimal point
<br><code><a href="gradcomdsetdigsize.html">set digsiz</a>
     </code> 
Sets the size of plotted numbers
<br><code><a href="gradcomdsetfont.html">set font</a>
       </code> 
Selects the font for text display
<br><code><a href="gradcomdsetgrads.html">set grads</a>
      </code> 
Turns on/off the GrADS logo in each plot
<br><code><a href="gradcomdsetstring.html">set string</a>
     </code>
Sets string drawing attributes
<br><code><a href="gradcomdsetstrsiz.html">set strsiz</a>
     </code>
Sets the string character size
<br><code><a href="gradcomdsettimelab.html">set timelab</a>
    </code>
Turns on/off display of the time label 
<br><code><a href="gradcomdsettlsupp.html">set tlsupp</a>
     </code>
Suppresses the annotation of the year and/or month in date/time labels


<p><font size=+1>Station Data</font>
<br><code><a href="gradcomdcollect.html">collect</a>
        </code>
Saves station data in memory as a set
<br><code><a href="gradcomdsetmdlopts.html">set mdlopts</a>
    </code>
<br><code><a href="gradcomdsetwxopt.html">set wxopt</a>
      </code>
Controls weather symbol output; used with <code>set gxout wxsym</code>
<br><code><a href="gradcomdsetstid.html">set stid</a>
       </code>
Turns on/off display of the station ID next to the data values 
<br><code><a href="gradcomdsetstnprint.html">set stnprint</a>
   </code>
Controls printing of station data values; used with <code>set gxout stat</code>
<br><code><a href="gradutilstnmap.html">stnmap</a>
         </code>
Writes out a hash table and/or link list information for station data


<p><font size=+1>Variables</font>
<br><code><a href="gradcomddefine.html">define</a>
         </code>
Creates a new GrADS variable that is loaded into memory
<br><code><a href="gradcomdmodify.html">modify</a>
         </code>
Defines a climatological variable
<br><code><a href="gradcomdsetdefval.html">set defval</a>
     </code>
Interactively modifies grid point values for 2-D defined variables
<br><code><a href="gradcomdundefine.html">undefine</a>
       </code>
Frees the memory used by a defined variable


<p><font size=+1>Vectors</font>
<br><code><a href="gradcomdsetarrlab.html">set arrlab</a>
     </code>
Toggles drawing the vector arrow label 
<br><code><a href="gradcomdsetarrowhead.html">set arrowhead</a>
  </code>
Sets the size of the vector arrowhead
<br><code><a href="gradcomdsetarrscl.html">set arrscl</a>
     </code>
Specifies arrow length scaling
<br><code><a href="gradcomdsetgxout.html">set gxout vector</a>
  </code>
Graphics output type for vector plots
<br><code><a href="gradcomdsethempref.html">set hempref</a>
    </code>
Controls wind barb drawing conventions
<br><code><a href="gradcomdsetstrmden.html">set strmden</a>
    </code>
Sets density of streamlines; used with <code>set gxout stream</code>


<p><font size=+1>Widgets</font>
<br><code><a href="gradcomddrawbutton.html">draw button</a>     </code>
Draws a button widget
<br><code><a href="gradcomdredrawbutton.html">redraw button</a>   </code>
Resets a button widget on/off
<br><code><a href="gradcomddrawdropmenu.html">draw dropmenu</a>   </code>
Draws a dropmenu widget
<br><code><a href="gradcomdsetbutton.html">set button</a>
     </code>
Specifies the color characteristics of a button widget
<br><code><a href="gradcomdsetdialog.html">set dialog</a>
     </code> 
Sets color properties of dialog box widgets
<br><code><a href="gradcomdsetdropmenu.html">set dropmenu</a>
   </code>
Sets color properties of dropmenu widgets
<br><code><a href="gradcomdsetrband.html">set rband</a>
      </code>
Sets characteristics for the 'rubber band' widget


</body>
</html>


\ No newline at end of file
diff --git a/doc/commandsatt.html b/doc/commandsatt.html
new file mode 100644
index 0000000..2d6d25c
--- /dev/null
+++ b/doc/commandsatt.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Commands</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<center><h3>GrADS Commands Sorted by Attribute</h3></center>

<p><font size=+1>Animation</font>
<br><code><a href="gradcomdsetloopdim.html">set loopdim</a>
    </code>
Sets dimension to animate
<br><code><a href="gradcomdsetloopincr.html">set loopincr</a>
   </code>
Sets looping increment
<br><code><a href="gradcomdsetlooping.html">set looping</a>
    </code> 
Turns on animation when fewer than three dimesions are varying
<br><code><a href="gradcomdsetdbuff.html">set dbuff</a>
      </code>
Turns on/off double buffer mode
<br><code><a href="gradcomdswap.html">swap</a>
           </code>
Swaps buffers when in double buffer mode


<p><font size=+1>Annotation and Labeling</font>
<br><code><a href="gradcomddrawstring.html">draw string</a>
    </code>
Draws a string anywhere on the page
<br><code><a href="gradcomddrawtitle.html">draw title</a>
     </code>
Draws a title centered over a plot
<br><code><a href="gradcomdsetdignum.html">set dignum</a>
     </code> 
Sets the number of significant digits after the decimal point
<br><code><a href="gradcomdsetdigsize.html">set digsiz</a>
     </code> 
Sets the size of plotted numbers
<br><code><a href="gradcomdsetfont.html">set font</a>
       </code> 
Selects the font for text display
<br><code><a href="gradcomdsetgrads.html">set grads</a>
      </code> 
Turns on/off the GrADS logo in each plot
<br><code><a href="gradcomdsetstring.html">set string</a>
     </code>
Sets string drawing attributes
<br><code><a href="gradcomdsetstrsiz.html">set strsiz</a>
     </code>
Sets the string character size
<br><code><a href="gradcomdsettimelab.html">set timelab</a>
    </code>
Turns on/off display of the time label 
<br><code><a href="gradcomdsettlsupp.html">set tlsupp</a>
     </code>
Suppresses the annotation of the year and/or month in date/time labels


<p><font size=+1>Axis Labeling</font>
<br><code><a href="gradcomddrawxlab.html">draw xlab</a>
      </code>
Draws an X-axis label
<br><code><a href="gradcomddrawylab.html">draw ylab</a>
      </code>
Draws a Y-axis label
<br><code><a href="gradcomdsetvrange.html">set vrange</a>
     </code>
Sets the range of values for Y-axis scaling
<br><code><a href="gradcomdsetvrange2.html">set vrange2</a>
    </code>
Sets the range of values for X-axis scaling
<br><code><a href="gradcomdsetxaxis.html">set xaxis</a>
      </code>
Specifies where the labeled tick marks will be placed on the X-axis
<br><code><a href="gradcomdsetxflip.html">set xflip</a>
      </code>
Flips the order of the horizontal axis
<br><code><a href="gradcomdsetxlab.html">set xlab</a>
       </code>
Controls the format of X-axis tick mark labels
<br><code><a href="gradcomdsetxlabs.html">set xlabs</a>
      </code>
Gives specific text for X-axis labels
<br><code><a href="gradcomdsetxlevs.html">set xlevs</a>
      </code>
Specifies each individual labeled tick mark for the X-axis
<br><code><a href="gradcomdsetxlint.html">set xlint</a>
      </code>
Specifies the interval between labeled tick marks on the X-axis
<br><code><a href="gradcomdsetxlopts.html">set xlopts</a>
     </code>
Controls X-axis label options
<br><code><a href="gradcomdsetxlpos.html">set xlpos</a>
      </code>
Controls position of X-axis labels
<br><code><a href="gradcomdsetxyrev.html">set xyrev</a>
      </code>
Reverses the X and Y axes on a plot
<br><code><a href="gradcomdsetyaxis.html">set yaxis</a>
      </code>
Specifies where the labeled tick marks will be placed on the Y-axis
<br><code><a href="gradcomdsetyflip.html">set yflip</a>
      </code>
Flips the order of the vertical axis
<br><code><a href="gradcomdsetylab.html">set ylab</a>
       </code>
Controls the format of Y-axis tick mark labels
<br><code><a href="gradcomdsetylabs.html">set ylabs</a>
      </code>
Gives specific text for Y-axis labels
<br><code><a href="gradcomdsetylevs.html">set ylevs</a>
      </code>
Specifies each individual labeled tick mark for the Y-axis
<br><code><a href="gradcomdsetylint.html">set ylint</a>
      </code>
Specifies the interval between labeled tick marks on the Y-axis
<br><code><a href="gradcomdsetylopts.html">set ylopts</a>
     </code>
Controls Y-axis label options
<br><code><a href="gradcomdsetylpos.html">set ylpos</a>
      </code>
Controls position of Y-axis labels
<br><code><a href="gradcomdsetzlog.html">set zlog</a>
       </code>
Sets log scaling of the Z dimension


<p><font size=+1>Bar Graph Options</font>
<br><code><a href="gradcomdsetbarbase.html">set barbase</a>
    </code>
Sets the reference point for bar graphs
<br><code><a href="gradcomdsetbargap.html">set bargap</a>
     </code>
Sets the gap between bars for bar graphs
<br><code><a href="gradcomdsetbaropts.html">set baropts</a>
    </code>
Specifies whether bars are outlined or filled


<p><font size=+1>Color Control</font>
<br><code><a href="gradcomdsetfgvals.html">set fgvals</a>
     </code> 
Assigns a color to a particular value; used with 'set gxout fgrid'
<br><code><a href="gradcomdsetlfcols.html">set lfcols</a>
     </code> 

<br><code><a href="gradcomdsetrbcols.html">set rbcols</a>
     </code>
Specifies a new rainbow color sequence
<br><code><a href="gradcomdsetrbrange.html">set rbrange</a>
    </code>
Assigns a range of values to rainbow colors
<br><code><a href="gradcomdsetrgb.html">set rgb</a>
        </code>
Defines a new color
<br><code><a href="gradcomdsetwxcols.html">set wxcols</a>
     </code>
Controls color of weather symbols


<p><font size=+1>Contour Settings</font>
<br><code><a href="gradcomdsetannot.html">set annot</a>
      </code>
Sets color and thickness of axis border, axis labels, and tickmarks
<br><code><a href="gradcomdsetblack.html">set black</a>
      </code>
Specifies a range of values for which no contours will be drawn
<br><code><a href="gradcomdsetccolor.html">set ccolor</a>
     </code>
Specifies the color of the plotted contours
<br><code><a href="gradcomdsetccols.html">set ccols</a>
      </code>
Assigns specific colors for each contour level
<br><code><a href="gradcomdsetcint.html">set cint</a>
       </code> 
Sets the contour interval
<br><code><a href="gradcomdsetclab.html">set clab</a>
       </code>
Controls contour labels
<br><code><a href="gradcomdsetclevs.html">set clevs</a>
      </code>
Sets specific contour levels
<br><code><a href="gradcomdsetclopts.html">set clopts</a>
     </code>
Contour label options
<br><code><a href="gradcomdsetclskip.html">set clskip</a>
     </code>
Sets the number of contour lines to skip when labelling
<br><code><a href="gradcomdsetcmax.html">set cmax</a>
       </code>
Contours not drawn above this value
<br><code><a href="gradcomdsetcmin.html">set cmin</a>
       </code>
Contours not drawn below this value
<br><code><a href="gradcomdsetcsmooth.html">set csmooth</a>
    </code>
Interpolates the grid to a finer resolution before contouring
<br><code><a href="gradcomdsetcstyle.html">set cstyle</a>
     </code>
Sets the contour line style
<br><code><a href="gradcomdsetcterp.html">set cterp</a>
      </code>
Turns on/off spline smoothing
<br><code><a href="gradcomdsetcthick.html">set cthick</a>
     </code> 
Sets contour line thickness


<p><font size=+1>Display Controls</font>
<br><code><a href="gradcomdclear.html">clear</a>
          </code>
Clears the display window and resets many graphics options
<br><code><a href="gradcomddisplay.html">display</a>
        </code>
Draws a plot
<br><code><a href="gradcomdreset.html">reset</a>
          </code>   
Returns GrADS settings to default state with some exceptions
<br><code><a href="gradcomdsetbackground.html">set background</a>
 </code>
Sets background color
<br><code><a href="gradcomdsetclip.html">set clip</a>
       </code>
Sets the coordinates for clipping the plot area
<br><code><a href="gradcomdsetcmark.html">set cmark</a>
      </code>
Sets the type of line marker
<br><code><a href="gradcomdsetdisplay.html">set display</a>
    </code> 
Sets the mode of display
<br><code><a href="gradcomdsetframe.html">set frame</a>
      </code> 
Draws a frame around plot borders
<br><code><a href="gradcomdsetgridln.html">set gridln</a>
     </code>
Controls appearance of grid lines; used with 'set gxout grid'
<br><code><a href="gradcomdsetgxout.html">set gxout</a>
      </code>  
Sets a graphics output type
<br><code><a href="gradcomdsetline.html">set line</a>
       </code>
Sets line attributes
<br><code><a href="gradcomdsetmissconn.html">set missconn</a>
   </code>
Connects plots lines over missing data
<br><code><a href="gradcomdsetparea.html">set parea</a>
      </code>
Specifies the area for plotting contour plots, maps, or line graphs
<br><code><a href="gradcomdsetvpage.html">set vpage</a>
      </code>
Sets dimensions of the virtual page
<br><code><a href="gradcomdsetxsize.html">set xsize</a>
      </code>
Resizes the graphics display window 


<p><font size=+1>Data and Image Output</font>
<br><code><a href="gradcomddisablefwrite.html">disable fwrite</a>
 </code>
Closes output file containing gridded data 
<br><code><a href="gradcomddisableprint.html">disable print</a>
  </code>
Closes output file containing images in metacode format 
<br><code><a href="gradcomdenableprint.html">enable print</a>
   </code>  
Opens output file containing images in metacode format
<br><code><a href="gradutilgxeps.html">gxeps</a>
          </code>
Converts GrADS metacode format image files into postscript
<br><code><a href="gradutilgxps.html">gxps</a>
           </code>
Converts GrADS metacode format image files into postscript
<br><code><a href="gradutilgxtran.html">gxtran</a>
         </code>
Displays GrADS metacode format image files
<br><code><a href="gradcomdoutxwd.html">outxwd</a>
         </code>
Copies the contents of the display window into a file in XWD format 
<br><code><a href="gradcomdprint.html">print</a>
          </code>
Copies the contents of display window to a file in a metacode format
<br><code><a href="gradcomdprintim.html">printim</a>
        </code>
Copies the contents of display window to a file in PNG or GIF format
<br><code><a href="gradcomdsetfwrite.html">set fwrite</a>
     </code>
Sets filename, byte ordering, and format for data output
<br><code><a href="gradcomdwi.html">wi</a>
             </code>
Dumps the contents of the display window into a file in a variety of formats


<p><font size=+1>Dimension Environment</font>
<br><code><a href="gradcomdsetxyzte.html">set x</a>
          </code>
Specifies the X-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set y</a>
          </code>
Specifies the Y-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set z</a>
          </code>
Specifies the Z-dimension in grid coordinates
<br><code><a href="gradcomdsetxyzte.html">set t</a>
          </code>
Specifies the T-dimension in grid coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a>
        </code>
Specifies the X-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lat</a>
        </code>
Specifies the Y-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set lev</a>
        </code>
Specifies the Z-dimension in world coordinates
<br><code><a href="gradcomdsetlatlonlevtimeens.html">set time</a>
       </code>
Specifies the T-dimension in world coordinates


<p><font size=+1>File Manipulation</font>
<br><code><a href="gradcomdclose.html">close</a>
          </code>
Closes a GrADS data file
<br><code><a href="gradcomdopen.html">open</a>
           </code>
Opens a GrADS data file
<br><code><a href="gradcomdreinit.html">reinit</a>
         </code>   
Returns GrADS to its initial state
<br><code><a href="gradcomdexec.html">exec</a>
           </code>
Executes the list of GrADS commands contained in a file
<br><code><a href="gradutilgribmap.html">gribmap</a>
        </code>
Creates a map of data sets in GRIB format
<br><code><a href="gradutilgribscan.html">gribscan</a>
       </code>
Extracts grid info from data sets in GRIB format
<br><code><a href="gradcomdrun.html">run</a>
            </code> 
Runs a GrADS script
<br><code><a href="gradcomdsdfopen.html">sdfopen</a>
        </code>
Opens a COARDS-compliant NetCDF or HDF-SDS file 
<br><code><a href="gradcomdxdfopen.html">xdfopen</a>
        </code>
Opens a non-COARDS-compliant NetCDF or HDF-SDS file 
<br><code><a href="gradcomdsetdfile.html">set dfile</a>
      </code>
Changes default file
<br><code><a href="gradcomdsetimprun.html">set imprun</a>
     </code>
Sets up automatic script execution before every display command


<p><font size=+1>GrADS-User Interface</font>
<br><code><a href="gradcomdgrads.html">grads</a>
          </code>
Starts the GrADS program
<br><code><a href="gradcomdhelp.html">help</a>
           </code>
Lists a few basic GrADS commands
<br><code><a href="gradcomdquery.html">query</a>
          </code>
Returns information about many aspects of the current GrADS session
<br><code><a href="gradcomdquit.html">quit</a>
           </code>  
Quits GrADS
<br><code><a href="gradcomdsetdatawarn.html">set datawarn</a>
   </code>
Prints "Entire Grid Undefined" in display window if all data are missing
<br><code><a href="gradcomdsetstat.html">set stat</a>
       </code>
Turns on/off printing of statistical information for each display
<br><code><a href="gradcomdsetwarn.html">set warn</a>
       </code>
Turns on/off messages about the progress of certain mathematical operations
<br><code><a href="gradcomdshell.html">!shell</a>
         </code>
Sends a command to the shell


<p><font size=+1>Graphical Elements</font>
<br><code><a href="gradcomddrawline.html">draw line</a>
      </code>
Draws a line
<br><code><a href="gradcomddrawmark.html">draw mark</a>
      </code>
Draws a mark
<br><code><a href="gradcomddrawpolyf.html">draw polyf</a>
     </code>
Draws a filled polygon
<br><code><a href="gradcomddrawrec.html">draw rec</a>
       </code>
Draws a rectangle
<br><code><a href="gradcomddrawrecf.html">draw recf</a>
      </code>
Draws a filled rectangle
<br><code><a href="gradcomddrawwxsym.html">draw wxsym</a>
     </code>
Draws a weather symbol


<p><font size=+1>Map Settings</font>
<br><code><a href="gradcomddrawmap.html">draw map</a>        </code>
Draws a map outline
<br><code><a href="gradcomdsetgrid.html">set grid</a>
       </code>
Sets characteristics of displayed grid lines
<br><code><a href="gradcomdsetmap.html">set map</a>
        </code>
Sets map background characteristics
<br><code><a href="gradcomdsetmpdraw.html">set mpdraw</a>
     </code>
Turns on/off drawing of map background
<br><code><a href="gradcomdsetmpdset.html">set mpdset</a>
     </code>
Sets the resolution of the coastal outline
<br><code><a href="gradcomdsetmproj.html">set mproj</a>
      </code>
Sets current map projection
<br><code><a href="gradcomdsetmpt.html">set mpt</a>
        </code>
Controls map background characteristics 
<br><code><a href="gradcomdsetmpvals.html">set mpvals</a>
     </code>
Sets reference longitudes and latitudes for polar stereographic plots
<br><code><a href="gradcomdsetpoli.html">set poli</a>
       </code>
Turns on/off the drawing of political boundaries


<p><font size=+1>Station Data</font>
<br><code><a href="gradcomdcollect.html">collect</a>
        </code>
Saves station data in memory as a set
<br><code><a href="gradcomdsetmdlopts.html">set mdlopts</a>
    </code>
<br><code><a href="gradcomdsetwxopt.html">set wxopt</a>
      </code>
Controls weather symbol output; used with 'set gxout wxsym'
<br><code><a href="gradcomdsetstid.html">set stid</a>
       </code>
Turns on/off display of the station ID next to the data values 
<br><code><a href="gradcomdsetstnprint.html">set stnprint</a>
   </code>
Controls printing of station data values; used with 'set gxout stat'
<br><code><a href="gradutilstnmap.html">stnmap</a>
         </code>
Writes out a hash table and/or link list information for station data


<p><font size=+1>Variables</font>
<br><code><a href="gradcomddefine.html">define</a>
         </code>
Creates a new GrADS variable that is loaded into memory
<br><code><a href="gradcomdmodify.html">modify</a>
         </code>
Defines a climatological variable
<br><code><a href="gradcomdsetdefval.html">set defval</a>
     </code>
Interactively modifies grid point values for 2-D defined variables
<br><code><a href="gradcomdundefine.html">undefine</a>
       </code>
Frees the memory used by a defined variable


<p><font size=+1>Vectors</font>
<br><code><a href="gradcomdsetarrlab.html">set arrlab</a>
     </code>
Toggles drawing the vector arrow label 
<br><code><a href="gradcomdsetarrowhead.html">set arrowhead</a>
  </code>
Sets the size of the vector arrowhead
<br><code><a href="gradcomdsetarrscl.html">set arrscl</a>
     </code>
Specifies arrow length scaling
<br><code><a href="gradcomdsethempref.html">set hempref</a>
    </code>
Controls wind barb drawing conventions
<br><code><a href="gradcomdsetstrmden.html">set strmden</a>
    </code>
Sets density of streamlines; used with 'set gxout stream'


<p><font size=+1>Widgets</font>
<br><code><a href="gradcomddrawbutton.html">draw button</a>     </code>
Draws a button widget
<br><code><a href="gradcomdredrawbutton.html">redraw button</a>   </code>
Resets a button widget on/off
<br><code><a href="gradcomddrawdropmenu.html">draw dropmenu</a>   </code>
Draws a dropmenu widget
<br><code><a href="gradcomdsetbutton.html">set button</a>
     </code>
Specifies the color characteristics of a button widget
<br><code><a href="gradcomdsetdialog.html">set dialog</a>
     </code> 
Sets color properties of dialog box widgets
<br><code><a href="gradcomdsetdropmenu.html">set dropmenu</a>
   </code>
Sets color properties of dropmenu widgets
<br><code><a href="gradcomdsetrband.html">set rband</a>
      </code>
Sets characteristics for the 'rubber band' widget


</body>
</html>


\ No newline at end of file
diff --git a/doc/compression.html b/doc/compression.html
new file mode 100644
index 0000000..1fb2de9
--- /dev/null
+++ b/doc/compression.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<H2><strong>Reading and Writing Compressed Data Sets </strong></H2>
<p><strong><a href="#intro">Introduction</a><br />
    <a href="#chunking">Chunking and Cacheing</a> <br />
    <a href="#cachesize">Setting Cache Size</a><br />
    <a href="#reading">Reading Compressed  Files</a><br />
    <a href="#writing">Writing Compressed NetCDF Files</a><br />
    <a href="#chunksize">Setting Chunk Size</a></strong><br />
</p>
<p><img src="../../assets/colaline.gif" alt="line" width="600" height="4" />
<P><em><strong><a name="intro" id="intro"></a>Introduction</strong></em><br />
  GrADS version 2.0.a8 introduces the capability to  read write compressed netCDF files. The use of compression can significantly reduce data volume and speed up the I/O. Optimizing the performance depends on a number of factors: configuration of the software, available memory on the local hardware, data volume, even the nature of the I/O request (e.g. an X-Y plane or a Z-T cross section). It is impossible to customize GrADS to account for all the external factors, but it is possible to m [...]
<P><em><strong><a name="chunking" id="chunking"></a>Chunking and Cacheing</strong></em><br />
  A compressed netCDF file is actually an HDF5 file, so we begin with some HDF5 vocabulary. In HDF5, a chunk is an atomic unit of data -- chunks are handled individually for compression, reading and writing to disk, and storing in the cache. A multi-dimensional variable is a collection of chunks; each chunk has the same number of dimensions as the variable, and the size of a chunk in any dimension is equal to or less than the size of the variable's dimensions. 
<P>When a compressed data set is written out to a file, it is first divided into chunks, then each chunk is compressed, and finally the compressed chunk is written out to disk. When a client (such as GrADS) reads a compressed data set, a compressed chunk is read from disk, decompressed, and then the requested data values are returned to the client. The HDF5 library uses a cache to store  decompressed chunks in memory in case the client requests data from the same chunk again; data values  [...]
<p>To understand and optimize the performance of GrADS when reading a compressed netCDF file, it is helpful to know that GrADS does I/O by rows. Suppose a chunk contains 10 rows of a 2D grid, and the user wants to display 100 rows. The first chunk is read from disk, decompressed, cached, and the first row is delivered to GrADS. For the next nine rows, the library has cached the chunk, so the I/O is faster. For the 11th row, the next chunk is read from disk and the process repeats. If the  [...]
<p>The HDF5 library allocates the chunk cache  on a per-variable basis, so if you open a file and display many variables,  you can quickly eat up a lot of memory. Be careful that the cache does not get too large, otherwise you may use up all the available memory on your system which  will cause GrADS to crash. </p>
<p><em><strong><a name="cachesize" id="cachesize"></a>Setting Cache Size</strong></em><br />
It has been established that the cache size must be big enough to hold many chunks, but not so big that reading several variables in a file will use up all available memory. So how big should it be? The answer depends on the chunk size.  For good performance in GrADS, the cache should be at least big enough to hold  enough chunks to cover the global lat/lon domain. GrADS will set a default cache size that is based on the grid dimensions of a data set. The formula to calculate the default  [...]
<p>Before you open a compressed netCDF file, you can find out what the chunk size is by using the ncdump utility with the -s option, or the h5dump utility with the -p option. These utilities are compiled along with the HDF5 and NetCDF-4 libraries, but they are not included in the GrADS  distribution. </p>
<p><em><strong><a name="reading" id="reading"></a>Reading Compressed  Files</strong></em><br />
As long as GrADS has been compiled with netCDF library version 4.1 or higher (check <code><a href="gradcomdquery.html">q config</a></code> to discover the version number), then reading a compressed netCDF file will work exactly the same way in GrADS as reading a "classic" netCDF file. The fact that the data are compressed should be nearly invisible to the user. The HDF5 interface also automatically handles compressed files. </p>
<p>For example, suppose you have a data set with a grid resolution of 0.10 degrees, with 3600 grid points in the X dimension and 1800 grid points in the Y dimension, and the chunk size is 360 x 180. The size of a single chunk is about 256 Kb, and there are 100 chunks in a  global grid. GrADS will set the default cache size to 51840000 bytes, which is more than enough to keep all the chunks in a single global grid in the cache. This variable would be read in quickly. Subsequent displays of [...]
<p>When a user opens a file and issues an initial I/O request, GrADS will compare the chunk size and the current cache size and make sure that at least one chunk will fit in the cache. If the chunks are too big, GrADS will issue a warning ("<em>... The I/O for this variable will be extremely slow...</em>") and show you the chunk and cache sizes. If you see this message, follow these instructions:<br />
  1. Close the file<br />
  2(a). Add a <code><a href="descriptorfile.html#CACHESIZE">CACHESIZE</a></code> entry in the data descriptor file with a suitable value, OR  <br />
  2(b). Increase the cache size scale factor with  the <code><a href="gradcomdsetcachesf.html">set cachesf</a></code> command<br />
3. Re-open the file</p>
<p><em><strong><a name="writing" id="writing"></a>Writing Compressed NetCDF Files</strong></em><br />
You can create compressed netCDF output files with GrADS by using the <code><a href="gradcomdsdfwrite.html">sdfwrite</a></code> command. To do this, use the <code>-zip</code> option with the <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command, and then set the chunk size with the <code><a href="gradcomdsetchunksize.html">set chunksize</a></code> command before invoking <code><a href="gradcomdsdfwrite.html">sdfwrite</a></code>. More on how to set good chunk sizes is in [...]
<p><em><strong><a name="chunksize" id="chunksize"></a>Setting Chunk Size</strong></em><br />
The chunk dimension sizes are set at the time the data are written out to file. Once the data are written, there is no way to change the chunk sizes except to copy the data to a new file. If you are creating a compressed netCDF file, be sure to set the chunk size carefully and keep in mind that other users of your data file may not have the same memory resources that you do. An  estimate of the size of an decompressed chunk is 4 bytes (for floating point data values) multiplied by the all [...]
<p>The default behavior of GrADS is to  set the chunk size equal to the variable's full grid  size for the longitude (X) and latitude (Y) dimensions, and 1 (one) for all other dimensions. In this case, a chunk would be a single global 2-D lon/lat grid. However, if your data set is of sufficiently high resolution (e.g., if the grid size is less than 1.0 degree latitude/longitude), then you should use the <code><a href="gradcomdsetchunksize.html">set chunksize</a></code> command to set the  [...]
  
  Unless your data set does not vary in longitude and latidude, keep the chunk size equal to 1 for the level (Z), time (T), and ensemble (E) dimensions. If the chunk size is too big, then  the cache can never be adequate to support the I/O at a reasonable speed. Chunks that are too small do a lot less harm than chunks that are too big. </p>
<p> </p>
<p> </p>
<P>

<P>

<P>
\ No newline at end of file
diff --git a/doc/coordinate.html b/doc/coordinate.html
new file mode 100644
index 0000000..ec99917
--- /dev/null
+++ b/doc/coordinate.html
@@ -0,0 +1,144 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>INTRODUCTION</h2>
+<ul>
+I believe the most significant contribution of GrADS to the data
+"slicing" problem is its support of a universal,
+EXTERNAL-TO-THE-DATA "world coordinate."  <p>
+
+There are three coordinate systems in GrADS:<p>
+
+<ul>
+<li>GRID or index coorindate where data are reference by indices
+<li>WORLD or some external physical coordinate
+<li>PLOT or x-y location on the screen</ul>
+
+We'll first concentrate on the data cooridinates GRID and WORLD
+before discussing PLOT coordinates since these are the most
+important for data display and analysis.<p>
+
+The world coordinate is 4-D and is DEFINED INSIDE GrADS as the
+variables or dimensions with the names <code>lon</code>,
+<code>lat</code>, <code>lev</code> and
+<code>time</code>.  The typical correspondence between these GrADS
+world
+coordinates and the "real world" is:<p>
+
+<ul>
+lon 	=	longitude on the earth in degrees east<br>
+lat	=	latitude on the earth in degrees N<br>
+lev	=	pressure levels, sigma levels or theta levels<br>
+time	=	REAL TIME in min, hours, days, months and years
+(Gregorian calendar)<br></ul>
+
+For example, the point in the physical world (NOT DATA) of
+(<code>14.3N; 145E; 500 mb; 00:12 UTC on 7 March 1996</code> (a point
+above
+Guam)) in GrADS world coordinates (<code>lon;lat;lev;time</code>) would
+be
+(<code>14.3;145.0;500;12:00Z7Mar1996</code>).<p>
+
+The grid coordinate is also 4-D and is DEFINED INSIDE GrADS as
+(<code>x,y,z,t</code>).  In FORTRAN, the data would written out<p>
+
+<ul>
+<code>parameter (nx=144,ny=73,nz=17,nt=2)<br>
+dimension u(nx,ny,nz,nt)<br>
+integer x,y,z,t<p>
+
+do t=1,nt	  
+    do z=1,nz<br>
+        write(10) ((u(x,y),x=1,nx),y=1,ny)<br>
+    end do<br>
+end do</code></ul>
+
+
+In GrADS, one can REFERENCE data in the GrADS world coordinate
+IRRESPECTIVE of the underlying data structure.  This feature is
+something that the netCDF data access procedures do NOT support
+and is what makes GrADS a powerful data slicer.<p>
+
+However, as in the real world, GrADS only supports ONE
+relationship or "map" between world and grid coordinates at a
+time.  This map is based on the "default" file which by default
+is the first file opened.  To understand where this world->grid
+and grid->world map comes from consider the following data
+descriptor or <code>.ctl</code> file:<p>
+
+<ul>
+<code>
+dset ^bm.dat<br>
+title the best model ver data<br> 
+options yrev zrev<br>
+xdef 72 linear 0.0 5.0<br>
+ydef 46 linear -90 4.0<br>
+zdef  3 levels 850 500 200<br>
+tdef  1 linear 00z1jan1996 12hr<br>
+vars 1<br>
+  z 3 0 geopotential height
+endvars</code></ul>
+
+the map is defined by the <code>x(y,z,t)def</code> cards and
+(optionally)
+the <code>options</code> card.  In GrADS the world coordinate is ALWAYS
+defined such that longitude (<code>lon</code>) increases from West to
+East,
+latitutde (<code>lat</code>) increases toward the North and pressure
+level
+(<code>lev</code>) DECREASES with height (this is not strictly true but
+is
+very important when doing calculations such as vint). Time is a
+special case and can ONLY be linear with equal spacing
+(<code>12hr</code> in
+the example).  While the <code>?def</code> "cards" can be ordered in
+any way
+in the <code>.ctl</code> file, the world coordinate inside GrADS is
+ALWAYS
+(<code>lon,lat,lev,time</code>).  However, this does NOT mean the DATA
+has be
+arranged this way and the "options" card tells GrADS how the data
+differs from the standard.  In the above example case, the
+latitudes in GRID cooridates DECREASES with INCREASING <code>y</code>,
+that is
+<code>y=1 -> lat=90; y=2 -> lat=86; y=45 -> lat=-90</code> (some models
+and
+graphics systems prefer this orientation).  Similarly,
+<code>lev=200</code> is
+stored first, followed by <code>lev=500</code> and
+<code>lev=200</code>. Other
+modifications to the world<->grid map are possible, as described
+below.</ul><p>
+<br>
+<h2>DISPLAYING DATA RELATIVE TO THE WORLD COORDINATE</h2>
+<ul>
+The first task in intercomparing two or more data sets with
+different grids (i.e., different grid and world coordinates or
+grid-world "maps") is the graphical overlay or plotting two
+fields on top of each other.  One specifies a 0-3 dimensional
+volume in either grid or world coordinates and then <a
+href="gradcomddisplay.html"><code>display</code></a> a
+variable.  Consider the typical case of a 2-D contour plot:<p>
+
+<ul>
+<code>open psl.ecmwf.ctl<br>
+open psl.ncep.ctl<br>
+set gxout contour<br>
+set t 1<br>
+set lon 0 180<br>
+set lat 0 90<br>
+d psl</code></ul><p>
+
+and let's see what is happening inside GrADS.<p>
+
+the "default" file is the first one or the data in
+<code>psl.ecmwf.ctl</code>.
+This specifes that the grid-world and world-grid map will be
+based on the <code>psl.ecmwf.ctl</code>.
+
+<ul><code>set t 1</code> - look at the first time in the file or 
+
+'set time 00z1mar96' if that were the actual time corresponding the 
+
+
+
+
diff --git a/doc/descriptorfile.html b/doc/descriptorfile.html
new file mode 100644
index 0000000..740c28f
--- /dev/null
+++ b/doc/descriptorfile.html
@@ -0,0 +1,1804 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Data Descriptor File</title>
+<link href="/assets/NewIGES.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+<!--
+.style2 {color: #990000}
+.style3 {color: #009933}
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+.italic {
+	font-style: italic;
+}
+-->
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body text="#000000">
+<h2><a name="TOP"></a><span class="banner20">Components of a GrADS Data Descriptor 
+  File</span></h2>
+<p> <span class="plaintext">
+  <a href="#DSET">DSET</a><br>
+  <a href="#CHSUB">CHSUB</a><br>
+  <a href="#DTYPE">DTYPE</a><br>
+  <a href="#INDEX">INDEX</a><br>
+  <a href="#STNMAP">STNMAP</a><br>
+  <a href="#TITLE">TITLE</a><br>
+  <a href="#UNDEF">UNDEF</a><br>
+  <a href="#unpack">UNPACK</a> <br>
+  <a href="#FILEHEADER">FILEHEADER</a><br>
+  <a href="#XYHEADER">XYHEADER</a><br>
+  <a href="#THEADER">THEADER</a><br>
+  <a href="#THEADER">HEADERBYTES</a><br>
+  <a href="#TRAILERBYTES">TRAILERBYTES</a><br>
+  <a href="#XVAR">XVAR</a><br>
+  <a href="#YVAR">YVAR</a><br>
+  <a href="#ZVAR">ZVAR</a><br>
+  <a href="#STID">STID</a><br>
+  <a href="#TVAR">TVAR</a> <br>
+  <a href="#TOFFVAR">TOFFVAR</a><br>
+  <a href="#CACHESIZE">CACHESIZE</a><br>
+  <a href="#OPTIONS">OPTIONS</a><br>
+  <a href="#PDEF">PDEF</a> <br>
+  <a href="#XDEF">XDEF</a><br>
+  <a href="#YDEF">YDEF</a><br>
+  <a href="#ZDEF">ZDEF</a><br>
+  <a href="#TDEF">TDEF</a><br>
+  <a href="#EDEF">EDEF</a><br>
+  <a href="#VECT">VECTORPAIRS</a><br>
+  <a href="#VARS">VARS</a><br>
+  <a href="#VARS">ENDVARS</a><br>
+  <a href="#ATTR">ATTRIBUTE METADATA</a> <br>
+  <a href="#COMMENT">COMMENTS</a> <br>
+  </span>
+
+<hr>
+<table width="600" border="0" cellpadding="4" cellspacing="0" class="plaintext">
+  <tr> 
+    <td width="510" bgcolor="#CCCCCC"><a name="DSET"> <b>DSET</b> <i>data_filename</i></a>    </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p>This entry specifies the filename of the data file being 
+        described. If the data and the descriptor file are not in the same directory, 
+        then <i>data_filename</i> must include a full path. If a ^ character is 
+        placed in front of <i>data_filename</i>, then <i>data_filename</i> is 
+        assumed to be relative to the path of the descriptor file. If you are 
+        using the ^ character in the DSET entry, then the descriptor file and 
+        the data file may be moved to a new directory without changing any entries 
+        in the data descriptor file, provided their relative paths remain the 
+        same. For example:</p>
+      <p>If the data descriptor file is: <br>
+              /data/wx/grads/sa.ctl<br>
+        and the binary data file is:<br>
+              /data/wx/grads/sa.dat<br>
+        then the data file name in the data descriptor file can be:<br>
+              DSET ^sa.dat<br>
+        instead of:<br>
+              DSET /data/wx/grads/sa.dat 
+      <p>If <i>data_filename</i> does not include a full path or a ^, then GrADS 
+        will only look for data files in the directory where you are running GrADS. 
+      <p>GrADS allows you use a single DSET entry to aggregate multiple data files 
+        and handle them as if they were one individual file. The individual data 
+        files must be identical in all dimensions except time, and the time range 
+        of each individual file must be indicated it its filename. To accomplish 
+        this, the DSET entry has a substitution template instead of a filename. 
+        See the section on <a href="/grads/gadoc/templates.html">Using Templates</a> 
+        for a description of all the possible components of the template. Second, 
+        the <a href="#OPTIONS">OPTIONS</a> entry must contain the template keyword.<br>
+    </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="CHSUB"> <b>CHSUB</b> <i> t1  t2  string</i></a>    </td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p>(<font color="#990000">GrADS version 1.9b4</font>) This 
+        entry is used with a new option for templating data files that allows 
+        for any user-specified string substitution, instead of only date string 
+        substitution. This is useful when none of the standard template options 
+        match the time ranges in the files you wish to aggregate, or if the files 
+        are located on different disks. When you put the <code>%ch</code> template 
+        in your <a href="#DSET">DSET</a> entry, then you also need to put additional 
+        <a href="/grads/gadoc/descriptorfile.html#CHSUB">CHSUB</a> entries in 
+        the descriptor file. The <em>string</em> will be substituted for <code>%ch</code> 
+        in the data file name for the time steps beginning with <em>t1</em> and 
+        ending with <em>t2</em>.See the section on <a href="/grads/gadoc/templates.html">Using 
+        Templates</a> for examples. <br>
+        <br>
+      </p>    </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="DTYPE"> <b>DTYPE</b></a><em> keyword</em></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">The DTYPE entry specifies the type of data being described. 
+      There are four options: grib, hdfsds, netcdf, or station. If the data type 
+      is none of these, then the DTYPE entry is omitted completely from the descriptor 
+      file and GrADS will assume the data type is gridded binary. <br> <table width="100%" border="0" cellpadding="4" cellspacing="4" class="plaintext">
+        <tr> 
+          <td valign="top" bgcolor="b8c8d7">bufr</td>
+          <td bgcolor="b8c8d7" class="plaintext">(<font color="#990000">GrADS 
+            version 1.9</font>) Data file is a BUFR station data file. This data 
+            type must be accompanied by the following special entries: <a href="#XVAR">XVAR</a>, 
+            <a href="#YVAR">YVAR</a>, <a href="#TVAR">TVAR</a>, <a href="#STID">STID</a>. 
+            Optional special entries are: <a href="#ZVAR">ZVAR</a>, <a href="#TOFFVAR" class="plaintext">TOFFVAR</a>.          </td>
+        </tr>
+        <tr> 
+          <td width="11%" valign="top" bgcolor="ccdceb">grib</td>
+          <td width="89%" bgcolor="ccdceb">Data file is an indexed GRIB (version 1) file. 
+            This data type requires a secondary entry in the descriptor file: 
+            <a href="#INDEX">INDEX</a>. The <a href="#INDEX">INDEX</a> entry provides 
+            the filename (including the full path or a ^) for the GRIB index file. 
+            The index file is created by the <a href="util/gribmap.html">gribmap</a> 
+            utility. You must run <a href="util/gribmap.html">gribmap</a> and 
+            create the index file before you can display the GRIB data in GrADS.          </td>
+        </tr>
+        <tr>
+          <td valign="top" bgcolor="b8c8d7">grib2</td>
+          <td bgcolor="b8c8d7" class="plaintext">(<font color="#990000">GrADS version 2.0</font>) Data file is an indexed GRIB2 file. This data type requires a secondary entry in the descriptor file: : 
+          <a href="#INDEX">INDEX</a>. The <a href="#INDEX">INDEX</a> entry provides the filename (including the full path or a ^) for the GRIB2 index file. The index file is created by the <a href="util/gribmap.html">gribmap</a> utility. You must run <a href="util/gribmap.html">grib2map</a> and create the index file before you can display the GRIB2 data in GrADS. </td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top">hdfsds</td>
+          <td bgcolor="ccdceb" class="plaintext">(<font color="#990000">GrADS 
+            version 1.9</font>) Data file is an HDF Scientific Data Set (SDS). 
+            Although HDF-SDS files are self-describing and may be read automatically 
+            using the <a href="cmd/sdfopen.html">sdfopen</a>/<a href="cmd/xdfopen.html">xdfopen</a> commands, this DTYPE gives you the option of overriding the file's 
+            own metadata and creating a descriptor file for some or all of the 
+            variables in the file. This DTYPE may also be used if the metadata 
+            in the HDF-SDS file is insufficient or is not coards-compliant. This 
+            data type requires a special entry in the <em>units</em> field of 
+            the <a href="#VARS">variable declaration.</a> The <a href="#UNDEF">undef</a> and <a href="#UNPACK">unpack</a> entries contain special options for 
+            this dtype. </td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="b8c8d7">hdf5_grid</td>
+          <td bgcolor="b8c8d7" class="plaintext">(<font color="#990000">GrADS version 2.0.a7+</font>) Data file is HDF5 gridded format. The HDF5 format is extremely general and is designed to store a variety of data types. The GrADS interface is only for grids, and requires a complete descriptor file -- there is no sdfopen/xdfopen interface for HDF5.</td>
+        </tr>
+        <tr bgcolor="b8c8d7">
+          <td valign="top" bgcolor="ccdceb">netcdf</td>
+          <td bgcolor="ccdceb">(<font color="#990000">GrADS version 1.9</font>) 
+            Data file is NetCDF. Although NetCDF files are self-describing and 
+            may be read automatically using the <a href="cmd/sdfopen.html">sdfopen</a>/<a href="cmd/xdfopen.html">xdfopen</a> commands, this DTYPE gives you the option of overriding the file's 
+            own metadata and creating a descriptor file for some or all of the 
+            variables in the file. This DTYPE may also be used if the metadata 
+            in the NetCDF file is insufficient or is not coards-compliant. This 
+            data type requires a special entry in the<em> units</em> field of 
+            the <a href="#VARS">variable declaration.</a> The <a href="#UNDEF">undef</a> and <a href="#UNPACK">unpack</a> entries contain special options for 
+            this dtype. </td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="b8c8d7">station</td>
+          <td bgcolor="b8c8d7">Data file is in GrADS station data format. This 
+            data type requires a secondary entry in the descriptor file: STNMAP. 
+            The STNMAP entry provides the filename (including the full path or 
+            a ^) for the station data map file. The map file is created by the <a href="util/stnmap.html">stnmap</a> utility. You must run <a href="util/stnmap.html">stnmap</a> and create the map file before you can display the station data in 
+            GrADS. </td>
+        </tr>
+        
+      </table>    </td>
+  </tr>
+  <tr> 
+    <td valign="middle" bgcolor="#CCCCCC"> <p><a name="INDEX"></a> <b>INDEX</b> 
+        <i>filename</i> </p></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">This entry specifies the name of the grib map file. It is 
+      required when using the <a href="#DTYPE">DTYPE</a> grib or grib2 entry to read GRIB formatted data. The file is generated by running the external utility <a href="util/gribmap.html">gribmap</a>. or <a href="util/grib2map.html">grib2map</a>.      Filenaming conventions are the same as those described for the <a href="#DSET">DSET</a> 
+      entry.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="STNMAP"></a><strong>STNMAP</strong><em> filename</em></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">This entry specifies the name of the station map file. It 
+      is required when using the <a href="#DTYPE">DTYPE</a> station entry to read 
+      GrADS-formatted station data. The file is generated by running the external 
+      utility <a href="util/stnmap.html">stnmap</a>. Filenaming conventions are 
+      the same as those described for the <a href="#DSET">DSET</a> entry.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <p> <a name="TITLE"> <b>TITLE</b> <i>string</i></a> 
+    </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p>This entry gives brief description of the contents of the 
+        data set. <em>String</em> will be included in the output from a <a
+href="cmd/query.html">query</a> command and it will appear in the directory listing 
+        if you are serving this data file with the <a href="/grads/gds">GrADS-DODS 
+        Server (GDS)</a>, so it is helpful to put meaningful information in the 
+        title field. For GDS use, do not use double quotation marks (") in 
+        the title.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="UNDEF"> <b>UNDEF</b> <i>value</i></a> <em><undef_attribute_name></em></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2" class="plaintext"><p>This entry specifies the undefined or 
+        missing data value. UNDEF is a <i>required entry </i>even if there are 
+        no undefined data. GrADS operations and graphics routines will ignore 
+        data with this value from this data set. <br>
+        (<font color="#990000">GrADS version 1.9b4</font>) An optional second 
+        argument has been added for data sets of <a href="#DTYPE">DTYPE</a> netcdf 
+        or hdfsds -- it is the name of the attribute that contains the undefined 
+        value. This should be used when individual variables in the data file 
+        have different undefined values. After data I/O, the missing values in 
+        the grid are converted from the variable undef to the file-wide undef 
+        (the numerical value in the first argument of the UNDEF record). Then 
+        it appears to GrADS that all variables have the same undef value, even 
+        if they don't in the original data file. If the data require a transformation 
+        using the attributes named in the <a href="#unpack">UNPACK</a> entry, 
+        GrADS assumes the variable undef value corresponds to the data values 
+        as they appear in the file, i.e., <em>before</em> they are transformed 
+        using a scale factor and offset. Missing packed data values are thus assigned 
+        the file-wide undef value and are never unpacked. Attribute names are 
+        case sensitive, and it is assumed that the name is identical for all variables 
+        in the netcdf or hdfsds data file. If the name given does not match any 
+        attributes, or if no name is given, the file-wide undef value will be 
+        used. <br>
+        Example: UNDEF 1e+33 _FillValue</p>    </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="unpack"></a><strong>UNPACK</strong> <em>scale_factor_attribute_name 
+      <add_offset_attribute_name></em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><div align="left">(<font color="#990000">GrADS version 1.9</font>) 
+        This entry is used with <a href="#DTYPE">DTYPE</a> netcdf, hdfsds, or hdf5_grid (<font color="#990000">GrADS version 2.0.a7+</font>) for 
+        data variables that are 'packed' -- i.e. non-float data that need to be 
+        converted to float by applying the following formula: <br>
+             y = x * <em>scale_factor</em> + <em>add_offset</em><br>
+        If your self-describing file does not have an offset attribute, the 2nd argument may 
+        be omitted, and the offset will be assigned the default value of 0.0. 
+        If your self-describing file has an offset attribute, but not a scale factor, use "NULL" for the <em>scale_factor_attribute_name</em>. (This "NULL" option is in <span class="style2">GrADS version 2.0.0+</span>). Attribute names are case sensitive, and it is assumed that the names are 
+        identical for all variables in the netcdf or hdfsds data file. If the 
+        names given do not match any attributes, the scale factor will be assigned 
+        a value of 1.0 and the offset will be assigned a value of 0.0. The transformation 
+        of packed data is done after the undef test has been applied. <br>
+        Examples: <br>
+        UNPACK scale_factor add_offset<br>
+        UNPACK NULL add_offset<br>
+        UNPACK Slope Intercept<br>
+      </div></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <p> <a name="FILEHEADER"> <b>FILEHEADER</b> <i>length</i></a> 
+    </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">This optional entry tells GrADS that your data file has a 
+      header record of <em>length</em> bytes that precedes the data. GrADS will 
+      skip past this header, then treat the remaineder of the file as though it 
+      were a normal GrADS binary file after that point. This optional descriptor 
+      file entry is only valid for GrADS gridded data sets. </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <p> 
+	<a name="THEADER"> <b>THEADER</b> <i>length</i></a><br>   
+	<b>HEADERBYTES</b> <i>length</i><
+    </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">These two equivalent  optional entries tell GrADS that the data file has a header 
+      record of <em>length</em> bytes preceding each time block of binary data. Use one or the other but not both.
+      These entries are only valid for GrADS gridded data 
+      sets. See the section on <a href="aboutgriddeddata.html#structure">structure 
+      of a gridded binary data file</a> for more information.</td>
+  </tr>
+  <tr>
+    <td bgcolor="#CCCCCC"> <a name="TRAILERBYTES"> <b>TRAILERBYTES</b> <i>length</i></a> </td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back to top</a></td>
+  </tr>
+  <tr>
+    <td colspan="2">This optional entry tell GrADS that the data file has a trailer record of <em>length</em> bytes following
+	 each time block of binary data. This entry is only valid for GrADS gridded data sets. See the section on <a href="aboutgriddeddata.html#structure">structure of a gridded binary data file</a> for more information.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="XYHEADER"> <b>XYHEADER</b> <i>length</i></a>    </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">This optional entry tells GrADS that the data file has a header 
+      record of length bytes preceding each horizontal grid (XY block) of binary 
+      data. This entry is only valid for GrADS gridded 
+      data sets. See the section on <a
+href="aboutgriddeddata.html#structure">structure of a gridded binary data file</a> 
+      for more information.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="XVAR"></a>XVAR</strong> <em>x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2" class="plaintext">(<font color="#990000">GrADS version 1.9</font>) 
+      This entry provides the x,y pair for the station's longitude. This entry 
+      is required for <a href="#DTYPE">DTYPE</a> bufr.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="YVAR"></a>YVAR</strong> <em>x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">(<font color="#990000">GrADS version 1.9</font>) This entry 
+      provides the x,y pair for the station's latitude. This entry is required 
+      for <a href="#DTYPE">DTYPE</a> bufr.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="ZVAR"></a>ZVAR</strong> <em>x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">(<font color="#990000">GrADS version 1.9</font>) This entry 
+      provides the x,y pair for the station data's vertical coordinate (e.g., 
+      pressure). This is an optional entry for <a href="#DTYPE">DTYPE</a> bufr.    </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="STID"></a>STID</strong><em> x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">(<font color="#990000">GrADS version 1.9</font>) This entry 
+      provides the x,y pair for the station ID. This entry is required for <a href="#DTYPE">DTYPE</a> 
+      bufr.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="TVAR"></a>TVAR</strong> yr <em>x,y</em> 
+      mo <em>x,y</em> dy <em>x,y</em> hr <em>x,y</em> mn <em>x,y</em> sc <em>x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2" class="plaintext">(<font color="#990000">GrADS version 1.9</font>) 
+      This entry provides the x,y pairs for all the <strong>base time</strong> 
+      coordinate variables. Each time unit (year=yr, month=mo, day=dy, hour=hr, 
+      minute=mn, second=sc) is presented as a 2-letter abbreviation followed by 
+      the x,y pair that goes with that time unit. The time for any individual 
+      station report is the base time plus the offset time (see <a href="#TOFFVAR">TOFFVAR</a>). 
+      All six base time units are not required to appear in the TVAR record, only 
+      those that are in the data file. This entry is required for <a href="#DTYPE">DTYPE</a> 
+      bufr.</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><strong><a name="TOFFVAR"></a>TOFFVAR</strong> yr <em>x,y</em> 
+      mo <em>x,y</em> dy <em>x,y</em> hr <em>x,y</em> mn <em>x,y</em> sc <em>x,y</em></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2" class="plaintext">(<font color="#990000">GrADS version 1.9</font>) 
+      This entry provides the x,y pairs for all the <strong>offset time</strong> 
+      coordinate variables. The syntax is the same as <a href="#TVAR">TVAR</a>. 
+      The time for any individual station report is the base time plus the offset 
+      time. All six offset time units are not required to appear in the TOFFVAR 
+      record, only those that are in the data file. This is an optional entry 
+      for <a href="#DTYPE">DTYPE</a> bufr. </td>
+  </tr>
+  <tr>
+    <td bgcolor="#CCCCCC"><p><a name="CACHESIZE" id="CACHESIZE"> <b>CACHESIZE</b> <i>bytes</i></a></p></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr>
+    <td>(<font color="#990000">GrADS version 2.0.a8+</font>) 
+    This entry overrides the default size of the cache for reading HDF5 or NetCDF4 files. It is not relevant for other data types. It should not be necessary to set the cache size explicitly unless the data file has especially large chunks. Please see the documentation on <a href="compression.html">compression</a>. </td>
+    <td align="right" valign="top"> </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><p><a name="OPTIONS"> <b>OPTIONS</b> <i>keyword</i></a></p></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p>This entry controls various aspects of the way GrADS interprets 
+        the raw data file. It replaces the old FORMAT record. The <i>keyword</i> 
+        argument may be one or more of the following:</p>
+      <table width="100%" border="0" cellpadding="4" cellspacing="4" class="plaintext">
+        <tr bgcolor="b8c8d7">
+          <td valign="top" bgcolor="b8c8d7">pascals</td>
+          <td>(<font color="#990000">GrADS version 2.0</font>) (<span class="style3">For DTYPE grib2 only</span>) Indicates that pressure values that appear in the descriptor file (in the ZDEF entry and in the GRIB2 codes in the variable declarations)  are given in units of Pascals. The <a href="gradutilgribmap.html">gribmap</a> utility requires pressure to be given in Pascals. If this keyword is present, the pressure level values will be converted to millibars after the gribmap index is [...]
+        </tr>
+        <tr bgcolor="ccdceb"> 
+          <td valign="top" bgcolor="ccdceb">yrev</td>
+          <td>Indicates that the Y dimension (latitude) in the data file has been 
+            written in the reverse order from what GrADS assumes. An important 
+            thing to remember is that GrADS still presents the view that the data 
+            goes from south to north. The YDEF statement does not change; it still 
+            describes the transformation from a grid space going from south to 
+            north. The reversal of the Y axis is done as the data is read from 
+            the data file.</td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="b8c8d7">zrev</td>
+          <td bgcolor="b8c8d7">Indicates that the Z dimension (pressure) in the 
+            data file has been written from top to bottom, rather than from bottom 
+            to top as GrADS assumes. The same considerations as noted above for 
+            yrev also apply. </td>
+        </tr>
+        <tr bgcolor="ccdceb"> 
+          <td valign="top">template</td>
+          <td>Indicates that a template for multiple data files is in use. For 
+            more information, see the section on <a href="templates.html">Using 
+            Templates</a>. </td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="b8c8d7">sequential</td>
+          <td bgcolor="b8c8d7">Indicates that the file was written in sequential 
+            unformatted I/O. This keyword may be used with either station or gridded 
+            data. If your gridded data is written in sequential format, then each 
+            record must be an X-Y varying grid. If you have only one X and one 
+            Y dimension in your file, then each record in the file will be one 
+            element long (it may not be a good idea to write the file this way).</td>
+        </tr>
+        <tr bgcolor="ccdceb"> 
+          <td valign="top">365_day_calendar </td>
+          <td>Indicates the data file was created with perpetual 365-day years, 
+            with no leap years. This is used for some types of model ouput.</td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="b8c8d7">byteswapped</td>
+          <td bgcolor="b8c8d7">Indicates the binary data file is in reverse byte 
+            order from the normal byte order of your machine. Putting this keyword 
+            in the OPTIONS record of the descriptor file tells GrADS to swap the 
+            byte order as the data is being read. May be used with gridded or 
+            station data.</td>
+        </tr>
+        <tr> 
+          <td colspan="2" valign="top">The best way to ensure hardware independence 
+            for gridded data is to specify the data's source platform. This facilitates 
+            moving data files and their descriptor files between machines; the 
+            data may be used on any type of hardware without having to worry about 
+            byte ordering. The following three OPTIONS keywords are used to describe 
+            the byte ordering of a gridded or station data file:</td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="ccdceb">big_endian</td>
+          <td bgcolor="ccdceb">Indicates the data file contains 32-bit IEEE floats 
+            created on a big endian platform (e.g., sun, sgi)</td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="b8c8d7">little_endian</td>
+          <td bgcolor="b8c8d7">Indicates the data file contains 32-bit IEEE floats 
+            created on a little endian platform (e.g., iX86, and dec)</td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="ccdceb">cray_32bit_ieee</td>
+          <td bgcolor="ccdceb">Indicates the data file contains 32-bit IEEE floats 
+            created on a cray.</td>
+        </tr>
+      </table></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="PDEF"></a><strong>PDEF</strong></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">PDEF is so powerful it has<a href="pdef.html"> its own documentation 
+      page</a>. </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <p><a name="XDEF"></a> <b>XDEF</b> <i>xnum mapping 
+        <additional arguments></i> </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p> This entry defines the grid point values for the X dimension, 
+        or longitude. The first argument, <i>xnum</i>, specifies the number of 
+        grid points in the X direction. <i>xnum</i> must be an integer >= 1. <i>mapping</i> 
+        defines the method by which longitudes are assigned to X grid points. 
+        There are two options for <i>mapping</i>: 
+      <ul>
+        LINEAR    Linear mapping <br>
+        LEVELS    Longitudes specified individually 
+      </ul>
+      <p> The LINEAR mapping method requires two additional arguments: <i>start</i> 
+        and <i>increment</i>. <i>start</i> is a floating point value that indicates 
+        the longitude at grid point X=1. Negative values indicate western longitudes. 
+        <i>increment</i> is the spacing between grid point values, given as a 
+        positive floating point value. 
+      <p> The LEVELS mapping method requires one additional argument, <i>value-list</i>, 
+        which explicitly specifies the longitude value for each grid point. <i>value-list</i> 
+        should contain <i>xnum</i> floating point values. It may continue into 
+        the next record in the descriptor file, but note that records may not 
+        have more than 255 characters. There must be at least 2 levels in <i>value-list</i>; 
+        otherwise use the LINEAR method. 
+      <p> Here are some examples: 
+      <ul>
+        <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+          <tr> 
+            <td width="6%">XDEF</td>
+            <td width="4%" align="right">144</td>
+            <td width="11%" align="center">LINEAR</td>
+            <td width="79%">0.0 2.5</td>
+          </tr>
+          <tr> 
+            <td>XDEF</td>
+            <td align="right">72</td>
+            <td align="center">LINEAR</td>
+            <td>0.0 5.0 </td>
+          </tr>
+          <tr> 
+            <td>XDEF</td>
+            <td align="right">12</td>
+            <td align="center"> LEVELS</td>
+            <td>0 30 60 90 120 150 180 210 240 270 300 330 </td>
+          </tr>
+          <tr> 
+            <td>XDEF</td>
+            <td align="right">12</td>
+            <td align="center"> LEVELS</td>
+            <td>15 45 75 105 135 165 195 225 255 285 315 345</td>
+          </tr>
+        </table>
+      </ul></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="YDEF"> <b>YDEF</b><em> ynum mapping <additional 
+      arguments></em></a></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">This entry defines the grid point values for the Y dimension, 
+      or latitude. The first argument, <i>ynum</i>, specifies the number of grid 
+      points in the Y direction. <i>ynum</i> must be an integer >= 1. <i>mapping</i> 
+      defines the method by which latitudes are assigned to Y grid points. There 
+      are several options for <i>mapping</i>: 
+      <p> 
+      <ul>
+        LINEAR    Linear mapping <br>
+        LEVELS    Latitudes specified individually <br>
+        GAUST62   Gaussian T62 latitudes<br>
+        GAUSR15   Gaussian R15 latitudes<br>
+        GAUSR20   Gaussian R20 latitudes<br>
+        GAUSR30   Gaussian R30 latitudes<br>
+        GAUSR40   Gaussian R40 latitudes<br>
+      </ul>
+      <p> The LINEAR mapping method requires two additional arguments: <i>start</i> 
+        and <i>increment</i>. <i>start</i> is a floating point value that indicates 
+        the latitude at grid point Y=1. Negative values indicate southern latitides. 
+        <i>increment</i> is the spacing between grid point values in the Y direction. 
+        It is assumed that the Y dimension values go from south to north, so <i>increment</i> 
+        is always positive. 
+      <p> The LEVELS mapping method requires one additional argument, <i>value-list</i>, 
+        which explicitly specifies the latitude for each grid point, from south 
+        to north. <i>value-list</i> should contain <i>ynum</i> floating point 
+        values. It may continue into the next record in the descriptor file, but 
+        note that records may not have more than 255 characters. There must be 
+        at least 2 levels in <i>value-list</i>; otherwise use the LINEAR method. 
+      <p> The Gaussian mapping methods require one additional argument: start. 
+        This argument indicates the first gaussian grid number. If the data span 
+        all latitudes, start would be 1, indicating the southernmost gaussian 
+        grid latitude. 
+      <p> Here are some examples: 
+      <ul>
+        <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+          <tr> 
+            <td width="6%">YDEF</td>
+            <td width="4%" align="right">73</td>
+            <td width="12%" align="center">LINEAR</td>
+            <td width="78%">-90 2.5</td>
+          </tr>
+          <tr> 
+            <td>YDEF</td>
+            <td align="right">180</td>
+            <td align="center">LINEAR</td>
+            <td>-90 1.0</td>
+          </tr>
+          <tr> 
+            <td>YDEF</td>
+            <td align="right">18</td>
+            <td align="center">LEVELS</td>
+            <td>-85 -75 -65 -55 -45 -35 -25 -15 -5 5 15 25 35 45 55 65 75 85 </td>
+          </tr>
+          <tr> 
+            <td>YDEF</td>
+            <td align="right">94</td>
+            <td align="center">GAUST62</td>
+            <td>1</td>
+          </tr>
+          <tr> 
+            <td>YDEF</td>
+            <td align="right">20</td>
+            <td align="center">GAUSR40</td>
+            <td>15</td>
+          </tr>
+        </table>
+      </ul>
+      <p> The NCEP/NCAR Reanalysis surface variables are on the GAUST62 grid. 
+      <p> The final example shows that there are 20 Y dimension values which start 
+        at Gaussian Latitude 15 (64.10 south) on the Gaussian R40 grid</td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="ZDEF"> <b>ZDEF</b> <i>znum mapping <additional 
+      arguments></i></a> </td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p> This entry defines the grid point values for the Z dimension. 
+        The first argument, <i>znum</i>, specifies the number of pressure levels. 
+        <i>znum</i> must be an integer >= 1. <i>mapping</i> defines the method 
+        by which level values are assigned to Z grid points. There are two options 
+        for <i>mapping</i>: 
+      <ul>
+        <p>LINEAR    Linear mapping <br>
+          LEVELS    Pressure levels specified individually 
+      </ul>
+      <p> The LINEAR mapping method requires two additional arguments: <i>start</i> 
+        and <i>increment</i>. <i>start</i> is a floating point value that indicates 
+        the level value at grid point Z=1. <i>increment</i> is the spacing between 
+        grid point values in the Z direction, or from lower to higher. <i>increment</i> 
+        must be non-zero and non0negative.</p>
+      <p>The LEVELS mapping method requires one additional argument, <i>value-list</i>, 
+        which explicitly specifies the pressure level for each grid point in ascending 
+        order. <i>value-list</i> should contain <i>znum</i> floating point values. 
+        It may continue into the next record in the descriptor file, but note 
+        that records may not have more than 255 characters. </p>
+      <p> Here are some examples: 
+      <ul>
+        <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+          <tr> 
+            <td width="7%">ZDEF</td>
+            <td width="2%" align="right">7</td>
+            <td width="10%" align="center">LEVELS</td>
+            <td width="81%">1000 850 700 500 300 200 100 </td>
+          </tr>
+          <tr> 
+            <td>ZDEF</td>
+            <td align="right">17</td>
+            <td align="center">LEVELS</td>
+            <td>1000 925 850 700 600 500 400 300 250 200 150 100 70 50 </td>
+          </tr>
+        </table>
+      </ul>
+        <p>(<font color="#990000">GrADS version 2.0</font>) (<span class="style3">For DTYPE grib2 only</span>) If your Z axis is pressure, the <a href="gradutilgribmap.html">gribmap</a> utility requires the level values to be given in units of Pascals instead of millibars. Use the "options pascals" keyword to convert the unit of the level values to millibars after the gribmap index is generated and when the descriptor file is opened with GrADS. Pressure level values may remain  [...]
+        </ul></td>
+  </tr>
+  <tr>
+    <td bgcolor="#CCCCCC"> <a name="TDEF"> <b>TDEF</b> <i>tnum</i> LINEAR <i>start increment</i></a> </td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back to top</a></td>
+  </tr>
+  <tr>
+    <td colspan="2"><p> This entry defines the grid point values for the T dimension. The first argument, <i>tnum</i>, specifies the number of time steps. <i>tnum</i> must be an integer >= 1. The method by which times are assigned to T grid points is always LINEAR. 
+          <p> <i>start</i> indicates the initial time value at grid point T=1. <i>start</i> must be specified in the GrADS absolute date/time format: 
+          <ul>
+            <i>hh</i>:<i>mm</i>Z<i>ddmmmyyyy</i>
+          </ul>
+          <p> where: 
+          <ul>
+            <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+              <tr valign="top">
+                <td width="6%">hh</td>
+                <td width="2%" align="center">=</td>
+                <td width="92%">hour (two digit integer)</td>
+              </tr>
+              <tr valign="top">
+                <td>mm</td>
+                <td align="center">=</td>
+                <td>minute (two digit integer) </td>
+              </tr>
+              <tr valign="top">
+                <td>dd</td>
+                <td align="center">=</td>
+                <td>day (one or two digit integer)</td>
+              </tr>
+              <tr valign="top">
+                <td>mmm</td>
+                <td align="center">=</td>
+                <td>3-character month </td>
+              </tr>
+              <tr valign="top">
+                <td>yyyy</td>
+                <td align="center">=</td>
+                <td>year (may be a two or four digit integer; 2 digits implies a year between 1950 and 2049)</td>
+              </tr>
+            </table>
+          </ul>
+          <p>If not specified, <i>hh</i> defaults to 00, <i>mm</i> defaults to 00, and <i>dd</i> defaults to 1. The month and year must be specified. No intervening blanks are allowed in the GrADS absolute date/time format. 
+          <p> <i>increment</i> is the spacing between grid point values in the T direction. <i>increment</i> must be specified in the GrADS absolute time increment format: 
+          <ul>
+            <i>vvkk</i>
+          </ul>
+          <p> where: 
+          <ul>
+            <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+              <tr valign="top">
+                <td width="4%">vv</td>
+                <td width="2%" align="center">=</td>
+                <td width="94%">an integer number, 1 or 2 digits </td>
+              </tr>
+              <tr valign="top">
+                <td>kk</td>
+                <td align="center">=</td>
+                <td>mn (minute) <br>
+            hr (hour) <br>
+            dy (day) <br>
+            mo (month) <br>
+            yr (year) </td>
+              </tr>
+            </table>
+          </ul>
+          <p> Here are some examples: </p>
+          <ul>
+            <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+              <tr>
+                <td width="7%">TDEF</td>
+                <td width="4%" align="right">60</td>
+                <td width="10%" align="center">LINEAR</td>
+                <td width="79%">00Z31dec1999 1mn </td>
+              </tr>
+              <tr>
+                <td>TDEF</td>
+                <td align="right">73</td>
+                <td align="center">LINEAR</td>
+                <td> 3jan1989 5dy</td>
+              </tr>
+              <tr>
+                <td>TDEF</td>
+                <td align="right">730</td>
+                <td align="center">LINEAR</td>
+                <td>00z1jan1990 12hr </td>
+              </tr>
+              <tr>
+                <td>TDEF</td>
+                <td align="right">12</td>
+                <td align="center">LINEAR</td>
+                <td>1jan2000 1mo </td>
+              </tr>
+              <tr>
+                <td>TDEF</td>
+                <td align="right">365</td>
+                <td align="center">LINEAR</td>
+                <td>12Z1jan1959 1dy</td>
+              </tr>
+              <tr>
+                <td>TDEF</td>
+                <td align="right">40</td>
+                <td align="center">LINEAR</td>
+                <td> 1jan1950 1yr</td>
+              </tr>
+            </table>
+        </ul></td>
+  </tr>
+  <tr>
+    <td bgcolor="#CCCCCC"> <a name="EDEF"> <b>EDEF</b> <i>enum</i> NAMES <i><list of names></i></a> </td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back to top</a></td>
+  </tr>
+  <tr>
+    <td height="4" colspan="2"></td>
+  </tr>
+  <tr>
+    <td bgcolor="#CCCCCC">  <b>EDEF</b> <i>enum</i><br>
+    ensemble_record_1<br>
+    ensemble_record_2<br>
+    ...<br>
+    ensemble_record_<i>enum</i><br>
+    <b>ENDEDEF</b></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back to top</a></td>
+  </tr>
+
+  <tr>
+    <td colspan="2"><p>(<font color="#990000">GrADS version 2.0</font>) This entry defines the ensemble dimension. All ensemble members must have identical X, Y, and Z dimensions, the same list of variables, and the same time axis increment. There are two different syntaxes for the EDEF entry: the first  is simpler and requires only the names for each ensemble member, the second expanded form contains a name, individual time axis information, and optional GRIB2 codes.</p>
+      <p>Both EDEF syntaxes begin with the <em>enum</em> argument, an integer >=1 which specifies the number of ensemble members.</p>
+      <p>If all of the ensemble members have an identical time axis (i.e. length, initial time, and increment are the same for each one), then it is only necessary to distinguish the ensembles by their names, and the simplified EDEF syntax with the NAMES keyword may be used. A simple space-delimited list of names is all that is required. Ensemble names must have between 1 and 15 alphanumeric characters, lower case only. (<span class="style2">In version 2.0.0 and later, mixed case ensembl [...]
+      <ul>
+      <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+        <tr>
+          <td width="8%">EDEF</td>
+          <td width="3%" align="right">10</td>
+          <td width="12%" align="center">NAMES</td>
+          <td width="81%">1 2 3 4 5 6 7 8 9 10 </td>
+        </tr>
+        <tr>
+          <td width="8%">EDEF</td>
+          <td width="5%" align="right">12</td>
+          <td width="12%" align="center">NAMES</td>
+          <td>m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 ensm </td>
+        </tr>
+        <tr>
+          <td width="8%">EDEF</td>
+          <td width="5%" align="right">7</td>
+          <td width="12%" align="center">NAMES</td>
+          <td>e1 e2 e3 e4 e5 e6 e7 </td>
+        </tr>
+      </table>
+    </ul>    
+    <p>When the <a href="#OPTIONS">OPTIONS</a> TEMPLATE entry is used with EDEF, the ensemble names are used in the %e substitution template to generate the file name. See <a href="templates.html">Using Templates</a> for more details. </p>
+    <p>If the ensemble members do not have identical time axes (i.e., their lengths or initial times are not the same), 
+	  or if you need to include the GRIB2 codes, then you must use the expanded EDEF syntax: a collection of records framed by EDEF and ENDEDEF. 
+	  The format of the ensemble records is as follows: </p>
+    <ul>
+        <p><i>ensname length start <grib2 codes> </i></p>
+      </ul>
+    <p>The <em>ensname</em> is the  1-15 character "name" for the ensemble member. The<em> length </em>is the size of the time axis of the ensemble, which must be less than or equal to the <em>tnum</em> argument in the TDEF entry. (The time axis described by <a href="#TDEF">TDEF</a> must span all the ensemble members.) The<em> start </em> argument is the initial time  of the ensemble member and must be given in GrADS absolute date/time format. (See <a href="#TDEF">TDEF</a> for  [...]
+    <p>The <i>grib2 codes</i> are required if (1) the DTYPE is grib2 and (2) there is more than one ensemble member (<i>enum</i> > 1). The expanded form of the EDEF entry must be used when <i>grib2 codes</i> are required, even if the length and start times are the same for all members. For GRIB2 ensembles, support currently exists for four different Product Definition Template (PDT) numbers: 1, 2, 11, and 12. These are grouped into two types: individual ensemble forecasts (PDT 1 and 1 [...]
+    <p>The first example illustrates ensemble members with different lengths and start times: </p>
+    <ul>
+  <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+    <tr>
+      <td colspan="3">TDEF 591 linear 12z09dec1980 12hr </td>
+    </tr>
+    <tr>
+      <td colspan="3">EDEF 16 </td>
+      </tr>
+    <tr>
+      <td>ensm</td>
+      <td align="center">591</td>
+      <td>12z09dec1980</td>
+    </tr>
+    <tr>
+      <td width="6%">m01</td>
+      <td width="8%" align="center">591</td>
+      <td width="86%">12z09dec1980 </td>
+    </tr>
+    <tr>
+      <td>m02</td>
+      <td align="center">589</td>
+      <td>12z10dec1980 </td>
+    </tr>
+    <tr>
+      <td>m03</td>
+      <td align="center">587</td>
+      <td>12z11dec1980</td>
+    </tr>
+    <tr>
+      <td>m04</td>
+      <td align="center">585</td>
+      <td>12z12dec1980</td>
+    </tr>
+    <tr>
+      <td>m05</td>
+      <td align="center">583</td>
+      <td>12z13dec1980</td>
+    </tr>
+    <tr>
+      <td>m06</td>
+      <td align="center">571</td>
+      <td>12z19dec1980</td>
+    </tr>
+    <tr>
+      <td>m07</td>
+      <td align="center">569</td>
+      <td>12z20dec1980</td>
+    </tr>
+    <tr>
+      <td>m08</td>
+      <td align="center">567</td>
+      <td>12z21dec1980</td>
+    </tr>
+    <tr>
+      <td>m09</td>
+      <td align="center">565</td>
+      <td>12z22dec1980</td>
+    </tr>
+    <tr>
+      <td>m10</td>
+      <td align="center">563</td>
+      <td>12z23dec1980</td>
+    </tr>
+    <tr>
+      <td>m11</td>
+      <td align="center">549</td>
+      <td>12z30dec1980</td>
+    </tr>
+    <tr>
+      <td>m12</td>
+      <td align="center">547</td>
+      <td>12z31dec1980</td>
+    </tr>
+    <tr>
+      <td>m13</td>
+      <td align="center">545</td>
+      <td>12z01jan1981</td>
+    </tr>
+    <tr>
+      <td>m14</td>
+      <td align="center">543</td>
+      <td>12z02jan1981</td>
+    </tr>
+    <tr>
+      <td>m15</td>
+      <td align="center">541</td>
+      <td>12z03jan1981</td>
+    </tr>
+    <tr>
+      <td colspan="3">ENDEDEF</td>
+      </tr>
+  </table>
+</ul>
+<p>The second example illustrates the use of GRIB2 codes:</p>
+<ul>
+  <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+    <tr>
+      <td colspan="4">TDEF 31 linear 00z24apr2007 12hr </td>
+    </tr>
+    <tr>
+      <td colspan="4">EDEF 23 </td>
+    </tr>
+    <tr>
+      <td width="6%">p01</td>
+      <td width="8%" align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,1</td>
+    </tr>
+    <tr>
+      <td>p02</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,2</td>
+    </tr>
+    <tr>
+      <td>p03</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,3</td>
+    </tr>
+    <tr>
+      <td>p04</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,4</td>
+    </tr>
+    <tr>
+      <td>p05</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,5</td>
+    </tr>
+    <tr>
+      <td>p06</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,6</td>
+    </tr>
+    <tr>
+      <td>p07</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,7</td>
+    </tr>
+    <tr>
+      <td>p08</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,8</td>
+    </tr>
+    <tr>
+      <td>p09</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,9</td>
+    </tr>
+    <tr>
+      <td>p10</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,10</td>
+    </tr>
+    <tr>
+      <td>p11</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,11</td>
+    </tr>
+    <tr>
+      <td>p12</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,12</td>
+    </tr>
+    <tr>
+      <td>p13</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,13</td>
+    </tr>
+    <tr>
+      <td>p14</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,14</td>
+    </tr>
+    <tr>
+      <td>p15</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,15</td>
+    </tr>
+    <tr>
+      <td>p16</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,16</td>
+    </tr>
+    <tr>
+      <td>p17</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,17</td>
+    </tr>
+    <tr>
+      <td>p18</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,18</td>
+    </tr>
+    <tr>
+      <td>p19</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,19</td>
+    </tr>
+    <tr>
+      <td>p20</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>3,20</td>
+    </tr>
+    <tr>
+      <td>c00</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>1,0</td>
+    </tr>
+    <tr>
+      <td>avg</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>0</td>
+    </tr>
+    <tr>
+      <td>spr</td>
+      <td align="center">31</td>
+      <td width="20%">00z24apr2007</td>
+      <td>2</td>
+    </tr>
+    <tr>
+      <td colspan="4">ENDEDEF</td>
+    </tr>
+  </table>
+</ul></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"><a name="VECT"><strong>VECTORPAIRS</strong></a> <i>U-component,V-component 
+      </i> </td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"> <p>(<font color="#990000">GrADS version 1.9b4</font>) This 
+        entry is for explicity identifying vector component pairs. This is only 
+        necessary if the data are on a native projection other than lat/lon (i.e. 
+        you are using <a href="#PDEF">PDEF</a>) and if the winds have to be <a href="pdef.html#rotation">rotated</a> 
+        from a grid-relative sense to an Earth-relative sense. (GrADS has to retrieve 
+        both the u and v component in order to do the rotation calculation.)</p>
+      <p>Using this entry replaces the old technique of putting 33 (for U) or 
+        34 (for V) in the first element of the units field in the variable declaration. 
+        The <i>U-component</i> and <i>V-component </i>arguments should be variable 
+        names that appear in the <a href="#VARS">VARS</a> list. They are separated 
+        by a comma, with no spaces. More than one pair of components may be listed; 
+        in this case, the pairs should be separated by a space. For example: </p>
+      <ul>
+        VECTORPAIRS  u,v  u10,v10  uflx,vflx</p> </ul></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="VARS"> <b>VARS</b> <i>varnum</i><br>
+      </a> variable_record_1<br>
+      variable_record_2<br>
+      ...<br>
+      variable_record_<i>varnum</i><br> <b>ENDVARS</b></td>
+    <td width="74" align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"><p> This ensemble of entries describes all the variables contained 
+        in the data set. <em>varnum</em> indicates the number of variables in 
+        the data set and is therefore also equal to the number of variable records 
+        that are listed between the VARS and ENDVARS entries. ENDVARS must be 
+        the final line of the Grads data descriptor file. Any blank lines after 
+        the ENDVARS statement may cause <a href="cmd/open.html">open</a> to fail! 
+      <p> The format of the variable records is as follows: 
+      <ul>
+        <p><i>varname levs units description</i>                                 (<span class="red">Version 2.0.1 or earlier</span>)<br>
+        <i>varname levs <additional_codes> units description</i>    (<span class="red">Version 2.0.2 or later</span>)</p>
+      </ul>
+<p>The syntax of <em>varname</em> and <em>units</em> is different depending 
+        on what kind of data format (DTYPE) you are describing. The <i> <additional_codes></i> are only necessary for certain types of GRIB2 data sets. Details provided 
+        below:</p>
+      <table width="100%" border="0" cellpadding="4" cellspacing="4" class="plaintext">
+        <tr bgcolor="b8c8d7"> 
+          <td valign="top" bgcolor="#b8c8d7"><em>varname</em></td>
+          <td bgcolor="#b8c8d7">This is a 1-15 character "name" or abbreviation for the data variable. 
+            <i>varname</i> may contain alphabetic and numeric characters but it 
+            must start with an alphabetic character (a-z). </td>
+        </tr>
+        <tr> 
+          <td width="12%" valign="top" bgcolor="ccdceb"><em>varname<br>
+            </em>(DTYPE netcdf,  hdfsds, or hdf5_grid)</td>
+          <td width="88%" bgcolor="ccdceb">(<font color="#990000">GrADS version 
+            1.9+</font>) For <a href="#DTYPE">DTYPE</a> netcdf or hdfsds, <em>varname</em> 
+            may have a different syntax. This syntax is required when the name of the data variable in the SDF does not conform to the GrADS naming conventions (see below for list of criteria), but it may also be used to shorten or change the variable name to make it easier to work with inside GrADS. The syntax is:
+            <ul>
+              SDF_varname=>grads_varname 
+            </ul>
+            <p>SDF_varname is the name the data variable was given when the SDF 
+              file was originally created. For NetCDF files, this name appears 
+              in the output from ncdump. It is important that SDF_varname exactly 
+              matches the variable name in the data file. SDF_varname may contain 
+              uppercase letters and non-alpha-numeric characters. </p>
+            <p>The classic <em>varname</em> syntax (i.e., when "SDF_varname 
+              =>" is omitted) may be used if SDF_varname meets the criteria 
+              for GrADS variable names: it must be less than 16 characters, start 
+              with an alphabetic character, and cannot contain any upper case 
+              letters or non-alpha-numeric characters. </p>
+            <p>(<font color="#990000">GrADS version 
+            2.0.a3+</font>) If the SDF_varname contains spaces, substitute "~" for each space -- the spaces in the variable name string will be swapped back in later after the descriptor file has been parsed.</p>
+          <p>(<font color="#990000">GrADS version 2.0.a7+</font>) For dtype hdf5_grid, the SDF_varname may be particularly long since it must contain the names of all the nested groups (separated by "/") to which the data set belongs. <br>
+            For example:<br>
+            /HDFEOS/GRIDS/EarthSurfaceReflectanceClimatology/Data~Fields/MonthlySurfaceReflectance=>msr</p>          </td>
+        </tr>
+        <tr> 
+          <td valign="top" bgcolor="#b8c8d7"><em>levs</em></td>
+          <td bgcolor="#b8c8d7"><p>This is an integer that specifies the number 
+              of vertical levels the variable contains. <i>levs</i> may not exceed 
+              <i>znum</i> as specified in the ZDEF statement. If <i>levs</i> is 
+              0, the variable does not correspond to any vertical level. Surface 
+              variables (e.g. sea level pressure) have a <i>levs</i> value of 
+              0. </p>
+            <p>For <a href="#DTYPE">DTYPE</a> station or bufr, surface variables 
+              have a <i>levs</i> value of 0 and upper air variables have a <i>levs</i> 
+              value of 1. (Exception to this rule for bufr data: replicated surface 
+              variables are given a levs value of 2). </p></td>
+        </tr>
+        <tr>
+          <td valign="top" bgcolor="ccdceb"><p><em>levs</em><br>
+          (DTYPE grib2) </p></td>
+          <td bgcolor="ccdceb"><p>(<font color="#990000">GrADS version 2.0</font>) This is a comma-delimited list of numbers that provide information about the vertical dimension of a variable. The first number in the list is the number of vertical levels the variable contains or zero if the variable doesn't vary in Z. The remaining numbers are the GRIB2 parameters that specify the veritcal level or layer. The levs field may contain up to five comma-delimited numbers: </p>
+            <ul>
+              NLEVS,LTYPE,LVAL,LVAL2,LTYPE2
+            </ul>
+            where            <ul>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td width="9%" valign="top">NLEVS</td>
+                  <td width="2%" align="center" valign="top">=</td>
+                  <td width="89%"> The number of vertical levels, or 0 if not Z-varying (Required) </td>
+                </tr>
+                <tr>
+                  <td valign="top">LTYPE</td>
+                  <td align="center" valign="top">=</td>
+                  <td>The level type indicator (Required)</td>
+                </tr>
+                <tr>
+                  <td valign="top">LVAL</td>
+                  <td align="center" valign="top"> =                  </td>
+                  <td>The value of the 1st level (Not Required for all level types) </td>
+                </tr>
+                <tr>
+                  <td valign="top">LVAL2</td>
+                  <td align="center" valign="top">=</td>
+                  <td>The  value of the 2nd level (Only Required for layers between 2 fixed levels) </td>
+                </tr>
+                <tr>
+                  <td valign="top">LTYPE2</td>
+                  <td align="center" valign="top">= </td>
+                  <td>The level type indicator for the 2nd level (Only required  if different from LTYPE)</td>
+                </tr>
+              </table>
+            </ul>            
+            <p>If NLEVS > 0 and is followed only by the LTYPE, the values for LVAL will be determined by the <a href="#ZDEF">ZDEF</a> entry. If a variable has an NLEVS entry that is > 0 but less than the number of levels declared in the  <a href="#ZDEF">ZDEF</a> entry, then the values for LVAL will correspond to the first NLEVS values of the Z axis. If LTYPE is 100 (the GRIB2 code for an isobaric surface), the units of LVAL must be Pascals. If the values of LVAL are taken from the  [...]
+            <p>Examples:</p>
+            <ul>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td width="10%">hgt</td>
+                  <td width="20%" align="center">26,100</td>
+                  <td width="12%" align="center">0,3,5</td>
+                  <td>Geopotential Height [gpm] </td>
+                </tr>
+                <tr>
+                  <td>hgt500</td>
+                  <td align="center">0,100,50000</td>
+                  <td align="center">0,3,5</td>
+                  <td> Geopotential Height at 500mb [gpm] </td>
+                </tr>
+                <tr>
+                  <td>slp</td>
+                  <td align="center">0,101</td>
+                  <td align="center">0,3,1</td>
+                  <td>Sea Level Pressure [Pa]</td>
+                </tr>
+                <tr>
+                  <td>t2m</td>
+                  <td align="center">0,103,2</td>
+                  <td align="center">0,0,0</td>
+                  <td>2-meter Temperature [K]</td>
+                </tr>
+                <tr>
+                  <td>soilt1</td>
+                  <td align="center">0,106,0,0.1</td>
+                  <td align="center">0,0,0</td>
+                  <td>Soil Temp, 0-0.10m below surface [K]</td>
+                </tr>
+                <tr>
+                  <td>cloud</td>
+                  <td align="center">0,1,,,8</td>
+                  <td align="center">0,6,1</td>
+                  <td>Total Cloud Cover, from surface to  TOA [%]</td>
+                </tr>
+              </table>
+          </ul>            <p>The external utilities <a href="util/grib2scan">grib2scan</a> and <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/index.html">wgrib2</a> are quite useful in determining what the values for the <em>levs</em> field should be for a GRIB2 data file.</p></td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="#b8c8d7"><i>additional_codes<br>
+(DTYPE grib2)<br>
+(optional) </i></td>
+          <td bgcolor="#b8c8d7">(<font color="#990000">GrADS version 2.0.2+</font>) This field specifies any additional GRIB2 codes that are required to uniquely identify the record when the elements in the <span class="italic">levs</span> and <span class="italic">units</span> fields are not sufficient. It is only required for certain Product Definition Templates: the Probability Forecasts (PDT 5 and 9) and the Optical Properties of Aerosol (PDT 48). The <i>additional_codes</i> field alw [...]
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="#ccdceb"><i> additional_codes<br>
+            (PDT 5 or 9) </i></td>
+          <td bgcolor="#ccdceb"><p>For the Probability Forecasts (PDT 5 or  9), the <i>additional_codes</i> field has 2 or 3 comma-delimted numbers, preceded by the letter "a" :</p>
+            <ul>
+              aPTYPE,LIMIT,LIMIT2
+            </ul>
+            where
+         
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td width="9%" valign="top">PTYPE</td>
+                  <td width="2%" align="center" valign="top">=</td>
+                  <td width="89%">The probability type indicator </td>
+                </tr>
+                <tr>
+                  <td valign="top">LIMIT</td>
+                  <td align="center" valign="top"> = </td>
+                  <td>The value of the limit (for probabilities above or below the given limit) </td>
+                </tr>
+                <tr>
+                  <td valign="top">LIMIT2</td>
+                  <td align="center" valign="top">=</td>
+                  <td>The  value of the 2nd limit (for probabilities between the 2 given limits)<br>
+                  (only needed for PTYPE=2)</td>
+                </tr>
+              </table>
+         
+            <p>Examples:</p>
+           
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td>pt2m273</td>
+                  <td align="center">0,103,2</td>
+                  <td align="center">a0,273</td>
+                  <td align="center">0,0,0</td>
+                  <td>Prob. of 2-m Temp below 273</td>
+                </tr>
+                <tr>
+                  <td width="11%">pcape250</td>
+                  <td width="10%" align="center">0,1,0</td>
+                  <td width="11%" align="center">a1,250</td>
+                  <td width="11%" align="center">0,7,6</td>
+                  <td width="57%">Prob. of CAPE above 250</td>
+                </tr>
+                <tr>
+                  <td>pcape500</td>
+                  <td align="center">0,1,0</td>
+                  <td align="center">a1,500</td>
+                  <td align="center">0,7,6</td>
+                  <td>Prob. of CAPE above 500</td>
+                </tr>
+                <tr>
+                  <td>pcape1000</td>
+                  <td align="center">0,1,0</td>
+                  <td align="center">a1,1000</td>
+                  <td align="center">0,7,6</td>
+                  <td>Prob. of CAPE above 1000</td>
+                </tr>
+                <tr>
+                  <td>pcsnow1</td>
+                  <td align="center">0,1,0</td>
+                  <td align="center">a2,1,1</td>
+                  <td align="center">0,1,195</td>
+                  <td>Prob. of categor. snow between 1 and 1</td>
+                </tr>
+              </table>
+          
+            <p>The external utilities <a href="util/grib2scan">grib2scan</a> (with the -c option) and <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/index.html">wgrib2</a> are quite useful in determining what the values for the <i>additional_codes</i><em> </em>field should be for a GRIB2 data file.</p></td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="#ccdceb"><i> additional_codes<br>
+            (PDT 48)          </i></td>
+          <td bgcolor="#ccdceb"><p>For the Aerosol Forecasts (PDT 48), the  <i>additional_codes</i> field may have up to 7 comma-delimted numbers, preceded by the letter "a": 
+  </p>
+            <ul>
+            <p>aATYPE,STYPE,S1,S2,WTYPE,W1,W2</p>
+</ul>
+where
+
+  <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+    <tr>
+      <td width="9%" valign="top">ATYPE</td>
+      <td width="2%" align="center" valign="top">=</td>
+      <td width="89%">  The aerosol type indicator </td>
+    </tr>
+    <tr>
+      <td valign="top">STYPE</td>
+      <td align="center" valign="top"> = </td>
+      <td> The type of interval for the first and second size</td>
+    </tr>
+    <tr>
+      <td valign="top">S1</td>
+      <td align="center" valign="top">=</td>
+      <td><p> The first size (in meters)</p></td>
+    </tr>
+    <tr>
+      <td valign="top">S2</td>
+      <td align="center" valign="top">=</td>
+      <td> The second size (in meters)</td>
+    </tr>
+    <tr>
+      <td valign="top">WTYPE</td>
+      <td align="center" valign="top">=</td>
+      <td> The type of interval for the first and second wavelength</td>
+    </tr>
+    <tr>
+      <td valign="top">W1</td>
+      <td align="center" valign="top">=</td>
+      <td> The first wavelength (in meters)</td>
+    </tr>
+    <tr>
+      <td valign="top">W2</td>
+      <td align="center" valign="top">=</td>
+      <td> The second wavelength (in meters)</td>
+    </tr>
+  </table>
+
+<p>The ATYPE code is always required. If the STYPE is non-missing, then the trio of numbers STYPE,S1,S2 must be included in the <i>additional_codes</i> field. Similarly, if WTYPE is non-missing, then the trio of numbers WTYPE,W1,W2 must be included in the <i>additional_codes</i> field. If both STYPE and WTYPE are non-missing, then all six codes must be present in the order listed above. </p>
+<p>Examples:</p>
+
+  <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+    <tr>
+      <td width="9%" height="20">aotk</td>
+      <td width="9%" align="center">0,10,0</td>
+      <td width="54%" align="center">a62000,0,2e-5,0,7,5.45e-7,5.65e-7</td>
+      <td width="14%" align="center">0,0,0 </td>
+      <td width="14%" align="center">*desc1</td>
+      </tr>
+
+    <tr>
+      <td>aemflx</td>
+      <td align="center">0,10,0</td>
+      <td align="center">a62001,0,2e-05,0</td>
+      <td align="center">0,20,3</td>
+      <td align="center">*desc2 </td>
+      </tr>
+
+  </table>
+  <br>
+  *desc1=Total Aerosol Optical Thickness,
+        size  < 2e-5, 
+        wavelength >= 5.45e-7 
+        and <= 5.65e-7<br>
+        *desc2=Atmosphere Emission Mass Flux
+        for Dry Dust, 
+        size is < 2e-5        <p>The external utilities <a href="util/grib2scan">grib2scan</a> (with the -c option) and <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/index.html">wgrib2</a> are quite useful in determining what the values for the <i>additional_codes</i><em> </em>field should be for a GRIB2 data file. </p></td>
+        </tr>
+        <tr> 
+          <td colspan="2" valign="top">The <i>units</i> component of the variable 
+            record is used for data with <a href="#DTYPE">DTYPE</a> bufr, grib, 
+            netcdf, or hdfsds. It is also used for non-standard binary data files 
+            that require special "unpacking" instructions, and special 
+            cases of pre-projected wind components. If the data you are describing 
+            does not fall into any of these categories, put a value of 99 in the 
+            <em>units</em> field. </td>
+        </tr>
+        <tr bgcolor="b8c8d7"> 
+          <td valign="top" bgcolor="#b8c8d7"><em>units</em></td>
+          <td bgcolor="#b8c8d7">For flat binary files containing 4-byte floating-point data that 
+            are not pre-projected, this field is ignored but must be included. 
+            Put in a value of 99. </td>
+        </tr>
+        <tr bgcolor="ccdceb"> 
+          <td valign="top"><em>units<br>
+            </em>(DTYPE bufr)</td>
+          <td valign="top" bgcolor="ccdceb">(<font color="#990000">GrADS version 
+            1.9</font>) For <a href="#DTYPE">DTYPE</a> bufr files, this field 
+            contains the x,y pair for the named variable. </td>
+        </tr>
+        <tr bgcolor="b8c8d7"> 
+          <td valign="top" bgcolor="b8c8d7"><em>units<br>
+            </em>(DTYPE grib)</td>
+          <td bgcolor="b8c8d7"> <p>For <a href="#DTYPE">DTYPE</a> grib, the <em>units</em> 
+              field specifies the GRIB parameters of the variable. This information 
+              is used by the <a href="util/gribmap.html">gribmap</a> utility for 
+              mapping the variables listed in the descriptor file to the data 
+              records in the GRIB files. This parameter may contain up to four 
+              comma-delimited numbers: 
+            <ul>
+              VV,LTYPE,LVAL,TRI 
+                <br>
+                 or<br>
+            VV,LTYPE,LVAL,LVAL2
+</ul>
+            where, 
+            <ul>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr> 
+                  <td width="9%">VV</td>
+                  <td width="2%" align="center"> = </td>
+                  <td width="89%">The GRIB parameter number (Required)</td>
+                </tr>
+                <tr> 
+                  <td>LTYPE</td>
+                  <td align="center">=</td>
+                  <td>The level type indicator (Required)</td>
+                </tr>
+                <tr> 
+                  <td>LVAL</td>
+                  <td align="center">=</td>
+                  <td>The value of the 1st level  (Required if NLEVS=0)</td>
+                </tr>
+                <tr>
+                  <td>LVAL2</td>
+                  <td align="center">=</td>
+                  <td>The value of the 2nd level (Optional)</td>
+                </tr>
+                <tr> 
+                  <td>TRI</td>
+                  <td align="center">=</td>
+                  <td>The "time range indicator"                    (Optional) </td>
+                </tr>
+              </table>
+            </ul>
+            <p>The external utilities <a href="util/gribscan">gribscan</a> and 
+              <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib.html">wgrib</a> 
+              are quite useful in determining what the values for the <em>units</em> 
+              field should be for a GRIB data file. Examples:</p>
+            <ul>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr> 
+                  <td width="6%">u</td>
+                  <td width="5%" align="center">39</td>
+                  <td width="20%" align="center">33,100</td>
+                  <td>U Winds [m/s]</td>
+                </tr>
+                <tr> 
+                  <td>t</td>
+                  <td align="center">39</td>
+                  <td align="center">11,100</td>
+                  <td> Temperature [K]</td>
+                </tr>
+                <tr> 
+                  <td>ts</td>
+                  <td align="center">0</td>
+                  <td align="center">11,1</td>
+                  <td>Surface Temperature [K]</td>
+                </tr>
+                <tr> 
+                  <td>tb</td>
+                  <td align="center">0</td>
+                  <td align="center">11,116,60,30</td>
+                  <td>Temperature, 30-60mb above surface [K]</td>
+                </tr>
+                <tr> 
+                  <td>dpt</td>
+                  <td align="center">0</td>
+                  <td align="center">17,100,1000</td>
+                  <td> Dew Point Temperature at 1000 mb [K]</td>
+                </tr>
+              </table>
+            </ul></td>
+        </tr>
+        <tr>
+          <td valign="top" bgcolor="ccdceb"><em>units<br>
+          </em>(DTYPE grib2)</td>
+          <td bgcolor="ccdceb"><p>(<font color="#990000">GrADS version 2.0</font>) This is a comma-delimited list of  values that identify  a GRIB2 parameter (variable): </p>
+            <ul>
+              DISC,CAT,NUM,SP,SP2
+            </ul>
+            <p>where, </p>
+            <ul>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td width="8%">DISC</td>
+                  <td width="3%" align="center">=</td>
+                  <td width="89%">The  parameter Discipline (Required)</td>
+                </tr>
+                <tr>
+                  <td>CAT</td>
+                  <td align="center">=</td>
+                  <td>The  parameter Category  (Required)</td>
+                </tr>
+                <tr>
+                  <td>NUM</td>
+                  <td align="center">=</td>
+                  <td>The  parameter Number   (Required)</td>
+                </tr>
+                <tr>
+                  <td valign="top">SP</td>
+                  <td align="center" valign="top">=</td>
+                  <td>The Statistical Process used to derive the parameter <br>
+                  (May be required if parameter is not an instantaneous value)</td>
+                </tr>
+                <tr>
+                  <td valign="top">SP2</td>
+                  <td align="center" valign="top">=</td>
+                  <td>The Spatial Process used to interpolate the parameter<br>
+                  (Required only for Product Definition Template 4.15)</td>
+                </tr>
+              </table>
+            </ul>
+            <p>Some examples are: </p>
+           
+              <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
+                <tr>
+                  <td width="8%">u</td>
+                  <td width="18%" align="center">26,100</td>
+                  <td width="16%" align="center">0,2,2</td>
+                  <td width="58%">U-Component of Wind [m/s]</td>
+                </tr>
+                <tr>
+                  <td>v</td>
+                  <td align="center">26,100</td>
+                  <td align="center">0,2,3</td>
+                  <td>V-Component of Wind [m/s]</td>
+                </tr>
+                <tr>
+                  <td>t2max</td>
+                  <td align="center">0,103,2</td>
+                  <td align="center">0,0,5</td>
+                  <td> 2-meter Temperature Maximum [K] (NCEP)</td>
+                </tr>
+                <tr>
+                  <td>t2max</td>
+                  <td align="center">0,103,2</td>
+                  <td align="center">0,0,0,2</td>
+                  <td> 2-meter Temperature Maximum [K] (TIGGE)</td>
+                </tr>
+                <tr>
+                  <td>soilm1</td>
+                  <td align="center">0,106,0,0.1</td>
+                  <td align="center">2,0,192</td>
+                  <td>Soil Moisture, 0-0.10m below surface [K]</td>
+                </tr>
+                <tr>
+                  <td>catave</td>
+                  <td align="center">10,100</td>
+                  <td align="center">0,19,22,0,3</td>
+                  <td> Spatial Avg. of Clear Air Turbulence [%]</td>
+                </tr>
+                <tr>
+                  <td>catmax</td>
+                  <td align="center">10,100</td>
+                  <td align="center">0,19,22,2,3</td>
+                  <td> Spatial Max of Clear Air Turbulence [%]</td>
+                </tr>
+              </table>
+          <p> </p></td>
+        </tr>
+        <tr bgcolor="b8c8d7"> 
+          <td valign="top"><em>units<br>
+            </em>(DTYPE netcdf, <br>
+            hdfsds, or hdf5_grid)</td>
+          <td> <p class="plaintext">(<font color="#990000">GrADS 
+              version 1.9</font>) For <a href="#DTYPE">DTYPE</a> netcdf or hdfsds or hdf5_grid (<font color="#990000">GrADS 
+              version 2.0.a7+</font>) , 
+              the <em>units</em> field is a comma-delimited list of the varying 
+              dimensions of the variable. Dimensions expressed as x, y, z, or 
+              t correspond to the four axes defined by XDEF, YDEF, ZDEF and TDEF. 
+              For example, a surface variable such as sea level pressure might 
+              look like this: 
+            <ul>
+              presSFC=>psfc   0   y,x   Surface 
+              Pressure 
+            </ul>
+            <p>A time-varying atmospheric variable such as geopotential height 
+              might look like this:</p>
+            <ul>
+              Height=>hght   17   t,z,y,x   Geopotential 
+              Height (m) 
+            </ul>
+            <p class="plaintext">The order of the dimensions listed in the <em>units</em> 
+              field does matter. They must describe the shape of the variable 
+              as it was written to the SDF data file. For NetCDf files, this information 
+              appears in the output from ncdump next to the variable name. 
+            <p class="plaintext">If your data file contains a variable that also 
+              varies in a non-world-coordinate dimension (e.g. histogram interval, 
+              spectral band, ensemble number) then you can put a non-negative 
+              integer in the list of varying dimensions that will become the array 
+              index of the extra dimension. For example: 
+            <ul>
+              <p class="plaintext"> VAR=>hist0   0   0,y,x   
+                First historgram interval for VAR<br>
+                VAR=>hist1   0   1,y,x   Second 
+                historgram interval for VAR<br>
+                VAR=>hist2   0   2,y,x   Third 
+                histogram interval for VAR </p>
+            </ul>
+            <p class="plaintext">Another option in this example would be to fill 
+              the unused Z axis with the histogram intervals: </p>
+            <ul>
+              <p class="plaintext"> zdef 3 linear 1 1<br>
+                ... <br>
+                VAR=>hist   3   z,y,x   VAR Histogram</p>
+            </ul>
+            <p class="plaintext">In this case, it would appear to GrADS that variable 
+              'hist' varies in Z, but the user would have to remember that the 
+              Z levels correspond to histogram intervals. The latter technique 
+              makes it easier to slice through the data, but is not the most accurate 
+              representation. And if you don't have an unsued world-coordinate 
+              axis available, then you still have a way to access your data<em>.</em></p></td>
+        </tr>
+        <tr bgcolor="ccdceb"> 
+          <td valign="top"><em>units</em> <br>
+            (non-standard binary)</td>
+          <td> <p>For non-standard binary files, the <i>units</i> field is used 
+              to instruct GrADS how to read binary files that do not conform to 
+              the <a href="aboutgriddeddata.html#structure">default structure</a> 
+              or do not contain 4-byte float data. GrADS assumes the data were 
+              written in the following order (starting from the fastest varying 
+              dimension to the slowest): longitude (X), latitude (Y), vertical 
+              level (Z), variable (VAR), time (T). If your binary data set was 
+              created or "packed" according to a different dimension sequence, 
+              then you can use the <i>units</i> field to tell GrADS exactly how 
+              to unpack the data. </p>
+            <p>For these non-standard binary files, the <i>units</i> field is 
+              a series of one or more comma-delimited numbers, the first of which 
+              is always -1. The syntax is as follows: 
+            <ul>
+              -1, <i>structure</i> <,arg> 
+            </ul>
+            <p>There are four options for <i>structure</i>, outlined below. Some 
+              of these options have additional attributes which are specified 
+              with <i>arg</i>. </p>
+            <table width="100%" border="1" cellpadding="2" cellspacing="0" bordercolor="#999999" class="plaintext">
+              <tr> 
+                <td width="13%" valign="top"> -1,10,<em>arg</em> </td>
+                <td width="87%"> <p><span class="style2">(GrADS 1.9 or earlier)</span> This option indicates that "VAR" and "Z" have 
+                    been transposed in the dimension sequence. The order is: longitude 
+                    (X), latitude (Y), variable (VAR), vertical level (Z), time(T). 
+                    Thus, all variables are written out one level at a time. This feature was designed to be used with NASA GCM data in 
+                    the "phoenix" format. The upper air <i>prognostic</i> variables 
+                    were transposed, but the <i>diagnostic</i> variables were 
+                    not. Thus an <i>arg</i> of 1 means the variable has been var-z 
+                    transposed, and an <i>arg</i> of 2 means the variable has 
+                    not. </td>
+              </tr>
+              <tr> 
+                <td valign="top">-1,20</td>
+                <td><p>This option indicates that "VAR" and "T" have been transposed 
+                    in the dimension sequence. The order is: longitude (X), latitude 
+                    (Y), vertical level (Z), time(T), variable (VAR). Thus, all 
+                    times for one variable are written out in order followed by 
+                    all times for the next variable, etc. Data files for which 
+					"VAR" and "T" have been transposed may not be templated together.</td>
+              </tr>
+              <tr> 
+                <td valign="top">-1,30 </td>
+                <td><span class="style2">(GrADS 1.9 or earlier)</span> This option handles the cruel and unusual case where X and 
+                  Y dimensions are transposed and the horizontal grids are (lat,lon) 
+                  as opposed to (lon,lat) data. This option causes GrADS to work 
+                  very inefficiently. However, it is useful for initial inspection 
+                  and debugging. </td>
+              </tr>
+              <tr> 
+                <td valign="top">-1,40,<em>arg</em> </td>
+                <td><p>This option handles non-float data. If there are multiple variables in the same file, they must all be the same type. The dimension sequence is assumed to be the default. The secondary 
+                    <i>arg</i> tells GrADS what type of data values are in the 
+                    binary file: 
+                  <ul>
+                    <i>units</i> = -1,40,1     = 1-byte unsigned 
+                    chars (0-255) <br>
+                    <i>units</i> = -1,40,2     = 2-byte unsigned 
+                    integers<br>
+                    <i>units</i> = -1,40,2,-1 = 2-byte signed 
+                    integers<br>
+                    <i>units</i> = -1,40,4     = 4-byte integers<br>
+                  </ul></td>
+              </tr>
+            </table></td>
+        </tr>
+        <tr bgcolor="b8c8d7">
+          <td valign="top" bgcolor="b8c8d7"><em>units</em> <br>
+            (pre-projected wind components)</td>
+          <td bgcolor="b8c8d7">For pre-projected vector component data that require the use of <a href="/grads/gadoc/pdef.html">PDEF</a> and <a href="/grads/gadoc/pdef.html#rotation">rotation</a>, 
+            GrADS has to retrieve both the u and v component in order to do the 
+            rotation calculation. The new (and recommended) method for matching 
+            vector components is to use the <a href="#VECT">VECTORPAIRS</a> descriptor 
+            file entry. The old technique (for versions older than 1.9b4) is to 
+            use the<em> units</em> field of the variable record. The u-component 
+            variable must have a <em>units</em> value of 33, and the v-component 
+            variable must have a <em>units</em> value of 34. (This is the GRIB 
+            convention). If there are more than one u/v pairs, secondary <em>units</em> values are used.</td>
+        </tr>
+        <tr bgcolor="ccdceb">
+          <td valign="top" bgcolor="#b8c8d7"><em>description</em></td>
+          <td bgcolor="#b8c8d7">This is text description or long name for the variable. Max 140 characters. </td>
+        </tr>
+      </table>
+      <p><br>
+    </td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="ATTR"> <b>@  </b><em>varname  attribute_type 
+       attribute_name  attribute_value </em></a></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2"> <p>(<font color="#990000">GrADS version 1.9b4</font>) To 
+        supplement the metadata in your descriptor file, use attribute comments. 
+        The first two characters of the attribute comment must be "@" 
+        followed by a space -- this distinguishes it from an ordinary comment 
+        (see below). Attribute comments may appear anywhere in the descriptor 
+        file, and they will be ignored if used with older versions of GrADS. </p>
+      <p>All file attributes may be retrieved with the <a href="gradcomdqattr.html">'query 
+        attr'</a> command. </p>
+      <p><em>varname</em> may be set to "global" to describe general 
+        attributes that are valid for the entire data set. Set <em>varname</em> 
+        to "lon", "lat", "lev", or "time" 
+        to describe attributes of the four coordinate axes; otherwise, use one 
+        of the variable names listed in the variable declarations. If a variable 
+        name is aliased, use the grads_varname instead of the native SDF_varname.</p>
+      <p><em>attribute_type</em> should be one of the following case-sensitive 
+        types: String, Byte, Int16, UInt16, Int32, UInt32, Float32, Float64.</p>
+      <p><em>attribute_name</em> may be any single word or string with no spaces 
+        (e.g.: "units", "minimum_value")</p>
+      <p><em>attribute_value</em> can be any string as long as the length of the 
+        entire entry does not exceed 512 characters. </p>
+      <p class="plaintext">For example:<br>
+        @ precip String units mm/day<br>
+        @ global String documentation http://put.your.documentation.url.here<br>
+        <br>
+      </p></td>
+  </tr>
+  <tr> 
+    <td bgcolor="#CCCCCC"> <a name="COMMENT"> <b>*</b> <em>comment</em></a></td>
+    <td align="right" valign="top" bgcolor="#CCCCCC"><a href="#TOP" class="item9">back 
+      to top</a></td>
+  </tr>
+  <tr> 
+    <td colspan="2">You may put comments in your descriptor file by beginning 
+      the entry with * . Use @ for formatted attribute comments (see above). </td>
+  </tr>
+  <tr> 
+    <td colspan="2"> </td>
+  </tr>
+</table>
+<p> </p>
+</body>
+</html>
+
diff --git a/doc/dimenv.html b/doc/dimenv.html
new file mode 100644
index 0000000..a1fe72b
--- /dev/null
+++ b/doc/dimenv.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<h2>Dimension Environment</h2>
<p>

The data set is always viewed by GrADS as a generalized 5-D (6-D
if you include variables) array located in physical space (lon,
lat, lev, time, ensemble), even if it is in reality a subset of a 5-D
space.<p>

The current dimension environment describes what part of the data
set you want to work with. Expressions are evaluated with respect
to the dimension environment (which allows for simplicity in the
expression syntax), and the final display will be determined by
the dimension environment.  Thus, the dimension environment is a
GrADS concept that is important to understand.<p>

The dimension environment is manipulated by the user by entering
one of the following set commands:<p>

<dd><code><a href="gradcomdsetlatlonlevtimeens.html">set lat|lon|lev|time|ens</a> <i>val1
<val2></i></code>
  <p>

This set command sets one dimension of the dimension environment
using world coordinates.<p>

Alternatively:<p>

<dd><code><a href="gradcomdsetxyzte.html">set x|y|z|t|e</a><i> val1
<val2></i></code>
  <p>

This sets one dimension of the dimension environment using grid
coordinates.  You may use whatever coordinates are convenient to
you.  Issuing <code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a></code> is
equivalent to issuing <code><a href="gradcomdsetxyzte.html">set x</a></code>, both
set the x dimension.  The difference is only the units you wish
to enter the command in.<p>

When you enter just one value, that dimension is said to be
"fixed".  When you enter two values, that dimension is said to be
"varying".  The combination of fixed and varying dimensions
defines the dimension environment.<p>

Examples:<p>
<ul>
<code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a> -180
0</code>      sets
longitude to vary from 180W to 0<br>
<code><a href="gradcomdsetlatlonlevtimeens.html">set lat</a> 0
90</code>         sets
latitude to vary from the equator to 90N<br>
<code><a href="gradcomdsetlatlonlevtimeens.html">set lev</a>
500</code>           sets
the level to 500mb - a fixed dimension<br> 
<code><a href="gradcomdsetxyzte.html">set t</a>
1</code>                  
sets time to the first time in the data set--using grid
coordinates in this case. Time is now a fixed dimension</ul><p>

When <b>all</b> dimensions are fixed, you are referring to a <b>single</b> data
point.<p>

When <b>one</b> dimension is varying, you are referring to a <b>1-D "slice"</b>
through the data set.<p>

When <b>two</b> dimensions are varying, you are referring to a <b>2-D
"slice"</b> through the data set.
<p>

When <b>three or more</b> dimension vary, GrADS interprets this as a <b>sequence of
2-D slices</b>.
<p>

<b>An important note:</b>  When you specificy the dimension environment in terms of  grid
coordinates, they are always converted to world coordinates. 
This conversion  requires some knowledge of what scaling is in
use for grid to world conversions.  The scaling that is used in
all cases (except one) is the scaling of the <i>default file</i>. The
exception is when you supply a dimension expression within a
variable specification, which will be covered later.


\ No newline at end of file
diff --git a/doc/display.html b/doc/display.html
new file mode 100644
index 0000000..f139bf2
--- /dev/null
+++ b/doc/display.html
@@ -0,0 +1,129 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Displaying Data in GrADS</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<a href="#DDP">Drawing Data Plots</a><br>
+<a href="#CTD">Clearing the Display</a><br>
+<a href="#GOT">Graphics Output Types</a><br>
+<a href="advdisplay.html">Advanced Display Options</a><br>
+<p>
+<hr>
+<a name="DDP"><h2>Drawing Data Plots</h2></a>
+
+The <code>display</code> command is how you actually display data (output
+expressions) plots via the graphics output window.  The command
+is:<p>
+
+<dd><code><a href="gradcomddisplay.html">display</a> <i>expression</i></code><p>
+
+or<p>
+
+<dd><code>d <i>expression</i></code><p>
+
+The simplest <code><i>expression</i></code> is a variable abbreviation.<p>
+
+If you display when <b>all</b> dimensions are fixed, you get a <b>single</b>
+value which is typed out.<p>
+
+If you display when <b>one</b> dimension varies, you get a <b>1-D line
+graph</b> by default.<p>
+
+If you display when <b>two</b> dimensions are varying, you get a <b>2-D
+contour plot</b> by default.<p>
+
+A variety of <a href="#GOT">plot types</a> are available in addition to the above
+defaults.<p>
+
+<a name="CTD"><h2>Clearing the Display</h2></a><p>
+
+GrADS will overlay the output from each display command. To clear
+the display, enter:<p>
+
+<dd><code><a href="gradcomdclear.html">clear</a></code> (or just <code>c</code>)<p>
+
+Issued without parameters, the <code>clear</code> command does pretty heavy
+duty clearing of many of the GrADS internal settings. Parameters
+can be added to limit what is cleared when using more advanced
+features, for example:<p>
+<ul>
+<code>c events</code>         flushes the events
+buffer (e.g., mouse clicks)<br>
+<code>c graphics</code>     clears the graphics, but <b>not</b> the
+widgets <br>
+<code>c hbuff</code>           clears
+the display buffer when in double buffer mode</ul><p>
+
+WARNING: If you make any error in the syntax of clear then
+GrADS
+does the full clear...<p>
+
+<a name="GOT"><h2>Graphics Output Types</h2></a>
+
+<p>
+Before you can display a graph of your data, you will need to set
+the type of plot you want and, probably, some other graphics
+parameters as well.
+
+<p>
+By default, when one dimension varies, you get a line graph, and
+when two dimensions vary, you get a contour plot.  These defaults
+can be changed by the command:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetgxout.html">set gxout</a> <i>graphics_type</i>
+</code>
+</ul>
+
+<p>
+Some examples of <code><i>graphics_type</i></code> are <code>contour,
+shaded, grid, bar, vector,</code> or <code>streamline</code>. For a
+complete list, see the <a href="gradcomdsetgxout.html">reference
+page</a>.
+
+<p>
+There are many options that can be set to control how the
+data will be displayed for each <code><i>graphics_type</i></code>.  
+
+<p>
+For the graphics output types <code>vector, stream,</code> and
+<code>barb</code>, the plotting routines need two result grids, where the
+first result grid is treated as the U component, and the second result
+grid is treated as the V component. These two result grids are
+provided to the <a href="gradcomddisplay.html">display</a> command by
+entering two expressions separated by a semicolon:
+<p>
+<ul>
+<code>
+display u ; v<br>
+display ave(u,t=1,t=10) ; ave(v,t=1,t=10)<br>
+</code>
+</ul>
+
+<p>
+For the graphics output types <code>vector</code> and
+<code>stream</code>, you can specify a third result grid that will be used to
+colorize the vectors or streamlines:
+
+<p>
+<ul>
+<code>
+display u ; v ; mag(u,v)<br>
+display u ; v ; hcurl(u,v)<br> 
+</code>
+</ul>
+
+<p>
+For a graphics output type <code>wxsym</code>, each value at a station
+location is assumed to be a wx symbol code number. To see a chart of
+all available wx symbols and their corresponding code numbers, run the
+sample script <code>wxsym.gs</code>.
+
+</body>
+</html>
+
diff --git a/doc/edemo1.png b/doc/edemo1.png
new file mode 100644
index 0000000..2f4c4b0
Binary files /dev/null and b/doc/edemo1.png differ
diff --git a/doc/edemo2.png b/doc/edemo2.png
new file mode 100644
index 0000000..be1cd4c
Binary files /dev/null and b/doc/edemo2.png differ
diff --git a/doc/edemo3.png b/doc/edemo3.png
new file mode 100644
index 0000000..5aad37b
Binary files /dev/null and b/doc/edemo3.png differ
diff --git a/doc/edemo4.png b/doc/edemo4.png
new file mode 100644
index 0000000..aaf8b45
Binary files /dev/null and b/doc/edemo4.png differ
diff --git a/doc/edemo5.png b/doc/edemo5.png
new file mode 100644
index 0000000..3337528
Binary files /dev/null and b/doc/edemo5.png differ
diff --git a/doc/edemo6.png b/doc/edemo6.png
new file mode 100644
index 0000000..079ec71
Binary files /dev/null and b/doc/edemo6.png differ
diff --git a/doc/edemo7.png b/doc/edemo7.png
new file mode 100644
index 0000000..3010b52
Binary files /dev/null and b/doc/edemo7.png differ
diff --git a/doc/ensembles.html b/doc/ensembles.html
new file mode 100644
index 0000000..5c534ef
--- /dev/null
+++ b/doc/ensembles.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>The Ensemble Dimension</title>
<link href="../../assets/NewIGES.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style2 {color: #990000}
-->
</style>
</head>
<body
 text="#000000">


<h2>The Ensemble Dimension</h2>
<h4>
  <a href="#intro">Ensemble Handling in GrADS</a><br>
  <a href="#ddf">The EDEF entry in a descriptor file </a><br>
  <a href="#data">How to organize the data</a><br>
  <a href="#example1">Example #1: Lag Ensembles</a><br>
  <a href="#example2">Example #2: Retrospective Daily Hindcasts from CFS</a><br>
  <a href="#example3">Example #3: Ensembles with Different Lengths and Start Times in Binary Format</a><br>
</h4>
<hr>

<h3><a name="intro"></a>Ensemble Handling in GrADS</h3>
<p> GrADS version 2.0 supports a fifth dimension for gridded data sets. This extra dimension has been implemented in a general way, but has been optimized for  use with ensembles. Thus the name of the dimension is E or "ens". A good way to illustrate how the E dimension has been implemented in GrADS is through a series of plots using real data. 
<p>Let's begin with  a 16-day forecast initialized 1 January. This is a 4-Dimensional data set that varies in space (X, Y, and Z) and time (T). To create the following display we fixed the latitude, longitude, and level dimensions and  set time  to span the entire forecast; the 1-D plot below shows  the time series of predicted data values (16-day forecast of 500mb height at 45N, 60W):
<p><img src="edemo1.png" alt="edemo1">
<p>Next, suppose you rerun the same forecast 20 more times, tweaking the initial conditions a little bit for each run -- you've created a 21-member ensemble forecast. All the ensemble members  have the same length and start time. A classic technique for illustrating variability among ensemble members is to draw a "spaghetti" plot -- one contour line for each member. The following display shows a spaghetti plot for the same location and vertical level as drawn above, with one lin [...]
<p><img src="edemo2.png" alt="edemo2" width="800" height="287">
<p>Using GrADS 2.0 and the ensemble dimension, we do not need to consider the ensemble members as separate data sets -- we can group them together and treat them as a single 5-dimensional data set. Thus we can display the  same data  in the spaghetti plot as a 2-D grid: Time on the X-axis vs. Ensemble Member on the Y-axis. Each contour line in the plot above becomes a row in the grid below, with grid boxes colored according to data values. 

<p><img src="edemo3.png" alt="edemo3" width="800" height="328">
<p>Because GrADS handles the ensemble members  as a single grid, we can perform some calculations over the ensemble dimension. The GrADS analysis functions operate on E the same way they do on X, Y, Z, and T. Below is yet another version of the same data in the spaghetti plot; this time the display shows the ensemble mean (the red line), the ensemble mean +/- one  standard deviation  (green bars), and the minimum and maximum values over all members (blue whiskers):
<p><img src="edemo4.png" alt="edemo4" width="799" height="294">

<h3><a name="ddf"></a>The EDEF entry in a descriptor file</h3>
<p>The first step in creating a  descriptor file for a 5-D gridded data set is to add an entry to describe the ensemble axis (E) using the keyword <a href="descriptorfile.html#EDEF">EDEF</a>. The E-axis is always linear, and there is no "world coordinate" equivalent for ensembles. An ensemble member is called by its grid index (1, 2, etc.) or its name. The ensemble names are aliases for the grid indices, but are also used as the substitution string  when file <a href="templates. [...]
<p>There are two different syntaxes for the EDEF entry: compact and expanded. The compact syntax   is simpler and contains  the number of ensembles, the "names" keyword, and a space-delimted list of the names for each ensemble member. The expanded syntax  is a collection of records framed by EDEF and ENDEDEF; each record contains a name, individual time axis information, and  GRIB2 codes (if they are required).
If all of the ensemble members have an identical time axis (i.e. length, initial time, and increment are the same for each one), and the data format is <em>not</em> GRIB2, then the members are distinguished only by their names, and the compact EDEF syntax may be used. For example:
<code><p>EDEF 6 names e1 e2 e3 e4 e5 e6 <br>
EDEF 21 names cntrl p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 n0 n1 n2 n3 n4 n5 n6 n7 n8 n9</p></code>
<p>If the ensemble members do not have identical time axes (i.e., their lengths or initial times are not the same), 
or if you need to include the GRIB2 codes, then you must use the expanded EDEF syntax.  Individual ensemble records contain the ensemble name, its length, and initial time. If the data are in GRIB2 format, then some additional comma-delimited codes are added following the initial time. (See the <a href="descriptorfile.html#EDEF">EDEF reference page</a> for more details.) <a href="ensembles.html#example2">Example #2</a> at the  bottom of this page shows the TDEF and EDEF entries for a set  [...]
<code></code>
<p>The EDEF entry is only required in a descriptor file if the data set varies in the E dimension.  A 4-D data set does not require an "EDEF 1 names 1" entry. If EDEF is omitted, GrADS will know the data set is 4-D, and will set up a default  E axis for internal use only. This is especially important if the descriptor file will be used to serve the data set via the GrADS Data Server. </p>
<p>To query the ensemble metadata once the file is opened, use the "<code><a href="gradcomdqens.html">q ens</a></code>" command. </p>
<p> </p>
<h3><a name="data"></a>How to organize the data</h3>
<p>As you create the descriptor file  for your 5-D ensemble data set, you must also consider how to organize the data. It is possible to have all  data in one file, but it is more likely that a data set will be an aggretation of separate files, organized using <a href="templates.html">templates</a>. GrADS supports templating over the T and E dimensions, but there are some limitations on templating that depend on the data format. Note that the substitution strings for templating on T may b [...]
Some additional considerations for constructing and managing ensemble data sets based on data format are given below. 
<p><strong>Binary  Format:</strong> The structure of a multi-dimensional binary data set is determined by the order in which the horizonal grids are written to file. The building blocks are stacked in a sequence according to dimension. The sequence goes in the following order starting from the fastest varying dimension to the slowest varying dimension: longitude (X), latitude (Y), vertical level (Z), variable (VAR), time (T), and ensemble (E).
5-D ensemble data sets are created by concatenating 4-D data sets together -- the ensemble dimension varies outside of all the others. If the data format is binary and file templating is used for the time dimension, then file templating for the ensemble dimension must also be used. If the data format is binary and files are templated together <em>only over the ensemble dimension</em>, then the entire time series for each member must be contained in the individual data files;  if the membe [...]
<p><strong>GRIB  Format: </strong> The structure of a multi-dimensional GRIB data set is determined by the  axis and variable declarations in the descriptor file; this information is contained in the  index file created by the <a href="gradutilgribmap.html">gribmap</a> utility. The order in which the horizontal grids (records) are written to file is not as critical as it is for binary data. The GRIB2 format has an expanded set of header fields for ensemble metadata, so  two records that a [...]
<p><strong>Self-Describing File Format:</strong> The structure of a multi-dimensional data set in NetCDF or HDF-SDS format is determined by the way the coordinate dimensions in the self-describing file are matched to the 5 grid dimensions in GrADS. This matching may be  accomplished in three ways: 
<ol>
<li>Use the <a href="gradcomdsdfopen.html">sdfopen</a> command -- GrADS uses only the metadata in the self-describing file to determine how to match  the coordinate dimensions in the file with longitude, latitude, level, time, and ensemble. You can use the <a href="gradcomdxdfopen.html">sdfopen</a> command  for 5-D ensemble data sets   served by the GrADS Data Server (GDS) -- the ensemble metadata  are tailored specifically for GrADS so that <a href="gradcomdsdfopen.html">sdfopen</a> will [...]
<li>Use the <a href="gradcomdxdfopen.html">xdfopen</a> command -- GrADS  needs some external metadata to supplement or replace what is in the  self-describing file in order to match the coordinate dimensions. This external metadata is provided in a special descriptor file with a syntax especially for the <a href="gradcomdxdfopen.html">xdfopen</a> command. In an xdfopen-style descriptor, there is support for three variations on the compact syntax of the EDEF entry:<br>
<code>edef <<i>SDF_dimension_name</i>> <br>
edef <<i>SDF_dimension_name</i>> <<em>size</em>><br>

edef <<i>SDF_dimension_name</i>> <<em>size</em>> names <<em>list of names</em>> </code><br>
Note these variations are different from the compact syntax for EDEF in a complete descriptor file because they include the name of the coordinate variable as defined in the data file. <br>
<li>Use the <a href="gradcomdopen.html">open</a> command -- GrADS uses a <a href="SDFdescriptorfile.html">complete descriptor file</a> that contains all the metadata it needs to map the coordinate dimensions. Metadata in the data file is ignored, and the mapping of variable dimensions to grid dimensions is accomplished through the units field of the variable declaration. </ol>
<p>Note that file templating on T and E in any combination is supported for the NetCDF and HDF-SDS formats (as of version 2.0.a5). </p>
<p> </p>
<h3><a name="example1"></a>Example #1: <strong>Creating a Lag Ensemble Data Set</strong
>
</h3>
<p> A lag ensemble is a collection of forecasts with different initialization times. It differs from the ensemble forecast described above because 
each member spans a  different (shifted) time range. If you consider the 24-hour geopotential height forecast in each member of a lag ensemble data set, the fields will not be valid at the same time. Similarly if you consider  the height fields from all members at a fixed valid time, each member will have a different lead time (offset from the initial time). Below is an illustration of a lag ensemble data set. The graphic is related to the example above because it shows similar 16-day for [...]
<p><img src="edemo5.png" alt="edemo5">
<p>If you want to create an ensemble data set using GRIB forecasts with varying initial times, and the data files are GRIB1 or GRIB2 without any ensemble metadata (i.e., Product Definition Template 0 or 8), then you must use file templating over E and your ensemble names must appear somewhere in your data file names. 
  It is not adequate to  use only %iy %im %id %ih and %f3 in the DSET entry and the expanded form of EDEF to indicate the different start times of each ensemble member. This would uniquely match a file name for each time and member, but only for the special case of each member having a different initial time. If you had some ensemble members with the same start time, then the time metadata in the grib headers would be identical and there would be no way to distinguish the members.  Omitti [...]
<p>
A convenient way to set up a lag ensemble data set is to create symbolic links for the ensemble names that point to each directory containing a single forecast. Suppose  you have a directory structure based on the YYYYMMDDHH of the forecast initialization time:
<p>  <code> 
  ./2009010100/gfs.*.grb2<br>
  ./2009010112/gfs.*.grb2<br>
  ./2009010200/gfs.*.grb2</code>
  
<p>Create a set of symbolic links that associate an ensemble name with each directory:</p>
<p>  <code>
  ./e1 -> ./2009010100<br>
  ./e2 -> ./2009010112<br>
  ./e3 -> ./2009010200</code></p>
<p>And the descriptor file would contain the following entries:
<p><code>DSET ^./%e/gfs.%iy4%im2%id2%ih2.f%f3.grb2<br>
  ...<br>
  TDEF 69 linear 00z1jan2009 6hr<br>
  EDEF 3<br>
  e1  65  00z1jan2009<br>
  e2  65  12z1jan2009<br>
  e3  65  00z2jan2009<br>
  ENDEDEF</code>
<p> </p>
<h3><a name="example2"></a>Example #2: Retrospective daily hindcasts from <a href="http://cfs.ncep.noaa.gov/">NCEP Climate Forecast System (CFS) </a></h3>
<p>The CFS daily hindcasts are an example of an ensemble data set with members that have different start times and different lengths. The hindcast  members are nominally 9 months long, with  unevenly staggered start times and identical end times. The following graphic shows  CFS forecasts of 500mb height at 45N, 60W, illustrating the  temporal coverage of the 15 ensemble members. A complete descriptor file for this data set is also provided.</p>
<p><img src="edemo6.png" alt="edemo6" width="800" height="283"></p>
<p><code>dset ^z500.%e.feb.2000.cfs.data<br>
  title 5D NCEP CFS Ensemble Hindcast Initialized February 2000 2.5 degree/12-hourly grid<br>
  dtype grib<br>
  index ^z500.feb.2000.cfs.map<br>
  undef 9.999e+20<br>
  options yrev template<br>
  xdef 144 linear   0 2.5<br>
  ydef  73 linear -90 2.5<br>
  zdef   1 levels 1<br>
  tdef 593 linear 12z09jan2000 12hr<br>
  edef 15<br>
  m01 593 12z09jan2000 <br>
  m02 591 12z10jan2000 <br>
  m03 589 12z11jan2000 <br>
  m04 587 12z12jan2000 <br>
  m05 585 12z13jan2000 <br>
  m06 573 12z19jan2000 <br>
  m07 571 12z20jan2000 <br>
  m08 569 12z21jan2000 <br>
  m09 567 12z22jan2000 <br>
  m10 565 12z23jan2000 <br>
  m11 551 12z30jan2000 <br>
  m12 549 12z31jan2000 <br>
  m13 547 12z01feb2000 <br>
  m14 545 12z02feb2000 <br>
  m15 543 12z03feb2000 <br>
  endedef<br>
  vars 1<br>
  z500    0  7,100,500   500mb Geopotential height [gpm]<br>
endvars<br>
@ z500 String units gpm</code></p>
<p> </p>
<h3><a name="example3" id="example3"></a>Example #3: Ensembles with different lengths and start times in binary format</h3>
<p>This example shows how you set up a data set with ensembles of different lengths and start times in binary format. There are 6 members, spanning a period of 20 years. The figure below illustrates the coverage in time of each member. Below the figure is the data descriptor file. Note that if this data set was only templated over E and not  templated over T, then the binary file for each member would have to be padded with missing values so that the data file for each member was the same [...]
<p><img src="edemo7.png" alt="edemo7" width="800" height="229"></p>
<p>
<code>DSET   /data/examples/monthly.%y4%m2.%e.dat<br>
  TITLE Example of Ensembles in Binary Format<br>
  undef -9.99e8<br>
  options template<br>
  XDEF  360 LINEAR -179.5 1.0<br>
  YDEF  180 LINEAR  -89.5 1.0<br>
  ZDEF    1 linear   1     1<br>
  TDEF  240 LINEAR  1jan1988 1mo<br>
  EDEF   6<br>
  e1    48  1jan1988<br>
  e2    83  1jan1991<br>
  e3  101  1jan1992<br>
  e4  152  1may1995<br>
  e5  128  1may1997<br>
  e6    96  1jan2000<br>
  ENDEDEF<br>
  VARS   8<br>
  lhf    0   99 latent heat flux (W/m**2)<br>
  tx      0   99 zonal wind stress (N/m**2)<br>
  ty      0   99 meridional wind stress (N/m**2)<br>
  shf    0   99 sensible heat flux (W/m**2)<br>
  hum    0   99 surface air (~10-m) specific humidity (g/kg)<br>
  pw      0   99 lowest 500-m precipitable water (g/cm**2)<br>
  wpd    0   99 10-m wind speed (m/s)<br>
  hd      0   99 sea-air humidity difference (g/kg)<br>
  ENDVARS</code></p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/expressions.html b/doc/expressions.html
new file mode 100644
index 0000000..ef6ca37
--- /dev/null
+++ b/doc/expressions.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
.style1 {color: #990000}
-->
</style>

<h1>Expressions</h1>

A GrADS expression consists of operators, operands, and
parentheses.  Parentheses are used to
control the order of operation.
<p>

Operators are:


<ul>
<code>+</code>    Addition <br>
<code>-</code>    Subtraction <br>
<code>*</code>    Multiplication <br>
<code>/</code>    Division</ul><p>

Operands are:


<dd><code><a href="variable.html">variable specifications</a>, <a href="functions.html">functions</a>, and constants</code>.
  <p>

Operations between two variables are done on equivalent grid points in each grid. 
Missing data values in either grid give a result of a missing
data value at that grid point.  Dividing by zero gives a result
of a missing data value at that grid point.<p>

Operations cannot be done between grids that have different
scaling in their varying dimensions -- i.e., grids that have
different rules for converting the varying dimensions from grid
space to world coordinate space.  This can only be encountered
when you are attempting operations between grids from different
files that have different scaling rules.
<p>

If one grid has more varying dimensions than the other, the grid
with fewer varying dimensions     is 'expanded' and the operation
is performed.
<p>Expression evaluation in GrADS is recursive, so that multiple expressions may be nested together. 
<p>(<span class="style1">GrADS version 2.0.a7+</span>) Variable specifications can include a dimension expression to set time as an <a href="offt.html">offset</a> from the variable's initial time. 

<p>

Some examples of expressions:

<ul>
<code>slp/100                     </code>(Convert sea level pressure units from hPa to mb)<br>
<code>z-z(t-1)                    </code>(Height change over one time step)<br>
<code>z-z(offt=0)                 </code>(Height change since initial time)<br>
<code>t(lev=500)-t(lev=850)       </code>(Temp difference between 500
and 850mb)<br>
<code>ave(z,t=1,t=5)              </code>(Average of z over first 5 times in file) <br>
<code>sum(prec(offt+0),t=1,t=4)   </code>(Accumulated precipitation -- sum of 2nd through 5th time steps in file) <br>
<code>z-ave(z,lon=0,lon=360,-b)   </code>(Remove zonal mean)<br>
<code>tloop(aave(p,global))       </code>(Time series of globally averaged precip)</ul>
\ No newline at end of file
diff --git a/doc/font.html b/doc/font.html
new file mode 100644
index 0000000..3b26c68
--- /dev/null
+++ b/doc/font.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<h1>Font File </h1>

GrADS  supports Hershey fonts numbered 0 to 9.  Fonts 0 to 5 are
provided with the GrADS distribution.  The files are named
<code>font0.dat</code>, <code>font1.dat</code>, etc.  If you create
a <code>font6.dat</code> file (or 7 through
9) and put it in the same place as the other font
files, you can use that font immediately, by using the <code><a
href="gradcomdsetfont.html">set font</a></code> command,  or via <a href="fontcontrol.html">font escape sequences</a>.
<p>

The font files are in an ASCII format.  Each file is 95
records in length.  Each record represents a character in the font,
and the records are ordered in the order of ASCII code values,
starting with the blank (code value 32 decimal).  So the last
record represents the tilde, the 17th record the zero, etc.  So when
you are using the font the file represents, and enter a zero
character, the character  in the 17th record is plotted, whatever it
may be.<p>

Each record starts with a 3 character number.  This is
the number of code pairs in the record.  This number is followed by
the indicated number of code pairs.  Each code pair is two
characters. Each character represents a value, which is determined
as an offset from the Capital R (decimal 82).  So, if the character
is Capital L, it represents a value of -6.  If the character is a
lower case k, it represents a value of +25.  <p>

The first code pair represents the horizontal extent of
the character. So the first character of the code pair would be the
minimum X, and the 2nd character the maximum X.  If I remember correctly,
this extent should include white space.  This is followed by code
pairs that represent drawing positions in X and Y, where the first
character is X, and the 2nd Y.  A "pen up" is indicated by the code pair " R" (blank,
followed by capital R).  <p>

You can look at the existing font files for examples.
If you look at 
<code>font0.dat</code>, the first record represents the blank.  It
thus has one code
pair, which just represents the width of the blank in
the font, thus
allocating white space when a blank is encountered.  If
you look at 
record <code>57</code> (which represents Cap X), you see:
<code>6H\KFY[ RYFK[</code>
Decoding this, you see there are 6 code pairs.  The
first is the 
width extent, <code>H\</code>, which is -10 to 10.  The next two
pairs, <code>KFY[</code>, 
are points -7,-12 and 7,9.  So a line would be drawn
between those
two points (appropriate scaled).  The next code pair
indicates pen up, 
followed by <code>YFK[</code>, which are 7,-12 and -7,9.  <p>

You can see the horizontal extent does not match too
well with the 
actual character.  I am not quite sure why this is, nor
why the 
character is not centered.  This is the way the fonts
came, so I assume
there are some font design issues involved.  
<p>

If you want to design your own font, you will need to
review the 
code GrADS uses to actually plot these fonts, which is
<code>gxchpl.c</code>.
I determined scale factors and centering issues by trial
and error, and
these values are contained in the code.<p>

\ No newline at end of file
diff --git a/doc/fontcontrol.html b/doc/fontcontrol.html
new file mode 100644
index 0000000..0d2894f
--- /dev/null
+++ b/doc/fontcontrol.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>Font Control</title>

<style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
.style1 {color: #990000}
-->
</style>
<H2><B> Font Control</B> in GrADS</H2>
<p><a href="#hershey">Hershey Fonts</a><br />
  <a href="#cairo">Cairo Fonts</a><br />
<a href="#size">Controlling Font Size</a><br />
<a href="#overrides">Temporary Overrides</a><br />
  <a href="#examples">Examples</a></H2>
<H3><a name="hershey" id="hershey"></a>Hershey Fonts</H3>
<P>GrADS has traditionally used the Hershey vector fonts for all text displays. The Hershey  fonts are drawn as a collection of line segments, and can be rotated or scaled (stretched) in the X or Y direction; this makes them extremely flexible for different applications in GrADS. The Hershey fonts are defined in a set of <a href="font.html">font files</a>, which are part of the GrADS distribution and should be stored in a directory named by the <a href="http://iges.org/grads/gadoc/gradcom [...]
<pre>
font 0 -- Simplex Roman 
font 1 -- Complex Roman
font 2 -- Complex Italic
font 3 -- Complex Greek
font 4 -- Duplex Roman
font 5 -- Triplex Roman
</pre>
<H3><a name="cairo" id="cairo"></a>Cairo Fonts</H3>
<P>Beginning with <span class="style1">GrADS version 2.1.a0</span>, additional fonts are available with the Cairo graphics library. GrADS employs Cairo's "toy" font API; it is simpler to implement, fast, and  meets GrADS's needs for drawing text. Cairo uses the freetype2 font library, which supports a number of scalable font formats including TrueType, Type 1, OpenType, X11 PCF, and Windows FNT. Whether GrADS will support all these font types depends on if they are available on  [...]

If your build of GrADS is not enabled with the Cairo graphics library, you will get an error message if you use  <code><a href="gradcomdsetfont.html">set font</a></code> to try to set a font number greater than 9.
<h3><a name="size" id="size"></a>Controlling Font Size</h3> 
<p>The <code><a href="gradcomdsetstrsiz.html">set strsiz</a></code> command controls the font size for Hershey and Cairo fonts. Because the Hershey fonts are vector-based, you can give different scaling factors for the width and height of the letters and the font will stretch accordingly. For Cairo fonts, only one scaling factor (the vertical size) is appropriate -- the fonts do not deform in the X or Y dimension, they simply get bigger or smaller. If the vertical size is not given with < [...]
<h3><a name="overrides" id="overrides"></a>Temporary Overrides</h3>
<P>Hershey fonts correspond to single-digit font numbers; Cairo fonts correspond to double-digit font numbers. When you invoke the <code><a href="gradcomdsetfont.html">set font</a></code> command and the font number is between 0 and 9, you are in <em>hershey mode</em>. If the font number is between 10 and 99, you are in <em>cairo mode</em>. 
Hershey and Cairo fonts cannot be mixed together in the same string. 
<P><em><strong>Font Override: </strong></em><br />
  To temporarily override the  font  in a string of text, use the back quote character (`). When you are in <em>hershey mode</em>, a back quote followed by a single digit selects that font number for the remainder of the string. When you are in <em>cairo mode</em>, a back quote followed by 'f' and a double-digit number selects that font number for the remainder of the string. See examples below.
<P><em><strong>Text Position Override:</strong></em><br />
  It is also possible to use the back quote to change the position of the text, to draw a string above or below the base line for subscripts or superscripts. A back quote followed by the letter a (`a) will draw the subsequent text in the string as a superscript (above normal). A back quote followed by the letter b (`b) will draw the subsequent text in the string as a subscript (below normal). A back quote followed by the letter n (`n) will draw the subsequent text in the string in a norma [...]
<P><em><strong>Degree Symbol:</strong></em><br />
If you are in <em>hershey mode</em>, you can draw a degree symbol by drawing a period with font number 3 (`3.) If you are in <em>cairo mode</em>, you can draw a degree symbol with a backquote followed by the letter d (`d). See examples below. 
<H3><a name="examples" id="examples"></a>Examples</H3>
<pre>Hershey Mode:
set font 0
draw string 1.5 1.25 `1use font 2 to `2emphasize `1a particular word
draw string 1.5 2.25 use font 3 for `3greek `0letters
draw string 1.5 3.25 `3p`0r`a2`n = area of a circle
draw string 1.5 4.25 label temperatures in `3.`0C or `3.`0F


Cairo Mode:
set font 10
draw string 1.5 1.25 use font 11 for `f11serif`f10 and font 12 for `f12monospace
set fontdef 13 symbol
draw string 1.5 2.25 use symbol font for `f13greek`f10 letters

draw string 1.5 4.25 label temperatures in `dC or `dF</pre>
\ No newline at end of file
diff --git a/doc/footnote1.html b/doc/footnote1.html
new file mode 100644
index 0000000..a87c044
--- /dev/null
+++ b/doc/footnote1.html
@@ -0,0 +1,6 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+With the
+exception of the MS-DOS version which only has one window  (the
+only non-X windows version)
+
diff --git a/doc/functions.html b/doc/functions.html
new file mode 100644
index 0000000..e13717d
--- /dev/null
+++ b/doc/functions.html
@@ -0,0 +1,77 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Functions</title>
+<link href="GrADS.css" rel="stylesheet" type="text/css">
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<center><h3>Alphabetical Listing of GrADS Functions</h3></center>
+<p class="plaintext">
+<br><code><a href="gradfuncaave.html">aave()</a>      </code>Calculates an areal average over an X-Y region (latitude-weighted)
+<br><code><a href="gradfuncabs.html">abs()</a>       </code>Returns the absolute value 
+<br><code><a href="gradfuncacos.html">acos()</a>      </code>Calculates the inverse cosine 
+<br><code><a href="gradfuncamax.html">amax()</a>      </code>Returns the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamaxlocx.html">amaxlocx()</a>  </code>Returns the the X location of the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamaxlocy.html">amaxlocy()</a>  </code>Returns the the Y location of the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamean.html">amean()</a>     </code>Calculates an areal average over an X-Y region (not latitude-weighted)
+<br><code><a href="gradfuncamin.html">amin()</a>      </code>Returns the minimum grid value over an X-Y region
+<br><code><a href="gradfuncaminlocx.html">aminlocx()</a>  </code>Returns the the X location of the minimum grid value over an X-Y region
+<br><code><a href="gradfuncaminlocy.html">aminlocy()</a>  </code>Returns the the Y location of the minimum grid value over an X-Y region
+<br><code><a href="gradfuncasin.html">asin()</a>      </code>Calculates the inverse sine
+<br><code><a href="gradfuncasum.html">asum()</a>      </code>Calculates the sum over an X-Y region (grid weighted)
+<br><code><a href="gradfuncasumg.html">asumg()</a>     </code>Calculates the sum over an X-Y region (not grid weighted)
+<br><code><a href="gradfuncatot.html">atot()</a>      </code>Calculates the sum over an X-Y region (grid and latitude weighted)
+<br><code><a href="gradfuncatan2.html">atan2()</a>     </code>Calculates the inverse tangent
+<br><code><a href="gradfuncave.html">ave()</a>       </code>Calculates an average over any dimension
+<br><code><a href="gradfunccdiff.html">cdiff()</a>     </code>Performs a centered difference operation
+<br><code><a href="gradfunccoll2gr.html">coll2gr()</a>   </code>Creates a grid from a collection of station data
+<br><code><a href="gradfuncconst.html">const()</a>     </code>Changes missing or non-missing values
+<br><code><a href="gradfunccos.html">cos()</a>       </code>Calculates the cosine
+<br><code><a href="gradfunceloop.html">eloop()</a>     </code>Reconstructs an E-varying result after doing calculations with the ensemble dimension fixed 
+<br><code><a href="gradfuncexp.html">exp()</a>       </code>Calculates the exponential
+<br><code><a href="gradfuncfndlvl.html">fndlvl()</a>    </code>Finds the vertical level at which a given value occurs in a variable
+<br><code><a href="gradfuncgint.html">gint()</a>      </code>General integral
+<br><code><a href="gradfuncgr2stn.html">gr2stn()</a>    </code>Grid-to-station interpolator
+<br><code><a href="gsf.html">gsfallow()</a>  </code>Enables the dynamic loading of script functions
+<br><code><a href="gsf.html">gsfpath()</a>   </code>Specifies the private path directory list where script functions are located
+<br><code><a href="gradfunchcurl.html">hcurl()</a>     </code>Calculates the vertical component of the curl
+<br><code><a href="gradfunchdivg.html">hdivg()</a>     </code>Calculates the horizontal divergence using finite differencing
+<br><code><a href="gradfunclog.html">log()</a>       </code>Calculates the natural logarithm
+<br><code><a href="gradfunclog10.html">log10()</a>     </code>Calculates the logarithm base 10
+<br><code><a href="gradfunclterp.html">lterp()</a>     </code>Performs bi-linear interpolation between two grids
+<br><code><a href="gradfuncmag.html">mag()</a>       </code>Calculates the wind speed given u,v components
+<br><code><a href="gradfuncmaskout.html">maskout()</a>   </code>Sets certain data values to missing
+<br><code><a href="gradfuncmax.html">max()</a>       </code>Returns the maximum value over a given grid dimension
+<br><code><a href="gradfuncmaxloc.html">maxloc()</a>    </code>Returns the grid location of the maximum value
+<br><code><a href="gradfuncmean.html">mean()</a>      </code>Calculates an average over any dimension (not latitude weighted)
+<br><code><a href="gradfuncmin.html">min()</a>       </code>Returns the minimum value over a given grid dimension
+<br><code><a href="gradfuncminloc.html">minloc()</a>    </code>Returns grid location of the minimum value
+<br><code><a href="gradfuncoabin.html">oabin()</a>     </code>Bins station observations into grid cells 
+<br><code><a href="gradfuncoacres.html">oacres()</a>    </code>Returns a gridded result that represents station data
+<br><code><a href="gradfuncpow.html">pow()</a>       </code>Raises the values of <code><i>arg1</i></code> to the power of <code><i>arg2</i></code>
+<br><code><a href="gradfuncs2g1d.html">s2g1d()</a>     </code>Converts a station timeseries to a 1D grid
+<br><code><a href="gradfuncscorr.html">scorr()</a>     </code>Calculates the spatial correlation over an X-Y domain 
+<br><code><a href="gradfuncsin.html">sin()</a>       </code>Calculates the sine
+<br><code><a href="gradfuncskip.html">skip()</a>      </code>Sets alternating data values to missing
+<br><code><a href="gradfuncsmth9.html">smth9()</a>     </code>Performs a 9 point smoothing operation on gridded data
+<br><code><a href="gradfuncsqrt.html">sqrt()</a>      </code>Calculates the square root
+<br><code><a href="gradfuncsregr.html">sregr()</a>     </code>Calculates the linear least-squares regression over an X-Y domain
+<br><code><a href="gradfuncstnave.html">stnave()</a>    </code>Calculates a time average of station data 
+<br><code><a href="gradfuncstnmin.html">stnmin()</a>    </code>Returns the minimum value over a time series of station data
+<br><code><a href="gradfuncstnmax.html">stnmax()</a>    </code>Returns the maximum value over a time series of station data
+<br><code><a href="gradfuncsum.html">sum()</a>       </code>Calculates the sum over any dimension (grid weighted)
+<br><code><a href="gradfuncsumg.html">sumg()</a>      </code>Calculates the sum over any dimension (not grid weighted)
+<br><code><a href="gradfunctan.html">tan()</a>       </code>Calculates the tangent
+<br><code><a href="gradfunctcorr.html">tcorr()</a>     </code>Produces a spatial map of temporal correlation coefficients
+<br><code><a href="gradfunctloop.html">tloop()</a>     </code>Reconstructs a time series after doing calculations at fixed times
+<br><code><a href="gradfunctmave.html">tmave()</a>     </code>Calculates a time averag while applying a mask
+<br><code><a href="gradfunctregr.html">tregr()</a>     </code>Calculates the least-squares regression over the time domain
+<br><code><a href="gradfunctvrh2q.html">tvrh2q()</a>    </code>Calculates specific humidity given virtual temperature and relative humidity
+<br><code><a href="gradfunctvrh2t.html">tvrh2t()</a>    </code>Calculates temperature given virtual temperature and relative humidity
+<br><code><a href="gradfuncvint.html">vint()</a>      </code>Calculates a mass-weighted vertical integral in mb pressure coordinates</p>
+
+</body>
+</html>
+
diff --git a/doc/functionsatt.html b/doc/functionsatt.html
new file mode 100644
index 0000000..c74b823
--- /dev/null
+++ b/doc/functionsatt.html
@@ -0,0 +1,112 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Functions</title>
+<link href="GrADS.css" rel="stylesheet" type="text/css">
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<center><h3> </h3>
+  <h3> </h3>
+  <h3>GrADS Functions Sorted by Attribute</h3>
+</center>
+
+<p class="plaintext">
+<font size=+1>Mathematical Operations</font>
+<br><code><a href="gradfuncabs.html">abs()</a>       </code>Returns the absolute value 
+<br><code><a href="gradfunccdiff.html">cdiff()</a>     </code>Performs a centered difference operation
+<br><code><a href="gradfuncexp.html">exp()</a>       </code>Calculates the exponential
+<br><code><a href="gradfuncgint.html">gint()</a>      </code>General integral
+<br><code><a href="gradfunclog.html">log()</a>       </code>Calculates the natural logarithm
+<br><code><a href="gradfunclog10.html">log10()</a>     </code>Calculates the logarithm base 10
+<br><code><a href="gradfuncpow.html">pow()</a>       </code>Raises the values of <code><i>arg1</i></code> to the power of <code><i>arg2</i></code>
+<br><code><a href="gradfuncsqrt.html">sqrt()</a>      </code>Calculates the square root
+<br><code><a href="gradfuncvint.html">vint()</a>      </code>Calculates a mass-weighted vertical integral in mb pressure coordinates
+
+<p class="plaintext">
+<font size=+1>Trigonometric Functions</font>
+<br><code><a href="gradfunccos.html">cos()</a>       </code>Calculates the cosine
+<br><code><a href="gradfuncacos.html">acos()</a>      </code>Calculates the inverse cosine 
+<br><code><a href="gradfuncsin.html">sin()</a>       </code>Calculates the sine
+<br><code><a href="gradfuncasin.html">asin()</a>      </code>Calculates the inverse sine
+<br><code><a href="gradfunctan.html">tan()</a>       </code>Calculates the tangent
+<br><code><a href="gradfuncatan2.html">atan2()</a>     </code>Calculates the inverse tangent
+
+<p class="plaintext">
+<font size=+1>Averaging and Summing</font>
+<br><code><a href="gradfuncaave.html">aave()</a>      </code>Calculates an areal average over an X-Y region (latitude-weighted)
+<br><code><a href="gradfuncamean.html">amean()</a>     </code>Calculates an areal average over an X-Y region (not latitude-weighted)
+<br><code><a href="gradfuncasum.html">asum()</a>      </code>Calculates the sum over an X-Y region (grid weighted)
+<br><code><a href="gradfuncasumg.html">asumg()</a>     </code>Calculates the sum over an X-Y region (not grid weighted)
+<br><code><a href="gradfuncatot.html">atot()</a>      </code>Calculates the sum over an X-Y region (grid and latitude weighted)
+<br><code><a href="gradfuncave.html">ave()</a>       </code>Calculates an average over any dimension
+<br><code><a href="gradfuncgint.html">gint()</a>      </code>General integral
+<br><code><a href="gradfuncmean.html">mean()</a>      </code>Calculates an average over any dimension (not latitude weighted)
+<br><code><a href="gradfuncsum.html">sum()</a>       </code>Calculates the sum over any dimension (grid weighted)
+<br><code><a href="gradfuncsumg.html">sumg()</a>      </code>Calculates the sum over any dimension (not grid weighted)
+<br><code><a href="gradfunctmave.html">tmave()</a>     </code>Calculates a time averag while applying a mask
+<br><code><a href="gradfuncvint.html">vint()</a>      </code>Calculates a mass-weighted vertical integral in mb pressure coordinates
+
+<p class="plaintext">
+<font size=+1>Correlation and Regression</font>
+<br><code><a href="gradfuncscorr.html">scorr()</a>     </code>Calculates the spatial correlation over an X-Y domain
+<br><code><a href="gradfunctcorr.html">tcorr()</a>     </code>Produces a spatial map of temporal correlation coefficients
+<br><code><a href="gradfuncsregr.html">sregr()</a>     </code>Calculates the linear least-squares regression over an X-Y domain
+<br><code><a href="gradfunctregr.html">tregr()</a>     </code>Calculates the least-squares regression over the time domain
+
+<p class="plaintext">
+<font size=+1>Meteorological Calculations</font>
+<br><code><a href="gradfunctvrh2q.html">tvrh2q()</a>    </code>Calculates specific humidity given virtual temperature and relative humidity
+<br><code><a href="gradfunctvrh2t.html">tvrh2t()</a>    </code>Calculates temperature given virtual temperature and relative humidity
+<br><code><a href="gradfuncv<int.html">vint()</a>      </code>Calculates a mass-weighted vertical integral in mb pressure coordinates
+
+<p class="plaintext">
+<font size=+1>Vector Operations</font>
+<br><code><a href="gradfunchcurl.html">hcurl()</a>     </code>Calculates the vertical component of the curl
+<br><code><a href="gradfunchdivg.html">hdivg()</a>     </code>Calculates the horizontal divergence using finite differencing
+<br><code><a href="gradfuncmag.html">mag()</a>       </code>Calculates the wind speed given u,v components
+<br><code><a href="gradfuncskip.html">skip()</a>      </code>Sets alternating data values to missing
+
+<p class="plaintext">
+<font size=+1>Grid Operations</font><br><code><a href="gradfuncamax.html">amax()</a>      </code>Returns the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamaxlocx.html">amaxlocx()</a>  </code>Returns the the X location of the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamaxlocy.html">amaxlocy()</a>  </code>Returns the the Y location of the maximum grid value over an X-Y region
+<br><code><a href="gradfuncamin.html">amin()</a>      </code>Returns the minimum grid value over an X-Y region
+<br><code><a href="gradfuncaminlocx.html">aminlocx()</a>  </code>Returns the the X location of the minimum grid value over an X-Y region
+<br><code><a href="gradfuncaminlocy.html">aminlocy()</a>  </code>Returns the the Y location of the minimum grid value over an X-Y region
+<br><code><a href="gradfuncatot.html">atot()</a>      </code>Calculates the sum over an X-Y region (grid and latitude weighted)
+<br><code><a href="gradfunccdiff.html">cdiff()</a>     </code>Performs a centered difference operation
+<br><code><a href="gradfuncfndlvl.html">fndlvl()</a>    </code>Finds the vertical level at which a given value occurs in a variable
+<br>
+<code><a href="gradfunclterp.html">lterp()</a>     </code>ßPerforms bi-linear interpolation between two grids <br><code><a href="gradfuncmax.html">max()</a>       </code>Returns the maximum value over a given grid dimension
+<br><code><a href="gradfuncmaxloc.html">maxloc()</a>    </code>Returns the grid location of the maximum value
+<br><code><a href="gradfuncmin.html">min()</a>       </code>Returns the minimum value over a given grid dimension
+<br><code><a href="gradfuncminloc.html">minloc()</a>    </code>Returns grid location of the minimum value
+<br><code><a href="gradfuncskip.html">skip()</a>      </code>Sets alternating data values to missing
+<br><code><a href="gradfuncsmth9.html">smth9()</a>     </code>Performs a 9 point smoothing operation on gridded data
+
+<p class="plaintext">
+<font size=+1>Station Data</font>
+<br><code><a href="gradfunccoll2gr.html">coll2gr()</a>   </code>Creates a grid from a collection of station data
+<br><code><a href="gradfuncgr2stn.html">gr2stn()</a>    </code>Grid-to-station interpolator
+<br><code><a href="gradfuncoabin.html">oabin()</a>     </code>Bins station observations into grid cells 
+<br><code><a href="gradfuncoacres.html">oacres()</a>    </code>Returns a gridded result that represents station data
+<br><code><a href="gradfuncs2g1d.html">s2g1d()</a>     </code>Converts a station timeseries to a 1D grid
+<br><code><a href="gradfuncstnave.html">stnave()</a>    </code>Calculates a time average of station data 
+<br><code><a href="gradfuncstnmin.html">stnmin()</a>    </code>Returns the minimum value over a time series of station data
+<br><code><a href="gradfuncstnmax.html">stnmax()</a>    </code>Returns the maximum value over a time series of station data
+
+<p class="plaintext">
+<font size=+1>Special Purpose</font>
+<br><code><a href="gradfuncconst.html">const()</a>     </code>Changes missing or non-missing values
+<br><code><a href="gsf.html">gsfallow()</a>  </code>Enables the dynamic loading of script functions
+<br><code><a href="gsf.html">gsfpath()</a>   </code>Specifies the private path directory list where script functions are located
+<br><code><a href="gradfuncmaskout.html">maskout()</a>   </code>Sets certain data values to missing
+<br><code><a href="gradfunctloop.html">tloop()</a>     </code>Reconstructs a time series after doing calculations at fixed times
+<br><code><a href="gradfunceloop.html">eloop()</a>     </code>Reconstructs an E-varying result after doing calculations with the ensemble dimension fixed
+
+</body>
+</html>
+
+
diff --git a/doc/gadoc.html b/doc/gadoc.html
new file mode 100644
index 0000000..3aeee95
--- /dev/null
+++ b/doc/gadoc.html
@@ -0,0 +1,160 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Online Documentation</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<style type="text/css">
+<!--
+-->
+</style>
+<script language="JavaScript">
+<!--
+
+
+
+function MM_preloadImages() { //v3.0
+  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
+    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
+    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
+}
+//-->
+</script>
+<link rel="stylesheet" href="GrADS.css">
+</head>
+
+<body bgcolor="#FFFFFF" link="#333399" vlink="#6666CC" topmargin="0" background="/assets/blue_margin.gif">
+<p> </p>
+<table width="80%" border="0">
+  <tr>
+    <td width="10%" valign="top"><img src="images/logom2.gif" width="98" height="81" border="1"></td>
+    <td width="90%"> 
+      <table width="600" border="0">
+        <tr> 
+          <td class="banner22">GrADS Documentation</td>
+        </tr>
+        <tr> 
+          <td class="fineprint"> 
+            <hr width="600" align="left">
+          </td>
+        </tr>
+        <tr> 
+          <td class="linkpage"><table width=600 border="0" align="left" cellpadding="0" cellspacing="0" class="plaintext">
+            <tr>
+              <td align="left" width="11"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="/home.html"> IGES </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="/cola.html"> COLA </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="http://crew.iges.org"> CREW </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="http://wxmaps.org/"> Weather Maps </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="/grads/grads.html"> GrADS </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="/ellfb/home.html"> ELLFB </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="http://adv-model-earth-syst.org/index.php/JAMES/index"> JAMES </a></td>
+              <td align="center" width="16"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+              <td align="center"><a href="http://aoes.gmu.edu"> Climate Dynamics PhD</a></td>
+              <td align="right" width="11"><img src="/assets/ball_sm_green.gif" alt="ball" width="6" height="6"></td>
+            </tr>
+          </table></td>
+        </tr>
+        <tr> 
+          <td class="linkpage"> <table border="0" cellspacing="0" cellpadding="0" align="center" class="plaintext">
+              <tr> 
+                <td align="left" width="11"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+                <td align="center"><a href="/grads/whatsnew.html"> What's New 
+                  </a></td>
+                <td align="center" width="16"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+                <td align="center"><a href="/grads/downloads.html"> Downloads 
+                  </a></td>
+                <td align="center" width="16"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+                <td align="center"><a href="/grads/gadoc/index.html" class="plaintextbold"> Documentation 
+                  </a></td>
+                <td align="center" width="16"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+                <td align="center"><a href="/grads/users.html"> Users Forum </a></td>
+                <td align="center" width="16"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+                <td align="center"><a href="/grads/gds/index.html"> GDS </a></td>
+                <td align="right" width="11"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+              </tr>
+            </table></td>
+        </tr>
+      </table>
+    </td>
+  </tr>
+</table>
+<table width="716" border="0">
+  <tr> 
+    <td class="itemmajor"> </td>
+    <td class="itemmajor"> </td>
+  </tr>
+  <tr> 
+    <td><img src="/assets/dot_clear.gif" width="80" height="1"></td>
+    <td > <p align="center" class="item14"> <span class="item16">Documentation 
+        Web Pages</span></p>
+      <p class="item14"> <span class="plaintext">The html version of the GrADS 
+        documentation has become the standard base documentation for GrADS. Follow 
+        the links below to the Users Guide, an introductory tutorial session, 
+        and an alphabetical subject index. Note the documentation is covered under 
+        the same <a href="COPYRIGHT">copyright</a> as the GrADS source code. </span></p>
+      <p><a href="users.html" class="item14">The Users Guide</a><br>
+        <span class="plaintext">The Users Guide is the fundamental document that 
+        provides information about how to use GrADS. The four main chapters are 
+        General Topics, Analysis Topics, Display Topics, and the GrADS Scripting 
+        Language</span>. </p>
+      <p><span class="itemmajor"><a href="tutorial.html"><span class="item14">Tutorial</span></a></span> 
+        <br>
+        <span class="plaintext">The tutorial will give you a feeling for how to use the 
+        basic capabilities of GrADS. This sample session takes about 30 minutes 
+        to run through. It is highly recommended for new users.  (<a href="Tutorial_Espanol.doc">En Español.</a>)</span></p>
+      <p><a href="gadocindex.html" class="item14">Index<br>
+        </a><span class="plaintext">The Index provides a quick and easy interface 
+        for checking the syntax and usage of any GrADS command or function. Subject 
+        headings from the User's Guide are also listed in the Index. </span></p>
+      <p><span class="item14">Download HTML Documentation</span><br>
+        <span class="plaintext">You can download a compressed tar file containing 
+        all the html source code. These can be useful to install on your local 
+        computer if you have a slow internet connection or if you travel often 
+        with a laptop.</span><br>
+        <img src="/assets/ball_sm_green.gif" width="6" height="6"> 
+        <span class="plaintext"><a href="http://iges.org/grads/gadoc/gadoc_files.tar.gz">http://iges.org/grads/gadoc/gadoc_files.tar.gz</a> 
+      (last updated 24 September 2012)</span> </p>
+      <p class="item14">Download Hard Copy Documentation<br>
+        <span class="plaintext">If you simply <i>must</i> 
+        have a printable version of the documentation, you will have to settle 
+        for a version that is outdated and no longer supported. The following 
+        formats are available: </span><br>
+      <table width="600" border="0" cellspacing="0" cellpadding="0">
+        <tr> 
+          <td width="11"><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+          <td><a href="ftp://cola.gmu.edu/grads/beta/doc/gadoc151.pdf" class="plaintext">PDF</a></td>
+        </tr>
+        <tr> 
+          <td><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+          <td><a href="ftp://cola.gmu.edu/grads/beta/doc/gadoc151.ps"><span class="plaintext">Postscript 
+            </span></a><span class="plaintext"> (<a href="ftp://cola.gmu.edu/grads/beta/doc/gadoc151.ps.gz">G-Zipped 
+            </a> and <a href="ftp://cola.gmu.edu/grads/beta/doc/gadoc151.ps.a4">A4</a>)</span></td>
+        </tr>
+        <tr> 
+          <td><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+          <td><a href="ftp://cola.gmu.edu/grads/beta/doc/gadoc151.txt" class="plaintext">ASCII</a></td>
+        </tr>
+        <tr> 
+          <td><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+          <td><a href="http://grads.iges.org/grads/gadoc/reference_card.pdf" class="plaintext">GrADS 
+            Commands Quick Reference Card</a></td>
+        </tr>
+        <tr> 
+          <td><img src="/assets/ball_sm_green.gif" width="6" height="6"></td>
+          <td><a href="http://grads.iges.org/grads/gadoc/reference_card_scl.pdf" class="plaintext">Scripting 
+            Language Quick Reference Card</a></td>
+        </tr>
+      </table>
+      
+    </td>
+  </tr>
+</table>
+<p> </p></body>
+</html>
diff --git a/doc/gadoc_files.tar.gz b/doc/gadoc_files.tar.gz
new file mode 100644
index 0000000..1aeebe4
Binary files /dev/null and b/doc/gadoc_files.tar.gz differ
diff --git a/doc/gadocindex.html b/doc/gadocindex.html
new file mode 100644
index 0000000..44ef28e
--- /dev/null
+++ b/doc/gadocindex.html
@@ -0,0 +1,27 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Documentation Index</title>
+</head>
+<frameset rows="110,*">
+  <frame name="alpha" src="indexalpha.html" target="list">
+  <frameset cols="165,*" border=0>
+    <frame name="list" src="indexlist.html" target="pages">
+    <frame name="pages" src="pages.html">
+  </frameset>
+</frameset>
+
+<noframes>
+<body bgcolor="#e0f0ff" text="#000000">
+<p>
+Your browser does not support frames. Your options are: 
+<p>
+1. Curse the universe for having to work with obsolete gear, then upgrade.
+<p>
+2. View the <a href="indexlist.html" target="_top">index list</a> without frames.
+</body>
+
+</noframes>
+</body>
+</html>
diff --git a/doc/gfs.ctl b/doc/gfs.ctl
new file mode 100644
index 0000000..a649a61
--- /dev/null
+++ b/doc/gfs.ctl
@@ -0,0 +1,176 @@
+* This is a GrADS descriptor file for NCEP GRIB2 file downloaded from:
+*   ftp://tgftp.nws.noaa.gov/SL.us008001/ST.opnl/MT.gfs_CY.hh/RD.yyyymmdd/PT.grid_DF.gr2/
+*
+* N.B. In this example descriptor file, the NCEP grib2 file name is changed 
+* from:
+*   fh.0fff_tl.press_gr.0p5deg 
+*      (the filename on the NCEP FTP server)
+* to:
+*   gfs.yyyymmddhh.fff.grib2 
+*      (a filename that includes initialization date and forecast hour)
+*
+* where:
+*     yyyy is the initialization year
+*       mm is the initialization month
+*       dd is the initialization day
+*       hh is the initialization hour
+*      fff is the forecast hour
+*
+dset /your_path_name_here/gfs.%iy4%im2%id2%ih2.%f3.grib2
+title GFS Forecast in GRIB2; 3-hourly out to 180 hours on a 0.5-degree grid
+dtype grib2
+index ^gfs.map
+options template pascals
+undef -9.99e33
+xdef 720 linear  0 0.5
+ydef 361 linear -90 0.5
+zdef 26 levels 100000 97500 95000 92500 90000 85000 80000 
+    75000 70000 65000 60000 55000 50000 45000 40000 35000 
+    30000 25000 20000 15000 10000 7000 5000 3000 2000 1000 
+tdef 61 linear 12z24jan08 3hr
+vars 144
+z           26,100           0,3,5      Geopotential Height [gpm]
+t           26,100           0,0,0      Temperature [K]
+u           26,100           0,2,2      U-Component of Wind [m/s]
+v           26,100           0,2,3      V-Component of Wind [m/s]
+vort        26,100           0,2,10     Absolute Vorticity [/s]
+vv          21,100           0,2,8      Vertical Velocity (Pressure) [Pa/s]
+rh          21,100           0,1,1      Relative Humidity [%]
+clwmr       21,100           0,1,22     Cloud Water Mixing Ratio [kg/kg]
+ps          0,1,0            0,3,0      Surface Pressure [Pa]
+ts          0,1,0            0,0,0      Surface Temperature [K]
+t2m         0,103,2          0,0,0      2m Temperature [K]
+t2min       0,103,2          0,0,4      2m Minimum Temperature [K]
+t2max       0,103,2          0,0,5      2m Maximum Temperature [K]
+q2          0,103,2          0,1,0      2m Specific Humidity [kg/kg]
+p           0,1,0            0,1,8,1    Total Accumulated Precipitation [kg/m2]
+pc          0,1,0            0,1,10,1   Convective Precipitation [kg/m2]
+crain       0,1,0            0,1,192,0  Categorical Rain (yes=1; no=0)
+cfrzr       0,1,0            0,1,193,0  Categorical Freezing Rain (yes=1; no=0)
+cicep       0,1,0            0,1,194,0  Categorical Ice Pellets (yes=1; no=0)
+csnow       0,1,0            0,1,195,0  Categorical Snow (yes=1; no=0)
+pwat        0,200,0          0,1,3      Precipitable Water (NCEP level 200) [kg/m^2]
+rhum        0,200,0          0,1,1      Relative Humidity (NCEP level 200) [%]
+o3mr100     0,100,10000      0,14,192   100mb Ozone Mixing Ratio [kg/kg]
+o3mr70      0,100,7000       0,14,192   70mb Ozone Mixing Ratio [kg/kg]
+o3mr50      0,100,5000       0,14,192   50mb Ozone Mixing Ratio [kg/kg]
+o3mr30      0,100,3000       0,14,192   30mb Ozone Mixing Ratio [kg/kg]
+o3mr20      0,100,2000       0,14,192   20mb Ozone Mixing Ratio [kg/kg]
+o3mr10      0,100,1000       0,14,192   10mb Ozone Mixing Ratio [kg/kg]
+wavh500     0,100,50000      0,3,193    5-Wave Geopotential Height [gpm]
+wava500     0,100,50000      0,3,197    5-Wave Geopotential Height Anomaly [gpm]
+soilw1      0,106,0,0.1      2,0,192    Volumetric Soil Moisture,0.0-0.1m below surface [fraction]
+soilw2      0,106,0.1,0.4    2,0,192    Volumetric Soil Moisture,0.1-0.4m below surface [fraction]
+soilw3      0,106,0.4,1      2,0,192    Volumetric Soil Moisture,0.4-1.0m below surface [fraction]
+soilw4      0,106,1,2        2,0,192    Volumetric Soil Moisture,1.0-2.0m below surface [fraction]
+soilt1      0,106,0,0.1      0,0,0      Soil Temperature,0.0-0.1m below surface [K]   
+soilt2      0,106,0.1,0.4    0,0,0      Soil Temperature,0.1-0.4m below surface [K] 
+soilt3      0,106,0.4,1      0,0,0      Soil Temperature,0.4-1.0m below surface [K]   
+soilt4      0,106,1,2        0,0,0      Soil Temperature,1.0-2.0m below surface [K]     
+tb          0,108,3000,0     0,0,0      Bottom 30mb Temperature [K]
+rhb         0,108,3000,0     0,1,1      Bottom 30mb Relative Humidity [%]
+qb          0,108,3000,0     0,1,0      Bottom 30mb Specific Humidity [kg/kg]
+ub          0,108,3000,0     0,2,2      Bottom 30mb U Winds [m/s]
+vb          0,108,3000,0     0,2,3      Bottom 30mb V Winds [m/s] 
+t6000       0,102,1829       0,0,0      Temperature at 6000ft AMSL [K]
+t9000       0,102,2743       0,0,0      Temperature at 9000ft AMSL [K]
+t12000      0,102,3658       0,0,0      Temperature at 12000ft AMSL [K]
+u6000       0,102,1829       0,2,2      U Winds at 6000ft AMSL [m/s]
+u9000       0,102,2743       0,2,3      U Winds at 9000ft AMSL [m/s]
+u12000      0,102,3658       0,2,2      U Winds at 12000ft AMSL [m/s]
+v6000       0,102,1829       0,2,3      V Winds at 6000ft AMSL [m/s]
+v9000       0,102,2743       0,2,2      V Winds at 9000ft AMSL [m/s]
+v12000      0,102,3658       0,2,3      V Winds at 12000ft AMSL [m/s]
+ztrop       0,7,0            0,3,5      Tropopause Geopotential Height [gpm]
+ttrop       0,7,0            0,0,0      Tropopause Temperature [K]
+ptrop       0,7,0            0,3,0      Tropopause Pressure [Pa]
+utrop       0,7,0            0,2,2      Tropopause U Winds [m/s]
+vtrop       0,7,0            0,2,3      Tropopause V Winds [m/s]
+strop       0,7,0            0,2,192    Tropopause Vertical Speed Shear [/s]
+rhl1        0,104,0.33,1     0,1,1      Relative Humidity, Sigma 0.33 to 1 [%]
+rhl2        0,104,0.44,1     0,1,1      Relative Humidity, Sigma 0.44 to 1 [%]
+rhl3        0,104,0.72,0.94  0,1,1      Relative Humidity, Sigma 0.72 to 0.94 [%]
+rhl4        0,104,0.44,0.72  0,1,1      Relative Humidity, Sigma 0.44 to 0.72 [%]
+ptls        0,104,0.995      0,0,2      Sigma 0.995 Potential Temperature [K]
+tls         0,104,0.995      0,0,0      Sigma 0.995 Temperature [K]
+vvls        0,104,0.995      0,2,8      Sigma 0.995 Vertical Velocity [Pa/s]
+rhls        0,104,0.995      0,1,1      Sigma 0.995 Relative Humidity [%]
+uls         0,104,0.995      0,2,2      Sigma 0.995 U Winds [m/s]
+vls         0,104,0.995      0,2,3      Sigma 0.995 V Winds [m/s]
+sli         0,1,0            0,7,192    Surface Lifted Index [K]
+capes       0,1,0            0,7,6      Convective Available Potential Energy (Surface) [J/kg]
+cins        0,1,0            0,7,7      Convective Inhibition (Surface) [J/kg]
+li          0,1,0            0,7,193    Best (4 Layer) Lifted Index [K]
+cape        0,108,18000,0    0,7,6      Convective Available Potential Energy (Lowest 180mb) [J/kg]
+cin         0,108,18000,0    0,7,7      Convective Inhibition (Lowest 180mb)  [J/kg]
+zwmx        0,6,0            0,3,5      Max Wind Level Geopotential Height [gpm]
+twmx        0,6,0            0,0,0      Max Wind Level Temperature [K]
+pwmx        0,6,0            0,3,0      Max Wind Level Pressure [Pa]
+uwmx        0,6,0            0,2,2      Max Wind Level U Winds [m/s]
+vwmx        0,6,0            0,2,3      Max Wind Level V Winds [m/s]
+zs          0,1,0            0,3,5      Surface Geopotential Height [gpm]
+slp         0,101,0          0,3,1      Sea Level Pressure [Pa]
+dlwrfs      0,1,0            0,5,192,0  Surface Downward Long Wave Rad. Flux [W/m^2]
+ulwrfs      0,1,0            0,5,193,0  Surface Upward Long Wave Rad. Flux [W/m^2]
+ulwrft      0,8,0            0,5,193,0  Top of Atmosphere Upward Long Wave Rad. Flux [W/m^2]
+uswrft      0,8,0            0,4,193,0  Top of Atmosphere Upward Short Wave Rad. Flux [W/m^2]
+uswrfs      0,1,0            0,4,193,0  Surface Upward Short Wave Rad. Flux [W/m^2]
+dswrfs      0,1,0            0,4,192,0  Surface Downward Short Wave Rad. Flux [W/m^2]
+z0c         0,4,0            0,3,5      Geopotential Height at 0C Isotherm [gpm]
+rh0c        0,4,0            0,1,1      Relative Humidity  at 0C Isotherm [%]
+shtfls      0,1,0            0,0,11,0   Surface Sensible Heat Net Flux [W/m^2]
+lhtfls      0,1,0            0,0,10,0   Surface Latent Heat Net Flux [W/m^2]
+weasd       0,1,0            0,1,13     Accumulated Snow Depth (water equivalent) [kg/m^2]
+prate       0,1,0            0,1,7,0    Precipitation Rate [kg/m^2 s^1]
+cprate      0,1,0            0,1,196,0  Convective Precipitation Rate [kg/m^2 s^1]
+gflux       0,1,0            2,0,193,0  Ground Heat Flux [W/m^2]
+land        0,1,0            2,0,0      Land Cover (1=land, 0=sea)
+icec        0,1,0            10,2,0     Ice Cover [Proportion]
+runoff      0,1,0            2,0,5,1    Surface Water Runoff [kg/m^2]
+pevpr       0,1,0            0,1,200    Surface Potential Evaporation Rate [W/m^2]     
+hpbl        0,1,0            0,3,196    Planetary Boundary Layer Height [m]
+albedo      0,1,0            0,19,1,0   Surface Albedo [%]
+rh2m        0,103,2          0,1,1      2m Relative Humidity [%]
+uflx        0,1,0            0,2,17,0   Surface U-Momentum Flux [N/m^2]
+vflx        0,1,0            0,2,18,0   Surface v-Momentum Flux [N/m^2]
+u10m        0,103,10         0,2,2      10m U Winds [m/s]
+v10m        0,103,10         0,2,3      10m V Winds [m/s]
+ugwd        0,1,0            0,3,194,0  Zonal Flux of Gravity Wave Stress [N/m^2]
+vgwd        0,1,0            0,3,195,0  Meridional Flux of Gravity Wave Stress [N/m^2]
+gpa1000     0,100,100000     0,3,9      1000mb Geopotential Height Anomaly [gpm]
+gpa500      0,100,50000      0,3,9      500mb Geopotential Height Anomaly [gpm]
+ozone200    0,200,0          0,14,0     NCEP level type 200 Total Ozone [Dobson]
+cwat200     0,200,0          0,6,6      NCEP level type 200 Cloud Water [kg/m^2]
+cwork200    0,200,0          0,6,193,0  NCEP level type 200 Cloud Work Function [J/kg]
+hgt204      0,204,0          0,3,5      NCEP level type 204 Geopotential Height [gpm]
+rh204       0,204,0          0,1,1      NCEP level type 204 Relative Humidity [%]
+pres212     0,212,0          0,3,0,0    NCEP level type 212 Pressure [Pa]
+pres213     0,213,0          0,3,0,0    NCEP level type 213 Pressure [Pa]
+pres222     0,222,0          0,3,0,0    NCEP level type 222 Pressure [Pa]
+pres223     0,223,0          0,3,0,0    NCEP level type 223 Pressure [Pa]
+pres232     0,232,0          0,3,0,0    NCEP level type 232 Pressure [Pa]
+pres233     0,233,0          0,3,0,0    NCEP level type 233 Pressure [Pa]
+pres242     0,242,0          0,3,0      NCEP level type 242 Pressure [Pa]
+pres243     0,243,0          0,3,0      NCEP level type 243 Pressure [Pa]
+tcc200      0,200,0          0,6,1,0    NCEP level type 200 Total Cloud Cover [%]
+tcc211      0,211,0          0,6,1,0    NCEP level type 211 Total Cloud Cover [%]
+tcc214      0,214,0          0,6,1,0    NCEP level type 214 Total Cloud Cover [%]
+tcc224      0,224,0          0,6,1,0    NCEP level type 224 Total Cloud Cover [%]
+tcc234      0,234,0          0,6,1,0    NCEP level type 234 Total Cloud Cover [%]
+tcc244      0,244,0          0,6,1      NCEP level type 244 Total Cloud Cover [%]
+t213        0,213,0          0,0,0,0    NCEP level type 213 Temperature [K]
+t223        0,223,0          0,0,0,0    NCEP level type 223 Temperature [K]
+t233        0,233,0          0,0,0,0    NCEP level type 233 Temperature [K]
+hgt2pv      0,109,2e-6       0,3,5      2PotVortSfc Geopotential Height [gpm]
+hgtneg2pv   0,109,-2e-6      0,3,5      neg2PotVortSfc Geopotential Height [gpm]
+pres2pv     0,109,2e-6       0,3,0      2PotVortSfc Pressure [Pa]
+presneg2pv  0,109,-2e-6      0,3,0      neg2PotVortSfc Pressure [Pa]
+t2pv        0,109,2e-6       0,0,0      2PotVortSfc Temperature [K]
+tneg2pv     0,109,-2e-6      0,0,0      neg2PotVortSfc Temperature [K]
+u2pv        0,109,2e-6       0,2,2      2PotVortSfc U-Component of Wind [m/s]
+uneg2pv     0,109,-2e-6      0,2,2      neg2PotVortSfc U-Component of Wind [m/s]
+v2pv        0,109,2e-6       0,2,3      2PotVortSfc V-Component of Wind [m/s]
+vneg2pv     0,109,-2e-6      0,2,3      neg2PotVortSfc V-Component of Wind [m/s]
+vss2pv      0,109,2e-6       0,2,192    2PotVortSfc Vertical speed sheer [1/s]
+vssneg2pv   0,109,-2e-6      0,2,192    neg2PotVortSfc Vertical speed sheer [1/s]
+endvars
diff --git a/doc/gfsens.ctl b/doc/gfsens.ctl
new file mode 100644
index 0000000..7a78ae7
--- /dev/null
+++ b/doc/gfsens.ctl
@@ -0,0 +1,79 @@
+* This is a GrADS descriptor file for NCEP GRIB2 file downloaded from:
+*   ftp://ftpprd.ncep.noaa.gov/pub/data/nccf/com/gens/prod/gefs.yyyymmdd/hh/pgrb2alr/
+*
+* N.B. In this example descriptor file, the NCEP grib2 file name is changed 
+* from:
+*    geENS.tHHz.pgrb2af* 
+*        (the filename on the NCEP FTP server)
+* to:
+*    gfsens.ENS.yyyymmddhh.fff.2p5.grib2
+*        (a filename that includes initialization date, forecast hour, and ensemble name)
+*
+* where:
+*     yyyy is the initialization year
+*       mm is the initialization month
+*       dd is the initialization day
+*       HH is the initialization hour
+*      ENS is the ensemble name 
+*
+dset /your_path_name_here/gfsens.%e.%iy4%im2%id2%ih2.%f3.2p5.grib2
+dtype grib2
+title NCEP 5D Ensemble Forecast in GRIB2 on a 2.5-degree grid
+index ^gfsens.map
+options template pascals
+undef -9.99e33
+xdef 144 linear  0.0 2.5
+ydef  73 linear -90.0 2.5
+zdef   7 levels 100000 92500 85000 70000 50000 25000 20000
+tdef  65 linear 12z24jan08 6hr
+edef 21
+*name length initialtime <type,pert or deriv>
+c00  65  12z24jan08  1,0
+p01  65  12z24jan08  3,1
+p02  65  12z24jan08  3,2
+p03  65  12z24jan08  3,3
+p04  65  12z24jan08  3,4
+p05  65  12z24jan08  3,5
+p06  65  12z24jan08  3,6
+p07  65  12z24jan08  3,7
+p08  65  12z24jan08  3,8
+p09  65  12z24jan08  3,9
+p10  65  12z24jan08  3,10
+p11  65  12z24jan08  3,11
+p12  65  12z24jan08  3,12
+p13  65  12z24jan08  3,13
+p14  65  12z24jan08  3,14
+p15  65  12z24jan08  3,15
+p16  65  12z24jan08  3,16
+p17  65  12z24jan08  3,17
+p18  65  12z24jan08  3,18
+p19  65  12z24jan08  3,19
+p20  65  12z24jan08  3,20
+endedef
+vars 22
+hgt    7,100         0,3,5      Geopotential Height [gpm]
+tmp    7,100         0,0,0      Temperature [K]
+rh     7,100         0,1,1      Relative Humidity [%]
+u      7,100         0,2,2      U-Component of Wind [m/s]
+v      7,100         0,2,3      V-Component of Wind [m/s]
+* these surface vars valid at initial time only 
+zs     0,1,0         0,3,5      Surface Geopotential Height [gmp]
+* these surface vars valid at all times
+ps     0,1,0         0,3,0      Surface Pressure [Pa]
+pwat   0,200,0       0,1,3      Precipitable Water [kg/m^2]
+cape   0,108,18000,0 0,7,6      CAPE, 180-0 mb above ground [J/kg]
+slp    0,101,0       0,3,1      Mean Sea Level Pressure [Pa]
+t2     0,103,2       0,0,0      2-meter Temperature [K]
+rh2m   0,103,2       0,1,1      2-meter Relative Humidity [%]
+u10    0,103,10      0,2,2      10-meter U-Component of Wind [m/s]	
+v10    0,103,10      0,2,3      10-meter V-Component of Wind [m/s]
+* these surface vars valid at forecast times only
+t2max  0,103,2       0,0,4,2    2-meter Maximum Temperature [K]	
+t2min  0,103,2       0,0,5,3    2-meter Minimum Temperature [K]	
+tc     0,200,0       0,6,1,0    Total Cloud Cover [%]
+p      0,1,0         0,1,8,1    Accumulated Precipitation [kg/m^2] 
+crain  0,1,0         0,1,192,0  Categorical Rain (yes=1; no=0)
+cfrzr  0,1,0         0,1,193,0  Categorical Freezing Rain (yes=1; no=0)
+cicep  0,1,0         0,1,194,0  Categorical Ice Pellets (yes=1; no=0)
+csnow  0,1,0         0,1,195,0  Categorical Snow (yes=1; no=0)
+endvars
diff --git a/doc/gradcomdclear.html b/doc/gradcomdclear.html
new file mode 100644
index 0000000..85ce1f5
--- /dev/null
+++ b/doc/gradcomdclear.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>GrADS Command: clear</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>clear</B></H2><P>
<code>clear</code> (or just <code>c</code>)<p>
Issued without parameters, the <code>clear</code> command does pretty
heavy duty clearing of many of the GrADS internal settings.  Parameters
can be added to limit what is cleared when using more advanced
features.<p>
<H3>Usage Notes</H3><P>
<b>WARNING</b>: If you make any error in the syntax of <code>clear</code>
then GrADS does the full <code>clear</code><p>
<H3>Examples</H3>
<P>
<code>clear norset        </code>clears without resetting user options<br>
<code>clear events        </code>flushes the events buffer (e.g., mouse clicks)<br>
<code>clear graphics      </code>clears the graphics, but <b>not</b> the widgets<br>
<code>clear hbuff         </code>clears
the  buffered display and turns off double buffer mode<br>
<code>clear button <i>num</i>    </code>clears button  <code><i>num</i></code> <br>
<code>clear rband <i>num</i>     </code>clears rband  <code><i>num</i></code> <br>
<code>clear dropmenu <i>num</i>  </code>clears dropmenu <code><i>num</i></code> <br>
<code>clear sdfwrite      </code>clears sdfwrite file name and attributes without resetting other user options (<span class="style1">2.0.a3+</span>)<br>
<code>clear mask          </code>clears contour label mask, which is enabled with the command <code>'<a href="gradcomdsetclab.html">set clab</a> masked'</code>(<span class="style1">2.0.a7+</span>)<br>
<code>clear shp           </code>clears shapefile output file name and  attributes without resetting other user options (<span class="style1">2.0.a9+</span>)<br>
\ No newline at end of file
diff --git a/doc/gradcomdclose.html b/doc/gradcomdclose.html
new file mode 100644
index 0000000..c7427ce
--- /dev/null
+++ b/doc/gradcomdclose.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>close</h2>
+<code>close <i>file#</i></code><p>
+close the last descriptor file number for current file<p>
+<h3>Usage</h3>
+<h3>Notes</h3>
diff --git a/doc/gradcomdcollect.html b/doc/gradcomdcollect.html
new file mode 100644
index 0000000..8fea195
--- /dev/null
+++ b/doc/gradcomdcollect.html
@@ -0,0 +1,48 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: collect</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>collect</b></h2>
+<p>
+This command provides a way for station data profiles and time series
+to be saved in memory as a set. The command format is:
+
+<p>
+<ul><code>collect <i>cnum expr</i></code></ul>
+
+<p>
+where <code><i>cnum</i></code> is the collection number, a value from
+0 to 31, and <code><i>expr</i></code> is any GrADS expression that
+gives a station data result. If <code>"free"</code> is given for
+<code><i>expr</i></code>, the collection is emptied and all storage is
+freed.
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>The <code>collect</code> command will only work when one dimension is
+varying, either Z or T. Each time <code>collect</code> is issued for a
+particular collection number, the station data is added to the
+collection of stations.  The order in which stations are added is
+important.
+
+<p>
+<li>After a group of station profiles or time series have been saved as a
+collection, use the <a href="gradfunccoll2gr.html">coll2gr</a>
+function to convert the collection into a grid. 
+
+<p>
+<li>See the section of the User's Guide on <a
+href="usingstationdata.html#xsection">Arbitrary Cross Sections</a> for more
+information. 
+</ol>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdddrawline.html b/doc/gradcomdddrawline.html
new file mode 100644
index 0000000..e2fbede
--- /dev/null
+++ b/doc/gradcomdddrawline.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw line</B></H2><P>
+<code>draw line <i>x1 y1 x2 y2</i></code><p>
+Draws a line from <code><i>x1, y1 to x2, y2</i></code> using current line
+drawing attributes. See the <code>set line</code> command. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
+
diff --git a/doc/gradcomddefine.html b/doc/gradcomddefine.html
new file mode 100644
index 0000000..806c2ae
--- /dev/null
+++ b/doc/gradcomddefine.html
@@ -0,0 +1,36 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: define</title>
+</head>
+<body text="#000000">
+
+<h2>define</h2>
+<p>
+The <code>define</code> command creates new Grads variables. The syntax is:
+<p>
+<ul>
+<code>define var = expression</code><br>
+or <br>
+<code>var = expression</code>   
+(the <code>define</code> command may be implied)<br>
+</ul>
+
+<p>
+where <code>var</code> is a variable name, and <code>expression</code>
+is any valid Grads expression.
+
+<p>
+<h3>Usage Notes</h3>
+
+<p>
+See the section in the User's Guide on <a
+href="variable.html#new">defining new variables</a> for more
+information.
+
+<h3>Examples</h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomddisablefwrite.html b/doc/gradcomddisablefwrite.html
new file mode 100644
index 0000000..a6f34e7
--- /dev/null
+++ b/doc/gradcomddisablefwrite.html
@@ -0,0 +1,6 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>disable fwrite</h2>
+close output grid file<p>
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
diff --git a/doc/gradcomddisableprint.html b/doc/gradcomddisableprint.html
new file mode 100644
index 0000000..abe2648
--- /dev/null
+++ b/doc/gradcomddisableprint.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<h2>disable print</h2>
This command closes the  GrADS metafile  that  contains the instructions  to create a hardcopy of the graphical display.
<p>
<h3>Usage Notes</h3>
<p>See the notes in the documentation page for <code><a href="gradcomdenableprint.html">enable print</a></code></p>
<h3> </h3>

\ No newline at end of file
diff --git a/doc/gradcomddisplay.html b/doc/gradcomddisplay.html
new file mode 100644
index 0000000..cb8a39c
--- /dev/null
+++ b/doc/gradcomddisplay.html
@@ -0,0 +1,41 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head><title>GrADS Command: display</title></head>
+<body>
+
+<H2><B>display</B></H2><P>
+
+<p>
+<code>display <i>expression</i></code><br>
+or<br>
+<code>d <i>expression</i></code>
+
+<p>
+The <code>display</code> command is how you actually display data via the
+graphics output window. <p>
+
+<H3>Usage Notes</H3>
+<P>
+If you <code>display</code> when all dimensions are fixed, you get a
+single value which is typed out in the command window. If you
+<code>display</code> when one dimension varies, you get a 1-D line
+graph (by default). If you <code>display</code> when two dimensions
+are varying, you get a 2-D contour plot (by default).
+<p>
+GrADS will automatically overlay the output from each successive
+display command.<br>
+To clear the display, enter: <p>
+
+<dd>
+<code>clear</code> (or just <code>c</code>) 
+</dd>
+
+<p>
+<H3>Examples</H3><P>
+
+The simplest example of an expression to display would be a variable named by the default data file.<br>
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/gradcomddrawbutton.html b/doc/gradcomddrawbutton.html
new file mode 100644
index 0000000..2a40214
--- /dev/null
+++ b/doc/gradcomddrawbutton.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: draw button</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>draw button</b></h2>
<p>
<code>draw button <i>number xpos ypos width height string</i></code>

<p>
Draws a button centered on <code><i>xpos,ypos</i></code> with the
following attributes:

<p>
<ul>
<code>number   </code>button number, can be 1 thru 255<br>
<code>xpos     </code>x center of the button in page coordinates (inches)<br>
<code>ypos     </code>y center of the button in page coordinates (inches)<br>
<code>width    </code>width (x) of the button (inches)<br>
<code>height   </code>height (y) of the button (inches)<br>
<code>string   </code>text to display centered in the button<br>
</ul>

<p>
<h3>Usage Notes</h3>
<ol>
<li>Button colors are specified with the <a
href="gradcomdsetbutton.html"><code>set button</code></a> command.
<p>
<li>A button's initial state is <code>ON</code>. If a user clicks on a
button following a <a href="gradcomdqpos.html"><code>q pos</code></a> command,
then the button state will switch from <code>ON (1)</code> to
<code>OFF (0)</code>. A second <a href="gradcomdqpos.html"><code>q pos</code></a>
followed by a mouse click on the button will return it to the
<code>ON</code> state.  
<p>
<li>The button "state" (i.e. <code>ON/OFF</code>) may also
be set with the <a href="gradcomdredrawbutton.html"><code>redraw
button</code></a> command.
<p>
<li>See the section of the User's Guide on <a
href="script.html#widgets">widgets</a> for more information on using
buttons.
</ol>

<p>
<h3>Example</h3>

<p>
<pre>
set rgb 90 100 100 100
set rgb 91  50  50  50
set rgb 92 200 200 200
set button 2 90 91 92 3 90 91 92 10
draw button  1 2.5 8.0 2.5 0.5  Click Here
</pre>

</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomddrawdropmenu.html b/doc/gradcomddrawdropmenu.html
new file mode 100644
index 0000000..3d9c1a1
--- /dev/null
+++ b/doc/gradcomddrawdropmenu.html
@@ -0,0 +1,122 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: draw dropmenu</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>draw dropmenu</b></h2>
+<p>
+<code>draw dropmenu <i>number xpos ypos width height text_list</i></code>
+<p>
+<p>
+Draws a drop menu with the following attributes:
+
+<p>
+<ul>
+<code><i>number      </i></code>
+menu number, 0 - 64<br>
+<code><i>xpos        </i></code>
+x center of the menu base in page coordinates (inches)<br>
+<code><i>ypos        </i></code>
+y center of the menu base in page coordinates (inches)<br>
+<code><i>width       </i></code>
+width (x) of the menu base (inches)<br>
+<code><i>height      </i></code>
+height (y) of the menu base (inches)<br>
+<code><i>text_list   </i></code>
+the contents of the menu, seperated by vertical bars (|)<br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>     
+<ol>
+<li>The first item in the text list is the string to put in the 'base' of the
+dropmenu (the base being the part that always appears); the rest of the
+text are the menu items. Empty spaces are allowed in the strings.
+<p>
+<li>When the user clicks on the 'base', the rest of the menu appears.
+<p>
+<li>The menu colors are controlled by the <a
+href="gradcomdsetdropmenu.html"><code>set dropmenu</code></a>
+command.
+<p>
+<li>Dropmenus can be nested or "cascading". The syntax for creating a
+"spawned" dropmenu is similar to that for the main dropmenu. First, any
+item in the <code><i>text_list</i></code> that will spawn a new
+dropmenu should have <code>"><i>num</i>>"</code> appended, where
+<code><i>num</i></code> will be the number assigned to the spawned
+dropmenu. This new dropmenu is then defined with the following syntax:
+<p>
+<code>draw dropmenu <i>num</i> cascade <i>new_text_list</i></code>
+<p>
+There can be up to three levels of nested cascading dropmenus
+launched from the main dropmenu. The 2nd example below illustrates how
+to implement cascading dropmenus.
+<p>
+<li>The section of the User's Guide on <a
+href="script.html#widgets">widgets</a> and the <a
+href="gradcomdqpos.html"><code>q pos</code></a> reference page have
+more information on using dropmenus.
+</ol>
+
+<p>
+<h3>Examples</h3>
+<p>
+<ol>
+<li>Here is a script that illustrates how to use a simple dropmenu:
+<p>
+<pre>
+'clear'
+'reset events'
+'set rgb 90 100 100 100'
+'set rgb 91 150 150 150'
+'set rgb 92 200 200 200'
+'set dropmenu 1 91 90 92 0 91 92 90 1 91 90 92 92 90 6'
+'draw dropmenu 1 1 8 1.5 0.5 Select a Variable | Wind | Temperature | Height | SLP '
+noselect = 1
+while (noselect)
+  'q pos'
+  menunum  = subwrd(result,7)
+  menuitem = subwrd(result,8)
+  if (menunum = 1)
+    if menuitem = 1 ; newbase = 'Variable = Wind'   ; endif
+    if menuitem = 2 ; newbase = 'Variable = Temp'   ; endif
+    if menuitem = 3 ; newbase = 'Variable = Height' ; endif
+    if menuitem = 4 ; newbase = 'Variable = SLP'    ; endif
+    'draw dropmenu 1 1 8 1.5 0.5 'newbase' | Wind | Temperature | Height | SLP '
+    noselect = 0
+  endif
+endwhile
+</pre>
+<p>
+
+<li>Here is a script that illustrates how to use cascading dropmenus:
+<p>
+<pre>
+'clear'
+'reset events'
+'set rgb 90 100 100 100'
+'set rgb 91 150 150 150'
+'set rgb 92 200 200 200'
+'set button 1 91 -1 -1 1 91 90 92 12'
+'draw button 1 1 8 1 0.5 quit'
+'set dropmenu 1 91 -1 -1 1 91 90 92 1 91 90 92 90 92 6'
+'draw dropmenu 1 1.5 7.5 2 0.5  Menu Base | Space | Earth >05> | Sun | Moon'
+'draw dropmenu 5 cascade Ocean | Land | Atmosphere >11> | Biosphere'
+'draw dropmenu 11 cascade Snow | Rain | Mist | Tornado '
+
+while (1)
+  'q pos'
+  say result
+  ev = subwrd(result,6)
+  if (ev!=3); break; endif;
+endwhile
+</pre>
+</ol>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomddrawline.html b/doc/gradcomddrawline.html
new file mode 100644
index 0000000..c26ff32
--- /dev/null
+++ b/doc/gradcomddrawline.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw line</B></H2><P>
+<code>draw line <i>x1 y1 x2 y2</i></code><p>
+Draws a line from <code>x1, y1</code> to <code>x2, y2</code> using current
+line
+drawing attributes. See the <a href="gradcomdsetline.html"><code>set
+line</code></a> command. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
+
diff --git a/doc/gradcomddrawmap.html b/doc/gradcomddrawmap.html
new file mode 100644
index 0000000..8ec53ce
--- /dev/null
+++ b/doc/gradcomddrawmap.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw map</B></H2><P>
+<code>draw map</code><p>
+Draw a map outlined as controlled by current settings and the dimension
+environment.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawmark.html b/doc/gradcomddrawmark.html
new file mode 100644
index 0000000..38bcfb6
--- /dev/null
+++ b/doc/gradcomddrawmark.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: draw mark</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>draw mark</B></H2><P>
<code>draw mark <i>marktype x y size</i></code>
<p>
Draws a marker of type <code><i>marktype</i></code> at position
<code><i>x, y</i></code> at the requested <code><i>size</i></code>. 
The <code><i> marktype</i></code> may be one of the following:
<ul>
<pre>
 0 - none
 1 - plus sign
 2 - open circle 
 3 - closed circle 
 4 - open square 
 5 - closed square 
 6 - multiplication sign
 7 - open diamond 
 8 - open triangle 
 9 - closed triangle
10 - open circle with vertical bar
11 - closed circle with vertical bar
</pre>
<p>
<h3>Usage Notes</h3>

<p>
<h3>Examples </h3>


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomddrawpolyf.html b/doc/gradcomddrawpolyf.html
new file mode 100644
index 0000000..4893bff
--- /dev/null
+++ b/doc/gradcomddrawpolyf.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw polyf</B></H2><P>
+<code>draw polyf <i>x1 y1 x2 y2 x3 y3 ... xn yn</i></code><p>
+Draw a filled polygon between a series of <code><i>x,y</i></code> points.
+The polygon is closed by having <code><i>xn=x1</i></code> and
+<code><i>yn=y1</i></code>. <a href="gradcomdsetline.html"><code>set
+line</code></a> controls the fill
+color.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawrec.html b/doc/gradcomddrawrec.html
new file mode 100644
index 0000000..2d1b17f
--- /dev/null
+++ b/doc/gradcomddrawrec.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw rec</B></H2><P>
+<code>draw rec <i>xlo ylo xhi yhi</i></code><p>
+Draws an unfilled rectangle from <code><i>xlo,ylo</i></code> to
+<code><i>xhi,ylo</i></code> to <code><i>xhi,yhi</i></code> to
+<code><i>xlo,yhi</i></code> to <code><i>xlo,ylo</i></code>. The
+rectangle is drawn using current line drawing attributes. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawrecf.html b/doc/gradcomddrawrecf.html
new file mode 100644
index 0000000..339db66
--- /dev/null
+++ b/doc/gradcomddrawrecf.html
@@ -0,0 +1,9 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw recf</B></H2><P>
+<code>draw recf <i>xlo ylo xhi yhi</i></code><p>
+Draws a filled rectangle in the area described by <code><i>xlo, ylo, xhi,
+yhi</i></code>. The fill color is the current line drawing attribute
+<code><i>color</i></code>. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawshp.html b/doc/gradcomddrawshp.html
new file mode 100644
index 0000000..6165d14
--- /dev/null
+++ b/doc/gradcomddrawshp.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: draw shp</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>draw shp</B></H2>
<P>
<code>draw shp <i>shapefile <n> <m> </i></code>
<p>
Draws the contents of a shapefile. The arguments are:
<p>
<code><i>shapefile</i>  </code>The name of the shapefile. It is not necessary to include the file extension (.shp)<br>
  <codoe>
  <code><i>n</i>          </code>Element number (if you want to draw only one)<br>
  <codoe>
<code><i>m</i>          </code>Use <code><i>n</i></code>  and <code><i>m</i></code> if you want to draw a range of elements
<p>If <code><i>n</i></code>  and <code><i>m</i></code> are omitted, all the elements in the shapefile will be drawn. <br>
<p>
<h3>Usage Notes</h3>
<p>This command is available with GrADS version 2.0.a8 or later.</p>
<p>If you put the three shapefile components  (*.shp, *.shx, and *.dbf) in the GrADS data directory (pointed to by the <a href="gradcomdgrads.html#env">GADDIR environment variable</a>), then it is not necessary to include the full path in <code><i>shapefile</i></code>. </p>
<p> Before invoking this command, it is necessary to draw a plot first in order to establish the dimensions and scaling of the display. Shapefiles contain 2-dimensional spatial features, so your plot must be varying in the X-Y (lon/lat) domain. A shapefile may contain one of three kinds of graphical elements: points, lines, or polygons. </p>
<ul>
  <li> For shapefiles that contain points, GrADS will draw a mark at each point location. The mark type and size are controlled by the <code><a href="gradcomdsetshpopts.html">set shpopts</a></code> command, and the color is controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. </li>
  <li>For shapefiles that contain lines, GrADS will draw the line elements using the color, style, and thickness settings that are controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. </li>
  <li>For shapefiles that contain polygons, the default behavior of GrADS is draw only the perimeter of each polygon element. Use  the <code><a href="gradcomdsetshpopts.html">set shpopts</a></code> command to draw filled polygons and set the fill color.  
The color, style, and thickness of the polygon perimeters are controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. </li>
</ul>
<p>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more details. </p>
<h3>Examples </h3>


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomddrawstring.html b/doc/gradcomddrawstring.html
new file mode 100644
index 0000000..7c2d448
--- /dev/null
+++ b/doc/gradcomddrawstring.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw string</B></H2><P>
+<code>draw string <i>x y string</i></code><p>
+Draws the character <code>string</code> at the <code><i>x,y</i></code>
+position. <code><i>x</i></code> and<code><i> y</i></code> are given in
+inches on the virtual page. The string is drawn using current string
+attributes -- set the <a href="gradcomdsetstring.html"><code>set
+string</code></a>
+and <a href="gradcomdsetstrsiz.html"><code>set strsiz</code></a>
+commands. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawtitle.html b/doc/gradcomddrawtitle.html
new file mode 100644
index 0000000..81885e2
--- /dev/null
+++ b/doc/gradcomddrawtitle.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw title</B></H2><P>
+<code>draw title <i>string</i></code><P>
+Draw <code>title</code> at top of graph.  Backslash within
+<code><i>string</i></code> denotes new line.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawwxsym.html b/doc/gradcomddrawwxsym.html
new file mode 100644
index 0000000..d778b20
--- /dev/null
+++ b/doc/gradcomddrawwxsym.html
@@ -0,0 +1,37 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+</style>
+
+
+<H2><B>draw wxsym</B></H2>
+<P>
+<code>draw wxsym <i>symbol x y size
+<color <thickness>></i></code><p>
+Draws the specified <code>wx</code> symbol at the specified location.
+where:<p>
+<ul><code><i>symbol</i></code>               is
+an integer specifying what symbol to
+draw<br>
+<code><i>x</i></code>                         x
+location, in plotter inches<br>
+<code><i>y</i></code>                         y
+location<br>
+<code><i>size</i></code>                   size
+of the symbol <br>
+<code><i>color</i></code>                 color
+of symbol. Use <code>-1</code> (the default) to get
+standard colors (red for storm, blue for snow, etc)<br>
+<code><i>thickness</i></code>         line
+thickness of the symbol (default is 3)
+</ul>
+<p>
+<H3>Usage Notes</H3><P>
+<ol>
+<li>To see what symbols are available, run the script <code><a href="ftp://cola.gmu.edu/grads/scripts/wxsym.gs">wxsym.gs</a></code> to see how to issue the <code>wxsym</code>
+command.
+<li>To change the default colors of the weather symbols, use <code><a href="gradcomdsetwxcols.html">set wxcols</a></code><br>
+</ol>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawxlab.html b/doc/gradcomddrawxlab.html
new file mode 100644
index 0000000..2fbe582
--- /dev/null
+++ b/doc/gradcomddrawxlab.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw xlab</B></H2><P>
+<code>draw xlab <i>string</i></code><p>
+Writes <code><i>string</i></code> in an appropriate position to label
+<code>x</code> axis.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomddrawylab.html b/doc/gradcomddrawylab.html
new file mode 100644
index 0000000..6f5935a
--- /dev/null
+++ b/doc/gradcomddrawylab.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>draw ylab</B></H2><P>
+<code>draw ylab <i>string</i></code><p>
+Writes <code><i>string</i></code> in an appropriate position to label
+<code>y</code> axis.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdenableprint.html b/doc/gradcomdenableprint.html
new file mode 100644
index 0000000..19a0511
--- /dev/null
+++ b/doc/gradcomdenableprint.html
@@ -0,0 +1,29 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
+<!--
+body {
+	background-color: #e0f0ff;
+}
+-->
+</style>
+
+<h2>enable print</h2>
+<code>enable print <i>fname</i></code>
+<p>
+This command opens the output file <code> <i>fname</i></code> that will contain the  instructions  in GrADS metacode format to create a hardcopy of the graphical display. Any existing contents of <code><i>fname</i></code>  will be lost.
+
+The output file  <code> <i>fname</i></code> is referred to as a GrADS metafile. 
+<p>
+
+<h3>Usage Notes</h3>
+<p>Creating a GrADS metafile for vector-graphic hardcopy involves four steps:</p>
+<p>1. Open the metafile with the <code><a href="gradcomdenableprint.html">enable print</a> </code> command<br />
+2. Create the graphical display that you want to print<br />
+3. Issue the <a href="gradcomdprint.html"><code>print</code></a>  command. For multiple images in your metafile, use <code><a href="gradcomdclear.html">clear</a></code> and then <a href="gradcomdprint.html"><code>print</code></a>  again.<br />
+4. Close the metafile with the <code><a href="gradcomddisableprint.html">disable print</a> </code> command</p>
+<p>After you have created a GrADS metafile, you can </p>
+<p>1. convert it to postscript using the external utility <code><a href="gradutilgxps.html">gxps</a></code> <br />
+  2. 
+convert it to encapsulated postscript using <code><a href="gradutilgxeps.html">gxeps</a></code> or you can <br />
+3. 
+display it using the external utilities <code><a href="gradutilgxtran.html">gxtran</a></code> or <code><a href="ftp://cola.gmu.edu/grads/gv/gv32.exe">gv32.exe</a></code> (for MS Windows)</p>
+<p> </p>
diff --git a/doc/gradcomdexec.html b/doc/gradcomdexec.html
new file mode 100644
index 0000000..2e5609e
--- /dev/null
+++ b/doc/gradcomdexec.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>exec</B></H2><P>
+<code>exec <i>file-name <arg0 arg1...arg9></i></code><p>
+<code><i>file-name</i></code>      the
+name of a file containing GrADS
+commands<p>
+<H3>Usage Notes</H3><P>
+The variables <code>&0</code> to <code>&9</code> may
+be used within the exec file to be
+replaced by blank delimited arguments to the exec.<p>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdflush.html b/doc/gradcomdflush.html
new file mode 100644
index 0000000..7858a30
--- /dev/null
+++ b/doc/gradcomdflush.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>GrADS Command: flush</title>
<body bgcolor="e0f0ff" text="#000000">

<h2>flush</h2>
<code>flush</code>
<p>
Releases all memory from the GRIB2 cache. 
<p>
<h3>Usage Notes</h3>
<p>This command is in GrADS version 2.0+</p>
\ No newline at end of file
diff --git a/doc/gradcomdgrads.html b/doc/gradcomdgrads.html
new file mode 100644
index 0000000..0f46250
--- /dev/null
+++ b/doc/gradcomdgrads.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
<html>
<link href="GrADS.css" rel="stylesheet" type="text/css">

<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
<body bgcolor="e0f0ff">
<h2><b>grads | gradsdap    <br>
gradsc | gradsnc | gradshdf | gradsdods</b>   </h2>
<table width="700" border="0">
  <tr>
    <td><p class="plaintext">GrADS is an interactive desktop tool for the analysis and 
      display of earth science data. GrADS is used worldwide and <a href="../downloads.html">freely 
        available</a> over the internet. 
      <p class="plaintext"> GrADS implements two data models: a 5-Dimensional gridded data model, and a station data model. In the gridded data model, the dimensions 
        are presumed to be latitude, longitude, level, time, and <a href="ensembles.html">ensemble</a>. In the station data model, data exist at arbitrary locations in space and time. Four dimensions (longitude, latitude, level, and time) are used as a framework in the station data model to guide which station reports are to be examined. Each data set is placed within 
        a 4- or 5-Dimensional space by the use of a data descriptor file. Both gridded 
        and station data may be described. Gridded data may be non-linearly spaced; 
        gaussian grids and variable resolution ocean model grids are directly supported. 
        The internal data format in a file may be binary, GRIB1, GRIB2, BUFR, NetCDF, HDF4-SDS, or HDF5. 
        
      <p class="plaintext"> Operations may be performed on the data directly, and interactively, 
        by entering expressions at the command line. The expression syntax allows complex 
        operations that range over very large amounts of data to be performed with simple 
        expressions. A rich set of built-in <a
href="functions.html">functions</a> are provided. In addition, users may add their 
        own functions as <a href="udf.html">external routines</a> written in any programming 
        language. 
    </td>
  </tr>
</table>
<p class="plaintext">The syntax for running GrADS is: 

<ul>
  <p class="plaintext"><code><em>GrADS_executable </em><<i> options </i>></code></p>
</ul>
<table width="680" border="0" cellpadding="5" cellspacing="5" class="plaintext">
  <tr bgcolor="c5d5ff">
    <td colspan="2" bgcolor="e0f0ff">Beginning with GrADS version 2.0.a8, there is only one choice for <code><em>GrADS_executable, </em></code> a single, fully-featured build: </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="75" bgcolor="c5d5ff"><code>grads</code></td>
    <td>Reads GRIB (version 1 and 2), gridded binary, BUFR, GrADS station 
      data, NetCDF (classic and NetCDF-4), HDF4-SDS, HDF5, and OPeNDAP (grids and station data)<br>
    Writes binary, NetCDF (classic and NetCDF-4), GeoTIFF, KML<br>
    Draws shapefiles</td>
  </tr>
</table>
<table width="680" border="0" cellpadding="5" cellspacing="5" class="plaintext">
  <tr bgcolor="c5d5ff">
    <td colspan="2" bgcolor="e0f0ff">For GrADS versions 2.0.a0 through 2.0.a7, the choices for <code><em>GrADS_executable</em></code> are: </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="75" bgcolor="c5d5ff"><code>grads</code></td>
    <td>Reads GRIB (version 1 and 2), gridded binary, BUFR, GrADS station 
    data, NetCDF, HDF4-SDS<br>
    Writes binary, NetCDF,  (starting with 2.0.a5) GeoTIFF, KML</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="75" bgcolor="c5d5ff"><code>gradsdap</code></td>
    <td>Reads GRIB (version 1 and 2), gridded binary, BUFR, GrADS station 
    data, NetCDF, HDF4-SDS, OPeNDAP <br>
    Writes binary, NetCDF,  (starting with 2.0.a5) GeoTIFF, KML</td>
  </tr></table>
<table width="680" border="0" cellpadding="5" cellspacing="5" class="plaintext">
  <tr bgcolor="c5d5ff">
    <td colspan="2" bordercolor="#F4F4F4" bgcolor="#E0F0FF">For GrADS version 1.9 and earlier, the choices for <code><em>GrADS_executable</em></code> are: </td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>gradsc</code></td>
    <td><span class="plaintext">Reads GRIB1, gridded binary, BUFR, 
      GrADS station data <br>
      Writes binary, GRIB1</span></td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>gradsnc</code></td>
    <td><span class="plaintext">Reads GRIB1, gridded binary, BUFR, GrADS station 
      data, NetCDF<br>
      Writes binary, GRIB1, NetCDF</span></td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>gradshdf</code></td>
    <td> 
      <p><span class="plaintext">Reads GRIB1, gridded binary, BUFR, GrADS station 
        data, NetCDF, HDF4-SDS<br>
        Writes binary, GRIB1, HDF-SDS</span></p></td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>gradsdods</code></td>
    <td><span class="plaintext">Reads GRIB1, gridded binary, BUFR, GrADS station 
      data, NetCDF, OPeNDAP (aka DODS) <br>
      Writes binary, GRIB1, NetCDF</span></td>
  </tr>
  <tr> 
    <td> </td>
    <td> </td>
  </tr>
  <tr> 
    <td colspan="2">Command line <code><i>options</i></code> are:</td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>-help</code></td>
    <td>Prints the command line options.</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-a <em>ratio</em></code></td>
    <td><p>(<span class="style1">GrADS 2.0.a9+</span>) Specifies the aspect ratio of the real page inside GrADS.  A valid <code><em>ratio</em></code>  is the X size divided by the Y size and must be greater than 0.2 and less than 5.0. Page size is scaled so the longer side will always be 11 inches. On startup, GrADS will provide the  page dimensions with the message that begins with "<code>GX Package Initialization: Size = </code>"</p>    </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-b</code></td>
    <td>Runs GrADS in batch mode. No graphics output window is opened. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-c <em>'command'</em></code></td>
    <td>Executes the supplied <code><i>command</i></code> after GrADS has started. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-C N</code></td>
    <td>(<span class="style1">GrADS 2.0.a9+</span>) Enables colorization of text displayed in the GrADS command window. N can be 0, 1, or 2. If -C is invoked but N is not provided, color scheme 0 will be used. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-E</code></td>
    <td>Disables command line editing</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-g <em>geometry</em></code></td>
    <td><p>Specifies the size of the graphics output window, which is a representation on your computer screen of the real page and may be any size at all. The size of the real page in GrADS is controlled by the -l or -p or -a options. The <code><em>geometry</em></code> argument has the syntax <code>W</code>x<code>H</code>+<code>X</code>+<code>Y</code> , where <code>W</code> is the width of window in pixels, <code>H</code> is the height of window in pixels, <code>X</code> is the starting pixel 
      point in x, and <code>Y</code> is the starting pixel point in y. Note that <code>X</code> and <code>Y</code> may be negative. </p></td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-H <em>filename</em></code></td>
    <td>Enables command line logging to <code><em>filename</em></code>. If <code><em>filename</em></code> is not provided, command history written to file $HOME/.grads.log</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-l</code></td>
    <td>Runs GrADS in landscape mode, sets the "real" page size to 11 x 8.5. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-m NNN</code></td>
    <td>Sets metafile buffer size to NNN, which must be an integer. Default value 
      is 1000000.</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-p</code></td>
    <td>Runs GrADS in portrait mode, sets the "real" page size to 8.5 x 11. <br>
      If neither the <code>-l</code> or <code>-p</code> options are used, GrADS 
      will prompt the user for a preferred mode. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-u</code></td>
    <td>Unbuffers output, needed for IPC mode</td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="100"><code>-x</code></td>
    <td>Generally used with the -c option, causes GrADS to automatically quit 
      after the supplied <code><i>command</i></code> has been executed.</td>
  </tr>
</table>
<p class="plaintext">Options that do not require arguments may be concatenated. Some examples follow: </p>
<p class="plaintext"><code>  grads -pb <br>
  grads -lbxc "myscript.gs" <br>
  grads -Ca 1.7778 <br>
  grads -C 2 -a 1.7778 <br>
  grads -pHm 5000000 -g 1100x850+70+0 <br>
  grads -pH mysession.log -m 5000000 -g 1100x850+70+0 </code>
<p>
<p>  
<h2><a name="env"></a>Environment Variables </h2>
<table width="680" border="0" cellpadding="5" cellspacing="5" class="plaintext">
  <tr> 
    <td colspan="2"><span class="plaintext">Some environment variables must be 
      set before starting the GrADS. </span></td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td width="55"><span class="plaintext"><code>GADDIR</code>  </span></td>
    <td width="590"><span class="plaintext"> Points to the directory containing 
      the supplemental font and map files in the GrADS release package. If GADDIR is not set, GrADS will look in the default location, /usr/local/lib/grads/. </span></td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td><span class="plaintext"><code>GASCRP</code> </span></td>
    <td><span class="plaintext"> Points to a list of directories containing GrADS 
      utility scripts and user scripts. If more than one directory is specified, acceptable delimiters are a space, a semi-colon, colon, or a comma.</span></td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>GASHP</code></td>
    <td>(<span class="style1">GrADS version 2.0.0+</span>) Points to a list of directories containing shapefiles. Put your shapefiles in those directories, and then it won't be necessary to use the full path when drawing or querying the shapefiles. If more than one directory is specified, acceptable delimiters are a space, a semi-colon, colon, or a comma.</td>
  </tr>
  <tr bgcolor="c5d5ff"> 
    <td><span class="plaintext"><code>GAUDFT</code> </span></td>
    <td><span class="plaintext">Points to the user defined function table. If 
      this variable is not set, the function table will not be read.</span> </td>
  </tr>
</table>
<p class="plaintext"> For example: 
<p> 

  <span class="plaintext"><i>C-shell</i> </span>
  <p> <span class="plaintext"><code>example% setenv GADDIR /ford1/local/lib/grads<br>
    example% setenv GASHP $HOME/grads/shapefiles<br>
example% setenv GASCRP "$HOME/grads/scripts /opt/local/share/grads/library" <br>
    example% setenv GAUDFT $HOME/grads/udf/table<br>
  </code></span>
  <p> <span class="plaintext"><i>Bourne shell</i></span>
  
<p> <span class="plaintext"><code>example% GADDIR=/ford1/local/lib/grads; export 
  GADDIR<br>
  example% GASCRP=$HOME/grads/scripts; export GASCRP<br>
  example% GAUDFT=$HOME/grads/udf/table; export GAUDFT<br>
</code></span> 
<p> 
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdhelp.html b/doc/gradcomdhelp.html
new file mode 100644
index 0000000..80cb099
--- /dev/null
+++ b/doc/gradcomdhelp.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>help</h2>
+Gives a summary list of operations essential to do anything in GrADS. This
+is intended to jog memory rather than provide an exhaustive help facility. 
+<h3>Usage</h3>
+<h3>Notes</h3>
diff --git a/doc/gradcomdmodify.html b/doc/gradcomdmodify.html
new file mode 100644
index 0000000..b7600b2
--- /dev/null
+++ b/doc/gradcomdmodify.html
@@ -0,0 +1,37 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+
+<link rel="stylesheet" href="GrADS.css">
+
+<body bgcolor="e0f0ff">
+<h2>modify</h2>
+<span class="code">modify <i>varname type</i></span> 
+<p class="plaintext"> This command defines a climatological variable, which is 
+  year-independent. <span class="code"><i>varname</i></span> is a defined grid. 
+  There are two options for <span class="code"><i>type</i></span>: 
+<ul>
+  <code>seasonal   </code> <span class="plaintext">- For creating 
+  monthly or multi-monthly climatologies</span><br>
+  <code>diurnal    </code> <span class="plaintext">- For creating 
+  climatologies over a time period less than a day<br>
+  </span>
+</ul>
+<p> 
+<h3>Usage Notes</h3>
+<h3>Example</h3>
+<p class="plaintext">Say you have a 50-year timeseries of monthly mean sea surface 
+  temperatures (a variable named sst with 600 time steps) and you want to create 
+  a climatology and then look at the monthly anomalies. First, set the time range 
+  for 1 to 12, to span a complete year. Second, define the variable "sstclim" 
+  which will contain the January mean in the first time step, the February mean 
+  in the second time set, etc. Then use 'modify' to turn 'sstclim' into a climatological 
+  variable. This means that the calendar year associated with 'sstclim' (the first 
+  year in the original sst data set) becomes a wild card. Then you can define 
+  the anomaly by subtracting the climatology from the original time series. The 
+  commands are as follows: </p>
+<p class="code"> 'set t 1 12'<br>
+  'define sstclim = ave(sst, t+0, t=600, 12)'<br>
+  'modify sstclim seasonal'<br>
+  'set t 1 last'<br>
+  'define anom = sst - sstclim'<br>
+</p>
diff --git a/doc/gradcomdopen.html b/doc/gradcomdopen.html
new file mode 100644
index 0000000..5041e0f
--- /dev/null
+++ b/doc/gradcomdopen.html
@@ -0,0 +1,47 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: open</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>open</b></h2>
+<p>
+<code>open <i>filename</i></code>
+<p>
+Opens <code><i>filename</i></code>, which should be the name of a
+GrADS data descriptor file, also called a control file.
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>The standard file extension for Grads data descriptor files is
+<code>.ctl</code>. Provided you adhere to this standard, there is no
+need to type the extension <code>.ctl</code> when issuing the
+<code>open</code> command.
+<p>
+<li>You will need to open at least one data-descriptor file before
+you can enter other GrADS commands.
+<p>
+<li>You can open more than one data-descriptor file.   Each file is
+numbered according to the order in which it was opened.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+<p>
+<code>
+open jandata.1966<br>
+open jandata.1966.ctl
+</code>
+</ul><p>
+
+<p>
+Both of these commands will have the same effect -- opening the GrADS
+data descriptor file <code>"jandata.1966.ctl"</code>.
+
+
+</body>
+</html>
diff --git a/doc/gradcomdoutxwd.html b/doc/gradcomdoutxwd.html
new file mode 100644
index 0000000..5f634bf
--- /dev/null
+++ b/doc/gradcomdoutxwd.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: outxwd</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style></head>
<body text="#000000">

<h2><b>outxwd</b></h2>

<p>
<p>
This command dumps the contents of the graphics window to a file. The output file is in XWD (X Windows Dump) format. The syntax is: 

<ul><code>outwxd <i>filename</i></code></ul>

<p>
where <code><i>filename</i></code> is the name of the XWD file. 

<p>
<h3>Usage Notes</h3>

<p>
The  <code><a href="gradcomdprintim.html">printim</a></code> command may also be used for creating image output  in other  formats. 
<p>
<h3>Examples </h3>
<p> </p>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdprint.html b/doc/gradcomdprint.html
new file mode 100644
index 0000000..89b5045
--- /dev/null
+++ b/doc/gradcomdprint.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<h2>print</h2>
<p><code>print <em><fname></em> </code></p>
<p>If a GrADS metafile has already been opened with the <code><a href="gradcomdenableprint.html">enable print</a></code> command, then the <code>print</code> command copies the contents of the current display into the metafile. </p>
<p>If a GrADS metafile is not open, then the <code>print</code> command will create an encapsulated postscript (EPS) file based on the contents of the current display. The optional argument <code><em>fname</em></code> is the output filename (<code>grads.eps</code> by default).  </p>
<p>
<h3>Usage Notes</h3>
<p>For additional guidance on how to use the print command to create a GrADS metafile, see the notes in the documentation page for <code><a href="gradcomdenableprint.html">enable print</a></code>.</p>
<p>Using the <code>print</code> command without opening a metafile first is essentially a quick shortcut for creating an EPS file from within GrADS. It allows the user to skip the steps of creating the GrADS metafile and invoking the external utility <code><a href="gradutilgxeps.html">gxeps</a></code>. However, using this shortcut means there can only be one image per file, and none of the options available when invoking <code><a href="gradutilgxeps.html">gxeps</a></code> directly can be  [...]
<h3> </h3>
\ No newline at end of file
diff --git a/doc/gradcomdprintim.html b/doc/gradcomdprintim.html
new file mode 100644
index 0000000..151110f
--- /dev/null
+++ b/doc/gradcomdprintim.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Commands: printim</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>printim</b></h2>
<p>
The <code>printim</code> command will produce a PNG, GIF, or JPG formatted
image file based on the current contents of the metabuffer, which is
usually the stuff displayed on the screen, minus any widgets.  The
syntax is:

<p>
<ul>
  <code>printim <i>filename options</i></code> 
</ul>

<p>
where: 
<p>
<ul>
  <code><i>filename:</i>  </code>The name of the output file. If this 
  file exists, it will be replaced. 
  <br>
  <code>            </code>If the filename ends with ".png" or ".PNG" then GrADS will automatically create the image in PNG format<br>
  <code>           </code>If the filename ends with ".gif" or ".GIF" then GrADS will automatically create the image in GIF format<br>
  <code>           </code>If the filename ends with ".jpg" or ".JPG" then GrADS will automatically create the image in JPEG format<br>
  <p> <code><i>options:</i>   png </code> 
    - produce PNG output (default)<br>
    <code>           gif </code>
     - produce GIF output <br>
    <code>           jpg </code>
     - produce JPEG output <br>
    <code>           black </code>
     - use black background (default is current display setting)<br>
    <code>           white </code>
     - use white background (default is current display setting)<br>
    <code>           xNNN </code> 
    - horizontal size in NNN pixels<br>
    <code>           yNNN </code> 
    - vertical size in NNN pixels<br>
    <code>           -t NN </code> 
    - color number NN is transparent<br>
    <code>           -b <i>bgImage</i> </code> 
    - Image file <code><i>bgImage</i></code> s included in the background of the output. <br>
    <code>           -f <i>fgImage</i> </code> 
    - Image file <code><i>fgImage</i></code> is included in the foreground of the output.<br>
  </p>
</ul>
<p> One or more <code><i>options</i></code> may be given in any order. <code><i>bgImage</i></code> 
  and <code><i>fgImage</i></code> must be PNG format. 
<p>
<h3>Usage Notes</h3>

<ol>
<li><code>printim</code> works with GrADS version 1.8 (or higher). 
<li><code>printim</code> can be used while in batch mode. 
<li>The option for JPEG formatted output became 'official' with version 2.0.a5. 
</ol>

<p>
<h3>Examples </h3>

<p>
The following command produces a 1000x800 PNG image into file out.png:
<p>
<ul><code>printim out.png x1000 y800</code></ul>

<p>
This command produces a 800x600 GIF image, with a white background, 
into file gifimage.out:
<p>
<ul>
  <p><code>printim gifimage.out gif x800 y600 white</code></p>
</ul>
  
<p>This command produces a GIF image with transparent color 0 and a background 
  image mybkg.png. This means that in image.gif, the background image mybkg.png 
  will be seen wherever the color 0 (background) appeared in the current display. 
</p>
<ul>
  <p><code>printim image.gif -b mybkg.png -t 0 </code><br>
  
</ul>  

</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdqattr.html b/doc/gradcomdqattr.html
new file mode 100644
index 0000000..7723403
--- /dev/null
+++ b/doc/gradcomdqattr.html
@@ -0,0 +1,122 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>GrADS Command: query attr</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="e0f0ff">
+<h2><b>q attr</b></h2>
+<p>
+<code>q attr <i><fnum></i></code>
+<p>
+<p class="plaintext"> This command returns all the attribute metadata associated 
+  with file number <code><i>fnum</i></code> in a formatted manner. If no value 
+  for <code><i>fnum</i></code> is given, then the attributes for the default file 
+  are returned. The output of 'q attr' may be read by the user in the command 
+  window, or parsed by a script for the purpose of capturing the metadata and 
+  including it in the analysis or display. There are three categories of attributes: 
+  (1) global, which means the attribute is relevant for all the data in the file, 
+  (2) coordinate, which means the attribute describes one of the four dimensions 
+  (lon, lat, lev, or time), or (3) variable, which means the attribute is assoicated 
+  with a particular variable in the file. The formatting of the attribute listing 
+  is as follows: 
+<p class="plaintext">global | <em><dimension></em> | <em><varname>   <attribute_type>   
+  <attribute_name>   <attribute_value></em> 
+<p class="plaintext"><em><dimension></em> is "lon", "lat", 
+  "lev", or "time"<br>
+  <em><varname> </em>is one of the variables in the data set<br>
+  <br>
+  <em><attribute_type></em> is one of the following case-sensitive types: 
+  String, Byte, Int16, UInt16, Int32, UInt32, Float32, Float64.<em><br>
+  <attribute_name></em> is any single word or string with no spaces<br>
+  <em><attribute_value></em> is be any string up to 512 characters. 
+<h3>Usage Notes</h3>
+<p class="plaintext">Attributes may be native to the data file (as with some HDF 
+  and NetCDF files), but they may be also be added manually in the GrADS <a href="descriptorfile.html#ATTR">descriptor 
+  file</a>. The output from 'q attr' will print all the attributes taken from 
+  the descriptor file followed by all the native attributes. Within these two 
+  categories (descriptor and native), attributes are listed in the following order:<br>
+  1. Global <br>
+  2. Coordinate -- these will have names "lon", "lat", "lev", 
+  or "time"<br>
+  3. Variable -- these will have names taken from the list of variables in the 
+  data file 
+<p class="plaintext">This command has been fully implemented starting with version 
+  1.9b4. 
+<h3>Examples</h3>
+<p>Here's a sample descriptor file (note the attributes added after the ENDVARS 
+  statement): </p>
+<p>dset ^hgt.%y4.nc<br>
+  dtype netcdf <br>
+  options template yrev<br>
+  title NCEP Reanalysis<br>
+  undef -999 missing_value<br>
+  unpack scale_factor add_offset<br>
+  xdef 144 linear 0 2.5<br>
+  ydef 73 linear -90 2.5<br>
+  zdef 17 levels 1000 925 850 700 600 500 400 300 250 200 150 100 70 50 30 20 
+  10<br>
+  tdef 730 linear 00Z01JAN1989 1dy<br>
+  vars 1<br>
+  hgt 17 t,z,y,x Mean Daily Geopotential height [m]<br>
+  ENDVARS<br>
+  @ global String comment This is an all-purpose test file<br>
+  @ hgt String comment This describes variable hgt<br>
+  @ lev String units millibar<br>
+  @ lat String units degrees_north<br>
+  @ lon String units degrees_east<br>
+  @ time String units hours since 1-1-1 00:00:0.0<br>
+  @ lev Float32 actual_range 1000. 10.<br>
+  @ lat Float32 actual_range 90. -90.<br>
+  @ lon Float32 actual_range 0. 357.5<br>
+  @ time Int32 actual_range 17426496. 17435232.<br>
+</p>
+<p>Here's the output from 'q attr' when the above descriptor file is opened: </p>
+<p class="plaintext">ga-> q attr<br>
+  Descriptor Attributes for File 1 : NCEP Reanalysis <br>
+  global String comment This is an all-purpose test file <br>
+  lon String units degrees_east <br>
+  lon Float32 actual_range 0. 357.5 <br>
+  lat String units degrees_north <br>
+  lat Float32 actual_range 90. -90. <br>
+  lev String units millibar <br>
+  lev Float32 actual_range 1000. 10. <br>
+  time String units hours since 1-1-1 00:00:0.0 <br>
+  time Int32 actual_range 17426496. 17435232. <br>
+  hgt String comment This describes variable hgt 
+<p class="plaintext">Native Attributes for File 1 : NCEP Reanalysis <br>
+  global String title mean daily NMC reanalysis<br>
+  global Int16 base_date 1989 1 1 <br>
+  global String history /home/hoop/crdc/cpreanjuke2farm/cpreanjuke2farm Wed Oct 
+  18 03:10:49 1995 from hgt.89.nc <br>
+  global String history created 95/02/06 by Hoop (netCDF2.3)<br>
+  global String description Data is from NMC initialized reanalysis <br>
+  global String description (4x/day). It consists of most variables interpolated 
+  to <br>
+  global String description pressure surfaces from model (sigma) surfaces.<br>
+  global String platform Model<br>
+  global String Conventions COARDS<br>
+  hgt String long_name mean Daily Geopotential height<br>
+  hgt Float32 actual_range -522 32306 <br>
+  hgt Float32 valid_range -700 35000 <br>
+  hgt String units m<br>
+  hgt Float32 add_offset 32066 <br>
+  hgt Float32 scale_factor 1 <br>
+  hgt Int16 missing_value 32766 <br>
+  hgt Int16 precision 0 <br>
+  hgt Int16 least_significant_digit 0 <br>
+  hgt Int16 GRIB_id 7 <br>
+  hgt String GRIB_name HGT<br>
+  hgt String var_desc Geopotential height <br>
+  hgt String var_desc H<br>
+  hgt String dataset NCEP Reanalysis Daily Averages <br>
+  hgt String dataset AJ<br>
+  hgt String level_desc Multiple levels <br>
+  hgt String level_desc F<br>
+  hgt String statistic Mean 
+<p class="plaintext"> 
+</body>
+</html>
diff --git a/doc/gradcomdqdbf.html b/doc/gradcomdqdbf.html
new file mode 100644
index 0000000..b941046
--- /dev/null
+++ b/doc/gradcomdqdbf.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: query dbf</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>q  dbf</B></H2>
<P>
<code>q  dbf <i>shapefile </i></code>
<p>
Lists the contents of a shapefile attribute database. 
  <code><i>shapefile</i> </code>is the name of the shapefile.  It is not necessary to include the file extension (.dbf) on the end of <code><i>shapefile</i></code>, just the filename root is adequate.<br>
  <codoe>
  <br>
<h3>Usage Notes</h3>
<p>This command is available with GrADS version 2.0.a8 or later.</p>
<p>If you put the three shapefile components  (*.shp, *.shx, and *.dbf) in the GrADS data directory (pointed to by the <a href="gradcomdgrads.html#env">GADDIR environment variable</a>), then it is not necessary to include the full path in <code><i>shapefile</i></code>. </p>
<p>The first line of output contains a comma-delimited list of the names of all the attributes for each record in the database. Subsequent lines contain the comma-delimited list of all the attribute values for each record. </p>
<p>A companion command, <code><a href="gradcomdqdbf.html">q shp</a></code>, lists the contents of the shapefile. There is a 1:1 correspondence between elements in the shapefile and records in the database. </p>
<p>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more details. </p>
<h3>Examples </h3>
<pre>ga-> q dbf /home/GIS/climatedivs/divisions <br>
RECORD#,AREA,PERIMETER,CLIMDIVS_,ST,DIV,NAME,DIVISION_I<br>
0,4.463,11.489,2,MN,2,NORTH CENTRAL,2102<br>
1,0.988,9.344,3,WA,3,PUGET SOUND LOWLANDS,4503<br>
2,3.066,16.450,4,WA,4,E OLYMPIC CASCADE FOOTHILLS,4504<br>
3,3.099,12.733,5,WA,6,EAST SLOPE CASCADES,4506<br>
4,2.030,8.359,6,WA,7,OKANOGAN BIG BEND,4507<br>
5,1.347,5.964,7,ID,1,PANHANDLE,1001
.<br>.<br>.<br>385,0.958,5.437,59,OR,4,NORTHERN CASCADES,3504<br>386,2.712,9.973,49,OR,6,NORTH CENTRAL,3506</pre>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdqdialog.html b/doc/gradcomdqdialog.html
new file mode 100644
index 0000000..b0f0a35
--- /dev/null
+++ b/doc/gradcomdqdialog.html
@@ -0,0 +1,80 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: q dialog</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>q dialog</b></h2>
+<p>
+<code>q dialog <i><x y w h> dialog_text</i></code>
+<p>
+Launches a dialog box widget that prompts for text or numeric data entry and also
+provides editing of an input text or value. Returns the text entered by the user.
+<p>
+<ul>
+<code><i>x</i>&nbsp&nbsp&nbsp&nbsp</code>X-coordinate of diaglog box center <br>
+<code><i>y</i>&nbsp&nbsp&nbsp&nbsp</code>Y-coordinate of diaglog box center <br>
+<code><i>w</i>&nbsp&nbsp&nbsp&nbsp</code>width of diaglog box <br>
+<code><i>h</i>&nbsp&nbsp&nbsp&nbsp</code>width of diaglog box <br>
+</ul>
+<p>
+There are two options for the formatting of <code><i>dialog_text</i></code>:
+<p>
+<ul>
+<code><i>prompt</i></code>
+<ul>
+The prompt string provides an instruction to the user (e.g.,
+"<code>Enter value for PI:</code>"). If
+<code><i>dialog_text</i></code> contains only a prompt, then the
+dialog box appears with the prompt and an empty entry point.
+</ul>
+<code><i>prompt</i> | <i>initial_string</i></code> <br>
+<code><i>prompt</i> / <i>initial_string</i></code>
+<ul>
+It is possible to give the user a head start or a suggestion as to
+what to type in the dialog box. For this option, 
+<code><i>dialog_text</i></code> contains a prompt and an initial
+string separated by a vertical bar or a backslash (e.g., "<code>Enter
+value for PI: | 3.14159</code>" or "<code>Enter value for PI: /
+3.14159</code>"). The dialog box appears with the prompt and the
+editable initial string at the entry point.
+</ul>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>The string input by the user is returned when the Enter/Return key is pressed. 
+Null text entries are accepted.  
+<p>
+<li>The x,y,w, and h arguments are optional. GrADS will use the default
+settings if they are omitted entirely or set to -1. If w and h are set
+to 0, a minimum sized window is drawn to contain just the 
+<code><i>dialog_text</i></code>.
+<p>
+<li>The cursor must be inside the dialog box to allow text entry or editing
+to occur. 
+<p>
+<li>All text is centered in the dialog box. If
+the new text exceeds the window size, the text will be right
+justified in the window; the left and right arrow keys can be used to
+scroll the text back and forth. 
+<p>
+<li>See the <a href="gradcomdsetdialog.html"><code>set
+dialog</code></a> refrence page for details on controlling the
+color properties of the dialog box widget.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<p>
+<pre>
+set dialog 1 0 5 1 6
+q dialog Hello World
+say result
+</pre>
+
+</body>
+</html>
diff --git a/doc/gradcomdqens.html b/doc/gradcomdqens.html
new file mode 100644
index 0000000..976b5a1
--- /dev/null
+++ b/doc/gradcomdqens.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: q ens</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>q ens</b></h2>
<p><code>q ens</code>
<p>This command returns information about the ensemble dimension. For each ensemble member, 
the printout includes the index number, ensemble name, length (number of time steps), start time in date format, time axis index of start time, and grib2 codes, if present.
<h3>Usage Notes</h3>
<p>This command is  available in GrADS v2.0.</p>
<h3>Example</h3>
<code>
<p>ga-> q ens<br>
  Ensemble 1 named avg has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=0<br>
  Ensemble 2 named c00 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=1,0<br>
  Ensemble 3 named p01 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,1<br>
  Ensemble 4 named p02 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,2<br>
  Ensemble 5 named p03 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,3<br>
  Ensemble 6 named p04 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,4<br>
  Ensemble 7 named p05 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,5<br>
  Ensemble 8 named p06 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,6<br>
  Ensemble 9 named p07 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,7<br>
  Ensemble 10 named p08 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,8<br>
  Ensemble 11 named p09 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,9<br>
  Ensemble 12 named p10 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,10<br>
  Ensemble 13 named p11 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,11<br>
  Ensemble 14 named p12 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,12<br>
  Ensemble 15 named p13 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,13<br>
  Ensemble 16 named p14 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,14<br>
  Ensemble 17 named p15 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,15<br>
  Ensemble 18 named p16 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,16<br>
  Ensemble 19 named p17 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,17<br>
  Ensemble 20 named p18 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,18<br>
  Ensemble 21 named p19 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,19<br>
Ensemble 22 named p20 has 31 timesteps and begins at 00Z01MAY2009 (t=1) grbcode=3,20</p>
</code><p>
<h3> </h3>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdqfile.html b/doc/gradcomdqfile.html
new file mode 100644
index 0000000..7a3b78d
--- /dev/null
+++ b/doc/gradcomdqfile.html
@@ -0,0 +1,91 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: q pos</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>q pos</b></h2>
+<p>
+After this command is issued, GrADS waits for user's mouse click, then
+returns the coordinates of the mouse click plus additional
+information. It is the returned information that makes '<code>q
+pos</code>' such a powerful command especialy when used in conjunction
+with the different 'classes' of widgets: buttons, rubber bands, and
+dropmenus.  Here is a template of the information that '<code>q
+pos</code>' returns after a mouse click (note the difference in output
+between the different widget classes):
+
+<p> <code>Position = <i>xpos ypos mbtn class </i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> 
+  (somewhere in the graphics window) <br>
+<code>Position = <i>xpos ypos mbtn class widget# btnstate</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> (for buttons) <br>
+<code>Position = <i>xpos ypos mbtn class widget# xpos2 ypos2</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> (for rbands) <br>
+<code>Position = <i>xpos ypos mbtn class widget# menuitem <casc# cascitem></i>&nbsp</code> (for dropmenus) <br>
+
+<p>
+where:
+<ul>
+<code><i>xpos, ypos</i>&nbsp&nbsp&nbsp&nbsp</code>
+- coordinates of the mouse click in virtual page units <br>
+
+<code><i>mbtn</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- either 1, 2, or 3 for the left, center, or right mouse button <br>
+
+<code><i>class</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- either 1, 2, 3, or 0 for button, rband, dropmenu, or 'not a widget' <br>
+
+<code><i>widget#</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- the number assigned to the widget when it was originally set up <br>
+
+<code><i>btnstate</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- either 0 (meaning "off") or 1 (meaning "on") <br>
+
+<code><i>xpos2, ypos2</i>&nbsp&nbsp</code>
+- coordinates of the mouse release point in virtual page units <br>
+
+<code><i>menuitem</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- the item number selected from the menu list <br>
+
+<code><i>casc#</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- the cascade menu number selected from the dropmenu list <br>
+
+<code><i>cascitem</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+- the item number selected from the cascade menu <br>
+
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If the user did not click on a widget, then
+<code><i>class</i></code> will be 0 and there will be no further
+output.
+<p>
+<li>If the user clicks on a dropmenu but no menu item is selected,
+then <code><i>widget#</i></code> and <code><i>menuitem</i></code>
+will both be -1.
+<p>
+<li>There can be up to three levels of nested cascading dropmenus launched
+from the main dropmenu. In other words, <code><i>casc#</i></code> and <code><i>cascitem</i></code> will
+repeat up to three times in the output from '<code>q pos</code>'. 
+<p>
+<li>
+The following reference pages contain information on configuring and drawing the widgets:<br>
+<a href="gradcomdsetbutton.html"><code>set button</code></a> <br> 
+<a href="gradcomddrawbutton.html"><code>draw button</code></a> <br> 
+<a href="gradcomdredrawbutton.html"><code>redraw button</code></a> <br>
+<a href="gradcomdsetrband.html"><code>set rband</code></a> <br>
+<a href="gradcomdsetdropmenu.html"><code>set dropmenu</code></a> <br>
+<a href="gradcomddrawdropmenu.html"><code>draw dropmenu</code></a>
+</ol>
+<p>
+<h3>Examples </h3>
+<p>
+See the section of the User's Guide on <a href="script.html#widgets">widgets</a>
+for plenty of script examples showing how to use 'q pos'. 
+
+</body>
+</html>
+
+
diff --git a/doc/gradcomdqfwrite.html b/doc/gradcomdqfwrite.html
new file mode 100644
index 0000000..2872dcc
--- /dev/null
+++ b/doc/gradcomdqfwrite.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: q fwrite</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>q fwrite</b></h2>
<p>
This command returns information on the status of the <code>fwrite</code> options:
<ol>
<li>Whether the <code>fwrite</code> file is open or closed
<li>The name of the <code>fwrite</code> file
<li>The byte ordering set for <code>fwrite</code> 
<li>The byte ordering for the machine
<li>The output undef value
</ol>
<p>
<h3>Usage Notes</h3>
<p>
The commands to set or change the <code>fwrite</code> options are 
<code><a href="gradcomdsetgxout.html">set gxout fwrite</a></code>, 
<code><a href="gradcomdsetfwrite.html">set fwrite</a></code>, and 
<code><a href="gradcomddisablefwrite.html">disable fwrite</a></code>.

<p>
<h3>Examples </h3>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdqpos.html b/doc/gradcomdqpos.html
new file mode 100644
index 0000000..4fcbdf8
--- /dev/null
+++ b/doc/gradcomdqpos.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: q pos</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>q pos</b></h2>
<p><code>q pos <nowait> </code></p>
<p> After this command is issued, GrADS waits for user's mouse click, then returns 
  the coordinates of the mouse click plus additional information. If the <code>nowait</code> 
  argument is used, then GrADS will query the mouse without waiting for a mouse 
  click. The returned information makes '<code>q pos</code>' such a powerful command 
  especialy when used in conjunction with the different 'classes' of widgets: 
  buttons, rubber bands, and dropmenus. Here is a template of the information 
  that '<code>q pos</code>' returns after a mouse click (note the difference in 
  output between the different widget classes): 
<p> <code>Position = <i>xpos ypos mbtn class </i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> 
  (somewhere in the graphics window) <br>
<code>Position = <i>xpos ypos mbtn class widget# btnstate</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> (for buttons) <br>
<code>Position = <i>xpos ypos mbtn class widget# xpos2 ypos2</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code> (for rbands) <br>
<code>Position = <i>xpos ypos mbtn class widget# menuitem <casc# cascitem></i>&nbsp</code> (for dropmenus) <br>

<p>
where:
<ul>
<code><i>xpos, ypos</i>&nbsp&nbsp&nbsp&nbsp</code>
- coordinates of the mouse click in real page units <br>

<code><i>mbtn</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- either 1, 2, or 3 for the left, center, or right mouse button <br>

<code><i>class</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- either 1, 2, 3, or 0 for button, rband, dropmenu, or 'not a widget' <br>

<code><i>widget#</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- the number assigned to the widget when it was originally set up <br>

<code><i>btnstate</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- either 0 (meaning "off") or 1 (meaning "on") <br>

<code><i>xpos2, ypos2</i>&nbsp&nbsp</code>
- coordinates of the mouse release point in virtual page units <br>

<code><i>menuitem</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- the item number selected from the menu list <br>

<code><i>casc#</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- the cascade menu number selected from the dropmenu list <br>

<code><i>cascitem</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
- the item number selected from the cascade menu <br>

</ul>

<p>
<h3>Usage Notes</h3>
<ol>
<li>If the user did not click on a widget, then
<code><i>class</i></code> will be 0 and there will be no further
output.
<p>
<li>If the user clicks on a dropmenu but no menu item is selected,
then <code><i>widget#</i></code> and <code><i>menuitem</i></code>
will both be -1.
<p>
<li>There can be up to three levels of nested cascading dropmenus launched
from the main dropmenu. In other words, <code><i>casc#</i></code> and <code><i>cascitem</i></code> will
repeat up to three times in the output from '<code>q pos</code>'. 
<p>
<li>
The following reference pages contain information on configuring and drawing the widgets:<br>
<a href="gradcomdsetbutton.html"><code>set button</code></a> <br> 
<a href="gradcomddrawbutton.html"><code>draw button</code></a> <br> 
<a href="gradcomdredrawbutton.html"><code>redraw button</code></a> <br>
<a href="gradcomdsetrband.html"><code>set rband</code></a> <br>
<a href="gradcomdsetdropmenu.html"><code>set dropmenu</code></a> <br>
<a href="gradcomddrawdropmenu.html"><code>draw dropmenu</code></a>
</ol>
<p>
<h3>Examples </h3>
<p>
See the section of the User's Guide on <a href="script.html#widgets">widgets</a>
for plenty of script examples showing how to use 'q pos'. 

</body>
</html>


\ No newline at end of file
diff --git a/doc/gradcomdqsdfwrite.html b/doc/gradcomdqsdfwrite.html
new file mode 100644
index 0000000..a34e6ca
--- /dev/null
+++ b/doc/gradcomdqsdfwrite.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: q sdfwrite</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>q sdfwrite</b></h2>
<p><code>q sdfwrite</code>
<p>This command returns information on the status of the <code>sdfwrite</code> options:
<ol>
<li>The name of the <code>sdfwrite</code> output file
<li>The format of the output file
  <br>
 <li>The output file's chunk dimensions, if the format is compressed. 
 <li>The output undef value
<li>Any attributes that have been set by the user 
</ol>
<p>
<h3>Usage Notes</h3>
<li>This command is  available in GrADS v2.0.a3 or higher.
<li>The command to create the self-describing  file is <code><a href="gradcomdsdfwrite.html">sdfwrite</a></code>.
<li>The command to set or change the self-describing output filename is <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code>. 
<li>The command to set attributes for the self-describing file is  <code><a href="gradcomdsetsdfattr.html">set sdfattr</a></code>. 
<li>The <code><a href="gradcomdreset.html">reset</a></code> command will reset the sdfwrite filename to the default and release all the attributes. To do this without resetting all the other user-specified options, use  the <code><a href="gradcomdclear.html">clear sdfwrite</a></code> command.</li>

<li>Please see the documentation on <a href="compression.html">compression</a> for  more details. </li>
<p>
<h3> </h3>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdqshades.html b/doc/gradcomdqshades.html
new file mode 100644
index 0000000..7ed316b
--- /dev/null
+++ b/doc/gradcomdqshades.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: query shades</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>q  shades</B></H2>
<P>
<code>q  shades<i> </i></code>
<p>
Lists the colors and levels of shaded plots.This command takes no arguments. <br>
  <codoe>
  <br>

<p> </p>
<h3>Examples</h3>
<pre>ga-> set gxout shaded
ga-> d t2m<br>Contouring: 220 to 300 interval 10 <br>ga-> q shades<br>Number of levels = 10<br>9 <= 220<br>14 220 230<br>4 230 240<br>5 240 250<br>13 250 260<br>10 260 270<br>7 270 280<br>8 280 290<br>2 290 300<br>6 300 ></pre>


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdqshp.html b/doc/gradcomdqshp.html
new file mode 100644
index 0000000..b8b3d40
--- /dev/null
+++ b/doc/gradcomdqshp.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: query shp</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>q  shp</B></H2>
<P>
<code>q  shp <i>shapefile </i></code>
<p>
Lists the contents of a shapefile. 
  <code><i>shapefile</i> </code>is the name of the shapefile. It is not necessary to include the file extension (.shp) on the end of <code><i>shapefile</i></code>, just the filename root is adequate.<br>
  <codoe>
  <br>
<h3>Usage Notes</h3>
<p>This command is available with GrADS version 2.0.a8 or later.</p>
<p> If you put the three shapefile components  (*.shp, *.shx, and *.dbf) in the GrADS data directory (pointed to by the <a href="gradcomdgrads.html#env">GADDIR environment variable</a>), then it is not necessary to include the full path in <code><i>shapefile</i></code>. </p>
<p>The first line of output contains the shapefile type, the number of shapes in the file, and the X and Y bounds of actual extent of the shapes in the file. Subsequent lines list information about each shape element in the file: the identification number, the shape type, the number of parts, the number of vertices, and the bounds of the shape in the X, Y, Z, and M (measure) dimesions. The current GrADS interface ignores the Z or M values of a shape, only it's position in X,Y (lon,lat) sp [...]
<p>A companion command, <code><a href="gradcomdqdbf.html">q dbf</a></code>, lists the attribute database entries for each element in the shapefile. There is a 1:1 correspondence between elements in the shapefile and records in the database. </p>
<p>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more details. </p>
<p> </p>
<h3>Examples </h3>
<pre>ga-> q shp /home/GIS/climatedivs/divisions<br>
Shapefile Type=Polygon #Shapes=387 XBounds=-124.761:-66.95 YBounds=24.545:49.385
0:  Polygon  parts=1  vertices=51  XBounds=-95.602:-93.056  YBounds=46.285:49.385  ZBounds=0:0  MBounds=0:0
1:  Polygon  parts=1  vertices=88  XBounds=-123.081:-121.919  YBounds=46.621:49.002  ZBounds=0:0  MBounds=0:0
2:  Polygon  parts=1  vertices=135  XBounds=-123.773:-121.207  YBounds=45.548:49.002  ZBounds=0:0  MBounds=0:0 
3:  Polygon  parts=1  vertices=91  XBounds=-121.611:-119.484  YBounds=45.681:49.001  ZBounds=0:0  MBounds=0:0 
4:  Polygon  parts=1  vertices=36  XBounds=-120.46:-117.558  YBounds=47.149:49.001  ZBounds=0:0  MBounds=0:0 
5:  Polygon  parts=1  vertices=25  XBounds=-117.041:-116.048  YBounds=47.006:49.001  ZBounds=0:0  MBounds=0:0
.
.
.
385:  Polygon  parts=1  vertices=46  XBounds=-122.513:-121.659  YBounds=43.551:45.647  ZBounds=0:0  MBounds=0:0
386:  Polygon  parts=1  vertices=67  XBounds=-121.946:-118.222  YBounds=44.771:46.001  ZBounds=0:0  MBounds=0:0
</pre>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdqshpopts.html b/doc/gradcomdqshpopts.html
new file mode 100644
index 0000000..652be4c
--- /dev/null
+++ b/doc/gradcomdqshpopts.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS command: query shpopts</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>q  shpopts</B></H2>
<P>
<code>q  shpopts<i> </i></code>
<p>
Lists the current settings for drawing and writing out shapefiles.<br>
  <codoe>
  <br>
<h3>Usage Notes</h3>
<p>This command is available with GrADS version 2.0.a9 or later.</p>
<p>The <code><a href="gradcomdclear.html">clear shp</a></code> command releases all user-defined shapefile attributes from memory, and resets the  output filename root and shapefile type to their default values. The <code><a href="gradcomdreset.html">reset</a></code> and <code><a href="gradcomdreinit.html">reinit</a></code> commands will do the same thing -- use <code><a href="gradcomdclear.html">clear shp</a></code> if you do not want to reset all the other user settings. </p>
<p>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more details. </p>
<p> </p>
<h3>Examples </h3>
<p>This example shows the default values: <br>
<pre>ga-> <a href="gradcomdreinit.html">reinit</a>
ga-> <a href="gradcomdqshpopts.html">q shpopts</a>
Settings for drawing shapefiles:
 polygon fill color: -1 
 mark type: 3 
 mark size: 0.05 
Settings for writing shapefiles:
 output filename root: grads
 output type: line
 format string: %12.6f
</pre>

<p>This example shows how to set and query shapefile options: <br>
<pre>ga-> <a href="gradcomdsetshpopts.html">set shpopts</a> 15
ga-> <a href="gradcomdsetshp.html">set shp</a> -pt -fmt 8 4 pointshp
ga-> <a href="gradcomdsetshpattr.html">set shpattr</a> Author string JMA
ga-> <a href="gradcomdsetshpattr.html">set shpattr</a> Date string 2010-05-23 
ga-> <a href="gradcomdsetshpattr.html">set shpattr</a> pi double 3.14159
ga-> <a href="gradcomdqshpopts.html">q shpopts</a>
Settings for drawing shapefiles:
 polygon fill color: 15 
 mark type: 3 
 mark size: 0.05 
Settings for writing shapefiles:
 output filename root: pointshp
 output type: point
 format string: %8.4f
 attributes:
  Author: JMA
  Date: 2010-05-23
  pi: 3.1416  
</pre>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdquery.html b/doc/gradcomdquery.html
new file mode 100644
index 0000000..f521cd3
--- /dev/null
+++ b/doc/gradcomdquery.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: query</title>
<link rel="stylesheet" href="GrADS.css">
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>query</b></h2>
<p class="plaintext"> The <code class="code">query</code> command allows the user 
  to get information about a variety of aspects of the current GrADS session. 
  Configuration, plot characteristics, graphics specifics, and file structure 
  are some examples. The use of <code class="code">query pos</code> combined with 
  the coordinate transformations is the basis of many interactive applications 
  with buttons and drop menus. The <code class="code">query</code> command may 
  be shortened to simply <code class="code">q</code>. The syntax is: 
<p>
<ul>
  <code class="code">query <i><option></i></code><br>
  or<br>
  <code class="code">q <i><option></i></code> 
</ul>
<p class="plaintext"> When given without an <code><i class="codeitalic">option</i></code>, 
  the <code class="code">query</code> command returns a list of the possible options. 
  These are: 
<blockquote>


  <table width="609" border="0" cellspacing="0" cellpadding="0">
    <tr> 
      <td class="code"><a href="gradcomdqattr.html">attr</a> <span class="codeitalic">n</span></td>
      <td class="plaintext">Returns all attributes for file n (or default file 
        if n is omitted)</td>
    </tr>
    <tr>
      <td class="code">cache n</td>
      <td class="plaintext">Returns netcdf4/hdf5 cache size  for file n (or default file 
      if n is omitted) (<span class="style1">2.0.a8+</span>)</td>
    </tr>
    <tr>
      <td class="code">cachesf</td>
      <td class="plaintext">Returns netcdf4/hdf5 cache scale factor (<span class="style1">2.0.a8+</span>)</td>
    </tr>
    <tr>
      <td class="code">calendar</td>
      <td class="plaintext">Returns calendar mode: unset, 365-day, or standard</td>
    </tr>
    <tr> 
      <td class="code" width="119">config</td>
      <td class="plaintext" width="490">Returns GrADS configuration information</td>
    </tr>
    <tr>
      <td class="code">contours</td>
      <td class="plaintext">Returns colors and levels of a line contours (<span class="style1">2.0.a8+</span>)</td>
    </tr>
    <tr> 
      <td class="code" width="119">ctlinfo</td>
      <td class="plaintext" width="490">Returns contents of data descriptor file</td>
    </tr>
    <tr>
      <td class="code"><a href="gradcomdqdbf.html">dbf</a></td>
      <td class="plaintext">Lists the contents of a shapefile attribute database (<span class="style1">2.0.a8+</span>)</td>
    </tr>
    <tr> 
      <td class="code" width="119">define</td>
      <td class="plaintext" width="490">Lists currently defined variables</td>
    </tr>
    <tr> 
      <td class="code" width="119">defval <span class="codeitalic">v1 i j</span></td>
      <td class="plaintext" width="490">Returns the value of defined variable 
        <code><i class="codeitalic">v1</i></code> at point <code><i class="codeitalic">i,j</i></code></td>
    </tr>
    <tr> 
      <td class="code" width="119"><a href="gradcomdqdialog.html">dialog</a> <span class="codeitalic">args</span></td>
      <td class="plaintext" width="490">Launches a dialog box that prompts for 
        text or numeric data entry</td>
    </tr>
    <tr> 
      <td class="code" width="119">dims</td>
      <td class="plaintext" width="490">Returns current dimension environment</td>
    </tr>
    <tr>
      <td class="code"><a href="gradcomdqens.html">ens</a></td>
      <td class="plaintext">Returns ensemble metadata</td>
    </tr>
    <tr> 
      <td class="code" width="119">file <span class="codeitalic">n</span></td>
      <td class="plaintext" width="490">Returns info on file number <code><i>n</i></code></td>
    </tr>
    <tr> 
      <td class="code" width="119">files</td>
      <td class="plaintext" width="490">Lists open files</td>
    </tr>
    <tr> 
      <td class="code" width="119"><a href="gradcomdqfwrite.html">fwrite</a></td>
      <td class="plaintext" width="490">Returns status and characteristics of 
        fwrite ouput file</td>
    </tr>
    <tr> 
      <td class="code" width="119">gxinfo</td>
      <td class="plaintext" width="490">Returns graphics environment info</td>
    </tr>
    <tr>
      <td class="code">gxout</td>
      <td class="plaintext">Returns current gxout settings</td>
    </tr>
    <tr> 
      <td class="code" width="119">lats</td>
      <td class="plaintext" width="490">Returns the status of the GrADS-LATS interface</td>
    </tr>
    <tr> 
      <td class="code" width="119"><a href="gradcomdqpos.html">pos</a></td>
      <td class="plaintext" width="490">Waits for mouse click, then returns position 
        plus additional widget information</td>
    </tr>
    <tr>
      <td class="code"><a href="gradcomdqsdfwrite.html">sdfwrite</a></td>
      <td class="plaintext">Returns the status of the sdfwrite options </td>
    </tr>
    <tr> 
      <td class="code" width="119"><a href="gradcomdqshades.html">shades</a></td>
      <td class="plaintext" width="490">Lists colors and levels of shaded contours</td>
    </tr>
    <tr>
      <td class="code"><a href="gradcomdqshp.html">shp</a></td>
      <td class="plaintext">Lists the contents of a shapefile (<span class="style1">2.0.a8+</span>)</td>
    </tr>
    <tr>
      <td class="code"><a href="gradcomdqshpopts.html">shpopts</a></td>
      <td class="plaintext">Returns  settings for drawing and writing shapefiles (<span class="style1">2.0.a9+</span>)</td>
    </tr>
    <tr> 
      <td class="code" width="119">string str</td>
      <td class="plaintext" width="490">Returns the width of string <code><i>str</i></code> in virtual page inches</td>
    </tr>
    <tr> 
      <td class="code" width="119">time</td>
      <td class="plaintext" width="490">Returns info about time settings</td>
    </tr>
    <tr> 
      <td class="code" width="119">udft</td>
      <td class="plaintext" width="490">Returns the user defined function table </td>
    </tr>
    <tr>
      <td class="code">undef</td>
      <td class="plaintext">Returns the output undefined value</td>
    </tr>
    <tr> 
      <td class="code" width="119">xinfo</td>
      <td class="plaintext" width="490">Returns characteristics of the graphics 
        display window</td>
    </tr>
    <tr> 
      <td class="code" width="119">xy2w<span class="codeitalic">  v1 v2</span></td>
      <td class="plaintext" width="490">Converts XY coords to world coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">xy2gr <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts XY coords to grid coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">w2xy  <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts world coords to XY coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">w2gr  <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts world coords to grid coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">gr2w  <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts grid coords to world coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">gr2xy <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts grid coords to XY coords</td>
    </tr>
    <tr> 
      <td class="code" width="119">pp2xy <span class="codeitalic">v1 v2</span></td>
      <td class="plaintext" width="490">Converts virtual page XY coords to real 
        page XY coords</td>
    </tr>
  </table>
</blockquote>
  <p> <code> </code> <br>
  <p> 
  <h3 class="item12bold">Usage Notes</h3>
  <p class="plaintext"> For more information on the use of the <code>query</code> 
    command, see the section of the User's Guide on <a
href="script.html#commands">commands that complement the scripting language</a>. 
  <p> 
  <h3 class="item12bold">Examples</h3>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdquit.html b/doc/gradcomdquit.html
new file mode 100644
index 0000000..280fda4
--- /dev/null
+++ b/doc/gradcomdquit.html
@@ -0,0 +1,4 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>quit</h2>
+Leaves GrADS
diff --git a/doc/gradcomdredrawbutton.html b/doc/gradcomdredrawbutton.html
new file mode 100644
index 0000000..6c1cf25
--- /dev/null
+++ b/doc/gradcomdredrawbutton.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: redraw button</title></head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>redraw button</b></h2>
<p><code>redraw button <i>num state <flag> <text></i></code></p>
<p><code>0|1</code>

Redraws button number <code><i>num</i></code> to either the <code>"ON"</code> state <code>(1)</code>
or <code>"OFF"</code> state <code>(0)</code>. 
<p>num is the button number, which can be between 1 and 255
<p>state is either 
  <code>"ON"</code> <code>(1)</code> or <code>"OFF"</code><code>(0)</code>. 
<p>
<h3>Usage Notes</h3>
<p>
See <a href="script.html#widgets">widgets</a> for more information on using buttons. 

<p>
<h3>Examples </h3>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdreinit.html b/doc/gradcomdreinit.html
new file mode 100644
index 0000000..0aa84b7
--- /dev/null
+++ b/doc/gradcomdreinit.html
@@ -0,0 +1,27 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: reinit</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>reinit</b></h2>
+
+<P>
+<code>reinit </code>
+
+<p>
+This command returns GrADS to its initial state. It closes all open
+files, releases all defined variables, and resets all graphics
+settings to their defaults.
+
+
+<h3>Usage Notes</h3>
+<p>
+See the section of the <a href="users.html">User's Guide</a> 
+on <a href="reinitialization.html">reinitialization of GrADS</a>.
+
+
+</body>
+</html>
diff --git a/doc/gradcomdreset.html b/doc/gradcomdreset.html
new file mode 100644
index 0000000..9326cdd
--- /dev/null
+++ b/doc/gradcomdreset.html
@@ -0,0 +1,55 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: reset</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<p>
+<h2><b>reset</b></h2>
+<p>
+<code>reset <i><qualifiers></i></code>
+<p>
+This command returns GrADS to its initial state with the following exceptions:
+
+<p>
+<ol>
+<li>No files are closed
+<li>No defined variables are released
+<li>The <a href="gradcomdsetdisplay.html"><code>set display</code></a> settings
+are not modified
+</ol>
+
+<p>
+If files are open, the default file is set to 1, and the
+dimension environment is set to X,Y varying and Z and T set to 1
+(as though file 1 were just opened).
+
+<p>
+The <code>reset</code> command may be qualified so that only certain
+aspects of GrADS are returned to their initial state.
+
+<p>
+The optional <code><i>qualifiers</i></code> are as follows:
+
+<p>
+<ul>
+<code>reset events    </code>
+resets the events buffer (e.g., mouse clicks) <br>
+<code>reset graphics  </code>
+resets the graphics, but not the widgets <br>
+<code>reset hbuff     </code>
+resets the display buffer when in double buffer mode <br>
+<code>reset norset    </code>
+resets the X events only
+</ul>
+
+<h3>Usage Notes</h3>
+<p>
+See the section of the <a href="users.html">User's Guide</a> 
+on <a href="reinitialization.html">reinitialization of GrADS</a>.
+
+
+</body>
+</html>
diff --git a/doc/gradcomdrun.html b/doc/gradcomdrun.html
new file mode 100644
index 0000000..c39513a
--- /dev/null
+++ b/doc/gradcomdrun.html
@@ -0,0 +1,34 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Command: run</title>
+<body>
+
+<H2><B>run</B></H2><P>
+
+<code>run <i>filename &ltarguments&gt</i></code>
+
+<p>
+This command runs the script contained in the named file, which
+generally has a <code>".gs"</code> tag at the end. Optional
+<code><i>arguments</i></code> are passed to the script as a string
+variable.
+
+<H3>Usage Notes</H3><P>
+<p>
+The <code>run</code> command and the <code>".gs"</code> extension may
+be implied. A Grads command such as: 
+<ul><code>run cbar.gs</code></ul>
+
+<p>
+may be simplified to: 
+<ul><code>cbar</code></ul>
+
+<p>
+See the discussion on <a href="script.html#storing">storing Grads
+scripts</a> for further information.
+
+<H3>Examples</H3><P>
+
+</body>
+</html>
diff --git a/doc/gradcomdscreen.html b/doc/gradcomdscreen.html
new file mode 100644
index 0000000..6e5443d
--- /dev/null
+++ b/doc/gradcomdscreen.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set wxopt</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>screen</b></h2>
<p>
<code>screen save|show|free <em>num</em></code>
<p>
This command allows the user to save the contents of the display window into a buffer in memory, and also to restore a saved buffer to the current display at any time. This command will work in double buffer mode and was written to facilitate animations when working interactively with GrADS. The options are as follows:
<p>
<ul>
<code>save</code>
<ul>
  Saves the contents of the display screen into  memory as buffer # 
  <code><em>num</em></code>.
</ul>
<p>
<code>show</code>
<ul>
  Draws the contents of buffer # 
  <code><em>num</em></code> to the screen.
</ul> 
<p>
<code>free</code>
<ul>
  Releases the contents of buffer # 
  <code><em>num</em></code> from memory. 
</ul> 
</ul>

<p>
<h3>Usage Notes</h3>
<p>This command does not work in batch mode. 
<h3>Examples </h3>


</body>
</html>


\ No newline at end of file
diff --git a/doc/gradcomdsdfopen.html b/doc/gradcomdsdfopen.html
new file mode 100644
index 0000000..a372672
--- /dev/null
+++ b/doc/gradcomdsdfopen.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS</title>
<link href="GrADS.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>sdfopen</b></h2>
<p> <span class="plaintext"><code>sdfopen <i>filename <template #timesteps></i></code></span>
<p> 
<p class="plaintext"> Opens a NetCDF or HDF-SDS format file that conforms to the 
  <a href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html" target="_parent">COARDS conventions</a>. The sdfopen command does not support the HDF5 format, but is does support netcdf4. The arguments and options are as follows: 
<p> 
<ul>
  <span class="plaintext"><code><i>filename</i></code> </span> 
  <ul>
    <span class="plaintext"> The name of the COARDS-compliant NetCDF or HDF-SDS 
    file. </span> 
  </ul>
  <span class="plaintext"><code><i>template</i></code> </span> 
  <ul>
    <span class="plaintext"> This optional argument is used when you want to aggregate 
    multiple data files and handle them as if they were one individual file. The 
    individual data files must be identical in all dimensions except time. <code><i>template</i></code> 
    has a similar structure to the substitution template in a GrADS data descriptor 
    file. See <a href="templates.html">Using Templates</a> for details. </span> 
  </ul>
  <span class="plaintext"><code><i>#timesteps</i></code> </span> 
  <ul>
    <span class="plaintext"> This argument must be included whenever <code><i>template</i></code> 
    is invoked. The <code><i>#timesteps</i></code> is the sum of the timestep 
    counts in all the files to be examined, not the count in any one file. </span> 
  </ul>
</ul>
<p> 
<h3>Usage Notes</h3>
<ol>
  <li>The template option with sdfopen was removed in version 2.0. If you want to aggregate multiple files together use the <a href="gradcomdxdfopen.html">xdfopen</a> command with the 'options template" keyword and a complete TDEF entry.  
  <li>Here's a brief summary of the metadata that sdfopen is looking for when it tries to open a self-describing file. As it goes through the list of dimension variables in the file, it checks each one for attributes named "units", "axis", and "grads_dim". Acceptable values for these attributes and the GrADS dimension the coordinate variable maps to are outlined in this table:<br>
    <br>
    <table width="763" border="0">
      <tr>
        <td width="150" bgcolor="cccccc"><div align="center">GrADS Dimension</div></td>
        <td width="603" bgcolor="cccccc"><div align="center">Acceptable Attribute Values</div></td>
      </tr>
      <tr>
        <td bgcolor="b8c8d7"><div align="center">X</div></td>
        <td bgcolor="b8c8d7">units: degrees_east, degree_east, degrees_E, degree_E<br>
          axis: x, X</td>
      </tr>
      <tr>
        <td bgcolor="ccdceb"><div align="center">Y</div></td>
        <td bgcolor="ccdceb">unit: degrees_north, degree_north, degrees_N, degree_N<br>
          axis: y, Y</td>
      </tr>
      <tr>
        <td bgcolor="b8c8d7"><div align="center">Z (pressure)</div></td>
        <td bgcolor="b8c8d7">units: mb, millibar, hybrid_sigma_pressure<br></td>
      </tr>
      <tr>
        <td bgcolor="ccdceb"><div align="center">Z (not pressure)</div></td>
        <td bgcolor="ccdceb">units: sigma_level, degreesk, degrees_k, level, layer, layers<br>
        axis: z, Z</td>
      </tr>
      <tr>
        <td bgcolor="b8c8d7"><div align="center">T</div></td>
        <td bgcolor="b8c8d7">units: yyyymmddhhmmss, yymmddhh, or a Udunits-acceptable time unit<br>
          axis: t, T</td>
      </tr>
      <tr>
        <td bgcolor="ccdceb"><div align="center">E</div></td>
        <td bgcolor="ccdceb">grads_dim: e<br>
          axis: e, E</td>
      </tr>
    </table>
    <br>  
  
  <li>If the sdfopen command fails to open your self-describing file, try using the <a href="gradcomdxdfopen.html"><code>xdfopen</code></a> 
    command which requires a special descriptor file to supplement or override the metadata in the file, or use the <a href="gradcomdopen.html">open</a> command with a <a href="SDFdescriptorfile.html">complete descriptor file</a>. 
</ol>

<p>
<h3>Examples </h3>
<ol>
  <li class="plaintext">If you had daily U-Wind data in two files, <code>uwnd.1989.nc</code> 
    and <code>uwnd.1990.nc</code>, you could access them both as one GrADS data 
    set by entering: 
    <p>
<code>sdfopen /data/uwnd.1989.nc uwnd.%y4.nc 730</code>
<p>
</ol>

</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsdfwrite.html b/doc/gradcomdsdfwrite.html
new file mode 100644
index 0000000..717b446
--- /dev/null
+++ b/doc/gradcomdsdfwrite.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Commands: sdfwrite</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>sdfwrite</b></h2>
<p><code>sdfwrite <i>varname </i></code>
<p>This<code></code> command will write out a defined variable <code><i>varname </i></code>into a NetCDF formatted
  data file.  

<ul>
  <p> </p>
</ul>
<h3>Usage Notes</h3>

<p>
The <code>sdfwrite</code> command was initially implemented in GrADS version <span class="style1">2.0.a3</span>. Additional features added in subsequent releases are as follows:
<ul>
  <li>(<span class="style1">2.0.a5</span>) NetCDF output may be forced to have 4 or 5 dimensions. </li>
  <li>(<span class="style1">2.0.a8</span>) NetCDF output may be floating point or double precision. NetCDF output may also be version 4, with chunking and compression enabled. </li>
  <li>(<span class="style1">2.0.a9</span>) If the output is not forced to have 4 or 5 dimensions, it will have the same number of dimensions as the defined variable being written out to file. </li>
</ul>
<p>Options to control the name and format of the output file are implemented with the <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command. The <a href="gradcomdqsdfwrite.html"><code>q sdfwrite</code></a> command
  returns the status of the <code>sdfwrite</code> options. 

<p>The name of the output file will be <code>grads.sdfwrite.nc</code> unless specified otherwise with the <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command. If the 
file exists, it will be replaced.  It is not possible to append variables to an existing file.  
<p>The dimensions of the variable written to file correspond to the dimension environment that is set when the variable is  defined. The dimension environment that is set when the 'sdfwrite' command is invoked is ignored. Note this behavior is different from the fwrite command.
<p>By default, the output file will have a coordinate variable only for  varying dimensions in the defined variable; non-varying dimensions will not appear as a coordinate variable with a size of 1. However, as of version <span class="style1">2.0.a5</span>,  options have been added to the  <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command to  force the variable in the output file to have at least 4 or all 5 dimensions. When either of these options to   <code><a href [...]
For example, if your defined variable is 500mb height on14may2002 (a 2D variable that varies only in lon and lat), and you use the -4d option, the output file with show height as a 4D variable with a Z dimension of size 1 called 'lev' with a value "500 mb", and a T dimension of size 1 called 'time' with a value of "0 minutes since 2002-05-14 00:00".
<p>The coordinate variables will be  type 'double' and will have two default attributes ("units" and "long_name") with values that are based on the GrADS 5-dimensional gridded data model. The data variable will also be  type 'double' by default; beginning with version <span class="style1">2.0.a8</span>, you can also write out data of type 'float' if you use the <code>-flt</code> option with    <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command. Da [...]
  <code><a href="gradcomdsetundef.html">set undef</a></code> command.
<p>For example, if <code><i>varname</i></code> is called "testvar" and varies in X, Y, Z, T, and E, then the output file might have a NetCDF header that looks like this: 
<p><code>netcdf foo {<br>
  dimensions:<br>
  longitude = 9 ;<br>
  latitude = 9 ;<br>
  level = 9 ;<br>
  time = 9 ;<br>
  ensemble = 9 ;<br>
variables:<br>
  double longitude(longitude) ;<br>
     longitude:units = "degrees_east" ;<br>
     longitude:long_name = "Longitude" ;<br>
  double latitude(latitude) ;<br>
     latitude:units = "degrees_north" ;<br>
     latitude:long_name = "Latitude" ;<br>
  double level(level) ;<br>
     level:units = "millibar" ;<br>
     level:long_name = "Level" ;<br>
  double time(time) ;<br>
     time:units = "minutes since 01-01-0001 00:00" ;<br>
     time:long_name = "Time" ;<br>
  double ensemble(ensemble) ;<br>
     ensemble:grads_dim = "e" ;<br>
     ensemble:long_name = "Ensemble member" ;<br>
  double testvar(ensemble, time, level, latitude, longitude) ;<br>
     testvar:missing_value = -888. ;<br>
}
</code>
<p>The time axis units will always be "minutes since ..." and the date of the time axis origin will correspond to the initial time of the defined variable. 
<p>If the variable has an ensemble dimension, the attribute "grads_dim" with the value "e" will always be present so that the resulting output file can be opened with GrADS using the 'sdfopen' command. 
<p>To supplement or override the default attributes of the output file, use the <code><a href="gradcomdsetsdfattr.html">set sdfattr</a></code> command. 
<p>Beginning with version 2.0.a8, the output file may also be a compressed netCDF file. Use the <code>-zip</code> option with the <code><a href="gradcomdsetsdfwrite.html">set sdfwrite</a></code> command to enable compression. Please see the documentation on <a href="compression.html">compression</a> for  more details.
<h3>Examples </h3>

<p>
The following commands produce a regional subset of a global precip forecast :</p>
  <pre>open gfs.ctl
set lon -111.3 -103.8 
set lat 40.9 45.0 
set t 1 last
define precip = ptot
set sdfwrite wyoming_precip.nc
sdfwrite precip</pre>
    


<p><em><strong>Appending Variables to a File</strong></em><br>
  The sdfwrite command does not allow you to write out more than one variable to a file. The way to do achieve this is to write out each variable in a separate file, then merge them with  the <a href="http://nco.sourceforge.net/nco.html" target="_blank">NetCDF Operators (NCO)</a>. Use the <a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank"><code>ncks</code></a> command to append variables defined on the same grid. The GrADS commands might look like this: 
<pre>
open gfs.ctl
set x 1 720
set y 1 361
set t 1 last
define slp = mslp
define precip = ptot
set sdfwrite -flt slp.nc
sdfwrite slp
sdt sdfwrite -flt precip.nc
sdfwrite precip
</pre>
Then, outside GrADS, or using the ! in front of the command to send it to the shell from within GrADS, merge these two files with <a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank"><code>ncks</code></a>: 
<pre><a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank">ncks</a> -O -h -A precip.nc slp.nc</pre>
<p>The -A is for appending to the output file, the -O is for overwriting existing output file, and the -h does not add anything to the output file's global 'history' attribute. Please see the <a href="http://nco.sourceforge.net/nco.html" target="_blank">NCO User's Guide</a> for more information. 
<p><em><strong>Concatenating Files</strong></em><br>
  Suppose you want to write out a long time series with the sdfwrite command, but your system does not have enough memory to define the whole grid. Use GrADS to write out the data in smaller time segments (e.g. one year, or one month, or one day), and then concatenate them together with the 
    <a href="http://nco.sourceforge.net/nco.html" target="_blank">NetCDF Operators (NCO)</a>. After you have created the separate files with GrADS, use the <a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank"><code>ncks</code></a> command to change the time dimension to a record dimension, then use the <a href="http://nco.sourceforge.net/nco.html#ncrcat" target="_blank"><code>ncrcat</code></a> command to concatenate them together. The GrADS commands might look like  this: 
<pre>
open long_time_series.ctl
set x 1 720
set y 1 361
set time 01jan2001 31dec2001
define slp = mslp
set sdfwrite -flt slp_2001.nc
sdfwrite slp
set time 01jan2002 31dec2002
define slp = mslp
set sdfwrite -flt slp_2002.nc
sdfwrite slp
set time 01jan2003 31dec2003
define slp = mslp
set sdfwrite -flt slp_2003.nc
sdfwrite slp
</pre>
Then, outside GrADS, or using the ! in front of the command to send it to the shell from within GrADS, modify the time dimension with <a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank"><code>ncks</code></a>, then concatenate with <a href="http://nco.sourceforge.net/nco.html#ncrcat" target="_blank"><code>ncrcat</code></a>: 
<pre><a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank">ncks</a> -O -h --mk_rec_dmn time slp_2001.nc
<a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank">ncks</a><a href="http://nco.sourceforge.net/nco.html#ncks"></a> -O -h --mk_rec_dmn time slp_2002.nc
<a href="http://nco.sourceforge.net/nco.html#ncks" target="_blank">ncks</a><a href="http://nco.sourceforge.net/nco.html#ncks"></a> -O -h --mk_rec_dmn time slp_2003.nc
<a href="http://nco.sourceforge.net/nco.html#ncrcat" target="_blank">ncrcat</a> -O -h slp_2001.nc slp_2002.nc slp_2003.nc slp.nc</pre>
<p>The --mk_rec_dmn options modifies the time dimension,  the -O is for overwriting existing output file, and the -h does not add anything to the output file's global 'history' attribute. Please see the <a href="http://nco.sourceforge.net/nco.html" target="_blank">NCO User's Guide</a> for more information -- there are  shortcuts for <a href="http://nco.sourceforge.net/nco.html#ncrcat" target="_blank"><code>ncrcat</code></a> to specify the long list of files to concatenate. 
<p><span class="style1">N.B. (For compressed NetCDF-4 files): </span>If the NetCDF files you create with GrADS are compressed netCDF-4 format, then you must use NCO version 4.0.4 (or higher) in order to maintain the compression in the output files. The chunk sizes may also be altered by ncks or ncrcat. Use the --cnk_dmn option to specify the name and chunk size of each dimension to manually override the defaults. For example: 
<pre><a href="http://nco.sourceforge.net/nco.html#ncrcat" target="_blank">ncrcat </a>-O -h --cnk_dmn lev,1 --cnk_dmn lat,361 --cnk_dmn lon,720 slp_2001.nc slp_2002.nc slp_2003.nc slp.nc</pre>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetannot.html b/doc/gradcomdsetannot.html
new file mode 100644
index 0000000..696b579
--- /dev/null
+++ b/doc/gradcomdsetannot.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<h2><b>set annot</b></h2><p>
<code>set annot <i>color</i> <<i>thickness</i>></code><p>
Sets <code></i>color</i></code> and line
<code><i>thickness</i></code>.<p>
<H3>Usage Note</H3>
<P> 
Default is <code>white</code>, thickness <code>6</code>.  This command
also sets the <code><i>color</i></code> and
<code><i>thickness</i></code> for the axis border, axis labels, and
tickmarks.  Axis tickmarks and labels are plotted at the specified
thickness minus 1.

<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetarrlab.html b/doc/gradcomdsetarrlab.html
new file mode 100644
index 0000000..3e3021a
--- /dev/null
+++ b/doc/gradcomdsetarrlab.html
@@ -0,0 +1,55 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set arrlab</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set arrlab</b></h2>
+<p>
+<code>set arrlab on|off</code>
+<p>
+Toggles drawing the vector arrow label for plots drawn with 
+<code><a href="gradcomdsetgxout.html">set gxout vector</a></code>. 
+
+The default is <code><i>on</i></code> and "sticks" until reset by another 
+<code>set arrlab</code> command. 
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+The position of the arrow label is fixed to be in the bottom right
+corner of the page, just under the plot. If you want it to appear
+somewhere else, see the example below which demonstrates how to draw
+an arrow key using GrADS graphical elements.
+
+<p>
+<h3>Examples </h3>
+<p>
+This example is a script sample that demonstrates how to turn off the default
+vector arrow scale and draw another one at any specified location:
+<pre>
+'set gxout vector'
+len = 0.3
+scale = 2
+xrit = 8.0
+ybot = 0.5
+'set arrscl 'len' 'scale
+'set arrlab off'
+'d u;v'
+rc = arrow(xrit-0.25,ybot+0.2,len,scale)
+
+function arrow(x,y,len,scale)
+'set line 1 1 4'
+'draw line 'x-len/2.' 'y' 'x+len/2.' 'y
+'draw line 'x+len/2.-0.05' 'y+0.025' 'x+len/2.' 'y
+'draw line 'x+len/2.-0.05' 'y-0.025' 'x+len/2.' 'y
+'set string 1 c'
+'set strsiz 0.1'
+'draw string 'x' 'y-0.1' 'scale
+return
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetarrowhead.html b/doc/gradcomdsetarrowhead.html
new file mode 100644
index 0000000..9af5243
--- /dev/null
+++ b/doc/gradcomdsetarrowhead.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set arrowhead</B></H2><P>
+<code>set arrowhead <i>size</i></code><p>
+where <code><i>size</i></code> is the size of the arrowhead. The default
+is <code>0.05</code>. If set to <code>0</code>, no arrowhead is plotted.
+If set to a negative value, the size of the arrowhead will be scaled to
+the size of the arrow. The value specified will be the size when the arrow
+is one inch  in length. <p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetarrscl.html b/doc/gradcomdsetarrscl.html
new file mode 100644
index 0000000..d6a9ff9
--- /dev/null
+++ b/doc/gradcomdsetarrscl.html
@@ -0,0 +1,20 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set arrscl</B></H2><P>
+<code>set arrscl <i>size <magnitude></i></code><p>
+Specifies arrow length scaling. <p>
+<ul>
+<code><i>size</i></code>              is
+the length of the
+arrow in plotting
+units (inches on the virtual page). A typical value would be
+<code>0.5</code> to <code>1.0</code>.<p>
+<code><i>magnitude</i></code>    is the vector
+magnitude that will
+produce an arrow of the specified size. </ul><p>
+Other arrow lengths will be scaled appropriately. If 
+ <code><i>magnitude</i></code> is not given, all the arrows will be the
+same length. Reset by <code><i>clear</i></code> or
+<code><i>display</i></code>. <p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetbackground.html b/doc/gradcomdsetbackground.html
new file mode 100644
index 0000000..54dacaf
--- /dev/null
+++ b/doc/gradcomdsetbackground.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set background</h2>
+<code>set background <i>index</i></code><p>
+set background color to color or color <code><i>index</i></code>
+<h3>Usage</h3>
+<h3>Notes</h3>
diff --git a/doc/gradcomdsetbarbase.html b/doc/gradcomdsetbarbase.html
new file mode 100644
index 0000000..2478fe1
--- /dev/null
+++ b/doc/gradcomdsetbarbase.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set barbase</B></H2><P>
+<code>set barbase<i> val|bottom|top</i></code><p>
+If <code>val</code> is given, each bar rises or falls from that value,
+assuming the value is within the plotting range. If <code>bottom</code> is
+specified, each bar rises from the bottom of the plot. If <code>top</code>
+is specified, each bar falls from the top of the plot.<p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetbargap.html b/doc/gradcomdsetbargap.html
new file mode 100644
index 0000000..56c9ffb
--- /dev/null
+++ b/doc/gradcomdsetbargap.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set bargap</B></H2><P>
+<code>set bargap<i> val</i></code><p>
+Sets the gap between bars in percent. <code><i>val</i></code> should range
+from <code>0</code> to <code>100</code>. The default is <code>0</code>, or
+no gap. A value of <code>100</code> gives a single vertical line for each
+bar. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetbaropts.html b/doc/gradcomdsetbaropts.html
new file mode 100644
index 0000000..828ca67
--- /dev/null
+++ b/doc/gradcomdsetbaropts.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set baropts</B></H2><P>
+<code>set baropts <i>opts</i></code><p>
+Description here..........opts can have the values of <p>
+<ul>
+<code>outline</code>     do <i>not</i> fill
+in
+the bar<br>
+<code>filled</code>       fill the
+bar</ul><p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetblack.html b/doc/gradcomdsetblack.html
new file mode 100644
index 0000000..2d3fdd1
--- /dev/null
+++ b/doc/gradcomdsetblack.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set black</B></H2><P>
+<code>set black <i>val1 val2</i></code><p>
+Contours not drawn within this interval. Reset by <code>clear</code> or
+<code>display</code>.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetbutton.html b/doc/gradcomdsetbutton.html
new file mode 100644
index 0000000..8cc8fc1
--- /dev/null
+++ b/doc/gradcomdsetbutton.html
@@ -0,0 +1,60 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set button</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set button</b></h2>
+<p>
+Sets up the color characteristics of a button widget. The syntax is:
+
+<p>
+<code>set button <i><button_ON_colors> <button_OFF_colors> thickness</i></code>
+
+<p>
+where <code><i><button_ON_colors></i></code> and
+<code><i><button_OFF_colors></i></code> each contain four 
+color numbers:
+
+<p>
+<ul>
+<code>text   </code>color of the button text <br>
+<code>face   </code>color of the button face<br>
+<code>bcol   </code>bright color of the shadow outline for 3-D look<br>
+<code>dcol   </code>dark color of the shadow outline for 3-D look<br>
+</ul>
+
+<p>
+and <code><i>thickness</i></code> is the thickness of the shadow outline<br>
+</ul>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li><code>set button</code> generally precedes the <a
+href="gradcomddrawbutton.html"><code>draw button</code></a> command.
+<p>
+<li>See the section of the User's Guide on <a
+href="script.html#widgets">widgets</a> for more information on using
+buttons.
+</ol>
+
+<p>
+<h3>Example</h3>
+
+<p>
+<pre>
+'set rgb 90 100 100 100'
+'set rgb 91  50  50  50'
+'set rgb 92 200 200 200'
+'set button 1 90 91 92 2 90 92 91 6'
+'draw button 1 1.5 8.0 2 0.5 Button #1'
+'draw button 2 4.0 8.0 2 0.5 Button #2'
+'draw button 3 6.5 8.0 2 0.5 Button #3'
+</pre>
+
+</body>
+</html>
diff --git a/doc/gradcomdsetcachesf.html b/doc/gradcomdsetcachesf.html
new file mode 100644
index 0000000..abdac3f
--- /dev/null
+++ b/doc/gradcomdsetcachesf.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<title>GrADS command: set cachesf</title><H2><B>set cachesf</B></H2>
<P>
<code>set cachesf <i>num</i></code>
<p>Use this command to change the scale factor for setting the default cache size (in bytes), which is calculated according to this formula:<br />
X grid size * Ygrid size * 8 * cachesf 
<p>The default cache scale factor is 1. <br>
<p>

<H3>Usage Notes</H3>
<P>This command is available with GrADS version 2.0.a8 or later. 
<P>The cache size is only relevant when reading HDF5 and NetCDF4 data types.

<P>Cache size is set on a per-file basis; the cache size will be different for each file opened in GrADS. After a file is opened, a new cache is allocated for each variable that gets displayed in the file.
 Be careful
<P>Current value of the cache size may be discovered with the <code><a href="gradcomdquery.html">query cache</a></code> command. 
<P>Please see the documentation on <a href="compression.html">compression</a> for more details.
<P>

<H3>Examples</H3>
<P>
\ No newline at end of file
diff --git a/doc/gradcomdsetccolor.html b/doc/gradcomdsetccolor.html
new file mode 100644
index 0000000..f50c2b8
--- /dev/null
+++ b/doc/gradcomdsetccolor.html
@@ -0,0 +1,63 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set ccolor</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set ccolor</b></h2>
+
+<p><ul>
+<code>set ccolor rainbow</code><br>
+<code>set ccolor <i>color#</i></code>
+</ul>
+
+<p>
+This command sets the color of the plotted contours. If
+<code>ccolor</code> is set to <code>rainbow</code>, then GrADS will
+use the <a href="16colors.html">default rainbow sequence</a> to assign
+colors to individual contours, resulting in a pleasing color palette
+that spans the range of the plotted values. To draw all contours with
+the same color, use the second option, where
+<code><i>color#</i></code> may be one of the <a
+href="16colors.html">16 GrADS default colors</a> or the number of a
+user-defined color created with <a href="gradcomdsetrgb.html">set
+rgb</a>.
+
+<p>
+<h3>Usage Notes</h3>
+
+<ol>
+<li><code>set ccolor</code> is reset by entering <a
+href="gradcomdclear.html"><code>clear</code></a> or <a
+href="gradcomddisplay.html"><code>display</code></a>.
+<p>
+<li>The color sequence for the <a href="16colors.html">default rainbow
+palette</a> is: <code>9 14 4 11 5 13 3 10 7 12 8 2 6</code>. This may
+be overridden by using the <a href="gradcomdsetrbcols.html">set rbcols</a>
+command.
+<p>
+<li>If the number of colors in the rainbow palette is smaller 
+than the number of contour levels, then some contour colors will be
+repeated -- i.e. not every contour color will be unique. Likewise, if
+the number of colors in the rainbow palette is larger than the number
+of contour levels, then some colors will be omitted.
+<p>
+<li>When overlaying contour plots, GrADS will automatically change the
+color of the contours for each successive plot in order to distinguish
+between different variables. The default order is: rainbow, foreground, 
+3 (green), 7 (yellow), 2 (red), 6 (magenta), 9 (purple), .... 
+
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
+
+
+
diff --git a/doc/gradcomdsetccols.html b/doc/gradcomdsetccols.html
new file mode 100644
index 0000000..60711bc
--- /dev/null
+++ b/doc/gradcomdsetccols.html
@@ -0,0 +1,44 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set ccols</title>
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+body {
+	background-color: #e0f0ff;
+}
+-->
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body text="#000000">
+
+<h2><b>set ccols</b></h2>
+<p>
+<code>set ccols <i>col1 col2 col3 ... colN</i></code>
+
+<p>
+Sets specific color numbers for contour levels specified by <a
+href="gradcomdsetclevs.html"><code>set clevs</code></a>. 
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>
+Contour colors are reset with every execution of <a
+href="gradcomdclear.html"><code>clear</code></a> or <a
+href="gradcomddisplay.html"><code>display</code></a>.
+<li>User-specified ccols won't take effect unless clevs are also set.
+<li>If any of the color numbers is < 0, it is set to 0 (the background color).
+
+<li>(<span class="style1">Version 2.0.0+</span>) When using 'gxout shade2' or 'gxout shade2b', if any of the color numbers is < 0, the contour is not drawn (i.e., it is effectively transparent).
+<li>See section of User's Guide on <a href="colorcontrol.html">controlling colors in Grads</a> for more details.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetchunksize.html b/doc/gradcomdsetchunksize.html
new file mode 100644
index 0000000..1a6f758
--- /dev/null
+++ b/doc/gradcomdsetchunksize.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<H2><B>set chunksize</B></H2>
<P>
<code>set chunksize <i>Xsize Ysize <Zsize> <Tsize> <Esize></i></code>
<p>
<code><i>Xsize</i>  </code> Size of the chunk in the X dimension. Default value is the grid size in X. <br>
<code><i>Ysize</i>  </code> Size of the chunk in the Y dimension. Default value is the grid size in Y. <br>
<code><i>Zsize</i>  </code> Size of the chunk in the Z dimension. Default value is 1. <br>
<code><i>Tsize</i>  </code> Size of the chunk in the T dimension. Default value is 1. <br>
<code><i>Esize</i>  </code> Size of the chunk in the E dimension. Default value is 1. <br>
<p>It is not necessary to specify the chunk size for the Z, T, or E dimensions if you wish to use the default values. 
<H3>Usage Notes</H3>
<P><em>Chunking </em>refers to the partitioning of a dataset into fixed-size multi-dimensional chunks. Chunks are treated as atomic objects; disk I/O, cacheing, and compression are always done on a per-chunk basis. Chunking can significantly improve I/O performance, provided the chunk size is set appropriately for the data set in question. 

<P>A chunk has the same number of dimensions as the original data set. The size of a chunk in any dimension should be equal to or less than the size of the data set's grid dimensions. For data sets with more than 2 dimensions, DO NOT set the chunk sizes equal to the grid dimension sizes, in which case the entire data set would be one chunk, and DO NOT set all the chunk sizes equal to 1 (one), in which case a chunk would be a single value. 
<P>The  default values  in GrADS set the chunk size equal to the grid dimension in X and Y, and 1 (one) for the Z, T, and E dimensions -- a chunk is a single 2D lat/lon grid. However, if your data set is of sufficiently high resolution (e.g., if the grid size is less than 1.0 degree latitude/longitude), then you should set the chunk size smaller than the grid size in X and Y -- divide by 2, or 5, or 10 as necessary to keep the chunk  in the ballpark of 512 kbytes.

It is recommended that you keep the chunk size equal to 1 for the Z, T, and E dimensions.
<P>Please see the documentation on <a href="compression.html">compression</a> for  more details.

<P>

<H3>Examples</H3>
<P>Suppose you have a high resolution data set (5120x2560) and you wish to save the variable as compressed netcdf. 
<p>
<code>set x 1 5120<br />
set y 1 2560<br />
set z 1<br />
set t 1<br />
define var = var<br /> 
set sdfwrite -flt -nc4 -chunk -zip var.nc<br />
set chunksize 512 256<br />
sdfwrite var<br />
</code>


<P>
\ No newline at end of file
diff --git a/doc/gradcomdsetcint.html b/doc/gradcomdsetcint.html
new file mode 100644
index 0000000..a231bcb
--- /dev/null
+++ b/doc/gradcomdsetcint.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set cint</B></H2><P>
+<code>set cint <i>value</i></code><p>
+Sets the contour interval to the specified value. Reset by
+<code>clear</code> or <code>display</code>.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetclab.html b/doc/gradcomdsetclab.html
new file mode 100644
index 0000000..775c413
--- /dev/null
+++ b/doc/gradcomdsetclab.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set clab</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set clab</b></h2>

<p>
<code>set clab <i>option</i></code>

<p>
Controls contour labeling. The <code><i>option</i></code>
argument may be one of the following:

<ul>
<code>on       </code>'fast' contour labels are plotted where the contour lines are horizontal <br>
<code>off      </code>no contour labels <br>
<code>forced   </code>an attempt is made to label all contour lines <br>
<code><i>format</i>   </code>gives a C-language template for conversion of the contour value to a string <br>
<code>masked   </code>(<span class="style1">version 2.0.a6+</span>) contour lines have gaps for the labels, so rectangles for label background are not drawn; contour labels never overlap.<br>
</ul>

<p>
<h3>Usage Notes</h3>
<ol>
<li>Changes to the contour labels are reset by <a
href="gradcomdclear.html">clear</a>, but not <a
href="gradcomddisplay.html">display</a>.
<li> When <code>'set clab masked'</code> is used, the contour lines are masked out wherever the labels are drawn. The mask creates small gaps in the contour lines, so the labels can be read clearly without the small rectangles that are usually drawn behind the contour label. The mask also ensures that labels do not overlap. If additional contour plots are overlaid, the new labels do not interfere with labels already drawn. The end result is a less cluttered graphic that is much more legible. 
<li> When <code>'set clab masked'</code> is used,  you can defer  drawing  the map until after all the labeled contours have been drawn, and then the label mask will also create gaps in the map outine for ultimate contour label legibility. 
<li>The <code>'clear mask'</code> command resets the contour label mask.
</ol>

<p>
<h3>Examples </h3>
<ol>
  <li>This command would cause all contour labels to have 2 digits after the decimal point:<br>
    <code>   set clab %.2f<br>
    <br>
</code> </li>
  <li>For contouring temperatures, this command would add a degree symbol and the letter "C":<br>
  <code>   set clab %.0f`3.`1C </code> <br>
    <br>
  </li>
  <li> Here are two graphics that illustrate the effect of using <code>'set clab masked'</code> in a display containing shaded contours and an overlay of labeled line contours. The default behavior is shown on the left; masked contour labels are shown on the right. The script fragments used to draw the plots are also provided below the images. Observe that contour lines and coastal boundaries are not drawn underneath the masked labels, so the white rectangles are not needed as a backgroun [...]
  </li>
</ol>
<table width="700" border="0">
  <tr>
    <td><img src="clab_default.png" alt="default" width="490" height="555"></td>
    <td><img src="clab_masked.png" alt="masked" width="484" height="554"></td>
  </tr>
  <tr>
    <td valign="top"><p><code>cl='480 490 500 510 520 530 540 550 560 570 580 590 600 610'<br>
      cc='   9   14     4   11     5   13     3   10     7   12     8     2     6'<br>
      'set rgb 16 70 70 70'<br>
      'set annot 16'<br>
    'set map 0'</code><code><br>
        * draw shaded contours<br>
        'set gxout shaded'<br>
        'set clevs 'cl<br>
        'set ccols 'cc <br>
        'set xlint 40'<br>
        'd z(lev=500)/10'<br>
        * draw labeled contours<br>
        'set gxout contour'<br>
        'set ccolor 16'<br>
        'set clevs 'cl</code><code><br>
        'set clopts 1'<br>
        'd z(lev=500)/10'<br>
        </code></p>
    </td>
    <td><p><code>cl='480 490 500 510 520 530 540 550 560 570 580 590 600 610'<br>
      cc='   9   14     4   11     5   13     3   10     7   12     8     2     6'<br>
      'set rgb 16 70 70 70'<br>
      'set annot 16'<br>
      'set map 0'<br>
      * turn off map<br>
      'set mpdraw off'<br>
      * draw shaded contours<br>
      'set gxout shaded'<br>
      'set clevs 'cl<br>
      'set ccols   'cc<br>
      'set xlint 40'<br>
      'd z(lev=500)/10'<br>
      * draw labeled contours<br>
      'set gxout contour'<br>
      'set ccolor 16'<br>
      'set clevs 'cl</code><code><br>
        'set clopts 1'<br>
        'set clab masked'<br>
        'd z(lev=500)/10'<br>
        * draw the map<br>
        'set mpdraw on'<br>
    'draw map'</code></p>
    </td>
  </tr>
</table>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdsetclevs.html b/doc/gradcomdsetclevs.html
new file mode 100644
index 0000000..ee9e210
--- /dev/null
+++ b/doc/gradcomdsetclevs.html
@@ -0,0 +1,37 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set clevs</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set clevs</b></h2>
+<p>
+<code>set clevs <i>lev1 lev2 lev3 ... levN</i></code>
+
+<p>
+Sets specific contour levels. 
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>
+Contour levels are reset with every execution of <a
+href="gradcomdclear.html"><code>clear</code></a> or <a
+href="gradcomddisplay.html"><code>display</code></a>.
+<p>
+<li>
+<code>set clevs</code> is often used with <a
+href="gradcomdsetccols.html"><code>set ccols</code></a> to override
+the default settings and specify exact contour levels and the colors
+that go with them.
+<p>
+<li>See section of User's Guide on <a href="colorcontrol.html">controlling colors in Grads</a> for more details.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetclip.html b/doc/gradcomdsetclip.html
new file mode 100644
index 0000000..1772973
--- /dev/null
+++ b/doc/gradcomdsetclip.html
@@ -0,0 +1,44 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set clip</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set clip</b></h2>
+<p>
+<code>set clip <i>xlo xhi ylo yhi</i> </code>
+
+<p>
+This command sets the coordinates for clipping the plot area for
+display and draw commands. The four arguments <code><i>xlo, xhi, ylo,
+yhi</i></code> are the clipping coordinates in real page inches.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>The default clipping region is the area specified by the
+<a href="gradcomdsetparea.html"><code>set parea</code></a> command. 
+<code>set clip</code> overrides this default. 
+<p>
+<li>Every time a <a
+href="gradcomddisplay.html"><code>display</code></a> command is
+executed, GrADS sets the clipping area to the region specified by <a
+href="gradcomdsetparea.html"><code>set parea</code></a> or <code>set
+clip</code>, draws the graphic, then resets the clipping region to the
+entire page.
+<p>
+<li>
+The clipping region is reset to the default by entering <a
+href="gradcomdclear.html"><code>clear</code></a> or <a
+href="gradcomddisplay.html"><code>display</code></a>.
+</ol>
+<p>
+<h3>Examples </h3>
+
+</body>
+</html>
+
+
+
diff --git a/doc/gradcomdsetclopts.html b/doc/gradcomdsetclopts.html
new file mode 100644
index 0000000..b68a0fd
--- /dev/null
+++ b/doc/gradcomdsetclopts.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<H2><B>set clopts</B></H2>
<P>
<code>set clopts <i>color <thickness <size>></i></code>
<p>
<ul>
<code><i>color</i></code>            is
the label
color. <code>-1</code> is
the default, and indicates to use the contour line color as the label
color <br>
<code><i>thickness</i></code>    is the label
thickness. <code>-1</code> is
the default.<br>
<code><i>size</i></code>              is
the label size. <code>0.09</code> is the
default</ul><p>
This setting stays set until changed by issuing another <code>set
clopts</code> command. <p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>

\ No newline at end of file
diff --git a/doc/gradcomdsetclskip.html b/doc/gradcomdsetclskip.html
new file mode 100644
index 0000000..5f26a50
--- /dev/null
+++ b/doc/gradcomdsetclskip.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set clskip</B></H2>
<P>
<code>set clskip <i>number <spacing></i></code>
<p>
<code><i>number</i></code> is the number of contour lines to skip when
labelling<br />
<code><i>spacing</i></code> is an optional argument that controls the minimum distance between labels on a contour line (default = 2.5)
<p> For example, <code>set clskip 2</code> would label every other
  contour.
<p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetcmark.html b/doc/gradcomdsetcmark.html
new file mode 100644
index 0000000..2a06cbb
--- /dev/null
+++ b/doc/gradcomdsetcmark.html
@@ -0,0 +1,45 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set cmark</b></h2>
+<p>
+<code>set cmark <i>marktype</i></code>
+<p>
+Set the style of the marker for line plots. 
+<code><i>marktype</i></code> may be one of the following:<p>
+<ul>
+<pre>
+ 0 - none
+ 1 - plus sign
+ 2 - open circle (default)
+ 3 - closed circle 
+ 4 - open square 
+ 5 - closed square 
+ 6 - multiplication sign
+ 7 - open diamond 
+ 8 - open triangle 
+ 9 - closed triangle
+10 - open circle with vertical bar
+11 - closed circle with vertical bar
+</pre>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Reset by <code>clear</code> or <code>display</code>.
+<p>
+<li>The size of the marker may be set by using 
+<a href="gradcomdsetdigsize.html"><code>set digsize</code></a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetcmax.html b/doc/gradcomdsetcmax.html
new file mode 100644
index 0000000..18d4da5
--- /dev/null
+++ b/doc/gradcomdsetcmax.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set cmax</B></H2><P>
+<code>set cmax <i>value</i></code><p>
+Contours not drawn above this value. Reset by <code>clear</code> or
+<code>display</code>. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetcmin.html b/doc/gradcomdsetcmin.html
new file mode 100644
index 0000000..d7619aa
--- /dev/null
+++ b/doc/gradcomdsetcmin.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set cmin</B></H2><P>
+<code>set cmin <i>value</i></code><p>
+Contours not drawn below this value. Reset by <code>clear</code> or
+<code>display</code>. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetcoslat.html b/doc/gradcomdsetcoslat.html
new file mode 100644
index 0000000..65e1b9a
--- /dev/null
+++ b/doc/gradcomdsetcoslat.html
@@ -0,0 +1,19 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set coslat</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<H2><B>set coslat</B></H2>
+<P> <code>set coslat <i>on</i>|<i>off</i></code>
+<p> Sets scaling of the Latitude dimension to be the cosine of latitude, producing 
+  a "crunched" effect near the poles. Will only work for 1-D plots in 
+  which Latitude (Y) is the varying dimension. Sticks until <code>reset</code>. 
+<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
+</body>
+</html>
diff --git a/doc/gradcomdsetcsmooth.html b/doc/gradcomdsetcsmooth.html
new file mode 100644
index 0000000..0312135
--- /dev/null
+++ b/doc/gradcomdsetcsmooth.html
@@ -0,0 +1,14 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set csmooth</B></H2><P>
+<code>set csmooth <i>on|off</i></code><p>
+If on, the grid is interpolated to a finer grid using cubic interpolation
+before contouring. "Sticks". <p>
+<H3>Usage Notes</H3><P>
+<ol>
+<li>This option will result in contour values below and above the min
+and max of the un-interpolated grid. This may result in physically invalid
+values such as in the case of negative rainfall. <p>
+</ol>
+<H3>Examples</H3><P>
+
diff --git a/doc/gradcomdsetcstyle.html b/doc/gradcomdsetcstyle.html
new file mode 100644
index 0000000..51be562
--- /dev/null
+++ b/doc/gradcomdsetcstyle.html
@@ -0,0 +1,49 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set cstyle</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set cstyle</b></h2>
+<p>
+<code>set cstyle <i>style</i></code>
+
+<p>
+Sets the contour linestyle. <code><i>style</i></code> options are:
+
+<p>
+<ul>
+<code>0 </code>- no contours <br>          
+<code>1 </code>- solid <br>          
+<code>2 </code>- long dash <br>  
+<code>3 </code>- short dash <br>  
+<code>4 </code>- long dash, short dash <br>  
+<code>5 </code>- dotted <br>  
+<code>6 </code>- dot dash <br>  
+<code>7 </code>- dot dot dash <br>  
+</ul>
+
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li><code>set cstyle</code> is reset by entering <a
+href="gradcomdclear.html"><code>clear</code></a> or <a
+href="gradcomddisplay.html"><code>display</code></a>.
+<p>
+<li><code>set cstyle 0</code> will generate the following message:
+<code>"WARNING cstyle = 0 ; no lines will be plotted; I suggest 1
+..."</code>. However, it may be used with <a
+href="gradcomdsetcmark.html"><code>set cmark</code></a> for drawing a
+'line' plot with marks at all the data points that are not connected
+by a line.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetcterp.html b/doc/gradcomdsetcterp.html
new file mode 100644
index 0000000..aed3a6f
--- /dev/null
+++ b/doc/gradcomdsetcterp.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set cterp</B></H2><P>
+<code>set cterp <i>on|off</i></code><p>
+Turns spline smoothing on or off. "Sticks" until reset. Shaded contours
+are drawn without spline fitting, so to insure an exact match when
+overlaying contour lines and shaded contours of the same field, specify
+<code>cterp</code> as off. You can still use the
+<a href="gradcomdsetcsmooth.html"><code>csmooth</code></a>
+option, which affects both contour lines and shaded contours.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetcthick.html b/doc/gradcomdsetcthick.html
new file mode 100644
index 0000000..85d34e3
--- /dev/null
+++ b/doc/gradcomdsetcthick.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set cthick</B></H2><P>
+<code>set cthick <i>thckns</i></code><p>
+Sets the line thickness for the contours given an integer in the range of
+<code>1</code> to <code>20</code> representing relative line thicknesses.
+Thickness of 6 or more will be thicker on the screen. Primarily used for
+controlling hardcopy output. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetdatawarn.html b/doc/gradcomdsetdatawarn.html
new file mode 100644
index 0000000..d5bc614
--- /dev/null
+++ b/doc/gradcomdsetdatawarn.html
@@ -0,0 +1,25 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set datawarn</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set datawarn</b></h2>
+<p>
+<code>set datawarn on | off</code>
+<p>
+If set to "on" (the default), when the user tries to display a variable that consists entirely of undefined values GrADS will print the message "Entire Grid Undefined" in the display window. 
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetdbuff.html b/doc/gradcomdsetdbuff.html
new file mode 100644
index 0000000..d4afe09
--- /dev/null
+++ b/doc/gradcomdsetdbuff.html
@@ -0,0 +1,9 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set dbuff</B></H2><P>
+<code>set dbuff <i>on|off</i></code><p>
+Sets double buffer mode <code>on</code> or <code>off</code>. This allows
+animation to be controlled from a script. The <code>clear</code> command
+also sets double buffer mode <code>off</code>.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetdefval.html b/doc/gradcomdsetdefval.html
new file mode 100644
index 0000000..ce0a50d
--- /dev/null
+++ b/doc/gradcomdsetdefval.html
@@ -0,0 +1,107 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set defval</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>set defval</b></h2>
+
+<p>
+This command is used to interactively modify grid point values for
+2-dimensional <a href="gradcomddefine.html"><code>defined</code></a>
+variables. It is generally used in conjunction with <a
+href="gradcomdquery.html"><code>query defval</code></a>. The syntax is:
+<p>
+<ul><code>set defval <i>var ival jval value</i></code></ul>
+
+<p>
+where:
+<ul>
+<code><i>var</i>    </code>- the 2-D defined variable<br>
+<code><i>ival</i>   </code>- X coordinate of the grid point<br>
+<code><i>jval</i>   </code>- Y coordinate of the grid point<br>
+<code><i>value</i>  </code>- the new value for the variable, or "missing" to set variable as undefined<br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>A typical application of <code>set defval</code> might be to correct the value of an isolated bad data value discoverd through a maskout operation. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+<p>'set defval var 8 22 missing' </p>
+<p>Here is a sample script <a
+href="ftp://cola.gmu.edu/grads/scripts/defval_demo.gs">defval_demo.gs</a>
+  that illustrates the use of <code>query defval</code> and <code>set
+    defval</code> commands.
+</p>
+<pre>
+'open model.ctl'
+
+* restrict the dimension environment to see things more clearly
+xmin =  0.5
+xmax = 15.5
+ymin =  0.5
+ymax = 10.5
+'set x 'xmin' 'xmax
+'set y 'ymin' 'ymax
+
+* the "defval" commands will only work with 2-D defined variables 
+'define var = ps'
+
+* Display the variable with colored grid cells and their values
+'c'
+'set grid off'
+'set mproj off'
+'set xaxis 'xmin' 'xmax
+'set yaxis 'ymin' 'ymax
+'set gxout grfill'
+'d var'
+'set gxout grid'
+'set digsiz .14'
+'d var'
+
+* Use the mouse to click on a grid point to change
+say 'Click on any grid point'
+'q pos'
+xscreen = subwrd(result,3)
+yscreen = subwrd(result,4)
+
+* Convert screen positions to grid coordinates
+'q xy2gr 'xscreen' 'yscreen
+xgrid = subwrd(result,3)
+ygrid = subwrd(result,6)
+
+* Round the grid values to the nearest integer
+gx = math_nint(xgrid)
+gy = math_nint(ygrid)
+
+* Get the value of the defined variable 
+'q defval var 'gx' 'gy
+val = subwrd(result,3)
+say 'The value at grid point ('gx','gy') is --> 'val
+
+* Ask for a new replacement value and assign it
+prompt 'Enter a new value --> ' 
+pull newval
+'set defval var 'gx' 'gy' 'newval
+
+* Display the newly updated variable
+'c'
+'set xaxis 'xmin' 'xmax
+'set yaxis 'ymin' 'ymax
+'set gxout grfill'
+'d var'
+'set gxout grid'
+'d var'
+</pre>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetdfile.html b/doc/gradcomdsetdfile.html
new file mode 100644
index 0000000..00185f6
--- /dev/null
+++ b/doc/gradcomdsetdfile.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set dfile</h2>
+<code>set dfile <i>file</i></code><p>
+change to descriptor file number for current file<p>
+<h3>Usage</h3>
+<h3>Notes</h3>
diff --git a/doc/gradcomdsetdialog.html b/doc/gradcomdsetdialog.html
new file mode 100644
index 0000000..7feb0ab
--- /dev/null
+++ b/doc/gradcomdsetdialog.html
@@ -0,0 +1,55 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set dialog</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set dialog</b></h2>
+<p>
+<code>set dialog <i>pc fc bc oc th</i> <numeric|n></code>
+
+<p>
+Sets color properties for dialog box widgets. 
+
+<p>
+<ul>
+<code><i>pc</i>    </code>prompt color <br>
+<code><i>fc</i>    </code>foreground text color <br>
+<code><i>bc</i>    </code>background color <br>
+<code><i>oc</i>    </code>outline color <br>
+<code><i>th</i>    </code>outline thickness <br>
+<code>n     </code>numeric input only (optional) <br>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If <code><i>th</i></code> is 1-5, a one-pixel border is drawn; if
+it is 6 or more, a two-pixel border is drawn.
+<p>
+<li>Default colors are accessed by setting the colors to -1. 
+<p>
+<li>If the numeric option is invoked, keyboard inputs are restricted
+to 0-9, ., -, +, e, and E.  Entered value is checked to assure it is a
+rational number of the form +/-nnnn, +/-nnnn.dddd, or
++/-nnnn.ddddE+/-xxxx. This assures the returned numeric value is valid
+for use by a GrADS script.
+<p>
+<li>See the <a href="gradcomdqdialog.html"><code>q dialog</code></a>
+refrence page for details on execution of the dialog box widgets.
+
+</ol>
+
+<p>
+<h3>Examples </h3>
+<p>
+<pre>
+set dialog 1 0 5 1 6
+q dialog Hello World
+say result
+</pre>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetdignum.html b/doc/gradcomdsetdignum.html
new file mode 100644
index 0000000..9a017ff
--- /dev/null
+++ b/doc/gradcomdsetdignum.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set dignum</B></H2><P>
+<code>set dignum <i>number</i></code><p>
+<code><i>number</i></code> of digits after the decimal place<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetdigsize.html b/doc/gradcomdsetdigsize.html
new file mode 100644
index 0000000..24bd1f7
--- /dev/null
+++ b/doc/gradcomdsetdigsize.html
@@ -0,0 +1,9 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set digsiz</B></H2><P>
+<code>set digsiz <i>size</i></code><p>
+Size (in inches, or plotter units) of the numbers. <code>0.1</code> to
+<code>0.15</code> is usually a good range to use. Both of these options
+stay the same until changed.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetdisplay.html b/doc/gradcomdsetdisplay.html
new file mode 100644
index 0000000..f79e9ed
--- /dev/null
+++ b/doc/gradcomdsetdisplay.html
@@ -0,0 +1,23 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set display</B></H2><P>
+<code>set display <i>grey|greyscale|color
+<black|white></i></code><P>
+Sets the mode of the display. <p>
+By default, the mode is <code>color</code>, where shading and contouring
+is done with a rainbow of colors. When using a monochrome display, these
+colors may not map to greyscale in a pleasing way. When the mode is set to
+<code>greyscale</code>, contours are displayed using a single grey level,
+and shaded contours are done using a sequence of greyscales. <p>
+
+You may optionally set the hardware background color to <code>black</code>
+or <code>white</code>. The default is <code>black</code>. <p>
+
+Issuing: <code>set display grey white</code> gives a result on the display
+that is very similar to the output produced by <code>gxps</code>. <p>
+<H3>Usage Note</H3><P>
+<ol>
+<li>This command DOES NOT affect hardcopy output. <p>
+</ol>
+<H3>Examples</H3><P>
+
diff --git a/doc/gradcomdsetdropmenu.html b/doc/gradcomdsetdropmenu.html
new file mode 100644
index 0000000..470543f
--- /dev/null
+++ b/doc/gradcomdsetdropmenu.html
@@ -0,0 +1,76 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set dropmenu</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set dropmenu</b></h2>
+<p>
+Sets up the color characteristics of a dropmenu widget. The syntax is:
+
+<p>
+<code>set dropmenu <i>fc bc oc1 oc2 tfc tbc toc1 toc2 bfc bbc boc1 boc2 soc1 soc2 thick</i></code>
+
+<p>
+where:
+<p>
+<ul>
+<code><i>fc     </i></code>
+menu base text color<br>
+<code><i>bc     </i></code>
+menu base face color<br>
+<code><i>oc1    </i></code>
+dark color of shadow outline for menu base<br>
+<code><i>oc2    </i></code>
+bright color of shadow outline for menu base<br>
+<code><i>tfc    </i></code>
+menu base text color when selected with a mouse click<br>
+<code><i>tbc    </i></code>
+menu base face color when selected with a mouse click<br>
+<code><i>toc1   </i></code>
+dark color of shadow outline for menu base when selected<br>
+<code><i>toc2   </i></code>
+bright color of shadow outline for menu base when selected<br>
+<code><i>bfc    </i></code>
+menu list text color<br>
+<code><i>bbc    </i></code>
+menu list face color<br>
+<code><i>boc1   </i></code>
+dark color of shadow outline for menu list<br>
+<code><i>boc2   </i></code>
+bright color of shadow outline for menu list<br>
+<code><i>soc1   </i></code>
+dark color of shadow outline for highlighted menu item<br>
+<code><i>soc2   </i></code>
+bright color of shadow outline for highlighted menu item<br>
+<code><i>thick  </i></code>
+thickness of the shadow outline<br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li><code>set dropmenu</code> generally precedes the <a
+href="gradcomddrawdropmenu.html"><code>draw dropmenu</code></a> command.
+<p>
+<li>See the section of the User's Guide on <a
+href="script.html#widgets">widgets</a> for more information on using
+dropmenus.
+</ol>
+
+<p>
+<h3>Example</h3>
+
+<p>
+<pre>
+set rgb 90 100 100 100
+set rgb 91  50  50  50
+set rgb 92 200 200 200
+set dropmenu 1 90 91 92 0 90 92 91 1 90 91 92 92 91 6
+draw dropmenu 1 1 8 1.5 0.5 Menu Base | Menu Item #1 | Menu Item #2 
+</pre>
+
+</body>
+</html>
diff --git a/doc/gradcomdsetfgvals.html b/doc/gradcomdsetfgvals.html
new file mode 100644
index 0000000..3b803dd
--- /dev/null
+++ b/doc/gradcomdsetfgvals.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set fgvals</B></H2><P>
+<code>set fgvals <i>value color <value color> <value
+color>...</i></code><p>
+The fgrid output type treats the grid values as rounded integers, and will
+shade a specified integer valued grid with the specified color.Unspecified
+values are not shaded. "Sticks". <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetfont.html b/doc/gradcomdsetfont.html
new file mode 100644
index 0000000..79caaf1
--- /dev/null
+++ b/doc/gradcomdsetfont.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>GrADS command: set font</title><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<H2><B>set font</B></H2><P>
<code>set font <i>number</i></code>
<p>
Selects the font for subsequent text operations, where:
<code>number=0...5</code>.<p>
<H3>Usage Note</H3>
<P>It is also possible to <a href="fontcontrol.html">override the  font  in a string of text by using the back quote character (`).  
</a>
<P>For information about how the Hershey font files are created, see <a href="font.html">font file format</a>.
<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetframe.html b/doc/gradcomdsetframe.html
new file mode 100644
index 0000000..e7d9669
--- /dev/null
+++ b/doc/gradcomdsetframe.html
@@ -0,0 +1,18 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set frame</B></H2><P>
+<code>set frame <i>on|off|circle</i></code><p>
+<ul>
+<code>on</code>           plots
+a rectangular frame around
+the clipped region <br>
+<code>off</code>         plots
+no frame
+<br>
+<code>circle</code>   plots a rectangular frame for
+lat-lon projections,
+plots a circular frame for a polar plot at the outermost latitude. Used
+for whole-hemisphere plots only. </ul><p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
+
diff --git a/doc/gradcomdsetfwrite.html b/doc/gradcomdsetfwrite.html
new file mode 100644
index 0000000..7e65c51
--- /dev/null
+++ b/doc/gradcomdsetfwrite.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set fwrite</title></head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set fwrite</b></h2>
<p>
<code>set fwrite <-be or -le> <-sq or -st> <-ap or -cl> <i>fname</i></code>
<p>
Sets the filename for data output as well as byte ordering and data format.

<ul>
  <p><code><i>fname</i>&nbsp&nbsp&nbsp</code>output filename (default = <code>grads.fwrite</code>)<br>
    <code><i>-be</i>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data byte ordering is big endian<br>
    <code><i>-le</i>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data byte ordering is little endian<br>
    <code><i>-sq</i>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data format is sequential<br>
    <code><i>-st</i>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data format is stream (default)<br>
  <code><i>-ap</i>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data is appended to existing file<br>
  <code><em>-cl</em>&nbsp&nbsp&nbsp&nbsp&nbsp</code>output data replaces existing file
  if it exists (default) </p>
  <p><br>
  </p>
</ul>
<p>

<p>
<h3>Usage Notes</h3>
<p>
The <a href="gradcomdqfwrite.html"><code>q fwrite</code></a> command
returns the status of the <code>fwrite</code> options. 

<p>
<h3>Examples </h3>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetgeotiff.html b/doc/gradcomdsetgeotiff.html
new file mode 100644
index 0000000..b8e9b0a
--- /dev/null
+++ b/doc/gradcomdsetgeotiff.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set geotiff</title></head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set geotiff</b></h2>
<p>
<code>set geotiff <-flt | -dbl> <i>fnameroot</i></code>
<p>
Sets the filename root and other characteristics for GeoTIFF output. </p>
<ul>
  <code><i>fnameroot</i>    </code>Output filename root -- GrADS will append ".tif" to the end <br>
                            (The default output file name is <code>gradsgeo.tif</code>)<br>
  <code>-flt         </code>Data will be written to file using floating-point precision (default)<br>
  <code>-dbl         </code>Data will be written to file using double precision<br>
</ul>
<p>
<h3>Usage Notes</h3>
<p>
This command is  available in GrADS v2.0.a5 or later. 
<p>This command is used in conjunction with   the <code><a href="gradcomdsetgxout.html">set gxout geotiff</a> </code> command which sets the graphics output type; the <code><a href="gradcomddisplay.html">display</a></code> command  will then create the output file instead of drawing a plot. The output data file will be in GeoTIFF format, which is a georeferenced raster image. The GeoTIFF output is a grid of data values, similar to the 'grfill' graphics output type, except the pixels (grid [...]

<p>The  file <code><i>fnameroot</i>.tif</code> will be replaced if it exists. 
<p>If the <code>-flt</code> or <code>-dbl</code> options are not given, the output will be written using floating-point precision. No compression algorithm is used when creating the GeoTIFF file. 
<h3>Examples </h3>
<p><code>set geotiff my_name<br>
set gxout geotiff<br>
d my_var</code><br>
</p>
<p>Note: The GrADS expression <code>my_var</code> must be a 2-dimensional grid that varies in X and Y (longitude and latitude). </p>
<p> </p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetgrads.html b/doc/gradcomdsetgrads.html
new file mode 100644
index 0000000..5df553d
--- /dev/null
+++ b/doc/gradcomdsetgrads.html
@@ -0,0 +1,29 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set grads</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set grads</b></h2>
+<p>
+<code>set grads <i>on</i>|<i>off</i></code>
+
+<P>
+This command turns on/off the display of the GrADS logo and the time label 
+for sreen and printed output.
+
+<p>
+<H3>Usage Notes</H3><P>
+<ol>
+<li>The default is <code><i>on</i></code> and is 
+reset by <a href="gradcomdclear.html"><code>clear</code></a>.
+<p>
+<li>
+To turn off only the time label, use <a
+href="gradcomdsettimelab.html"><code>set timelab</code></a>.
+</ol>
+
+</body>
+</html>
diff --git a/doc/gradcomdsetgrid.html b/doc/gradcomdsetgrid.html
new file mode 100644
index 0000000..6252dec
--- /dev/null
+++ b/doc/gradcomdsetgrid.html
@@ -0,0 +1,72 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set grid</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set grid</b></h2>
+<p>
+<code>set grid <i>status <linestyle> <color#></i></code>
+
+<p>
+Specifies the characteristics of the displayed grid lines. Default is to draw
+horizontal and vertical grid lines with color number 15 (grey) and linestyle 5 (dotted).
+
+<p>
+Options for <code><i>status</i></code> are:
+<ul>
+<code>on         </code>
+- both latitude and longitude lines are drawn<br>
+<code>off        </code>
+- no grid lines lines are drawn<br>
+<code>horizontal </code>
+- only latitude grid lines are drawn<br>
+<code>vertical   </code> 
+- only longigude grid lines are drawn<br>
+</ul>
+
+<p>
+Options for <code><i>linestyle</i></code> are:
+<ul>
+<code>1 </code>- solid <br>          
+<code>2 </code>- long dash <br>  
+<code>3 </code>- short dash <br>  
+<code>4 </code>- long dash, short dash <br>  
+<code>5 </code>- dotted <br>  
+<code>6 </code>- dot dash <br>  
+<code>7 </code>- dot dot dash <br>  
+</ul>
+
+<p>
+<code><i>color#</i></code> may be one of the <a href="16colors.html">16 GrADS default colors</a> 
+or a new color defined with <a href="gradcomdsetrgb.html"><code>set rgb</code></a>. 
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Changes to the grid display characteristics 'stick' until reset by a new
+execution of <code>set grid</code>.
+<p>
+<li>You cannot specify a <code><i>color#</i></code> without also specifying
+a <code><i>linestyle</i></code>.
+<p>
+<li>Grid lines are aligned with the labeled tick marks on the X and Y
+axes. GrADS chooses appropriate defaults for spacing of the labeled
+tick marks, but these defaults may be overridden by the commands <a
+href="gradcomdsetxaxis.html">set xaxis</a>, <a
+href="gradcomdsetyaxis.html">set yaxis</a>, <a
+href="gradcomdsetxlint.html">set xlint</a>, <a
+href="gradcomdsetylint.html">set ylint</a>, <a
+href="gradcomdsetxlevs.html">set xlevs</a>, and <a
+href="gradcomdsetylevs.html">set ylevs</a>.  Please consult these
+reference pages for more information.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetgridln.html b/doc/gradcomdsetgridln.html
new file mode 100644
index 0000000..713df1f
--- /dev/null
+++ b/doc/gradcomdsetgridln.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command:set gridln</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set gridln</b></h2>
+<p>
+<code>set gridln auto|off|<i>col#</i> </code>
+<p>
+Used with <a href="gradcomdsetgxout.html"> set gxout grid</a> to
+control the presence and appearance of the grid lines. 
+The options are as follows:
+<p>
+<ul>
+<code>auto</code> (default) 
+<ul>The grid lines are drawn and are the same color as the text.</ul>
+<p>
+<code>off</code>
+<ul>The grid lines are not drawn.</ul> 
+<p>
+<code><i>col#</i></code>
+
+<ul>The grid lines are drawn in the specified
+color. <code><i>col#</i></code> may be one of the <a
+href="16colors.html">16 GrADS default colors</a> or the number of a
+user-defined color created with <a href="gradcomdsetrgb.html">set
+rgb</a>.</ul>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li><code>set grdln</code> is reset by entering <a
+href="gradcomdclear.html"><code>clear</code></a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetgxout.html b/doc/gradcomdsetgxout.html
new file mode 100644
index 0000000..88e32b6
--- /dev/null
+++ b/doc/gradcomdsetgxout.html
@@ -0,0 +1,178 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set gxout</title>
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+-->
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body text="#000000">
+
+<h2><b>set gxout</b></h2>
+<p>
+<code>set gxout <i>graphics_type</i></code>
+
+<p>
+Where <code><i>graphics_type</i></code> can be one of the following:
+<ul>
+
+<code>bar       </code>
+Bar chart (The <a href="library.html">library</a> contains an <a href="ftp://cola.gmu.edu/grads/scripts/box_and_whisker.gs">example script</a> demonstrating how to use gxout bar and errbar)<br>
+
+<code>barb      </code>
+Wind barbs <br>
+
+<code>contour   </code>
+Contour plot<br>
+
+<code>errbar    </code>
+Error bars (The <a href="library.html">library</a> contains an <a href="ftp://cola.gmu.edu/grads/scripts/box_and_whisker.gs">example script</a> demonstrating how to use gxout bar and errbar)<br>
+
+<code>geotiff   </code>
+ (<span class="style1">2.0.a5+</span>) Generates a GeoTIFF format data file; options specified by <code><a href="gradcomdsetgeotiff.html">set geotiff</a></code><br>
+
+<code>grfill    </code>
+Shaded grid boxes<br>
+
+<code>fgrid     </code>
+Shaded grid boxes with values specified by 
+<a href="gradcomdsetfgvals.html"><code>set fgvals</code></a><br>
+
+<code>fwrite    </code>
+Writes data to file instead of drawing a plot; options specified by <code><a href="gradcomdsetfwrite.html">set fwrite</a></code><br>
+
+<code>grid      </code>
+Grid boxes with printed values<br> 
+<code>imap      </code>
+(<span class="style1">2.0.a8+</span>) Quickly drawn shaded grid boxes. No metafile, so no hard copy; image output only with <code><a href="gradcomdoutxwd.html">outxwd</a></code>.<br> 
+<code>kml       </code>
+ (<span class="style1">2.0.a5+</span>) Generates a TIFF  image file and a KML  text file; options specified by <code><a href="gradcomdsetkml.html">set kml</a></code><br>
+
+<code>line      </code>
+Line Graph <br>
+
+<code>linefill  </code>
+Color fill between two lines <br>
+
+<code>print     </code>
+Generates ascii output for anything displayed; controlled by
+<a href="gradcomdsetprnopts.html"><code>set prnopts</code></a><br>
+
+<code>scatter   </code> Generates a <a href="scatterplot.html">scatter diagram</a>. Requires two grid expressions as arguments, separated by a semicolon. See Usage Note #2 below.<br>
+
+<code>shaded    </code>
+Shaded contour plot, alias for original algorithm (shade1)<br> 
+<code>shade1    </code>
+(<span class="style1">2.0.0+</span>) Shaded contour plot, original  algorithm<br> 
+<code>shade2    </code>
+(<span class="style1">2.0.0+</span>) Shaded contour plot, new algorithm, polygons merged to be larger and fewer in number (faster to render)<br> 
+<code>shade2b   </code>
+(<span class="style1">2.0.0+</span>) Shaded contour plot, new algorithm, polygons all on sub-grid scale (slower to render)<br> 
+
+<code>shp       </code>
+(<span class="style1">2.0.a9+</span>) Generates a shapefile; options specified by <code><a href="gradcomdsetshp.html">set shp</a></code><br> 
+
+<code>stream    </code>
+Wind streamlines <br>
+
+<code>stat      </code>
+Prints statistical output to terminal instead of drawing a plot<br>
+
+<code>vector    </code>
+Wind vector arrows<br>
+</ul>
+<p>
+For station data, these additional graphics output types are also available:
+<ul>
+<code>findstn   </code>
+Finds nearest station<br> 
+
+<code>model     </code>
+Plots station model<br>
+
+<code>stnmark   </code>
+Plots a mark at station location that is colorized by data value<br>
+
+<code>tserbarb  </code>
+Time series of wind barbs at a point (1-D)<br>
+
+<code>tserwx    </code>
+Time series of weather symbols at a point (1-D)<br>
+
+<code>value     </code>
+Plots station values<br> 
+
+<code>wxsym     </code>
+Plots weather symbols at station, controlled by 
+<a href="gradcomdsetwxopt.html"><code>set wxopt</code></a><br> 
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+  <p> 
+  <li>For the graphics output types <code>vector, stream, </code>and <code>barb</code>, 
+    the plotting routines need two result grids, where the first result grid is 
+    treated as the U component, and the second result grid is treated as the V 
+    component. These two result grids are provided with the <a href="gradcomddisplay.html">display</a> 
+    command by entering two expressions separated by a semicolon:
+    <ul>
+      <code> display u ; v<br>
+      display ave(u,t=1,t=10) ; ave(v,t=1,t=10)</code> 
+    </ul>
+    <p> 
+  <li>For the graphics output types <code>vector</code> and <code>stream</code>, 
+    you can specify a third  grid expression that will be used to colorize the vectors 
+    or streamlines:
+    <ul>
+      <code> display u ; v ; mag(u,v)<br>
+        display u ; v ; hcurl(u,v)</code> 
+    </ul>
+    Beginning with <span class="red">GrADS version 2.0.2</span>, the graphics output type <code>scatter</code> will also take a third grid expression to colorize the points in the scatter diagrm.
+<p> 
+  <li>To draw a 1-D time series with graphics output types vector or barb, set 
+    the dimension environment so that only time is varying, then :
+    <ul>
+      <code> display const(u,0); u ; v </code> 
+    </ul>
+    <p> 
+  <li>For the graphics output type <code>wxsym</code>, each value at a station 
+    location is assumed to be a wx symbol code number. To see a chart of all available 
+    wx symbols and their corresponding code numbers, run the sample script <code>wxsym.gs</code>. 
+    <p> 
+  <li>The graphics output type <code>findstn</code> requires three arguments to 
+    be provided with the <a
+href="gradcomddisplay.html"><code>display</code></a> command. The first argument 
+    is a station data expression. The 2nd and 3rd arguments are the X and Y screen 
+    coordinates of the of the desired search location. GrADS will find the station 
+    closest to the specified X and Y position, and print its stid, lon, and lat. 
+    This graphics output type should only be used when X and Y are the varying 
+    dimensions and AFTER a regular display command (that results in graphics output) 
+    is entered. 
+    <p> 
+  <li>For the graphics output type <code>stnmark</code>, the size and style of 
+    the mark are controled by <a href="gradcomdsetdigsiz.html"><code>set digsiz</code></a> 
+    and <a href="gradcomdsetcmark.html"><code>set cmark</code></a>. To turn off 
+    rainbow colorizing and use a single color instead, use <code><a href="gradcomdsetccolor.html">set 
+    ccolor</a> <i>color#</i></code>. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+  The <a href="library.html">library</a> contains an <a href="ftp://cola.gmu.edu/grads/scripts/box_and_whisker.gs">example script</a> demonstrating how to use gxout bar and errbar
+
+<p> </p>
+</body>
+</html>
+
diff --git a/doc/gradcomdsethempref.html b/doc/gradcomdsethempref.html
new file mode 100644
index 0000000..0d628c3
--- /dev/null
+++ b/doc/gradcomdsethempref.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set hempref</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set hempref</b></h2>
+<p>
+<code>set hempref auto|nhem|shem</code>
+<p>
+This command controls the way wind barbs are plotted for any output
+where wind barbs are produced (e.g. <a
+href="gradcomdsetgxout.html"><code>set gxout barb</code></a>). 
+
+The options are as follows:
+<p>
+<ul>
+<code>auto</code> (default) 
+<ul>The Northern Hemisphere convention is used for wind barbs at
+positive latitudes and the Southern Hemisphere convention is used for
+wind barbs at negative latitudes. Barbs and flags are drawn on
+opposite sides of the wind arrow in the different Hemispheres.</ul>
+<p>
+<code>nhem</code>
+<ul>Overrides the default behavior so that all wind barbs 
+are plotted using the Northern Hemisphere convention.</ul> 
+<p>
+<code>shem</code>
+<ul>Overrides the default behavior so that all wind barbs 
+are plotted using the Southern Hemisphere convention.</ul> 
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetimprun.html b/doc/gradcomdsetimprun.html
new file mode 100644
index 0000000..cdbf7a7
--- /dev/null
+++ b/doc/gradcomdsetimprun.html
@@ -0,0 +1,33 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set imprun</B></H2><P>
+<code>set imprun <i>script-name</i></code>
+<p>
+
+This command sets up automatic execution of a Grads script before
+every <code><a href="gradcomddisplay.html">display</a></code>
+command.<p> <H3>Examples</H3><P>
+
+<p>
+This script is typically used to set an option that by default
+gets reset after each <code><a href="gradcomddisplay.html">display</a></code> 
+command, for example:
+<p>
+<dd><code><a href="gradcomdsetgrads.html">set grads </a>off</code>
+
+<p>
+<H3>Usage Notes</H3><P>
+
+You can issue any GrADS command from this script, but the
+interactions are not always clear. For example, if you issue a
+<code><a href="gradcomddisplay.html">display</a></code> command 
+from this script, you could enter an infinite recursion loop.
+
+<p>
+The argument to the script is the expression from the 
+<code><a href="gradcomddisplay.html">display</a></code>
+command.<p>
+
+
+
+
diff --git a/doc/gradcomdsetkml.html b/doc/gradcomdsetkml.html
new file mode 100644
index 0000000..d2525d5
--- /dev/null
+++ b/doc/gradcomdsetkml.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set kml</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set kml</b></h2>
<p>
<code>set kml <-<em>type</em>> <i>fnameroot</i></code>
<p>
Sets the filename root  and output options for Keyhole Markup Language (KML) output. </p>
<p>Where <code><em>type</em></code> may be one of the following:</p>
<ul>
  <code>img | image      </code>(default) For writing out an image file and complementary KML file<br>
  <code>ln  | line       </code>For writing out contour lines in a KML file<br>
  <code>poly             </code>For writing out polygons from the shaded contouring algorithm in KML format. <br>
</ul>
<p>When using the <code>-img</code> or <code>-image</code>  option (the default), two output files will be created: </p>
<ul>
  <p><code><i>fnameroot</i>.tif    </code>A TIFF image file with a pixel for each gridbox in the domain (default is <code>grads.tif</code>)<br>
    <code><i>fnameroot</i>.kml    </code>A text file  in the Keyhole Markup Language (KML) that contains <br>
    <code>                  </code>the georeferencing information for the TIFF image (default is <code>grads.kml</code>)<br>
</ul>
    Otherwise, only one file is written:</p>

<ul>
  <code><i>fnameroot</i>.kml    </code>A text file  in the KML format that contains the color, thickness, and <br>
  <code>                  </code>georeferencing information for the contour lines or polygons (default is <code>grads.kml</code>)
</ul>
<h3> </h3>
<h3>Usage Notes</h3>
<p>
This command is  available in version 2.0.a5 or later. 
The <code>-ln</code> option for writing out contours in KML format is available in version 2.0.a9 or later. The <code>-poly</code> option for writing out polygons in KML format is available in version 2.0.0 or later. In order to use the <code>-img</code> option, GrADS must be linked with the TIFF and GeoTIFF libraries. Check the output from 'q config' for the  message "GeoTIFF and KML/TIFF output ENABLED". The <code>-ln</code> and <code>-poly</code> options do not depend on the  [...]
<p>This command is used in conjunction with   the <code><a href="gradcomdsetgxout.html">set gxout kml</a> </code> command which sets the graphics output type; the <code><a href="gradcomddisplay.html">display</a></code> command  will then create the  output file(s) instead of drawing a plot. The display expression must be a 
2-dimensional grid that varies in X and Y (longitude and latitude), and the projection must be latlon. 
<p>The  files <code><i>fnameroot</i>.tif</code> and <code><i>fnameroot</i>.kml</code> will be replaced if they exist. If 
  <code> <i>fnameroot</i> </code>provided by the user ends in ".kml", GrADS will not append an additional ".kml", and will change the extension to ".tif" for the image file (if necessary). 
<p>The output in KML format is intended for use with GIS  tools such as <a href="http://earth.google.com/">Google Earth</a>. Please note that Google Earth prefers longitudes to range from -180 to 180 instead of 0 to 360.
<h3>Examples </h3>
<pre>clear
set gxout kml
set kml myimg
d var

clear
set gxout kml
set kml -ln mycntr
d var
 
</pre>
</p>
<p> </p>
<p> </p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetlatlonlevtimeens.html b/doc/gradcomdsetlatlonlevtimeens.html
new file mode 100644
index 0000000..d173454
--- /dev/null
+++ b/doc/gradcomdsetlatlonlevtimeens.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set lat|lon|lev|time|ens</B></H2>
<P>
<code>set lat|lon|lev|time|ens <i>val1 <val2></i></code><p>
This set command sets one dimension of the dimension environment using
world coordinates.<p>
<H3>Usage Notes</H3><P>
When you enter dimensions in grid coordinates, they are
always converted to world coordinates. This conversion requires some
knowledge of what scaling is in use for grid to world conversions. The
scaling that is used in all cases (except one) is the scaling of the
DEFAULT FILE. The exception is when you supply a dimension expression
within a variable specification, which will be covered later. <p>
<H3>Examples</H3><P>
<ol>
<li><code>set lon -180 0</code> (sets longitude to vary from 180W to 0).
<br>
<li><code>set lat 0 90</code> (sets latitude to vary from the equator to
90N)
<br>
<li><code>set lev 500</code> (sets the level to 500mb - a fixed dimension)
<li><code>set ens cntrl</code> (sets the ensemble to cntrl)<br>
</ol>
\ No newline at end of file
diff --git a/doc/gradcomdsetlats.html b/doc/gradcomdsetlats.html
new file mode 100644
index 0000000..1559fdd
--- /dev/null
+++ b/doc/gradcomdsetlats.html
@@ -0,0 +1,64 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set lats</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set lats</b></h2>
+<p>
+<code>set lats <i>arguments</i></code>
+<p>
+Valid <code><i>arguments</i></code> are: 
+<p>
+<pre>
+parmtab    <i>filename</i> 
+convention [ grads_grib | grib_only | coards ]
+calendar   [ standard | noleap | clim | climleap ]
+frequency  [ yearly | monthly | monthly_table_comp | weekly | daily | hourly | forecast_hourlyfixed] 
+delatat    <i>n</i>  
+fhour      <i>n</i>
+model      <i>model_name</i>
+center     <i>center_name</i>
+create     <i>filename</i>
+comment    <i>string</i>
+gridtype   [ linear | gaussian | generic ]
+vertdim    DIMNAME <i>val1 val2 ... valN</i> 
+var        VARNAME [ average | accum | instant ] LEVEL_ID
+timeoption [ grid | dim_env ]
+write      VAR_ID <i>level</i> 
+close 
+</pre>
+
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+<p>
+<pre>
+set lats parmtab lats.ncep.MRFtable
+set lats convention coards
+set lats calendar standard
+set lats frequency hourly
+set lats deltat 6
+set lats fhour 120
+set lats model MRF
+set lats center NCEP
+set lats create MRF.EXP1
+set lats comment "Latest MRF forecast with convection update"
+set lats gridtype gaussian
+set lats vertdim plev 1000 850 500 200
+set lats var u instant 1
+set lats v timeoption dim_env (use the GrADS dimension environment)
+set lats write 1 500 (return from t lats var)
+set lats close
+</pre>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetlfcols.html b/doc/gradcomdsetlfcols.html
new file mode 100644
index 0000000..a878b62
--- /dev/null
+++ b/doc/gradcomdsetlfcols.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set lfcols</B></H2><P>
+<code>set lfcols <i>1 2</i></code><br>
+<code>d a;b</code><p>
+Color where <code>a</code><<code>b</code> in white
+(<code><i>1</i></code>) and <code>b</code>><code>a</code> in red
+(<code><i>2</i></code>).<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetline.html b/doc/gradcomdsetline.html
new file mode 100644
index 0000000..28218ae
--- /dev/null
+++ b/doc/gradcomdsetline.html
@@ -0,0 +1,41 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set line</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set line</b></h2>
+<p>
+<code>set line <i>color# <style> <thickness></i></code>
+
+<p>
+Sets current <code>line</code> attributes. 
+
+
+<p>
+<code><i>color#:</i>    </code>one of the <a href="16colors.html">16 GrADS default colors</a> or a new color defined with <a href="gradcomdsetrgb.html"><code>set rgb</code></a><br>
+<code><i>style:</i>     1 </code>- solid <br>          
+<code>           2 </code>- long dash <br>  
+<code>           3 </code>- short dash <br>  
+<code>           4 </code>- long dash, short dash <br>  
+<code>           5 </code>- dotted <br>  
+<code>           6 </code>- dot dash <br>  
+<code>           7 </code>- dot dot dash <br>  
+<code><i>thickness: </i></code>values range from <code>1</code> to <code>6</code>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Line thicknesses 1-5 will take effect only in laser printed output; on
+the display screen thicknesses 1-5 will all look the same. For screen
+display, only thickness 6 will appear as a thick line.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetlog1d.html b/doc/gradcomdsetlog1d.html
new file mode 100644
index 0000000..94a36b5
--- /dev/null
+++ b/doc/gradcomdsetlog1d.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<h2>set log1d</h2>
<code>set log1d <i>arg</i></code>
<p>Where <code><i>arg</i></code> can be one of the following:

<ul>
  <code>logh     </code>make the horizontal axis logarithmic<br />
  <code>logv     </code>make the vertical axis logarithmic<br />
  <code>loglog   </code>make both axes logarithmic<br />
  <code>off      </code>disable for both axes
</ul>
<p><br />

<h3>Usage Notes</h3>
<p>This command is available in GrADS version 2.0 and higher (it is not in the 2.0.a* versions). </p>
<p>This setting is intended for use with 1-D plots of gridded data ONLY. </p>
<p>To override the axis labeling, use the "set xlevs" or "set ylevs" command.</p>
<p>If axis values approach zero, grads will automatically extend the axis to zero.  And then the display command will fail, with an error message.  In this case, it is necessary to use the "set vrange" command to force the axis range to be positive valued.</p>
<h3>Examples</h3>
<pre>'open gfs.ctl'
'set lat 40'
'set lev 500'
'set lon 1 10'
'set vrange 1 1050'
'set ylevs 1 2 5 10 20 50 100 200 500 1000'
'set log1d loglog'
'set mproj off'
'd pow(2,lon)'
</pre>
<p> </p>
\ No newline at end of file
diff --git a/doc/gradcomdsetloopdim.html b/doc/gradcomdsetloopdim.html
new file mode 100644
index 0000000..ff3ef18
--- /dev/null
+++ b/doc/gradcomdsetloopdim.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set loopdim</B></H2>
<P>
<code>set loopdim <i>x|y|z|t|e</i></code><p>
By default, the animation dimension is time. This command allows you to
set which dimension to animate.<p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>
 
\ No newline at end of file
diff --git a/doc/gradcomdsetloopincr.html b/doc/gradcomdsetloopincr.html
new file mode 100644
index 0000000..f2b2371
--- /dev/null
+++ b/doc/gradcomdsetloopincr.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set loopincr</h2>
+<code>set loopincr <i>incr</i></code><p>
+set looping increment<p>
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
diff --git a/doc/gradcomdsetlooping.html b/doc/gradcomdsetlooping.html
new file mode 100644
index 0000000..b0e73fd
--- /dev/null
+++ b/doc/gradcomdsetlooping.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set looping</B></H2><P>
+<code>set looping <i>on|off</i></code><p>
+Animate when fewer than three dimensions are varying (ie, animate a line
+graph).<p>
+<H3>Usage Notes</H3><P>
+<ol>
+<li>Remember to turn <code>looping off</code> when you are done animating,
+or
+you will get suprised when you enter your next expression. <P>
+</ol>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmap.html b/doc/gradcomdsetmap.html
new file mode 100644
index 0000000..d2304e7
--- /dev/null
+++ b/doc/gradcomdsetmap.html
@@ -0,0 +1,16 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set map</B></H2> 
+<P> 
+<code>
+set map <i>auto</i>
+<br>
+  OR 
+<br>
+set map <i>color style thickness</i>
+</code>
+<p>
+Draws the map background using the requested line attributes.<p>
+Settings stay the same until changed by new <code>set</code> commands. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmdlopts.html b/doc/gradcomdsetmdlopts.html
new file mode 100644
index 0000000..5b806d6
--- /dev/null
+++ b/doc/gradcomdsetmdlopts.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set mdlopts</B></H2><P>
+<code>set mdlopts <i>opt</i></code><p>
+<code><i>opt</i></code> = <code>noblank, blank, dig3, or nodig3</code><p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmissconn.html b/doc/gradcomdsetmissconn.html
new file mode 100644
index 0000000..c62fa91
--- /dev/null
+++ b/doc/gradcomdsetmissconn.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set missconn</B></H2><P>
+<code>set missconn <i>on|off</i></code><p>
+By default, when GrADS plots a line graph, missing data is indicated by a
+'break' in the line.<p>
+<ul><code>set missconn on</code>     connects the
+lines
+across missing data.<br>
+<code>set missconn off</code>   resets the default
+behavior.</ul><p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmpdraw.html b/doc/gradcomdsetmpdraw.html
new file mode 100644
index 0000000..5cbee33
--- /dev/null
+++ b/doc/gradcomdsetmpdraw.html
@@ -0,0 +1,9 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set mpdraw</B></H2><P>
+<code>set mpdraw <i>on|off</i></code><p>
+If <code>off</code>, does not draw the map background. Requested map
+scaling is still in force. <p>
+Settings stay the same until changed by new <code>set</code> commands. <p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmpdset.html b/doc/gradcomdsetmpdset.html
new file mode 100644
index 0000000..bdcd5c4
--- /dev/null
+++ b/doc/gradcomdsetmpdset.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set mpdset</B></H2><P>
+<code>set mpdset <<i>lowres|mres|hires|nmap</i>></code><p>
+ <code>lowres</code> is the default. <code>mres</code> and
+<code>hires</code> have state and country outlines. <code>nmap</code>
+covers only North America. <p>
+Settings stay the same until changed by new <code>set</code> commands. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetmproj.html b/doc/gradcomdsetmproj.html
new file mode 100644
index 0000000..2e31207
--- /dev/null
+++ b/doc/gradcomdsetmproj.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set mproj</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set mproj</b></h2>
+<p>
+<code>set mproj <i>proj</i></code><p>
+Sets current map projection. Options for <code><i>proj</i></code> are:
+<p>
+<ul>
+<code>latlon     </code>
+Lat/lon projection with aspect ratio maintained (default) <br>
+<code>scaled     </code>
+Lat/lon aspect ratio is not maintained; plot fills entire plotting area<br>
+<code>nps        </code>
+North polar stereographic <br>
+<code>sps        </code>
+South polar stereographic <br>
+<code>lambert    </code>
+Lambert conformal conic projection<br>
+<code>mollweide  </code>
+Mollweide projection<br>
+<code>orthogr    </code>
+Orthographic projection<br>
+<code>robinson   </code>
+Robinson projection, requires <code>set lon -180 180, set lat -90 90</code><br>
+<code>off        </code>
+No map is drawn; axis labels are not interpreted as lat/lon <br>
+</ul>
+<p>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetmpt.html b/doc/gradcomdsetmpt.html
new file mode 100644
index 0000000..127eaf0
--- /dev/null
+++ b/doc/gradcomdsetmpt.html
@@ -0,0 +1,50 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set mpt</h2>
+<code>set mpt <i>type off |
+<<col><style><thick>></i></code><p>
+command to control map background behavior. <code><i>type</i></code> is
+the map type; it can be a number from <code>0</code> to <code>255</code>,
+or it can be an asterick(*) to indicate this command applies to all the
+type values.  The <code>color</code> can be set to <code>-1</code>, which
+indicates to GrADS to use the <a href="gradcomdsetmap.html"><code>set
+map</code></a> settings for this map type, rather than the settings
+specified by the <code>set mpt</code> command.<p>
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
+<ol>
+<li>Lets say you want to use the hires data set and plot political 
+boundaries, but not state boundaries:<p>
+
+<ul>
+<code>
+set mpt * off<br>
+set mpt 0 -1<br>
+set mpt 1 -1</code></ul><p>
+
+<li>
+
+
+Lets say you want to use the hires data set, and have coastlines
+be thicker, and a different color, than political boundaries:<p>
+<ul>
+<code>
+set mpt * off<br>
+set mpt 0 1 1 6<br>
+set mpt 1 15 1 1</code></ul><p>
+
+<li>
+The <a href="gradcomdsetmpdraw.html"><code>set mpdraw</code></a> and
+<a href="gradcomddrawmap.html"><code>draw map</code></a> commands work as
+before; you can do some interesting line types by overlaying:<p>
+<ul>
+<code>
+set mpt 51 7 1 12<br>
+draw map<br>
+set mpt 51 0 1 1<br> 
+draw map</code></ul>
+<p>
+
+This would produce two yellow lines parallel and close together for 
+map type 51.  </ol>
+
diff --git a/doc/gradcomdsetmpvals.html b/doc/gradcomdsetmpvals.html
new file mode 100644
index 0000000..cd30a39
--- /dev/null
+++ b/doc/gradcomdsetmpvals.html
@@ -0,0 +1,15 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set mpvals</B></H2><P>
+<code>set mpvals <i>lonmin lonmax latmin latmax </i></code><p>
+Sets reference longitudes and latitudes for polar stereographic plots. By
+default, these are set to the current dimension environment limits. This
+command overrides that, and allows the data-reference to be decoupled with
+the map display. The polar plot will be drawn such that the region bounded
+by these longitudes and latitudes will be entirely included in the plot.
+<p> 
+
+GrADS will plot lat/lon lines on polar plots with no labels as yet. To
+turn this off, <code>set grid off</code>.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetparea.html b/doc/gradcomdsetparea.html
new file mode 100644
index 0000000..19b8014
--- /dev/null
+++ b/doc/gradcomdsetparea.html
@@ -0,0 +1,29 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set parea</B></H2><P>
+<code>set parea <i>xmin xmax ymin ymax</i></code><p>
+
+The command specifies the area for plotting contour plots, maps, or line
+graphs. This area does not include axis labels, titles, etc., so if you
+need to see those, provide for an adequate margin. <p>
+
+The region is specified in terms of virtual page units. By default, the
+virtual page is equal to the real page, so the units are approximately
+inches on the real page. <p>
+
+Maps are scaled to fit within the plotting area such that their correct
+aspect ratio is maintained. Thus, the map will not fill the entire
+plotting area except under certain lat/lon ranges. A line graph or a
+contour plot without a map will be scaled to fit entirely within the
+specified plotting area. <p>
+
+By default, an appropriate plotting area is chosen depending on the type
+of graphics output. To return to this default, enter: <p>
+
+<dd><code>set parea off </code><p>
+
+It is not appropriate to use this command to put multiple plots on one
+page. It is better to use the <a href="gradcomdsetvpage.html"><code>set
+vpage</code></a> command. <p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetpoli.html b/doc/gradcomdsetpoli.html
new file mode 100644
index 0000000..6b1d882
--- /dev/null
+++ b/doc/gradcomdsetpoli.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set poli</B></H2><P>
+<code>set poli <i>on|off</i></code><p>
+Selects whether you want political boundries drawn for the
+<code>mres</code> or <code>hires</code> map data sets. The default is
+<code>on</code>.<p>
+Settings stay the same until changed by new <code>set</code> commands. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetprnopts.html b/doc/gradcomdsetprnopts.html
new file mode 100644
index 0000000..2317b3e
--- /dev/null
+++ b/doc/gradcomdsetprnopts.html
@@ -0,0 +1,59 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set prnopts</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set prnopts</b></h2>
+<p>
+<code>set prnopts <i>format numl numb</i> <u></code>
+<p>
+Controls the way values are printed when <a href="gradcomdsetgxout.html"><code>set gxout print</code></a> is used. 
+<p>
+<ul>
+<code><i>format</i>&nbsp&nbsp</code>
+a C language template for formatting ascii output. Default is <code>%g</code>.<br>
+<code><i>numl</i>&nbsp&nbsp&nbsp&nbsp</code>
+number of values to print per record. Default is 8.<br>
+<code><i>numb</i>&nbsp&nbsp&nbsp&nbsp</code>
+number of blanks to insert between values. Default is 1.<br>
+<code>u&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
+print 'Undef' instead of the numerical value for missing data.<br>
+</ul>
+
+<h3>Usage Notes</h3>
+<ol>
+The first line of the ascii output will tell the user how many data
+values are being printed as well as the missing data value.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<ol>
+<li>This example will print all the values in exponential notation:
+<p>
+<ul><pre>
+set gxout print
+set prnopts %10.3e 5 1
+d t
+</code>
+</ul>
+<p>
+The output might look like this: 
+<ul>
+<pre>
+Printing Grid -- 30 Values -- Undef = -2.56e+33
+-2.560e+33 -2.560e+33  3.014e+02  3.011e+02  3.001e+02 
+-2.560e+33 -2.560e+33  3.010e+02 -2.560e+33 -2.560e+33 
+-2.560e+33 -2.560e+33 -2.560e+33 -2.560e+33 -2.560e+33 
+-2.560e+33 -2.560e+33 -2.560e+33  2.993e+02  2.995e+02 
+-2.560e+33 -2.560e+33  3.004e+02  3.008e+02  3.010e+02 
+-2.560e+33 -2.560e+33  2.999e+02  3.010e+02  3.012e+02 
+</pre>
+</ul>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetrband.html b/doc/gradcomdsetrband.html
new file mode 100644
index 0000000..54524a0
--- /dev/null
+++ b/doc/gradcomdsetrband.html
@@ -0,0 +1,57 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set rband</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set rband</b></h2>
+<p>
+<code>set rband <i>num mode x1 y1 x2 y2</i></code>
+<p>
+Sets the mode and defines the active region for the 'rubber band' widget. 
+<p>
+<ul>
+<code><i>num</i>   </code>
+- widget number<br>
+<code><i>mode</i>  </code>
+- may be either <code>box</code> or <code>line</code><br>
+<code><i>x1</i>    </code>
+- lowest X point where the widget will be active (in virtual page units)<br>
+<code><i>y1</i>    </code>
+- lowest Y point where the widget will be active (in virtual page units)<br>
+<code><i>x2</i>    </code>
+- highest X point where the widget will be active (in virtual page units)<br> 
+<code><i>y2</i>    </code>
+- highest Y point where the widget will be active (in virtual page units)<br>
+</ul>
+<p>
+After executing <code>set rband</code>, rubber bands are defined by
+executing <a href="gradcomdqpos.html"><code>q pos</code></a> which
+freezes the system until the user clicks, drags, and then releases the
+mouse somewhere within the active rband area. See the <a
+href="gradcomdqpos.html"><code>q pos</code></a> reference page for
+details on the returned information.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>In <code>box</code> mode, as the user clicks and drags the mouse in
+the active rband area a box is drawn with one corner located at the
+initial click and the opposite corner located at the release point. In
+<code>line</code> mode, a line is drawn between these two points.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+See <a href="script.html#widgets">widgets</a> for more information
+and examples.
+
+
+</body>
+</html>
+
+
+
diff --git a/doc/gradcomdsetrbcols.html b/doc/gradcomdsetrbcols.html
new file mode 100644
index 0000000..b94fcca
--- /dev/null
+++ b/doc/gradcomdsetrbcols.html
@@ -0,0 +1,39 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set rbcols</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>set rbcols</b></h2>
+<p>
+<code>set rbcols <i>color1 color2 ... colorN</i></code><br>
+
+<p>
+This command specifies a new rainbow color sequence. The
+<code><i>color#</i></code> arguments may be taken from the <a
+href="16colors.html">16 GrADS default colors</a> or they may be new
+color numbers defined via the <a href="gradcomdsetrgb.html"><code>set
+rgb</code></a> command. This sequence of colors replaces the <a
+href="16colors.html">default rainbow color sequence</a> whenever the
+rainbow colors are used.
+
+<p>
+<code>set rbcols </code> given without any arguments will return to
+the default GrADS rainbow sequence.
+
+<p>
+<h3>Usage Notes</h3>
+
+<ol>
+<li>Changes to the rainbow color sequence 'stick' until reset by a new
+execution of <code>set rbcols</code>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetrbrange.html b/doc/gradcomdsetrbrange.html
new file mode 100644
index 0000000..165fbd2
--- /dev/null
+++ b/doc/gradcomdsetrbrange.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set rbrange</B></H2><P>
+<code>set rbrange <i>low high</i></code><p>
+Sets the range of values used to determine which values acquire which
+rainbow color. By default, the <code><i>low</i></code> and
+<code><i>high</i></code> are set to the min and max of the
+result grid. This is reset by a <code>clear</code> command. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetrgb.html b/doc/gradcomdsetrgb.html
new file mode 100644
index 0000000..9e8c1b6
--- /dev/null
+++ b/doc/gradcomdsetrgb.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set rgb</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set rgb</b></h2>

<p>
This command allows the user to define a new color within GrADS. The syntax is:

<p>
<code>set rgb <i>color# R G B</i></code>

<p>
where:
<ul>
<code><i>color#</i>  </code>is the color number; it can range from 16 to 99  <span class="style1">(or 255 -- see Usage Note #1) </span><br>
<code><i>R</i>      </code> is the Red value (0-255) <br>
<code><i>G</i>      </code> is the Green value (0-255) <br>
<code><i>B</i>      </code> is the Blue value 0-255) </br>
</ul>

<p>
The new color is referred to by its <code><i>color#</i></code>
in any GrADS command that allows specification of colors.

<p>
<h3>Usage Notes</h3>

<ol>
<li>The <code><i>color#</i></code> must be a value between  <code>16</code> and <code>99</code> --  <a href="16colors.html"><code>0</code> to <code>15</code> are
    predefined</a>. 
    <br>
     <span class="style1">As of GrADS version 2.0.a6, the maximum  number 
    of colors increased from 99 to 255.<br>
    <br>
    </span>
<li>The GrADS metafile-to-postscript translator <a
href="gradutilgxps.html"><code>gxps</code></a> will make use of any
new color settings although the output colors will be
printer-dependent and should be checked for the desired
rendering. When converting new color settings into grayscales, <a
href="gradutilgxps.html"><code>gxps</code></a> will translate the
GREEN intensity ONLY into a new greyscale value. Note that <a
href="gradutilgxps.html"><code>gxps</code></a> does have a predefined
mapping between color values from 0 to 15 such that the <a
href="16colors.html">predefined rainbow sequence</a> is rendered into a
fairly pleasing greyscale gradation; this cannot be done for newly
defined colors.<br>
<br>
<li>For more details on using defined colors, see the section in the
User's Guide on <a href="colorcontrol.html">controlling colors in
GrADS</a>.
</ol>

<p>
<h3>Examples</h3>

<P>
<code>set rgb 50 200 200 200 </code>

<p>
Defines a new color number, <code>50</code>, and
assign a color to it. In this case, the color would be a light gray. 

<p>


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradcomdsetsdfattr.html b/doc/gradcomdsetsdfattr.html
new file mode 100644
index 0000000..97a57c3
--- /dev/null
+++ b/doc/gradcomdsetsdfattr.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>GrADS Command: set sdfattr</title>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>set sdfattr</B></H2>
<P>
<code>set sdfattr <i>varname attribute_type attribute_name attribute_value</i></code>
<p> Sets attribute metadata to be included in the output file created with the 
  <a href="gradcomdsdfwrite.html"><code>sdfwrite</code></a> command.
<ul>
  <p><code><i>varname</i>           </code>May be set to    "global", "longitude", "latitude", "level",  "time", "ensemble", or <br />
    <code>                  </code>a defined variable name<br>
  <code><i>attribute_type</i></code>       May be one of five data type types (valid aliases in parentheses): <br />
<code>                  </code>"char" (String, Str, Url) <br />
<code>                  </code>"short" (Int16, UInt16)<br />
 <code>                  </code>"int" (long, Int32, UInt32)<br />
<code>                  </code>"float" (Float32)<br />
<code>                  </code>"double" (Float64). <br>
    <code><i>attribute_name</i>    </code>May be any single word or string with no spaces (e.g.: "units", "long_name")<br />
    <code><i>attribute_value</i>   </code>May be any string as long as the length of the entire entry does not exceed 512 characters. <br />
                                        For numeric types, may be a list of comma-delimited numerals. </p>
  </ul>
<p>
<H3>Usage Notes</H3>
<P>This command is  available in GrADS v2.0.a3 or higher. 
<P>The <code><a href="gradcomdreset.html">reset</a></code> command will release all the attributes from memory. To do this without resetting all the other user-specified options, use  the <code><a href="gradcomdclear.html">clear sdfwrite</a></code> command.
<H3>Examples</H3>
<P><code>set sdfattr precip String units mm/day</code><br>
<code>set sdfattr precip String long_name Daily Precipiation </code><br />
<code>set sdfattr precip double actual_range 0,57.5</code>
\ No newline at end of file
diff --git a/doc/gradcomdsetsdfwrite.html b/doc/gradcomdsetsdfwrite.html
new file mode 100644
index 0000000..66f4167
--- /dev/null
+++ b/doc/gradcomdsetsdfwrite.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set sdfwrite</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set sdfwrite</b></h2>
<p>
<code>set sdfwrite <-4d or -5d> <-flt or -dbl> <-nc3 or -nc4> <-chunk> <-zip> <i>fname</i></code>
<p>
Sets the filename and other characteristics for self-describing  data output. Arguments in <code>< ></code> are optional. </p>
<ul>
  <p><code><i>fname</i>    </code>output filename (default = <code>grads.sdfwrite.nc</code>)<br>
    <code>-4d      </code>forces the output data file to have at least 4 coordinate dimensions (lon, lat, lev, and time)<br>
    <code>-5d      </code>forces the output data file to have 5 coordinate dimensions (lon, lat, lev, time, and ens)<br>
    <code>-flt     </code>output data written with floating point precision<br>
    <code>-dbl     </code>output data written with double precision (default)<br>
    <code>-nc3     </code>output data file written in  netCDF classic format (default)<br>
    <code>-nc4     </code>output data file written in netCDF-4 format<br>
    <code>-chunk   </code>output data will be chunked (only if <code>-nc4</code>); set chunk sizes with the <a href="gradcomdsetchunksize.html"><code>set chunksize</code></a> command<br>
    <code>-zip     </code>output data will be compressed (implies <code>-nc4</code> and <code>-chunk</code>)<br>
    </p>
</ul>
<p>
<h3>Usage Notes</h3>
<p>
This command is  available in GrADS <span class="style1">v2.0.a3+</span>. 
<p> The <code>-4d</code> and <code>-5d</code> options were introduced in GrADS <span class="style1">v2.0.a5+</span>. 
<p> The <code>-flt</code>, <code>-dbl</code>, <code>-nc3</code>,<code>-nc4</code>, <code>-chunk</code>, and <code>-zip</code> options were introduced in GrADS <span class="style1">2.0.a8+</span>.
<p>  If the <code>-4d</code> and <code>-5d</code> options are not used, the output will have the same number of dimensions as the defined variable being written out to file (GrADS <span class="style1">2.0.a9+</span>). In earlier versions, the <code>-4d</code> and <code>-5d</code> options "stuck" until the <code><a href="gradcomdreset.html">reset</a></code>, <code><a href="gradcomdreinit.html">reinit</a></code>, or <code><a href="gradcomdclear.html">clear sdfwrite</a></code> comm [...]
<p>The output data will be in NetCDF format.  The  file 
  <code><i>fname</i></code> will be replaced if it exists. Use the 
  <a href="gradcomdsdfwrite.html"><code>sdfwrite</code></a> command to create the output file. 
The <a href="gradcomdqsdfwrite.html"><code>query sdfwrite</code></a> command
  returns the status of the <code>sdfwrite</code> options. The <code><a href="gradcomdclear.html">clear sdfwrite</a></code> command resets the sdfwrite parameters back to their default values. 
<p>If you use the <code>-zip</code> option, then it is not necessary to also specify <code>-nc4</code> or <code>-chunk</code>; GrADS will automatically set these options. A compressed file is always in netCDF-4 format and is always chunked. Use the <a href="gradcomdsetchunksize.html"><code>set chunksize</code></a> command to set the chunk size before writing out the file. 
Please see the documentation on <a href="compression.html">compression</a> for more details. 
<p>
<h3>Examples </h3>
<p>Suppose you have a high resolution data set (5120x2560) and you wish to save the variable as compressed netcdf with floating point precsion. </p>
<p><code>set x 1 5120<br />
set y 1 2560<br />
set z 1<br />
set t 1<br />
define var = var<br /> 
set sdfwrite -flt  -zip var.nc<br />
set chunksize 512 256<br />
sdfwrite var<br />
</code></p>
<p> </p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetshp.html b/doc/gradcomdsetshp.html
new file mode 100644
index 0000000..ee68e70
--- /dev/null
+++ b/doc/gradcomdsetshp.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set shp</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set shp</b></h2>
<p>
<code>set shp <-<em>type</em>> <-fmt <em>n m</em> > <i>fnameroot</i></code>
<p>
Sets the filename root  for shapefile output and has additional arguments to control the type of shapefile created and the formatting of numerical values in the dBase file. This command is used in conjunction with <code><a href="gradcomdsetgxout.html">set gxout shp</a></code> and <code><a href="gradcomddisplay.html">display</a></code> to create four complementary files:</p>
<ul>
  <p><code><i>fnameroot</i>.shp    </code>The main binary file in which each record describes a shape with a list of vertices (default is <code>grads.shp</code>)<br>
    <code><i>fnameroot</i>.shx    </code>The index file  contains the offsets for each record in the main file  (default is <code>grads.shx</code>)<br>
    <code><i>fnameroot</i>.dbf    </code>A dBase table that contains feature attributes for each record in the main file (default is <code>grads.dbf</code>)<br>
  <code><i>fnameroot</i>.prj    </code>A text file that describes the default projection: the WGS84 lon-lat spheroid   (default is <code>grads.prj</code>)</p>
</ul>
  <p>Where <code><em>type</em></code> may be one of the following:</p>
  <ul>
    <p><code>ln | line        </code>(default) Shapefile output will contain shapes of the type PolyLineM (measured contour lines)<br>
      <code>pt | point       </code>Shapefile output will contain shapes of the type PointM (measured points)<br>
      <code>poly             </code>Shapefile output will contain polygons of the type PolygonM (measured polygons)</p>
    <p><code>-fmt <em>n m</em>         </code>Optional controls for the formatting of the numerical values in the dBase file. <br>
      <code>                 </code><code><em>n</em> </code>is the maximum number of digits to be used when formatting integers and doubles in the data base entry (default is 12)<br>
      <code>                 <i>m</i> </code>is the number of precsion decimal places to be used when formatting doubles in the data base entry (default is 6)<br>
      <code>                 Both <i>m</i> </code>and <i>n</i> must be provided when using the -fmt option
      </p>
        </p>
    <p>   </p>
</ul>
<h3>Usage Notes</h3>
<p>
This command is  available in GrADS v2.0.a9 or later. The -poly option is available in version 2.0.0 or later. 
<p>The  files <code><i>fnameroot</i>.* </code>will be replaced if they exist. 
<p>When creating a shapefile with contour lines, the <code><a href="gradcomdsetcterp.html">cterp</a></code> setting is ignored -- contours are written out as if <code> <a href="gradcomdsetcterp.html">cterp</a></code> is set to <code>off</code> (i.e. no spline fitting).
<p>Use the <code><a href="gradcomdqshpopts.html">q shpopts</a></code> command to get information on the status of the shapefile options; use  the <code><a href="gradcomdclear.html">clear shp</a></code> command to reset shapefile options to their default values.<p>The output in shapefile format is intended for use with GIS  tools, and can also be drawn with GrADS. Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more information.
<h3>Examples </h3>
<p><code>set gxout shp<br>
  set shp -ln  -fmt 8 3 my_shapefile_name<br>
 d my_var<br>
<br>
set shp -poly mypolyfile<br>
set shpattr author string your_name<br>
d my_var</code><br>
</p>
<p>Note: The GrADS expression <code>my_var</code> must be a 2-dimensional grid that varies in X and Y (longitude and latitude). In this example, GrADS will use the format string <code>%8.3f</code> to write out double precision numbers to the dBase file. <br>
</p>
<p> </p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetshpattr.html b/doc/gradcomdsetshpattr.html
new file mode 100644
index 0000000..e399090
--- /dev/null
+++ b/doc/gradcomdsetshpattr.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>GrADS Command: set dbfield</title>
<body bgcolor="e0f0ff" text="#000000">

<H2><B>set shpattr</B></H2>
<P>
<code>set shpattr <i>name type value</i></code>
<p> Sets attribute metadata to be included in the shapefile created with the 
  <a href="gradcomdsetgxout.html"><code>set gxout shp</code></a> command.
<ul>
  <p><code><i>name</i>    </code>Name of the data base field (attribute), must be 11 characters or less. <br>
  <code><i>type</i>    </code>May be one of three data types: "string" ("char"), "int", or "double". <br />
    <code><i>value</i>   </code>May be a numeric value (for types "int" and "double") or any string as long as the length of the entire entry does not exceed 512 characters. <br />
                        </p>
  </ul>
<H3>Usage Notes</H3>
<P>This command is  available in GrADS v2.0.a9 or higher. 
<P>Numerical attribute values (integers and doubles) are written to the shapefile in text format. The <code><a href="gradcomdsetshp.html">set shp</a></code> command controls 
 the formatting of the numbers, by specifiying the length of the number (total number of columns) and the precision (number of places to the right of the decimal place, which is only meaningful for attributes of type double). 
<P>The <code><a href="gradcomdreset.html">reset</a></code> or <code><a href="gradcomdreinit.html">reinit</a></code> commands will release all the user-specified shapefile attributes from memory. To do this without resetting all the other user-specified options, use  the <code><a href="gradcomdclear.html">clear shp</a></code> command.
<P>Use the <code><a href="gradcomdqshpopts.html">q shpopts</a></code> command

to see the current settings for drawing and writing shapefiles. <P>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more information.

<H3>Examples</H3>
<P><code>set shpattr Author string Put_Your_Name_Here</code>
<P>
<P><br>
\ No newline at end of file
diff --git a/doc/gradcomdsetshpopts.html b/doc/gradcomdsetshpopts.html
new file mode 100644
index 0000000..724a7dc
--- /dev/null
+++ b/doc/gradcomdsetshpopts.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set shpopts</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set shpopts</b></h2>
<p>
<code>set shpopts <i>fillpoly <marktype> <marksize></i></code>
<p>
Sets current attributes for drawing shapefiles. 
<p>
<code><i>fillpoly</i>   </code>color number to use when drawing filled polygon elements of a shapefile. Default is -1, which draws polygons unfilled.<br>
<code><i>marktype</i>   </code>Mark type to use when drawing point elements of a shapefile. Please see the <code><a href="gradcomddrawmark.html">draw mark</a></code> command for the list of options.
<br>
<code><i>marksize</i>   </code>Mark size of use when drawing point elements of a shapefile. 
<p>
<h3>Usage Notes</h3>
<p>This command is available with GrADS version 2.0.a8 or later.
<p>When drawing shapefiles that contain points, the default mark type is a closed circle (type 3) and the default size is 0.05.
<p>When drawing shapefiles that contain polygons, the default behavior is to draw only the perimeter of each polygon element. Use  the <code><i>fillpoly</i></code> option with <code><a href="gradomdsetshpopts.html">set shpopts</a></code> to draw filled polygons and set the fill color. The polygon perimeters will also be drawn when the <code><i>fillpoly</i></code> option is used. 
 The color, style, and thickness of the polygon perimeters are controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. 
<p>Use the <code><a href="gradcomdqshpopts.html">q shpopts</a></code> command

to see the current settings for drawing and writing shapefiles.

<p>Please see the documentation page on <a href="shapefiles.html">shapefiles</a> for more details.

<h3>Examples </h3>
<p><code>set shpopts 15 </code></p>
</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdsetstat.html b/doc/gradcomdsetstat.html
new file mode 100644
index 0000000..9685780
--- /dev/null
+++ b/doc/gradcomdsetstat.html
@@ -0,0 +1,74 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set stat</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set stat</b></h2>
+<p>
+<code>set stat on | off</code>
+<p>
+If <code>on</code>, GrADS will print statistical output to the terminal every time
+the <a href="gradcomddisplay.html">display</a> command is executed. The statistical
+information is the same as that which is output with <a href="gradcomdsetgxout.html">
+set gxout stat</a>. 
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If you <code>"set stat on"</code>, GrADS will continue to display
+the output statistics with every <a
+href="gradcomddisplay.html">display</a> until you <code>"set stat
+off"</code>.
+<p>
+<li>Use this command if you are overlaying plots and want to guarantee
+that the 2nd plot will be drawn with the same range of values. See example #2.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<ol>
+<li>Here is an example of the statistical output from a horizontal temperature plot:
+<p>
+<pre>
+Data Type = grid
+Dimensions = 0 1
+I Dimension = 1 to 73 Linear 0 5
+J Dimension = 1 to 46 Linear -90 4
+Sizes = 73 46 3358
+Undef value = -2.56e+33
+Undef count = 1763  Valid count = 1595
+Min, Max = 243.008 302.818
+Cmin, cmax, cint = 245 300 5
+Stats[sum,sumsqr,root(sumsqr),n]:     452778 1.29046e+08 11359.8 1595
+Stats[(sum,sumsqr,root(sumsqr))/n]:     283.874 80906.7 284.441
+Stats[(sum,sumsqr,root(sumsqr))/(n-1)]: 284.052 80957.4 284.53
+Stats[(sigma,var)(n)]:     17.9565 322.437
+Stats[(sigma,var)(n-1)]:   17.9622 322.64
+Contouring: 245 to 300 interval 5 
+</pre>
+<p>
+<li>Here is an example showing how to overlay plots with the same axis range:
+<p>
+<pre>
+* display a time series
+'set stat on'
+'d t(lon=180)'
+
+* get the yaxis range
+range = sublin(result,9)
+cmin = subwrd(range,5)
+cmax = subwrd(range,6)
+cint = subwrd(range,7)
+
+* draw an overlay
+'set vrange 'cmin' 'cmax
+'d t(lon=0)'
+'set stat off'
+</pre>
+</ol>
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetstid.html b/doc/gradcomdsetstid.html
new file mode 100644
index 0000000..2ae8702
--- /dev/null
+++ b/doc/gradcomdsetstid.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set stid</B></H2><P>
+<code>set stid <i>on|off</i></code><p>
+Controls whether the station id is displayed next to the
+values or not. When using 'set gxout model' with 'set stid on', the station id will appear just below the station model.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetstnprint.html b/doc/gradcomdsetstnprint.html
new file mode 100644
index 0000000..36ca62f
--- /dev/null
+++ b/doc/gradcomdsetstnprint.html
@@ -0,0 +1,27 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set stnprint</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set stnprint</b></h2>
+<p>
+<code>set stnprint on|off</code>
+<p>
+Controls whether station data values will be printed when using graphics
+output option <a href="gradcomdsetgxout.html"><code>set gxout stat</code></a>.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetstring.html b/doc/gradcomdsetstring.html
new file mode 100644
index 0000000..524dd58
--- /dev/null
+++ b/doc/gradcomdsetstring.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set string</B></H2><P>
<code>set string <i>color <justification <thickness
<rotation>>></i></code><p>
Sets <code>string</code> drawing attributes. <code><i>Color</i></code> is
as described above. <code><i>Justification</i></code> is the string
justification, or how the string is
plotted with respect to the x, y position given in the <code>draw
string</code> command. Refer to the following picture for the appropriate
codes: <p>
<br>
<pre>
           tl            tc              tr          tl - top left

            +-------------+--------------+           tc - center top

            |                            |           tr - right top

          l +             + c            + r              etc.

            |                            |

            +-------------+--------------+

           bl             bc             br
</pre>
The <code><i>rotation</i></code> option specifies the desired string
rotation in degrees. When rotated, the center of rotation is the
<code><i>justification</i></code> point. Rotation is counter-clockwise.
<p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>

\ No newline at end of file
diff --git a/doc/gradcomdsetstrmden.html b/doc/gradcomdsetstrmden.html
new file mode 100644
index 0000000..cb5f48e
--- /dev/null
+++ b/doc/gradcomdsetstrmden.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set strmden</B></H2><P>
+<code>set strmden <i>value</i></code><p>
+specifies the streamline density, where the value is from <code>1</code>
+to <code>10. 5</code> is default.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetstrsiz.html b/doc/gradcomdsetstrsiz.html
new file mode 100644
index 0000000..c379315
--- /dev/null
+++ b/doc/gradcomdsetstrsiz.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
<style type="text/css">
<!--
.style1 {color: #990000}
body {
	background-color: #e0f0ff;
}
-->
</style>


<H2><B>set strsiz</B></H2><P>
<code>set strsiz <i>hsiz <vsiz></i></code><p>
This command sets the string character size, where
<code><i>hsiz</i></code> is the width of the characters,
<code><i>vsiz</i></code> is the height of the characters, in virtual page
inches. If <code><i>vsiz</i></code> is not specified, it will be set the
the same value as <code><i>hsiz</i></code>. <p>
<H3>Usage Notes</H3>
<p>Beginning with <span class="style1">GrADS version 2.1.a0</span>, additional fonts are available with the Cairo graphics library. Please see the documentation on <a href="fontcontrol.html">Font Control</a> for more information. This command controls the font size for both Hershey and Cairo fonts. Because the Hershey fonts are vector-based, you can give different scaling factors for the width and height of the letters and the font will stretch accordingly. For Cairo fonts, only one scali [...]
<P>
<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsettimelab.html b/doc/gradcomdsettimelab.html
new file mode 100644
index 0000000..fedbe98
--- /dev/null
+++ b/doc/gradcomdsettimelab.html
@@ -0,0 +1,29 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set timelab</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set timelab</b></h2>
+<p>
+<code>set timelab <i>on</i>|<i>off</i></code>
+
+<P>
+This command turns on/off the display of the time label 
+for sreen and printed output.
+
+<p>
+<H3>Usage Notes</H3><P>
+<ol>
+<li>The default is <code>on</code> and "sticks" until reset by another
+<code>set timelab</code> command.
+<p>
+<li>
+To turn off the time label and the GrADS label, use <a
+href="gradcomdsetgrads.html"><code>set grads</code></a>.
+</ol>
+
+</body>
+</html>
diff --git a/doc/gradcomdsettlsupp.html b/doc/gradcomdsettlsupp.html
new file mode 100644
index 0000000..9a7b41e
--- /dev/null
+++ b/doc/gradcomdsettlsupp.html
@@ -0,0 +1,30 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set tlsupp</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set tlsupp</b></h2>
+<p>
+<code>set tlsupp year|month </code>
+<p>
+Suppresses the annotation of the year or the month-and-year whenever
+date/time labels are plotted. 
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li><code>set tlsupp</code> is reset by entering <a
+href="gradcomdclear.html"><code>clear</code></a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<ol>
+<li>Use 'set tlsupp year' when plotting a climatology. 
+</ol>
+</body>
+</html>
+
diff --git a/doc/gradcomdsetundef.html b/doc/gradcomdsetundef.html
new file mode 100644
index 0000000..8aacebb
--- /dev/null
+++ b/doc/gradcomdsetundef.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
<style type="text/css">
<!--
.style1 {
	color: #990000;
	font-style: italic;
	font-weight: bold;
}
body {
	background-color: #e0f0ff;
}
-->
</style>


<H2><B>set undef</B></H2>
<p>
This command allows the user to set the undefined data value for all forms of GrADS output. This command controls the undefined values printed to screen with the 'gxout stat' and the 'gxout print' output, as well as the undefined values in fwrite, sdfwrite, and geotiff files. 
<p>The output undef value will not necessarily be the same as the native undef value of the data set -- the default value is -9.99e8. The user can easily change the output undef value to match the undef value of the default file or a specific open file.<br />

<h3>Syntax</h3>
  <code>set undef <i>value</i>    </code>(sets output undef value to <em>value</em>)<br />
  <code>set undef file <i>n</i>    </code>(copies undef value from file <i>n</i>)<br />
  <code>set undef dfile     </code> (copies undef value from default file)

<H3>Usage Notes</H3>
<P><span class="style1">This is a new feature with GraDS version 2.0.a6, that changes the default behavior of GrADS!</span><br />By default, the output undef value will be -9.99e8 instead of the undef value given in the data descriptor file. You may easily revert to the old behavior by using the 'set undef file n' option. 
<P>You can find out what the current output undef value is with the <code>'<a href="gradcomdquery.html">query undef</a>'</code> command.
<P>The  <code><a href="gradcomdreinit.html">reinit</a></code> command will return the output undef value  to the default (-9.99e8); the <code><a href="gradcomdreset.html">reset</a></code> command leaves it unchanged. 
<P>If you issue the '<code>set undef dfile</code>' command, the output undef value will be copied from the default file's undef value. If you subsequently change the default file number, the output undef value will not change. You must issue '<code>set undef dfile</code>' again if you wish the output undef value to be the same as the new default file. 

<H3> </H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetvpage.html b/doc/gradcomdsetvpage.html
new file mode 100644
index 0000000..023afc3
--- /dev/null
+++ b/doc/gradcomdsetvpage.html
@@ -0,0 +1,25 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set vpage</B></H2><P>
+<code>set vpage <i>xmin xmax ymin ymax</i></code><p>
+This command defines a "virtual page" that fits within the specified
+limits of the real page. All graphics output will be drawn into this
+"virtual page" until another <code>set vpage</code> command is entered. A
+<code>clear</code> command clears the physical page (and any virtual pages
+drawn on it). <p>
+
+When GrADS is first started, it prompts for landscape or portrait mode.
+This defines the size of the real page (11x8.5 or 8.5x11), and the
+dimensions for the virtual page must fit within this real page.<p> 
+
+The <code>set vpage</code> command will define virtual page limits in
+terms of inches (virtual page inches), which are the coordinates that will
+be used in the various commands that require inches to be used. The new
+page limits are printed when the <code>set vpage</code> command completes.
+<p>
+
+To return to the default state where the real page equals the virtual
+page, enter: <p> 
+<dd><code>set vpage off </code><p>
+<H3>Usage Note</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetvrange.html b/doc/gradcomdsetvrange.html
new file mode 100644
index 0000000..a9bd002
--- /dev/null
+++ b/doc/gradcomdsetvrange.html
@@ -0,0 +1,30 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+</style>
+
+
+<h2><b>set vrange</b></h2>
+<p><code>set vrange v1 v2</code></p>
+<p>When drawing a 1-D plot, this command specifies the range of the  values for the scale on the Y-axis (from v1
+to v2).</p>
+<p> When drawing a 2-D scatter plot  using graphics output type <code><a href="gradcomdsetgxout.html">gxout scatter</a></code>, this command specifies the range of values for the scale on the X axis; use the <code><a href="gradcomdsetvrange2.html">set vrange2</a></code> command to control the range of the Y-axis values on your scatter plot.</p>
+<p>
+<H3>Usage Note</H3>
+<P> Reset by <code><a href="gradcomdclear.html">clear</a></code> only. 
+<H3>Examples</H3>
+<pre>
+set lat 50
+set lon 0 360
+set gxout contour
+set vrange -20 20
+d u10
+
+set gxout scatter
+set vrange 250 300
+set vrange2 980 1040
+d temp;slp
+</pre>
+
diff --git a/doc/gradcomdsetvrange2.html b/doc/gradcomdsetvrange2.html
new file mode 100644
index 0000000..c93ce44
--- /dev/null
+++ b/doc/gradcomdsetvrange2.html
@@ -0,0 +1,16 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+</style>
+
+
+<h2><b>set vrange2</b></h2>
+<code> set vrange2 v1 v2</code>
+<p>
+When drawing a 2-D scatter plot  using graphics output type <code><a href="gradcomdsetgxout.html">gxout scatter</a></code>, this command specifies the range of values for the scale on the Y axis (from v1 to v2).
+<H3>Usage Note</H3><P> Reset by <code>clear</code> only.
+
+<P> Use the <code><a href="gradcomdsetvrange.html">set vrange</a></code> command to control the range of the X-axis values on your scatter plot.
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetwarn.html b/doc/gradcomdsetwarn.html
new file mode 100644
index 0000000..05be473
--- /dev/null
+++ b/doc/gradcomdsetwarn.html
@@ -0,0 +1,28 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set warn</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set warn</b></h2>
+<p>
+<code>set warn <i>on</i>|<i>off</i></code>
+<p>
+Turns on/off the messages GrADS sends to the terminal that report 
+on the progress of certain mathematical operations. Default is "on"; 
+turn "off" to suppress messages. 
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradcomdsetwxcols.html b/doc/gradcomdsetwxcols.html
new file mode 100644
index 0000000..0159a7c
--- /dev/null
+++ b/doc/gradcomdsetwxcols.html
@@ -0,0 +1,23 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+</style>
+
+
+<H2><B>set wxcols</B></H2>
+<P>
+<code>set wxcols <i>c1 c2 c3 c4 c5 </i></code>
+<P>
+where<code> <i>c1...c5</i> </code>are the weather symbol colors
+<P>c1 (default color 2, red) :  thunder/sleet/freezing/hurricane [used in symbols 1-13,24-27,31-32,38,40,41]<br />
+  c2 (default color 10, green) :  rain/drizzle [used in symbols 3,8,12-18,24,26-30,37] <br />
+  c3 (default color 11, blue) :  snow [used in symbols 4,9,19-23,37] <br />
+  c4 (default color 7, yellow):  fog [used in symbol 34] <br />
+  c5 (default color 15, gray):  blowing snow/sand/smoke [used in symbols 33,35,36,39] <br />
+
+<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3>
+<P>Run the script <a href="ftp://cola.gmu.edu/grads/scripts/wxsym.gs">wxsym.gs</a> to see how the colors of the various symbols are implemented. 
diff --git a/doc/gradcomdsetwxopt.html b/doc/gradcomdsetwxopt.html
new file mode 100644
index 0000000..6d52c1c
--- /dev/null
+++ b/doc/gradcomdsetwxopt.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: set wxopt</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>set wxopt</b></h2>
<p>
<code>set wxopt wxsym|mark|char</code>
<p>
Controls output when using graphics output option <a
href="gradcomdsetgxout.html">set gxout wxsym</a>. 

The options are as follows:
<p>
<ul>
<code>wxsym</code> (default) 
<ul>Plots a weather symbol, based on the numerical value at the station
location.</ul>
<p>
<code>mark</code>
<ul>Plots a marker, based on the numerical station value.</ul> 
<p>
<code>char</code>
<ul>Plots a character, based on the ascii numerical value at the station.</ul> 
</ul>

<p>
<h3>Usage Notes</h3>
<ol>
<li>This command only used with station data. 
</ol>

<p>
<h3>Examples </h3>


</body>
</html>


\ No newline at end of file
diff --git a/doc/gradcomdsetxaxis.html b/doc/gradcomdsetxaxis.html
new file mode 100644
index 0000000..5666161
--- /dev/null
+++ b/doc/gradcomdsetxaxis.html
@@ -0,0 +1,33 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set xaxis</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set xaxis</b></h2>
+<p>
+<code>set xaxis <i>start end <increment></i></code>
+
+<p>
+Specifies where the labeled tick marks will be placed on the
+X-axis. Labeled tick marks begin at the specified
+<code><i>start</i></code> value and end at the specified
+<code><i>end</i></code> value with the specified
+<code><i>increment</i></code>. Labeled tick marks may have no relation
+to data or dimensions. <p>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<li>See also <a href="gradcomdsetyaxis.html">set yaxis</a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetxflip.html b/doc/gradcomdsetxflip.html
new file mode 100644
index 0000000..9f6186e
--- /dev/null
+++ b/doc/gradcomdsetxflip.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set xflip</B></H2><P>
+<code>set xflip <i>on|off</i></code><p>
+Flips the order of the horizontal axis (whatever axis is horizontal after
+<a href="gradcomdsetxyrev.html"><code>xyrev</code></a> is applied). Reset
+by a <code>clear</code> or <a href="gradcomdsetvpage.html"><code>set
+vpage</code></a> command.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetxlab.html b/doc/gradcomdsetxlab.html
new file mode 100644
index 0000000..79ba007
--- /dev/null
+++ b/doc/gradcomdsetxlab.html
@@ -0,0 +1,47 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set xlab</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set xlab</b></h2>
+
+<p>
+<code>set xlab <i>option</i></code>
+
+<p>
+Controls the format of X-axis tick mark labels. The <code><i>option</i></code>
+argument may be one of the following:
+
+<ul>
+<code>on       </code>
+labeled tick marks are drawn with the default characteristics<br>
+<code>off      </code>
+labeled tick marks are not drawn<br>
+<code><i>format</i>   </code>
+gives a C-language template for conversion of the label value to a string <br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If the X axis represents longitude, then the default behavior is to append an 
+"E" or "W" to all tick mark labels depending on the hemisphere. 
+<p>
+<li>Changes to the X-axis tick mark labels are reset by <a
+href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<ol>
+<li>This command would cause all X-axis labels to have 2 digits after the decimal point:
+<ul><code>set xlab %.2f </code></ul>
+</ul>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetxlabs.html b/doc/gradcomdsetxlabs.html
new file mode 100644
index 0000000..f3b00e5
--- /dev/null
+++ b/doc/gradcomdsetxlabs.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<h2>set xlabs</h2>
<code>set xlabs <i>lab1 </i>|<i> lab2 </i>| ...</code><p>
label the <code>x axis</code> with <code><i>lab1, lab2,
lab3,...</i></code><p>
<h3>Usage Notes</h3>
<h3>Examples</h3>
<p> </p>
<p>set xlabs | 0 | 1 | 2 | 3 |</p>
\ No newline at end of file
diff --git a/doc/gradcomdsetxlevs.html b/doc/gradcomdsetxlevs.html
new file mode 100644
index 0000000..fc1601a
--- /dev/null
+++ b/doc/gradcomdsetxlevs.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set xlevs</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set xlevs</b></h2>
+
+<p>
+<code>set xlevs <i>lev1 lev2 ... levN</i></code>
+
+<p>
+Allows the user to specify each individual labeled tick mark for the X-axis.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<p>
+<li><code>set xlevs</code> will override the tick mark interval specified with the
+<a href="gradcomdsetxlint.html"><code>set xlint</code></a> command. 
+<p>
+<li>If you use <a href="gradcomdsetxaxis.html"><code>set
+xaxis</code></a> to specify labeled tick marks and also invoke
+<code>set xlevs</code>, then the tick marks <code><i>lev1
+... levN</i></code> specified with <code>set xlevs</code> will appear
+if they fall within the <code><i>start</i></code> and
+<code><i>end</i></code> range specified in the <a
+href="gradcomdsetxaxis.html"><code>set xaxis</code></a> command.
+<p>
+<li>This command does not apply to a date/time axis. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
+
+
+
diff --git a/doc/gradcomdsetxlint.html b/doc/gradcomdsetxlint.html
new file mode 100644
index 0000000..ecd41ce
--- /dev/null
+++ b/doc/gradcomdsetxlint.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set xlint</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set xlint</b></h2>
+
+<p>
+<code>set xlint <i>interval</i></code>
+
+<p>
+Specifies the <code><i>interval</i></code> between labeled tick marks
+on the X-axis.
+
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If <code><i>interval</i></code> is a positive value, the labeled tick marks will
+'start' at <code>0</code>, regardless of the current dimension environment. 
+For example, if you set the <code><i>interval</i></code> to
+<code>3</code>, the labeled tick marks will be at <code>0, 3, 6, 9</code> ...
+<p>
+<li>If <code><i>interval</i></code> is a negative value, the labeled tick marks
+will 'start' at the axis start value, which is usually the lower limit
+of the X dimension environment. If this were <code>30</code> (with an
+<code><i>interval</i></code> of <code>10</code>), then the labeled tick marks would
+be at <code>30, 40, 50, 60</code>...
+<p>
+<li>This command is overridden by the <a href="gradcomdsetxlevs.html">
+<code>set xlevs</code></a> command. 
+<p>
+<li>This command will override the X-axis tick mark interval specified with the
+<a href="gradcomdsetxaxis.html"><code>set xaxis</code></a> command. 
+<p>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<p>
+<li>This command does not apply to a date/time axis. 
+<p>
+<li><code>set xlint</code> and <a href="gradcomdsetylint.html"><code>set ylint</code></a> 
+may not work as described when used to
+control grid lines for polar stereographic projections.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetxlopts.html b/doc/gradcomdsetxlopts.html
new file mode 100644
index 0000000..d040bfa
--- /dev/null
+++ b/doc/gradcomdsetxlopts.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set xlopts</B></H2><P>
<code>set xlopts <i>color <thickness <size>></i></code><p>
Controls aspects of axis display<p>

<ul>
<code>xlopts</code>            controls
the X Axis<br>
<code><i>color</i></code>              Label
color (Default 1) <br>
<code><i>thickness</i></code>      Label
thickness (Default 3) <br>
<code><i>size</i></code>                
Label size (Default 0.11) 
</ul><p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetxlpos.html b/doc/gradcomdsetxlpos.html
new file mode 100644
index 0000000..ba273f7
--- /dev/null
+++ b/doc/gradcomdsetxlpos.html
@@ -0,0 +1,14 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set xlpos</B></H2><P>
+<code>set xlpos <i>offset side</i></code><p>
+Controls position of x axis labels<p>
+<ul>
+<code><i>offset</i></code>    offset in
+inches<br>
+<code><i>side</i></code>
+      &nbsp<code>b</code>
+or <code>t</code> (bottom or
+top)</ul><p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetxsize.html b/doc/gradcomdsetxsize.html
new file mode 100644
index 0000000..508444d
--- /dev/null
+++ b/doc/gradcomdsetxsize.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set xsize</h2>
+<code>set xsize <i>x y</i></code><p>
+Resizes the window to <code><i>x,y</i></code> pixels.
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
+
diff --git a/doc/gradcomdsetxyrev.html b/doc/gradcomdsetxyrev.html
new file mode 100644
index 0000000..0821942
--- /dev/null
+++ b/doc/gradcomdsetxyrev.html
@@ -0,0 +1,16 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set xyrev</B></H2><P>
+<code>set xyrev <i>on|off</i></code><p>
+Reverses the axes on a plot. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+By default for a Z, T plot, the time dimension is plotted horizontally,
+and the Z dimension is plotted vertically. By setting <code>xyrev</code>,
+the time dimension would be plotted vertically and the Z dimension would
+be plotted horizontally. Reset by a <code>clear</code> or <a
+href="gradcomdsetvpage.html"><code>set
+vpage</code></a> command.<p>
+<H2><B></B></H2><P>
+<code></code>
+
diff --git a/doc/gradcomdsetxyzte.html b/doc/gradcomdsetxyzte.html
new file mode 100644
index 0000000..4ffbcd9
--- /dev/null
+++ b/doc/gradcomdsetxyzte.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<H2><B>set x|y|z|t|e</B></H2>
<P>
<code>set x|y|z|t|e <i>val1 <val2></i></code>
<p>
This sets one dimension of the <a href="dimenv.html">dimension environment </a>using grid
coordinates. You may use whatever coordinates are convenient to you.
Issuing <code>set lon</code> is equivalent to issuing <code>set x</code>,
both set the <code>x</code> dimension. The difference is only the units
you wish to use when entering the command. 
<p>

When you enter just one value, that dimension is said to be "fixed". When
you enter two values, that dimension is said to be "varying". The
combination of fixed and varying dimensions defines the dimension
environment. <p>
<H3>Usage Notes</H3>
<P>
The 'set e' command is only available in GrADS version 2.0+, when the <a href="ensembles.html">ensemble dimension</a> was introduced. 
<P>An important note: When you enter dimensions in grid coordinates, they are
  always converted to world coordinates. This conversion requires some
  knowledge of what scaling is in use for grid to world conversions. The
  scaling that is used in all cases (except one) is the scaling of the
  DEFAULT FILE. The exception is when you supply a dimension expression
  within a <a href="variable.html">variable specification</a>. 
<P>If you are setting the T or E dimension using grid coordinates, the value given in <code><i>val1</i></code>  or 
  <code><i>val2</i></code>  may be the word "last" to set the dimension to the max value of that  grid coordinate. 

<p>
<H3>Examples</H3><P>
<code>set t 1</code> <br />
This sets time to the first time in the data set -- using
grid coordinates. T is now a fixed
dimension. 
<P><code>set z 1 4</code><br />
This sets the vertical dimension to vary between the first and the fourth levels in the data set -- using
grid coordinates. Z is now a varying
dimension.
<P><code>set t 1 last</code><br />
This sets time to vary between the first and the last time in the data set -- using
grid coordinates. T is now a varying
dimension.
<P><code>set e last </code> <br />
This sets the ensemble to the final member in the data set. E is now a fixed
dimension.
\ No newline at end of file
diff --git a/doc/gradcomdsetyaxis.html b/doc/gradcomdsetyaxis.html
new file mode 100644
index 0000000..71dd35d
--- /dev/null
+++ b/doc/gradcomdsetyaxis.html
@@ -0,0 +1,33 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set yaxis</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set yaxis</b></h2>
+<p>
+<code>set yaxis <i>start end <increment></i></code>
+
+<p>
+Specifies where the labeled tick marks will be placed on the
+Y-axis. Labeled tick marks begin at the specified
+<code><i>start</i></code> value and end at the specified
+<code><i>end</i></code> value with the specified
+<code><i>increment</i></code>. Labeled tick marks may have no relation
+to data or dimensions. <p>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<li>See also <a href="gradcomdsetxaxis.html">set xaxis</a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetyflip.html b/doc/gradcomdsetyflip.html
new file mode 100644
index 0000000..814faf6
--- /dev/null
+++ b/doc/gradcomdsetyflip.html
@@ -0,0 +1,9 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set yflip</B></H2><P>
+<code>set yflip <i>on|off</i></code><p>
+flips the order of the vertical axis. Reset by a <code>clear</code> or
+<code>set vpage</code> command.<p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
diff --git a/doc/gradcomdsetylab.html b/doc/gradcomdsetylab.html
new file mode 100644
index 0000000..4bd6d1f
--- /dev/null
+++ b/doc/gradcomdsetylab.html
@@ -0,0 +1,48 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set ylab</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set ylab</b></h2>
+
+<p>
+<code>set ylab <i>option</i></code>
+
+<p>
+Controls the format of Y-axis tick mark labels. The <code><i>option</i></code>
+argument may be one of the following:
+
+<ul>
+<code>on       </code>
+labeled tick marks are drawn with default characteristics<br>
+<code>off      </code>
+labeled tick marks are not drawn<br>
+<code><i>format</i>   </code>
+gives a C-language template for conversion of the label value to a string <br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If the Y axis represents latitude, then the default behavior is to label the equator 
+with "EQ" and append either "N" or "S" to all other tick mark labels depending
+on the hemisphere.  
+<p>
+<li>Changes to the Y-axis tick mark labels are reset by <a
+href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+</ol>
+
+<p>
+<h3>Examples </h3>
+<ol>
+<li>This command would cause all Y-axis labels to have 2 digits after the decimal point:
+<ul><code>set ylab %.2f </code></ul>
+</ul>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetylabs.html b/doc/gradcomdsetylabs.html
new file mode 100644
index 0000000..e1e959a
--- /dev/null
+++ b/doc/gradcomdsetylabs.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>set ylabs</h2>
+<code>set ylabs <i>lab1 | lab2 | ...</i></code><p>
+label the <code>y axis</code> with <code><i>lab1, lab2,
+lab3,...</i></code><p>
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
diff --git a/doc/gradcomdsetylevs.html b/doc/gradcomdsetylevs.html
new file mode 100644
index 0000000..139a8d4
--- /dev/null
+++ b/doc/gradcomdsetylevs.html
@@ -0,0 +1,45 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set ylevs</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set ylevs</b></h2>
+
+<p>
+<code>set ylevs <i>lev1 lev2 ... levN</i></code>
+
+<p>
+Allows the user to specify each individual labeled tick mark for the Y-axis.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<p>
+<li><code>set ylevs</code> will override the tick mark interval specified with the
+<a href="gradcomdsetylint.html"><code>set ylint</code></a> command. 
+<p>
+<li>If you use <a href="gradcomdsetyaxis.html"><code>set
+yaxis</code></a> to specify labeled tick marks and also invoke
+<code>set ylevs</code>, then the tick marks <code><i>lev1
+... levN</i></code> specified with <code>set ylevs</code> will appear
+if they fall within the <code><i>start</i></code> and
+<code><i>end</i></code> range specified in the <a
+href="gradcomdsetyaxis.html"><code>set yaxis</code></a> command.
+<p>
+<li>This command does not apply to a date/time axis. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
+
+
diff --git a/doc/gradcomdsetylint.html b/doc/gradcomdsetylint.html
new file mode 100644
index 0000000..175cdef
--- /dev/null
+++ b/doc/gradcomdsetylint.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set ylint</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>set ylint</b></h2>
+
+<p>
+<code>set ylint <i>interval</i></code>
+
+<p>
+Specifies the <code><i>interval</i></code> between labeled tick marks
+on the Y-axis.
+
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If <code><i>interval</i></code> is a positive value, the labeled tick marks will
+'start' at <code>0</code>, regardless of the current dimension environment. 
+For example, if you set the <code><i>interval</i></code> to
+<code>3</code>, the labeled tick marks will be at <code>0, 3, 6, 9</code> ...
+<p>
+<li>If <code><i>interval</i></code> is a negative value, the labeled tick marks
+will 'start' at the axis start value, which is usually the lower limit
+of the Y dimension environment. If this were <code>30</code> (with an
+<code><i>interval</i></code> of <code>10</code>), then the labeled tick marks would
+be at <code>30, 40, 50, 60</code>...
+<p>
+<li>This command is overridden by the <a href="gradcomdsetylevs.html">
+<code>set ylevs</code></a> command. 
+<p>
+<li>This command will override the Y-axis tick mark interval specified with the
+<a href="gradcomdsetyaxis.html"><code>set yaxis</code></a> command. 
+<p>
+<li>Reset by <a href="gradcomdclear.html">clear</a>, but not <a
+href="gradcomddisplay.html">display</a>.
+<p>
+<li>This command does not apply to a date/time axis. 
+<p>
+<li><code>set ylint</code> and <a href="gradcomdsetxlint.html"><code>set xlint</code></a> 
+may not work as described when used to
+control grid lines for polar stereographic projections.
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
diff --git a/doc/gradcomdsetylopts.html b/doc/gradcomdsetylopts.html
new file mode 100644
index 0000000..f45766c
--- /dev/null
+++ b/doc/gradcomdsetylopts.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<H2><B>set ylopts</B></H2><P>
<code>set ylopts <i>color <thickness <size>></i></code><p>
Controls aspects of axis display<p>

<ul>
<code>ylopts</code>
               controls
the Y Axis<br>
<code><i>color</i></code>                  
Label color (Default 1) <br>
<code><i>thickness</i></code>          
Label thickness (Default 3) <br>
<code><i>size</i></code>                    
Label size (Default 0.11) 
</ul><p>
<H3>Usage Notes</H3><P>
<H3>Examples</H3><P>
\ No newline at end of file
diff --git a/doc/gradcomdsetylpos.html b/doc/gradcomdsetylpos.html
new file mode 100644
index 0000000..aa1e1c6
--- /dev/null
+++ b/doc/gradcomdsetylpos.html
@@ -0,0 +1,15 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<H2><B>set ylpos</B></H2><P>
+<code>set ylpos <i>offset side</i></code><p>
+Controls position of y axis labels<p>
+<ul><code><i>offset</i></code>      offset
+in
+inches<br>
+<code><i>side</i></code>
+
+         <code>r</code></code>
+or <code>l</code> (right or
+left)</ul><p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradcomdsetzlog.html b/doc/gradcomdsetzlog.html
new file mode 100644
index 0000000..9993196
--- /dev/null
+++ b/doc/gradcomdsetzlog.html
@@ -0,0 +1,17 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set zlog</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<H2><B>set zlog</B></H2><P>
+<code>set zlog <i>on</i>|<i>off</i></code><p>
+Sets log scaling of the Z dimension <code><i>on</i></code> or
+<code><i>off</i></code>. Sticks until <code>reset</code>. <p>
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
+</body>
+</html>
diff --git a/doc/gradcomdshell.html b/doc/gradcomdshell.html
new file mode 100644
index 0000000..8e54906
--- /dev/null
+++ b/doc/gradcomdshell.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>!shell-command</h2>
+
+Any expression preceded by a <code>!</code> will be executed as a
+shell command from the GrADS command line. 
+
+<H3>Usage Notes</H3>
+<P>
+Output from the shell command will be displayed in the Grads command
+window. If the shell command is executed from a Grads script, the
+output will not returned as a string buffer to the script.
+
diff --git a/doc/gradcomdstat.html b/doc/gradcomdstat.html
new file mode 100644
index 0000000..05b2a2f
--- /dev/null
+++ b/doc/gradcomdstat.html
@@ -0,0 +1,78 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<code>set gxout stat <br>
+d </code><br>
+<ul>sends output to the terminal as opposed to a
+plot or data output (e.g., <code>set fwrite out.dat ; set gxout fwrite;
+d rh</code>).  Or the output goes to the script variable
+<code>result</code> which
+can be parsed inside a script (see the <code>corr.gs</code> GrADS
+script)<p>
+
+The output allows many statistical calculations to be made. 
+Here's an example of opening up a global model file and looking
+at the 1000 mb relative humidity, statistically,<p>
+
+<ul>
+<code>ga-> set gxout stat <br>
+ga-> d rh <br>
+Data Type = grid <br>
+Dimensions = 0 1<br>
+I Dimension = 1 to 145 <br>
+J Dimension = 1 to 73 <br>
+Sizes = 145 73 10585<br>
+Undef value = 1e+20 <br>
+Undef count = 0  Valid count = 10585 <br>
+Min, Max = 0.0610352 100.061 <br>
+Stats(sum,sumsqr,n):     787381 6.35439e+07 10585 <br>
+Stats(sum,sumsqr)/n: 74.3865 6003.2<br>
+Stats(sum,sumsqr)/(n-1): 74.3935 6003.77 <br>
+Stats(sigma,var)(n):    21.6761 469.854 <br>
+Stats(sigma,var)(n-1): 21.6771 469.898<br>
+Cmin, cmax, cint = 10 100 10</code></ul><p>
+
+Let's break it down:<p>
+
+<ul>
+<code>Data Type = grid</code> -----  you have a grid <p>
+<code>Dimensions = 0 1</code> -----  the dimension type for the variable
+<br>
+<ul>
+<code>0</code> - lon <br>
+<code>1</code> - lat <br>
+<code>2</code> - lev <br>
+<code>3</code> - time </ul><br>
+<code>1</code> - not varying <p>
+<code>I Dimension = 1 to 145</code> ------ obvious <p>
+<code>J Dimension = 1 to 73</code><p>
+<code>Sizes = 145 73 10585</code>  ------- <code>10585</code> is 145*73
+or total number of points <p>
+<code>Undef value = 1e+20</code>   ------- undefined value <p>
+<code>Undef count = 0 Valid count = 10585</code> ----- # of defined and
+undefined points in the grid. Remember that if GrADS can't find
+any data it returns undefs. This is useful for checking if you
+have any data, <code>Valid count = 0</code> means no... <p>
+<code>Min, Max = 0.0610352 100.061</code>  ---- UHHH OHHHH! we have slight
+supersaturation..<p>
+<code>Stats(sum,sumsqr,n):     787381 6.35439e+07 10585</code> - This
+should
+be fairly obvious, sum = the simple sum of all <b>defined</b> points.<p> 
+<code>sumsqr</code> = sum of, in this case, <code>rh*rh</code> and
+<code>10585</code> is <code>n</code>.<p>
+<code>Stats(sum,sumsqr)/n:     74.3865 6003.2</code> - Divide by
+<code>n</code> for convenience, the first number is the "biased"
+mean...<p>
+<code>Stats(sum,sumsqr)/(n-1): 74.3935 6003.77</code> - the so called
+<code>unbiased</code> mean (remove 1 degree of freedom), etc.<p>
+<code>Stats(sigma,var)(n):     21.6761 469.854</code> - the standard
+deviation
+and variance "biased" (<code>n</code>) <p>
+<code>Stats(sigma,var)(n-1): 21.6771 469.898</code> - the standard
+deviation and variance "unbiased" (<code>n-1</code>)<p>
+<code>Cmin, cmax, cint = 10 100 10</code> - What GrADS will use when
+contouring.<p>
+
+</ul><b>NOTE</b>: This works for both <code>gridded</code> and
+<b>station</b> data
+
+
diff --git a/doc/gradcomdswap.html b/doc/gradcomdswap.html
new file mode 100644
index 0000000..4c54e4b
--- /dev/null
+++ b/doc/gradcomdswap.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>swap</h2>
+swaps buffers, when double buffer mode is <code>on</code><p>
+<h3>Usage Notes</h3>
+<h3>Examples</h3>
+
diff --git a/doc/gradcomdtserbarb.html b/doc/gradcomdtserbarb.html
new file mode 100644
index 0000000..f51457b
--- /dev/null
+++ b/doc/gradcomdtserbarb.html
@@ -0,0 +1,8 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+For example:<p>
+<ul>
+<code>
+set gxout tserbarb<br>
+d us(stid=79001;vs(stid=79001)
+</code></ul>
diff --git a/doc/gradcomdtserwx.html b/doc/gradcomdtserwx.html
new file mode 100644
index 0000000..89ebec6
--- /dev/null
+++ b/doc/gradcomdtserwx.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+For example:<p>
+<ul><code>
+set parea 0.75 10.5 3.875 4.25<br>
+set grads off<br>
+set gxout tserwx<br>
+set digsiz 0.11<br>
+d wx (stid=79001)</code></ul><p>
+where the grid <code>wx</code> contains codes for weather symbols
diff --git a/doc/gradcomdundefine.html b/doc/gradcomdundefine.html
new file mode 100644
index 0000000..8b55923
--- /dev/null
+++ b/doc/gradcomdundefine.html
@@ -0,0 +1,7 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>undefine</h2>
+<code>undefine <i>var</i></code><p>
+free the resources used by the defined variable<p>
+<h3>Usage</h3>
+<h3>Notes</h3>
diff --git a/doc/gradcomdwi.html b/doc/gradcomdwi.html
new file mode 100644
index 0000000..b91a586
--- /dev/null
+++ b/doc/gradcomdwi.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: wi</title>
<style type="text/css">
<!--
.style1 {
	color: #990000;
	font-style: italic;
	font-weight: bold;
}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>wi</b></h2>
<p class="style1">
N.B.: This command was deprecated long ago and is not included in GrADS version 1.9 or later. 
<p>The <code>wi</code> (write image) command dumps an exact copy of the
  contents of the GrADS graphics screen directly to an image file. This
  feature is implemented by means of an interface to the <a
href="http://dao.gsfc.nasa.gov/software/grads/win32/latest/pc-dist/doc/magick/ImageMagick.html">ImageMagick</a> library.  The syntax is:
  
<ul><code>wi <i>filename.fmt</i></code></ul>

<p>
where <code><i>filename</i></code> can be any meaningful file name,
and <code><i>fmt</i></code> is one of the ImageMagick supported
formats: gif, bmp, cgm, eps, fax, ico, jpeg, pcx, hdf, <a
href="http://dao.gsfc.nasa.gov/software/grads/win32/latest/pc-dist/doc/etc/img-formats.htm">and
many more</a>.

<p>
<h3>Usage Notes</h3>
<p>
<ol>
<li>Because it requires a connection to an X-server, <code>wi</code>
does not work when running GrADS in batch mode (-b option). A similar
command that <i>does</i> work in batch mode is <a
href="gradcomdprintim.html"><code>printim</code></a>.

<li>Some ImageMagick formats (tiff, png, mpeg, et al.) are not yet
supported by GrADS. If a specified format is not recognized or
supported, the image will be saved in MIFF, ImageMagick's native
format. If a file name extension is <i>not</i> specified, GIF is the default. 

<li>Make sure no other window is on top of your GrADS graphics windows
when issuing a <code>wi</code> command, because <code>wi</code> takes
a snapshot of the current state of this window. If another window is
partially covering your graphics window, your image file will contain
the combination of these 2 windows.

</ol>

<p>
<h3>Examples </h3>
<p>
To try out <code>wi</code>, display something on the graphics screen,
and then at the ga-> prompt enter:
<p>
<ul>
<code>wi test.gif </code> for writing a GIF file<br>
<code>wi test.jpeg</code> for writing a JPEG file<br>
<code>wi test.bmp </code> for writing a Windows BMP file<br>
</ul>

<h3>Bugs for Win32 GrADS Users</h3>
<p>
<ol>
<li>On Windows 95 systems, GradsHDF, the version built with the NCSA
MFHDF library, has a subtle bug when reading certain 16-bit (short)
packed NetCDF files (e.g. NCEP re-analysis files converted to
NetCDF at CIRES/CDC). Although GrADS is able to produce a plot, it
mistankenly produces very large values for a few grid
points. Work around: use GradsNC in such cases. This problem has not
been reported on Windows NT systems.<br>

<li>X Windows widgets built with gs scripts may miss/delay some X
events (keyboard/mouse clicks). This problem appears to occur only on
Windows 95; it has not been reported on Windows NT.<br>

<li>Athena widgets built with gui scripts: menu items become invisible
when selected (MI/X Server only); some mouse delays on Windows 95. <br>

<li><code>wi</code> has been reported to produce black and white GIF
output on VGA systems with more than 256 colors. The workaround is to
write a JPEG image, or to change your Windows display to 256 colors.
</ol>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradcomdxdfopen.html b/doc/gradcomdxdfopen.html
new file mode 100644
index 0000000..8150472
--- /dev/null
+++ b/doc/gradcomdxdfopen.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: xdfopen</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>xdfopen</b></h2>
<p>
<code>xdfopen <i>filename</i></code>
<p>
GrADS requires a certain amount of metadata in order to understand how
to read a NetCDF/HDF-SDS data file, also called a self-describing file
(SDF).  The <a href="gradcomdsdfopen.html"><code>sdfopen</code></a>
command assumes all the metadata is internal to the self-describing
file, whereas the <code>xdfopen</code> command allows the user to supplement
or replace any internal metadata via a data descriptor file. In this
way, <code>xdfopen</code> provides access to some self-describing files
that do not comply with the 
<a href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html">COARDS conventions</a>.

<p>
<code><i>filename</i></code> is the name of the data descriptor file that
contains the supplemental metadata. It has a syntax very similar to
the <a href="descriptorfile.html">regular data descriptor files </a>
that are used with the 
<a href="gradcomdopen.html"><code>open</code></a> command.  
The few differences are noted below:

<p>
<ol>
<li>
<code><a href="descriptorfile.html#DSET">DSET</a> <i>SDF_filename</i></code>
<p>
This is the only required entry. <code><i>SDF_filename</i></code> 
may be either the name of a netCDF or HDF-SDS file or a <a
href="templates.html">substitution template</a> for a collection of
netCDF or HDF-SDS files.
<p>
Other than <code><a href="descriptorfile.html#DSET">DSET</a></code>,
the only other data descriptor file entries that are supported are 
<code><a href="descriptorfile.html#UNDEF">UNDEF</a></code>,
<code><a href="descriptorfile.html#TITLE">TITLE</a></code>,
<code><a href="descriptorfile.html#XDEF">XDEF</a></code>,
<code><a href="descriptorfile.html#YDEF">YDEF</a></code>,
<code><a href="descriptorfile.html#ZDEF">ZDEF</a></code>,
<code><a href="descriptorfile.html#TDEF">TDEF</a></code>, 
<code><a href="descriptorfile.html#EDEF">EDEF</a></code>, 
<code><a href="descriptorfile.html#OPTIONS">OPTIONS</a></code>, 
<code><a href="descriptorfile.html#VARS">VARS</a></code>, and 
<code><a href="descriptorfile.html#ENDVARS">ENDVARS</a></code>. 
Valid arguments for the 
<a href="descriptorfile.html#OPTIONS"><code>OPTIONS</code></a> entry are: 
<code>yrev, zrev, template,</code> and <code>365_day_calendar</code>. 
<p>
<li>
<code><a href="descriptorfile.html#XDEF">XDEF</a></code>,
<code><a href="descriptorfile.html#YDEF">YDEF</a></code>,
<code><a href="descriptorfile.html#ZDEF">ZDEF</a></code>, 
<code><a href="descriptorfile.html#TDEF">TDEF</a></code>, and
<code><a href="descriptorfile.html#EDEF">EDEF</a></code>:
<p>
Each of these entries requires an additional argument,
<code><i>SDF_dimension_name</i></code>, which comes before all the
other arguments. The <code><i>SDF_dimension_name</i></code> is used to
achieve dimension order independence, so it must be a real dimension
in the SDF. The <code><i>SDF_dimension_name</i></code> string may be
mixed case and should appear exactly as it is listed in the output
from ncdump.
<p>
If the coordinate variables in the SDF file exist and have the
required metadata, then <code><i>SDF_dimension_name</i></code> is the
only argument needed for the corresonding axis definition entry
(<code>XDEF, YDEF, ZDEF,</code> <code>TDEF, and EDEF</code>) in the data
descriptor file. If you need to supplement or override the coordinate metadata in the SDF file, you can fill out the axis definition entries in the descriptor file with the remaining arguments describing the size, linearity, start, and increment. For EDEF, there is support for three variations on the compact syntax of the EDEF entry:<br>
<code>edef <<i>SDF_dimension_name</i>> <br>
edef <<i>SDF_dimension_name</i>> <<em>size</em>><br>
edef <<i>SDF_dimension_name</i>> <<em>size</em>> names <<em>list of names</em>> </code>
<p>
<li>
The first argument ("<code><i>varname</i></code>") of the variable
definition lines that appear between <code><a
href="descriptorfile.html#VARS">VARS</a></code> and <code><a
href="descriptorfile.html#ENDVARS">ENDVARS</a></code> has the following syntax:<br>
<code><i>SDF_varname</i>=><i>grads_varname</i></code>
<p>
<code><i>SDF_varname</i></code> is the name of the variable as it appears
in the output from the NetCDF utility ncdump. 
It may be of mixed case. If it includes blanks, substitute "~" for the blanks. 
If everything up to and including the <code>"=>"</code> is omitted,
then <code><i>grads_varname</i></code> must be identical to
<code><i>SDF_varname</i></code>. This syntax (when
"<code><i>SDF_varname</i>=></code>" is omitted) will only work
properly in GrADS if <code><i>SDF_varname</i></code> is less than 15
characters and does not contain any upper case letters.
As it was with the coordinate variables, if the data variables in the
SDF file have the required metadata, then
<code><i>SDF_varname</i>=><i>grads_varname</i></code> is the only
argument needed for the corresonding variable definition entry in the
data descriptor file. 
<li>The order of the variable definition lines between VARS
and ENDVARS is not important. 
</ol>


<p>
<h3>Usage Notes</h3>
<ol>
<li>If <code><i>filename</i></code> contains only the DSET entry, then 
<code>xdfopen</code> devolves into working just like 
<a href="gradcomdsdfopen.html"><code>sdfopen</code></a>.
<li><code><i>filename</i></code> does not need to be a full data
descriptor file, it only needs to contain whatever metadata the SDF
file lacks. Anything not specified in <code><i>filename</i></code>
will be looked for in the file's internal metadata.
<li>The <code><i>SDF_dimension_name</i></code> parameter in the XDEF,
YDEF, ZDEF, TDEF, and EDEF entries and the first parameter of the VARIABLE
  definition lines are the only parts of the data descriptor file that
  aren't converted to lower case before they are interpreted.
<li>For further information on the COARDS conventions, check out <a
href="http://ferret.wrc.noaa.gov/noaa_coop/coop_cdf_profile.html">Conventions
for the standardization of NetCDF files</a>.
<li><span class="style1">(GrADS version 2.0.a7.1+) </span>The <a href="descriptorfile.html#CHSUB">CHSUB </a>entry will work with xdfopen.
</ol>
<h3>Examples </h3>
<p>This example shows the data descriptor file that would be required
in order to open a self-describing file that is missing much of the
required metadata. Below is the sample data descriptor file for the
NetCDF file moisture.nc. Follow <a href="xdfsample1.txt">this link</a>
to see output from ncdump for this file.
<pre>
DSET ^moisture.nc
TITLE This is a sample 
UNDEF 99999.0
XDEF dimension1 144 LINEAR 0.0 2.5
YDEF dimension2  73 LINEAR 0.0 2.5
TDEF dimension3 365 LINEAR 0Z01JAN1979 1DY
VARS 1
Moisture=>moisture 1 99 Moisture
ENDVARS
</pre>

<p>
This second example comes from a real-world HDF-SDS file from the Data
Assimilation Office at NASA Goddard Space Flight Center. The data
descriptor file is shown below, and <a href="xdfsample2.txt">this
link</a> shows the output from running the HDF version of ncdump on
<code>DAOE054A.hdf</code>. (Note that the output has been annotated with
explanatory comments -- they are preceded with "//")
<pre>
DSET ^DAOE054A.hdf
TITLE This is only a test
OPTIONS YREV
UNDEF 1.0E15
XDEF XDim:DAOgrid 144 LINEAR -180.0 2.5
YDEF YDim:DAOgrid  91 LINEAR  -90.0 2.0
ZDEF HGHT18DIMS:DAOgrid 18 LEVELS 1000 850 700 500 400 300 250 200 150 100 70 50 30 10 5 2 1 0.4
TDEF TIME4DIMS:DAOgrid 4 LINEAR 0Z31JUL1993 6HR
VARS 3
GEOPOTENTIAL_HEIGHT=>hgt 18 99 geopotential height
SPECIFICHUMIDITY=>shum 18 99 specific humidity
TEMPERATURE=>temp 18 99 temperature
ENDVARS
</pre>


</body>
</html>

\ No newline at end of file
diff --git a/doc/gradfuncaave.html b/doc/gradfuncaave.html
new file mode 100644
index 0000000..29408f5
--- /dev/null
+++ b/doc/gradfuncaave.html
@@ -0,0 +1,127 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Function: aave</title>
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+</style>
+<body text="#000000">
+
+<H2><b>aave()</b></H2><p>This function takes an areal average over an X-Y region. The syntax is:
+<p>
+<code>aave(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+
+<p>
+where:
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>xdim1</i>   </code>- starting X dimension expression <br>
+<code><i>xdim2</i>   </code>- ending X dimension expression <br>
+<code><i>ydim1</i>   </code>- starting Y dimension expression <br>
+<code><i>ydim2</i>   </code>- ending Y dimension expression <br>
+</ul>
+<p>
+For global averaging, a shorthand may be used:
+
+<ul>
+<code>aave(<i>expr</i>, global)</code> or <br>
+<code>aave(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+<code>aave(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul> 
+
+<p>
+<H3>Usage Notes</H3>
+<ol>
+<li>In the absence of missing data values, <code>aave</code> gives the
+same result as nested <code><a href="gradfuncave.html">ave</a></code> 
+functions in the X and Y dimensions. The expression
+<p>
+<code>ave(ave(<i>expr</i>,x=1,x=72),y=1,y=46)</code>
+<p> 
+will produce the same numerical result as 
+<p>
+<code>aave(<i>expr</i>,x=1,x=72,y=1,y=46)</code>
+<p>
+but the <code>aave</code> function is faster more efficient. 
+
+<li>When there are missing data values, the <code>aave</code> function
+does <i><b>not</b></i> return the same result as nested <a
+href="gradfuncave.html"><code>ave</code></a> functions. To
+see this, consider the small grid:
+<pre>
+        6       18      3       5
+
+        10      10      10      10
+
+        12      U       U       U
+</pre>
+where U represents the missing data value. If we apply nested
+<code><a href="gradfuncave.html">ave</a></code> functions, the inner
+<code><a href="gradfuncave.html">ave</a></code> will provide row
+averages of 8, 10, and 12. When the outside 
+<code><a href="gradfuncave.html">ave</a></code> is applied,
+the result will be an average of 10. When <code>aave</code> is used, all
+the values participate equally (in this case, we are assuming no weights
+applied to the final average), and the result is 84/9 or about 9.33.
+
+
+<br>
+<br>
+<li>The <code>aave</code> function assumes that the world
+  coordinates are longitude in the X dimension and latitude in the Y
+  dimension, and does weighting in the latitude dimension by the
+  difference between the sines of the latitude at the northern and
+  southern edges of the grid box. For areal averaging without latitude weighting,
+  use the <a href="gradfuncamean.html"><code>amean</code></a> function.
+  <br>
+  <br>
+<li>Both the <code>aave</code> and <a
+href="gradfuncamean.html"><code>amean</code></a> functions use
+appropriate weighting to account for unevenly spaced grids.<br>
+<br>
+<li>The <code>aave</code> function always does its average to the exact
+  boundaries specified, in world coordinates. This is somewhat different
+  from the <a href="gradfuncave.html"><code>ave</code></a> function, where
+  the <code>-b</code> flag is used
+  to get this behavior. If the boundaries specified via the dimension
+  expressions do not fall on grid boundaries, then the boundary values are
+  weighted appropriately in the average.<br>
+  <br>
+<li>If grid coordinates are used in the dimensions expressions,
+then they are converted to world coordinates to determine the exact boundary values. This conversion is done using the scaling of the default
+file. Note that the conversion is done using the outside grid
+box boundary, rather than the grid box center. For example:
+  <p><code>asum(expr,x=1,x=72,y=1,y=46)</code>
+  <p> Here the boundary would be determined by using the X grid values ranging from 0.5 to 
+    72.5 and Y grid values ranging from 0.5 to 46.5. These four grid boundary values would be converted to world coordinates using the scaling information from the default file. If
+    we assume that <code>x=1</code> is 0 degrees longitude and <code>x=72</code> is 355 degrees longitude, then the averaging
+    boundary would be -2.5 to 357.5 degrees, which would cover the
+    earth. In the Y dimension, when the boundary is beyond the pole, the <code>asum</code> function recognizes this and weights
+    appropriately. 
+</ol>
+<p>
+
+<H3>Examples</H3> 
+
+<ol>
+<li>See the <a href="gradfunctloop.html"><code>tloop</code></a> function
+for an example of creating a time
+series of area averages. 
+<br><br>
+<li>An example of taking an area average of data only over land, given
+a
+mask grid: <p>
+
+<code>aave(maskout(p,mask.3(t=1)),x=1,x=72,y=1,y=46) </code><p>
+
+In this case, it is assumed the mask grid has negative values at ocean
+points. <p>
+</ol>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/gradfuncabs.html b/doc/gradfuncabs.html
new file mode 100644
index 0000000..e95e293
--- /dev/null
+++ b/doc/gradfuncabs.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>abs</b></h2><p>
+
+<code>abs(<i>expr</i>)</code><p>
+
+Takes the absolute value of the result of <code><i>expr</i></code>.
+Operates on both gridded and station data. Missing data values do not
+participate. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncacos.html b/doc/gradfuncacos.html
new file mode 100644
index 0000000..38ac9b7
--- /dev/null
+++ b/doc/gradfuncacos.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>acos</b></h2><p>
+
+<code>acos(<i>expr</i>)</code><p>
+
+Applies the cos<sup>-1</sup> function to the result of
+<code><i>expr</i></code>. Values from <code><i>expr</i></code> that exceed
+1 or are less than -1 are set to missing. The result of
+the <code>acos</code> function is in radians.
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncamax.html b/doc/gradfuncamax.html
new file mode 100644
index 0000000..a89de69
--- /dev/null
+++ b/doc/gradfuncamax.html
@@ -0,0 +1,78 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amax</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>amax()</b></h2>
+<p>This function returns an area maximum -- the maximum value in a grid spanning  an X-Y region. The syntax is:
+<p> <code>amax(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For global maximum, a shorthand may be used:
+  
+<ul>
+  <code>amax(<i>expr</i>, global)</code> or <br>
+  <code>amax(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>amax(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncmax.html">max</a></code> functions. 
+<li> Related functions  <code><a href="gradfuncamaxlocx.html">amaxlocx</a></code> and <code><a href="gradfuncamaxlocy.html">amaxlocy</a></code> will return the grid location (X or Y) of the maximum value. 
+ If more than one grid box contains the maximum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east. <li>A similar set of functions exists for finding the minimum over an area: <code><a href="gradfuncamin.html">amin</a></code>, <code><a href="gradfuncaminlocx.html">aminlocx</a></code>, and <code><a href="gradfuncaminlocy.html">aminlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+<ol> 
+<li>Get the maximum value of the variable <code>ps</code> over a specified grid domain:<br>
+  <code>d amax(ps,x=10,x=120,y=15,y=45)</code><br>
+  <br></li>
+<li>Get the maximum value of the variable <code>sstanom</code> over the nino3.4 domain:<br>
+  <code>d amax(sstanom,lon=-170,lon=-120,lat=-5,lat=5)</code><br>
+  <br></li>
+<li>Get the maximum value of the variable <code>slp</code> over the global domain, and also get the grid location of that minimum. Check results. 
+  <br>
+  <pre>
+ga-> d amax(slp,g)
+Result value = 105732 
+ga-> d amaxlocx(slp,g)
+Result value = 168 
+ga-> d amaxlocy(slp,g) 
+Result value = 13 
+ga-> set x 168
+LON set to 83.5 83.5 
+ga-> set y 13
+LAT set to -84 -84 
+ga-> d slp
+Result value = 105732 
+
+  </pre>
+</li>
+  </ol>
+  <p>
+</body>
+</html>
diff --git a/doc/gradfuncamaxlocx.html b/doc/gradfuncamaxlocx.html
new file mode 100644
index 0000000..e1de7f9
--- /dev/null
+++ b/doc/gradfuncamaxlocx.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amaxlocx</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>amaxlocx()</b></h2>
+<p>This function returns the X location of   maximum grid value over a spatial domain. The syntax is:
+<p> <code>amaxlocx(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For the X location of the global maximum, a shorthand may be used:
+  
+<ul>
+  <code>amaxlocx(<i>expr</i>, global)</code> or <br>
+  <code>amaxlocx(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>amaxlocx(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncmaxloc.html">maxloc</a></code> and <code><a href="gradfuncmax.html">max</a></code> functions. 
+<li> Related function  <code><a href="gradfuncamaxlocy.html">amaxlocy</a></code> will return the Y  location of the maximum grid value. 
+<li>Use the <code><a href="gradfuncamax.html">amax</a></code> function to retrieve the maximum value over the grid.  
+<li>If more than one grid box contains the maximum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east.
+<li>A similar set of functions exists for finding the minimum over an area: <code><a href="gradfuncamin.html">amin</a></code>, <code><a href="gradfuncaminlocx.html">aminlocx</a></code>, and <code><a href="gradfuncaminlocy.html">aminlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+Please see the documentation page for  <code><a href="gradfuncamax.html">amax</a></code>.
+</body>
+</html>
diff --git a/doc/gradfuncamaxlocy.html b/doc/gradfuncamaxlocy.html
new file mode 100644
index 0000000..407bef1
--- /dev/null
+++ b/doc/gradfuncamaxlocy.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amaxlocy</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>amaxlocy()</b></h2>
+<p>This function returns the Y location of   maximum grid value over a spatial domain. The syntax is:
+<p> <code>amaxlocy(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For the Y location of the global maximum, a shorthand may be used:
+  
+<ul>
+  <code>amaxlocy(<i>expr</i>, global)</code> or <br>
+  <code>amaxlocy(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>amaxlocy(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncmaxloc.html">maxloc</a></code> and <code><a href="gradfuncmax.html">max</a></code> functions. 
+<li> Related function  <code><a href="gradfuncamaxlocx.html">amaxlocx</a></code> will return the X  location of the maximum grid value. 
+<li>Use the <code><a href="gradfuncamax.html">amax</a></code> function to retrieve the maximum value over the grid.  
+<li>If more than one grid box contains the maximum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east.
+<li>A similar set of functions exists for finding the minimum over an area: <code><a href="gradfuncamin.html">amin</a></code>, <code><a href="gradfuncaminlocx.html">aminlocx</a></code>, and <code><a href="gradfuncaminlocy.html">aminlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+Please see the documentation page for  <code><a href="gradfuncamax.html">amax</a></code>.
+</body>
+</html>
diff --git a/doc/gradfuncamean.html b/doc/gradfuncamean.html
new file mode 100644
index 0000000..573e483
--- /dev/null
+++ b/doc/gradfuncamean.html
@@ -0,0 +1,31 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amean</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>amean()</b></h2>
+
+<p>
+<code>amean (<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+
+<p>
+This function is the same as <a
+href="gradfuncaave.html"><code>aave</code></a> in all respects except
+one: area means <b><i>are not</i></b> weighted by latitude. Means
+<b><i>are</i></b> weighted by grid interval to account for
+non-linear grid spacing.
+
+<p>
+<h3>Usage Notes</h3>
+
+<p>
+See the <a href="gradfuncaave.html"><code>aave</code></a> reference page for details. 
+
+<p>
+<h3>Examples</h3>
+
+</body>
+</html>
diff --git a/doc/gradfuncamin.html b/doc/gradfuncamin.html
new file mode 100644
index 0000000..afc4376
--- /dev/null
+++ b/doc/gradfuncamin.html
@@ -0,0 +1,77 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amin</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>amin()</b></h2>
+<p>This function returns an area minimum -- the minimum value in a grid spanning  an X-Y region. The syntax is:
+<p> <code>amin(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For global minimum, a shorthand may be used:
+  
+<ul>
+  <code>amin(<i>expr</i>, global)</code> or <br>
+  <code>amin(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>amin(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncmin.html">min</a></code> functions. 
+<li> Related functions  <code><a href="gradfuncaminlocx.html">aminlocx</a></code> and <code><a href="gradfuncaminlocy.html">aminlocy</a></code> will return the grid location (X or Y) of the minimum value. If more than one grid box contains the minimum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east. 
+<li>A similar set of functions exists for finding the maximum over an area: <code><a href="gradfuncamax.html">amax</a></code>, <code><a href="gradfuncamaxlocx.html">amaxlocx</a></code>, and <code><a href="gradfuncamaxlocy.html">amaxlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+<ol> 
+<li>Get the minimum value of the variable <code>ps</code> over a specified grid domain:<br>
+  <code>d amin(ps,x=10,x=120,y=15,y=45)</code><br>
+  <br></li>
+<li>Get the minimum value of the variable <code>sstanom</code> over the nino3.4 domain:<br>
+  <code>d amin(sstanom,lon=-170,lon=-120,lat=-5,lat=5)</code><br>
+  <br></li>
+<li>Get the minimum value of the variable <code>slp</code> over the global domain, and also get the grid location of that minimum. Check results. 
+  <br>
+  <pre>
+ga-> d amin(slp,g)     
+Result value = 94569 
+ga-> d aminlocx(slp,g)
+Result value = 523 
+ga-> d aminlocy(slp,g)
+Result value = 51 
+ga-> set x 523
+LON set to 261 261 
+ga-> set y 51
+LAT set to -65 -65 
+ga-> d slp
+Result value = 94569 
+  </pre>
+</li>
+</ol>
+  <p>
+</body>
+</html>
diff --git a/doc/gradfuncaminlocx.html b/doc/gradfuncaminlocx.html
new file mode 100644
index 0000000..6aefc89
--- /dev/null
+++ b/doc/gradfuncaminlocx.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: aminlocx</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>aminlocx()</b></h2>
+<p>This function returns the X location of   minimum grid value over a spatial domain. The syntax is:
+<p> <code>aminlocx(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For the X location of the global minimum, a shorthand may be used:
+  
+<ul>
+  <code>aminlocx(<i>expr</i>, global)</code> or <br>
+  <code>aminlocx(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>aminlocx(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncminloc.html">minloc</a></code> and <code><a href="gradfuncmin.html">min</a></code> functions. 
+<li> Related function  <code><a href="gradfuncaminlocy.html">aminlocy</a></code> will return the Y  location of the minimum grid value. 
+<li>Use the <code><a href="gradfuncamin.html">amin</a></code> function to retrieve the minimum value over the grid.  
+<li>If more than one grid box contains the minimum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east.
+<li>A similar set of functions exists for finding the maximum over an area: <code><a href="gradfuncamax.html">amax</a></code>, <code><a href="gradfuncamaxlocx.html">amaxlocx</a></code>, and <code><a href="gradfuncamaxlocy.html">amaxlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+Please see the documentation page for  <code><a href="gradfuncamin.html">amin</a></code>.
+</body>
+</html>
diff --git a/doc/gradfuncaminlocy.html b/doc/gradfuncaminlocy.html
new file mode 100644
index 0000000..89d6955
--- /dev/null
+++ b/doc/gradfuncaminlocy.html
@@ -0,0 +1,54 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: amaxinlocy</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+</head>
+<body text="#000000">
+
+<h2><b>aminlocy()</b></h2>
+<p>This function returns the Y location of   minimum grid value over a spatial domain. The syntax is:
+<p> <code>aminlocy(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p> where:
+<ul>
+  <code><i>expr</i>    </code>any valid GrADS grid expression <br>
+  <code><i>xdim1</i>   </code>starting X or LON dimension expression <br>
+  <code><i>xdim2</i>   </code>ending X or LON dimension expression <br>
+  <code><i>ydim1</i>   </code>starting Y or LAT dimension expression <br>
+  <code><i>ydim2</i>   </code>ending Y or LAT dimension expression <br>
+</ul>
+<p> For the Y location of the global minimum, a shorthand may be used:
+  
+<ul>
+  <code>aminlocy(<i>expr</i>, global)</code> or <br>
+  <code>aminlocy(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+  <code>aminlocy(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>This function will only work with <span class="red">GrADS version 2.0.2</span> or later.
+<li>This function is  more efficient that using nested <code><a href="gradfuncminloc.html">minloc</a></code> and <code><a href="gradfuncmin.html">min</a></code> functions. 
+<li> Related function  <code><a href="gradfuncaminlocx.html">aminlocx</a></code> will return the X  location of the minimum grid value. 
+<li>Use the <code><a href="gradfuncamin.html">amin</a></code> function to retrieve the minimum value over the grid.  
+<li>If more than one grid box contains the minimum value, the location returned will be the first one encountered as the grid is scanned. The grid is scanned by rows from south to north, and each row is scanned from west to east.
+<li>A similar set of functions exists for finding the maximum over an area: <code><a href="gradfuncamax.html">amax</a></code>, <code><a href="gradfuncamaxlocx.html">amaxlocx</a></code>, and <code><a href="gradfuncamaxlocy.html">amaxlocy</a></code>.
+</ol>
+
+<p>
+<h3>Examples</h3>
+Please see the documentation page for  <code><a href="gradfuncamin.html">amin</a></code>.
+</body>
+</html>
diff --git a/doc/gradfuncasin.html b/doc/gradfuncasin.html
new file mode 100644
index 0000000..66dba2c
--- /dev/null
+++ b/doc/gradfuncasin.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>asin</b></h2><p>
+
+<code>asin(<i>expr</i>)</code><p>
+
+Applies the sin<sup>-1</sup> function to the result of
+<code><i>expr</i></code>. Values of <code><i>expr</i></code> that exceed 1
+or are less than -1 are set to missing in the final result. The result of
+the <code>asin</code> function is in radians.
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncasum.html b/doc/gradfuncasum.html
new file mode 100644
index 0000000..370994d
--- /dev/null
+++ b/doc/gradfuncasum.html
@@ -0,0 +1,73 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Function: asum</title>
+<style type="text/css">
+.red {
+	color: #900;
+}
+body {
+	background-color: #e0f0ff;
+}
+</style>
+<body text="#000000">
+
+<H2><b>asum()</b></H2>
+<p>
+This function takes a sum over an X-Y region. The syntax is:
+<p>
+<code>asum(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+
+<p>
+where:
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>xdim1</i>   </code>- starting X dimension expression <br>
+<code><i>xdim2</i>   </code>- ending X dimension expression <br>
+<code><i>ydim1</i>   </code>- starting Y dimension expression <br>
+<code><i>ydim2</i>   </code>- ending Y dimension expression <br>
+</ul>
+<p>
+For global summing, a shorthand may be used:
+
+<ul>
+<code>asum(<i>expr</i>, global)</code> or <br>
+<code>asum(<i>expr</i>, g)</code>
+</ul>
+is the same as
+<ul>
+<code>asum(<i>expr</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul> 
+
+<p>
+<H3>Usage Notes</H3>
+<ol>
+<li>The <code>asum</code> function always does its average to the
+exact boundaries specified, in world coordinates. If the boundaries
+specified via the dimension expressions do not fall on grid box
+boundaries, then the  values in the boundary grid boxes are weighted in the sum according to the length of the partial grid box in world coordinates. <br>
+  <br>
+<li>If grid coordinates are used in the dimensions expressions,
+then they are converted to world coordinates to determine the exact boundary values. This conversion is done using the scaling of the default
+file. Note that the conversion is done using the outside grid
+box boundary, rather than the grid box center. For example: <p><code>asum(expr,x=1,x=72,y=1,y=46)</code>
+<p>
+  Here the boundary would be determined by using the X grid values ranging from 0.5 to 
+  72.5 and Y grid values ranging from 0.5 to 46.5. These four grid boundary values would be converted to world coordinates using the scaling information from the default file. If
+  we assume that <code>x=1</code> is 0 degrees longitude and
+  <code>x=72</code> is 355 degrees longitude, then the averaging
+  boundary would be -2.5 to 357.5 degrees, which would cover the
+  earth. In the Y dimension, when the boundary is beyond the pole, the
+  <code>asum</code> function recognizes this and weights
+  appropriately. To calculate a sum without any weighting of partial grid boxes at the domain boundaries, use the
+  <code><a href="gradfuncasumg.html">asumg</a></code> function.
+  
+  
+<li>There is no latitude-weighting of grid box values in <code>asum</code>. The <code><a href="gradfuncatot.html">atot</a></code> function (in <span class="red">GrADS version 2.0.2+</span>) will calculate a sum over an area and weight the grid box values according to the difference in the sine of the latitude at the northern and southern boundaries of each grid box. 
+</ol>
+<p>
+
+
+ 
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/gradfuncasumg.html b/doc/gradfuncasumg.html
new file mode 100644
index 0000000..b18e970
--- /dev/null
+++ b/doc/gradfuncasumg.html
@@ -0,0 +1,30 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: asumg</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>asumg()</b></h2>
+<p>
+<code>asumg(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p>
+This function is the same as <a
+href="gradfuncasum.html"><code>asum</code></a> in all respects except
+one: the sums are calculated without any weighting at all. 
+<p>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<p>
+See the <a href="gradfuncasum.html"><code>asum</code></a> reference page for details. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncatan2.html b/doc/gradfuncatan2.html
new file mode 100644
index 0000000..4f6f24e
--- /dev/null
+++ b/doc/gradfuncatan2.html
@@ -0,0 +1,29 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS function: atan2</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>atan2()</b></h2><p>
+
+<code>atan2 (<i>expr1, expr2</i>)</code>
+
+<p>
+Applies the tan<sup>-1</sup> function to the result of
+(<code><i>expr1/expr2</i></code>). 
+<p>
+If <code><i>expr1</i></code> and <code><i>expr2</i></code> are both
+zero, the result is arbitrarily set to zero. The result of the
+<code>atan2</code> function is in radians.
+
+
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
+
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncatot.html b/doc/gradfuncatot.html
new file mode 100644
index 0000000..1cb54cb
--- /dev/null
+++ b/doc/gradfuncatot.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Function: atot</title>
+<style type="text/css">
+.red {
+	color: #900;
+	font-weight: bold;
+}
+.red1 {	color: #900;
+}
+body {
+	background-color: #e0f0ff;
+}
+</style>
+<body text="#000000">
+
+<H2><b>atot()</b></H2>
+<p>Thie <code>atot</code> function (in <span class="red1">GrADS version 2.0.2+</span>) duplicates the summing capability of <code><a href="gradfuncasum.html">asum</a></code> but adds the latitude-weighting feature of <code><a href="gradfuncaave.html">aave</a></code>.  The syntax is:
+<p>
+<code>atot(<i>expr, xdim1, xdim2, ydim1, ydim2</i>)</code>
+<p>
+
+<H3>Usage Notes</H3>
+<p>Please see the reference page for <code><a href="gradfuncasum.html">asum</a></code> for details on the command syntax and usage notes.
+
+  <br>
+<H3>Examples</H3>
+
+<ol>
+<li>
+  <p>An instructive sanity check is to calculate the total  area over globe on any grid of data that has a constant value of 1 and no missing values: <br>
+    <br>
+  <code>ga-> d atot(const(temp,1,-a),global) <br>
+  Result value = 12.5664 </code><br>
+  <br>
+  The answer we get is 4*pi, and the unit of the result is steradians.   
+  
+<li>Suppose you have a data variable sea ice concentration (named 'sic') which is given as a % in each grid box, and you would like to calculate the total area in the Arctic covered by sea ice.
+  To calculate the  sea ice coverage in millions of km^2, we multiply the <code>atot</code> result by the square of the radius of the Earth in km:
+
+  <p><code>ga-> d atot(sic/100,lon=0,lon=360,lat=40,lat=90)*6371*6371*1e-6 <br>
+    Result value = 11.289</code>
+</ol>
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/gradfuncave.html b/doc/gradfuncave.html
new file mode 100644
index 0000000..279a841
--- /dev/null
+++ b/doc/gradfuncave.html
@@ -0,0 +1,141 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: ave</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>ave()</b></h2>
+<p>
+<code>ave(<i>expr, dim1, dim2 <,tinc></i> <,-b>)</code>
+<p>
+Averages the result of <code><i>expr</i></code> over the specified 
+dimension range. If the averaging dimension is time, an
+optional time increment <code><i>tincr</i></code> may be specified.
+
+<p>
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>dim1</i>    </code>- the start point for the average<br>
+<code><i>dim2</i>    </code>- the end point for the average<br>
+<code><i>tinc</i>    </code>- optional increment for time averaging<br>
+<code>-b      </code>- use exact boundaries<br>
+</ul>
+
+<p>
+<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
+GrADS dimension expressions whose dimensions must match.
+
+<p>
+<h3>Usage Notes</h3><p>
+<p>
+<ol>
+<li>The limits and intervals of the averaging are set according to the
+grid coordinates of the default file. If <code><i>dim1</i></code>
+and <code><i>dim2</i></code> are specified in world coordinates, the
+coordinates are converted to the nearest integer grid coordinates
+based on the scaling of the default file. See the examples below for
+further illustration. 
+<p>
+<li>
+The end points are given normal weighting, unless the <code>-b</code>
+boundary flag is specified. The boundry flag indicates that the
+average should be taken to the exact boundaries specified by
+<code><i>dim1</i></code> and <code><i>dim2</i></code>, rather than
+the nearest grid points.
+<p>
+<li>The average is weighted by grid interval to account for non-linear
+grid spacing. Averages in the latitude dimension are weighted by the
+difference between the sines of the latitude at the northern and
+southern edges of the grid box. The edges of the grid box are always
+defined as being the midpoint between adjacent grid points. To
+calculate an average without using the latitude weighting, use the
+<code><a href="gradfuncmean.html">mean</a></code> function.
+<p>
+
+</ol>
+
+<p>
+<h3>Examples</h3>
+<p>
+For the following examples, the dimension environment is X-Y varying; Z-T are fixed. 
+<p>
+
+<ol>
+<li>Consider the following average, when the default file is file #1: <p>
+
+<dd><code>ave(z.2,t=1,t=10) </code><p>
+
+We are averaging a variable from file #2, but using the scaling from file
+#1. File #1 has a time interval of 6 hours, but file #2 has a time
+interval of 12 hours. The average will thus attempt to access data from
+file #2 for times that are not available, and an error will
+ocurr. To avoid this, the default file should be set to file #2:
+<code><a href="gradcomdsetdfile.html">set dfile</a> 2</code>
+
+<p>
+<li>The average: <p>
+
+<dd><code>ave(z,t=1,t=120,4) </code><p>
+
+will average only 00Z reports from file #1, since the time increment is 4,
+which for this file is 24 hours. <p>
+
+<li>If you attempt to take a zonal average as follows: <p>
+
+<dd><code>ave(z,lon=0,lon=360) </code><p>
+
+the world coordinates will be converted to grid coordinates, here
+<code>X</code> varying from 1 to 181, and the grid point at longitude 0
+(and 360) will be used twice in the average. To have the end points of
+this average weighted properly, use the <code>-b</code> flag:<p>
+ 
+<dd><code>ave(z,lon=0,lon=360,-b)</code><p> 
+
+or average using the grid coordinates directly: <p>
+
+<dd><code>ave(z,x=1,x=180) </code><p>
+
+<li>You can nest averaging operations: <p>
+
+<dd><code>ave(ave(z,x=1,x=180),y=1,y=46) </code><p>
+
+In this case, to take an areal average. Note that for areal averaging, the
+<code>aave</code> function is better. See the <a
+href="gradfuncaave.html"><code>aave</code></a> function
+description. <p>
+
+When nesting averages, the order of the nesting can have a dramatic affect
+on performance. 
+Keep in mind the ordering of the data in a GrADS file: X varies the
+fastest, then Y, then Z, then T. When nesting averages, put the faster
+varying dimension within the inner average: <p>
+
+<dd><code>set lon -90 
+<dd>set lat -90 90 
+<dd>set lev 1000 100 
+<dd>d ave(ave(t,x=1,x=180),t=1,t=20) </code><p>
+
+This average would be more efficient than, for example: <p>
+
+<dd><code>ave(ave(t,t=1,t=20),x=1,x=180) </code><p>
+
+although the final numerical result would be the same. <p>
+
+<li>The use of the <a href="gradcomddefine.html"><code>define</code></a>
+command can make certain operations much more efficient. If you want to
+calculate standard deviation, for example: <p>
+
+<dd><code>sqrt(ave(pow(ave(z,t=1,t=20)-z,2),t=1,t=20)) </code><p>
+
+would be correct, but the inside average would be calculated 20 times.
+Defining the inside average in advance will be substantially faster: <p>
+
+<dd><code>define zave = ave(z,t=1,t=20) 
+<dd>d sqrt(ave(pow(zave-z,2),t=1,t=20)) </code>
+</ol>
+
+
+</body>
+</html>
diff --git a/doc/gradfunccdiff.html b/doc/gradfunccdiff.html
new file mode 100644
index 0000000..d1b2701
--- /dev/null
+++ b/doc/gradfunccdiff.html
@@ -0,0 +1,51 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>cdiff</b></h2><p> 
+
+<code>cdiff(<i>expr,dim</i>)</code><p> 
+
+Performs a centered difference operation on <code><i>expr</i></code> in
+the direction specified by <code><i>dim</i></code>. The difference is done
+in the grid space, and no adjustment is performed for unequally spaced
+grids. The result value at each grid point is the value at the grid point
+plus one minus the value at the grid point minus one. The
+<code><i>dim</i></code> argument
+specifies the dimension over which the difference is to be taken, and is a
+single character: X, Y, Z, or T. <p>
+
+Result values at the grid boundaries are set to missing. <p>
+<H3>Usage Notes</H3><P>
+<h3>Examples</h3><p> 
+
+<ol>
+<li>The <code>cdiff</code> function may be used to duplicate the
+calculation done by the <a
+href="gradfunchcurl.html"><code>hcurl</code></a> function: <p>
+
+<dd><code>define dv = cdiff(v,x) 
+<dd>define dx = cdiff(lon,x)*3.1416/180 
+<dd>define du = cdiff(u*cos(lat*3.1416/180),y) 
+<dd>define dy = cdiff(lat,y)*3.1416/180 
+<dd>display (dv/dx-du/dy)/(6.37e6*cos(lat*3.1416/180)) </code><p>
+
+The above example assumes an X-Y varying dimension environment. Note that
+the intrinsic variables <code>lat</code> and <code>lon</code> give results
+in degrees and must be converted to radians in the calaculation. Also note
+the radius of the earth is assumed to be <code>6.37e6</code> meters thus
+the U and V winds are assumed to have units of <code>m/sec</code>.<p> 
+
+<li>Temperature advection can be calculated using the <code>cdiff</code>
+function as follows: <p>
+
+<dd><code>define dtx = cdiff(t,x) 
+<dd>define dty = cdiff(t,y) 
+<dd>define dx = cdiff(lon,x)*3.1416/180 
+<dd>define dy = cdiff(lat,y)*3.1416/180 
+<dd>display -1*( (u*dtx)/(cos(lat*3.1416/180)*dx) + v*dty/dy )/6.37e6
+</code><p>
+
+where the variable <code>t</code> is temperature, <code>u</code> is the U
+component of the wind, and <code>v</code> is the V component of the wind. 
+</ol>
+
+
diff --git a/doc/gradfunccoll2gr.html b/doc/gradfunccoll2gr.html
new file mode 100644
index 0000000..745e359
--- /dev/null
+++ b/doc/gradfunccoll2gr.html
@@ -0,0 +1,69 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: coll2gr</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>coll2gr()</b></h2>
+<p>
+This function creates a grid from a collection of station data. The syntax is:
+
+<p>
+<code>coll2gr(<i>cnum <,num></i>)</code>
+
+<p>
+<ul>
+<code><i>cnum</i>    </code> collection number<br>
+<code><i>num</i>     </code> 
+number of vertical levels in the output grid (default is 10)<br>
+</ul>
+<p>
+If <code><i>num</i></code> is given as <code>"-u"</code>, then the
+vertical levels will be a union of all the levels in the collection of
+station data.
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>Before using <code>coll2gr</code>, you must create the collection of
+stations using the GrADS command <a
+href="gradcomdcollect.html"><code>collect</code></a>.
+
+<p>
+<li><code>coll2gr</code> does not yet support time slices; currently, it will
+only work when the collection of stations is a collection of
+vertical profiles. 
+
+<p>
+<li><code>coll2gr</code> produces an output grid that varies in X and Z;
+the dimension environment used when <code>coll2gr</code> is invoked
+must also be X and Z varying. The X axis of the output grid will contain
+the equally spaced station profiles and will span the range of the
+current X dimension environment. The Z axis of the output grid will
+span the range of the current Z dimension environment and will have
+either the specified number of levels or a union of the levels. Data
+points outside of the range of levels will be used for interpolating
+to within the range if appropriate.
+
+<p>
+<li>The <code>"-u"</code> option will only work for data in pressure
+vertical coordinates. If your vertical coordinate is height,
+<code><i>num</i></code> should be the actual number of vertical levels
+in the collection of profiles.
+
+
+<p>
+<li>See the section of the User's Guide on <a
+href="usingstationdata.html#xsection">Arbitrary Cross Sections</a> for more
+information. 
+</ol>
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncconst.html b/doc/gradfuncconst.html
new file mode 100644
index 0000000..31d5cd3
--- /dev/null
+++ b/doc/gradfuncconst.html
@@ -0,0 +1,104 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Function: const</title>
+<body bgcolor="e0f0ff" text="#000000">
+<h2><b>const()</b></h2> <p>
+
+<p>
+<code>const (<i>expr, value,</i> <-u|-a>)</code>
+
+<p>
+This is a powerful function that allows the user to change the missing
+values of a variable, set all the non-missing values of a variable to
+a constant, or set all possible values of a variable (both valid and
+missing) to a constant. 
+
+<p>
+<ul>
+<code><i>expr</i>   </code>a valid GrADS expression <br>
+<code><i>value</i>  </code>a constant, either an integer or floating point value <br>
+<code>-u     </code>all missing data are set to 
+<code><i>value</i></code>; non-missing data are unchanged<br>
+<code>-a     </code>all data are set to 
+<code><i>value</i></code>, both missing and non-missing<br>
+</ul>
+
+<p>
+Default behaviour is to set all non-missing data equal to 
+<code><i>value</i></code>; missing data are unchanged <br>
+</ul>
+
+
+<p>
+<h3>Usage Notes</h3> 
+
+<ol>
+<li>The <code>const</code> function operates on both gridded and
+station data.
+
+<li>If <code><i>value</i></code> is given as an integer, 
+it will still be treated as as floating point.
+</ol>
+
+<p>
+<h3>Examples</h3><p>
+
+<ol>
+<li>The <code>const</code> function assigns a new value to missing
+data, so that missing data may participate in operations: 
+<p>
+<ul><code>const(z, 0, -u)</code></ul>
+<p>
+<li>The <code>const</code> function is used with the <a
+href="gradcomdsetgxout.html"<code>set gxout linefill</code></a> graphics output
+option to define a straight horizontal line: 
+<p>
+<ul>
+<code>
+set lon -90 <br>
+set lat -90 90 <br>
+set gxout linefill <br>
+set lev 500 <br>
+d const(t, -20);t-273 <br>
+</code>
+</ul>
+<p>
+<li>In this example, <code>const</code> is used to calculate a daily
+timeseries of the fraction of the globe convered by precipitation
+greater than <code>10mm/day</code>:
+
+<p> 
+<ul>
+<code>
+set lon 0 360 <br>
+set lat -90 90 <br> 
+set t 1 last <br>
+define ones = const(const(maskout(p,p-10),1),0,-u) <br>
+set x 1 <br>
+set y 1 <br>
+display tloop(aave(ones,lon=0,lon=360,lat=0,lat=360)) <br>
+</code>
+</ul>
+
+<p>
+Notes: The <a href="gradcomddefine.html">defined</a> variable
+<code>"ones"</code> contains <code>1</code> wherever the precip value
+is greater than <code>10</code>, and <code>0</code> whever the precip
+value is less than <code>10</code>. This is done via nested functions;
+first <a href="gradfuncmaskout.html"><code>maskout</code></a> sets all
+values less than <code>10</code> to missing, then <code>const</code>
+sets all non-missing values to <code>1</code>, then <code>const</code>
+is used with the <code>-u</code> flag to set all the missing data
+values to <code>0</code>.  The <a
+href="gradfuncaave.html"><code>aave</code></a> function calculates an
+area weighted average. Since we are averaging zeros and ones, the
+result is the fraction of the area where there are ones. See the <a
+href="gradfunctloop.html"><code>tloop</code></a> function for a
+description of how to perform time series of areal averages.
+</ol>
+</body>
+</html>
+
+
+
diff --git a/doc/gradfunccos.html b/doc/gradfunccos.html
new file mode 100644
index 0000000..c7c24b4
--- /dev/null
+++ b/doc/gradfunccos.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>cos</b></h2><p> 
+
+<code>cos(<i>expr</i>)</code><p> 
+
+Takes the cosine of the <code><i>expr</i></code>. Values are assumed to be
+in radians. Works on both gridded and station data. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfunceloop.html b/doc/gradfunceloop.html
new file mode 100644
index 0000000..9334856
--- /dev/null
+++ b/doc/gradfunceloop.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style>

<title>eloop function</title><h2><b>eloop</b></h2>
<p> 

<code>eloop(<i>expr</i>)</code>
<p>

The <code>eloop</code> function is similar to the <code><a href="gradfunctloop.html">tloop</a></code> function. When displaying a GrADS expression (<code><i>expr</i></code>) with the E (Ensemble) dimension varying, the
<code>eloop</code> function will evaluate the <code><i>expr</i></code> with each designated ensemble member fixed, then reassemble the grids to obtain a final result
that is E-varying. 

The <code>eloop</code> function is provided as a way to obtain E-varying results
from functions or expressions that  are unable to operate
when E is a varying dimension. 
<p>

<h3>Examples</h3>
<p> 

<ol>
  <li>Suppose you have an ensemble forecast with 15 ensemble members, and you want to evaluate the accuracy of each ensemble member by comparing it to reanalysis. You need to calculate the difference between an E-varying data set (the forecast) with a non-E-varying data set (reanalysis). </li>
  <ul>
    <p><code>open fcst.ctl<br />
      open  rean.ctl<br />
      set lon -77<br />
      set lat 39<br />
      set e 1 15<br />
      set t 1 last<br />
      d eloop(t2m.1-t2m.2(e=1))</code><br />
    </p>
  </ul>
</ol>
\ No newline at end of file
diff --git a/doc/gradfuncexp.html b/doc/gradfuncexp.html
new file mode 100644
index 0000000..235cafa
--- /dev/null
+++ b/doc/gradfuncexp.html
@@ -0,0 +1,10 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>exp</b></h2><p> 
+
+<code>exp(<i>expr</i>)</code> <p>
+
+Performs the <code>e**x</code> operation, where <code><i>expr</i></code>
+is <code>x</code>. Works on both gridded and station data. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncfndlvl.html b/doc/gradfuncfndlvl.html
new file mode 100644
index 0000000..2d5f47d
--- /dev/null
+++ b/doc/gradfuncfndlvl.html
@@ -0,0 +1,57 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: fndlvl</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>fndlvl()</b></h2>
+<p>
+<code>fndlvl (<i>expr, expr_to_find, lev1, lev2</i>)</code>
+<p>
+Given two gridded variables, <code><i>expr</i></code> and
+<code><i>expr_to_find</i></code>, this function finds the first
+vertical level at which the <code><i>expr_to_find</i></code> value
+occurs in <code><i>expr</i></code>. <code><i>lev1</i></code> and 
+<code><i>lev2</i></code> specify the range of
+levels over which to search. The result is a grid of pressure values.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>The dimensions of <code><i>expr</i></code> and
+<code><i>expr_to_find</i></code> &nbsp must match. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+<p>
+<ol>
+<li>This example finds the pressure levels of the 240 degree isotherm:
+<p>
+<ul><code>d fndlvl (t, const(t,240), lev=1000, lev=100)</code></ul>
+<p>
+<li>The <code><i>expr_to_find</i></code> doesn't have to be a constant;
+it can change with location. This example returns the pressure
+level of the tropopause, given the variable <code>'ttrop'</code> that 
+contains the temperature at the tropopause: 
+<p>
+<ul><code>d fndlvl (t, ttrop, lev=1000, lev=100)</code></ul>
+<p>
+<li>This example illustrates the limitations of
+<code>fndlvl</code>. It returns the level of the surface pressure
+variable <code>psfc</code> in the coordinate system of
+<code>lev</code>, a GrADS <a href="variable.html">pre-defined variable</a>.
+<p>
+    <ul>
+      <code>d fndlvl (lev, psfc, lev=1000, lev=100)</code> 
+    </ul>
+<p>
+The display should be exactly the same as <code>psfc</code> except in 
+locations where <code>psfc</code> is greater than 1000 mb, the maximum value of 
+<code>lev<code>.
+</code></code></ol>
+
+</body>
+</html>
diff --git a/doc/gradfuncgint.html b/doc/gradfuncgint.html
new file mode 100644
index 0000000..31c5d18
--- /dev/null
+++ b/doc/gradfuncgint.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<h2>gint</h2>
<code>gint (<i>expr, dim1, dim2</i>)</code>
<p>
general integral, similar to the  <a href="gradfuncave.html"><code>ave</code></a>
function except the result is not divided by the total area. 
<ul>
  <code><i>expr</i>    </code>- any valid GrADS expression <br />
  <code><i>dim1</i>    </code>- the start point for the integral<br />
  <code><i>dim2</i>    </code>- the end point for the integral<br />
</ul>
<p> <code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
  GrADS dimension expressions whose dimensions must match. </p>
<p>
<h3>Usage Notes</h3>
<h3>Examples</h3>
\ No newline at end of file
diff --git a/doc/gradfuncgr2stn.html b/doc/gradfuncgr2stn.html
new file mode 100644
index 0000000..08b56ab
--- /dev/null
+++ b/doc/gradfuncgr2stn.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Function: gr2stn</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body text="#000000" bgcolor="e0f0ff">

<h2><b>gr2stn()</b></h2><p> 

<p>
This function is a grid-to-station interpolator. It creates "station"
data result by sampling a gridded data set and
interpolating to a given location. That location may be provided by
specifying a longitude and a latitude, or by providing a station
expression.
<h3>Syntax</h3>
<ul>
<code>gr2stn(<i>grid_expr, stn_expr,</i> <-n>)</code><br>
   or<br>
<code>gr2stn(<i>grid_expr, lon, lat</i>, <-n>)</code><br>
</ul>

<p>
where:
<ul>
<code><i>grid_expr</i></code> is a GrADS expression
that gives a grid result. The interpolation will be done on this
data. The 
<code><i>grid_expr</i></code>may be a 2-D grid that varies in X and Y, or a 1-D grid that varies in Z or T. 
<p> 
  <code><i>stn_expr</i></code> is a GrADS
  expression that gives a station data result. The interpolation will be
  done to the station <i>locations</i>, the station data values are not used. </p>
<p><code><i>lon,lat</i></code> may be used instead of <code><i>stn_expr</i></code> to specify the location to which the
  gridded data will be interpolated (see Usage Note #3.)</p>
<p><span class="style1">(Version 2.0.a6 or later)</span> The <code>-n</code> option was added to return the nearest neighbor to the station location
instead of the bi-linear interpolation of the four surrounding grid points.</p>
<p> </p>
</ul>

<H3>Usage Notes</H3>
<ol><li>The result of the function is station data. </li>
  <li>If <code><i>grid_expr</i></code> is a 2-D grid that varies in X and Y, then <code><i>stn_expr</i></code> should also be a 2-D expression that has multiple stations in the lat/lon domain. The result will be a station data set, with values interpolated from <code><i>grid_expr</i></code> to the station locations.</li>
  <li>If <code><i>grid_expr</i></code> is a 1-D grid, then only Z or T can be the varying dimension. In this case, <code><i>stn_expr</i></code> should  be an expression that has a single location, such as "temp(stid=kdca)". Alternatively, you may  provide  exact longitude and latitude values.</li>
  <li>By default, the interpolation is done
    bi-linearly within the grid space. No weighting is done to account for
    real-world coordinate systems. If any of the four grid points around the station location are missing, the result will also be missing. </li>
  <li>As of version 2.0.a6, the -n option may be used to return the nearest grid point value instead of the bi-linearly interpolated value.</li>
  <li>See the section of the User's Guide on <a
href="usingstationdata.html#xsection">Arbitrary Cross Sections</a> for more
    information on applications of <code>gr2stn</code>. </li>
</ol>
<h3>Examples</h3>
<ol>
<li>To examine the difference between an analysis (ie, gridded data) and
the original observations, one could:<br>
<br>
  <dd><code>d t.3-gr2stn(t.1,t.3)</code>
  <p>

where file 1 is gridded data, and file 3 is station data. The result would
display as differences at the station locations. 

<li>If one wanted to display the difference calculated in Example 1 as a
contour field, one can use the <a
href="gradfuncoacres.html"><code>oacres</code></a> function to do a quick
analysis of the station values:<br>
<br>
<dd><code>d oacres(t.1,t.3-gr2stn(t.1,t.3)) </code>
</ol>
</body>
</html>


\ No newline at end of file
diff --git a/doc/gradfunchcurl.html b/doc/gradfunchcurl.html
new file mode 100644
index 0000000..a1a0a26
--- /dev/null
+++ b/doc/gradfunchcurl.html
@@ -0,0 +1,48 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>hcurl</b></h2><p> 
+
+<code>hcurl(<i>uexpr,vexpr</i>)</code><p> 
+
+Calculates the vertical component of the curl (ie, vorticity) at each grid
+point using finite differencing on the grids provided. It is assumed that
+<code><i>uexpr</i></code> gives the U Wind component, and that
+<code><i>vexpr</i></code> provides the V Wind component.<p> 
+
+<h3>Usage Notes</h3><p> 
+
+<ol>
+<li>The alghorithm used for the finite difference calculation is described
+as an Example for the <a href="gradfunccdiff.html"><code>cdiff</code></a>
+function.<p> 
+
+<li>The function assumes an X-Y varying dimension environment, and will
+not operate unless that is the case. The <a
+href="gradcomddefine.html"><code>define</code></a> command can
+be used in conjunction with the <code>hcurl</code> function to create 3 or
+4 dimensional fields of vorticity, from which
+vertical cross-sections could be displayed. <p>
+
+<li>The boundaries of the grid are set to missing. <p>
+
+<li>The radius of the earth used in the calculation is in meters; thus the
+units of the wind expressions provided would normally be m/s. <p>
+</ol>
+<h3>Examples </h3><p>
+
+<ol>
+<li>To display the vorticity: <p>
+
+<dd><code>d hcurl(u,v) </code><p>
+
+<li>If you want to display a vertical cross section of vorticity, you
+first need to calculate it over a 3-Dimensional region: <p>
+
+<dd><code>set lon 0 360 
+<dd>set lat -90 90 
+<dd>set lev 1000 100 
+<dd>define vort = hcurl(u,v) 
+<dd>set lon -90 
+<dd>display vort </code>
+</ol>
+
diff --git a/doc/gradfunchdivg.html b/doc/gradfunchdivg.html
new file mode 100644
index 0000000..4b3c596
--- /dev/null
+++ b/doc/gradfunchdivg.html
@@ -0,0 +1,19 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>hdivg</b></h2><p> 
+
+<code>hdivg(<i>uexpr,vexpr</i>)</code><p> 
+
+Calculates the horizontal divergence using finite differencing. Exactly
+the same as <a href="gradfunchcurl.html"><code>hcurl</code></a> in all
+other respects; see the Usage Notes
+and Examples above. <p>
+
+<h3>Usage Notes </h3>
+
+<ol>
+<li>The numerical stability of calculating horizontal divergence using
+finite differencing is very low. Please use the function with caution. 
+</ol>
+
+<H3>Examples</H3><P>
diff --git a/doc/gradfunclog.html b/doc/gradfunclog.html
new file mode 100644
index 0000000..010e15e
--- /dev/null
+++ b/doc/gradfunclog.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>log</b></h2><p>
+
+<code>log(<i>expr</i>)</code><p> 
+
+Takes the natural logarithm of the expression. May be used with gridded or
+station data. Values less than or equal to zero are set to missing in the
+result. 
+
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfunclog10.html b/doc/gradfunclog10.html
new file mode 100644
index 0000000..1b04539
--- /dev/null
+++ b/doc/gradfunclog10.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>log10</b></h2><p> 
+
+<code>log10(<i>expr</i>) </code><p>
+
+Takes the logarithm base 10 of the expression. May be used with gridded or
+station data. Values less than or equal to zero are set to missing in the
+result. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfunclterp.html b/doc/gradfunclterp.html
new file mode 100644
index 0000000..a6d9efe
--- /dev/null
+++ b/doc/gradfunclterp.html
@@ -0,0 +1,92 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>lterp</title>
+
+<style type="text/css">
+body {
+	background-color: #e0f0ff;
+}
+.red {
+	color: #900;
+}
+</style>
+
+<h2><b>lterp</b></h2>
+<p>The lterp function performs  intepolation between two grids. It is a built-in function as of  version 2.0 -- in earlier versions it was implemented as a user defined function. Additional capabilities were added with version 2.0.2. The syntax is:
+<p><code>lterp (<i>source, dest</i>)                 </code> (<span class="red">Version 2.0.1 or earlier</span>) <br />
+  <code>lterp (<i>source, dest <,method> <,pct></i>)</code> (<span class="red">Version 2.0.2 or later</span>)
+<p> 
+
+Where 
+<p>	<code><i>source    </i></code>a grid expression that contains the data values to be interpolated<br />
+  <code><i>dest      </i></code>a grid expression that describes the grid that the data are to be interpolated to. 
+The data values in <code><i>dest</i></code>  are ignored, only the grid information is used. <br />
+<code><i>method    </i></code>an optional keyword that describes the interpolation method to be used. Options are:<br />
+<code>    bilin    </code>bilinear interpolation -- this is the default, the behavior when no method is specified, and is identical to the pre-2.0.2 behavior<br />
+<code>   bessel   </code> an enhancement to bilinear interpolation that uses 3rd order bessel interpolation <br />
+<code>    aave     </code>area average with latitude weighting -- may be better than bilin when interpolating from higher to lower grid resolution<br />
+<code>    amean    </code>area average without latitude weighting -- same as aave, but when weighting the grid box area by latitude is not desired <br />
+<code><i>pct       </i></code> the minimum percentage of area of each destination grid box that must contain non-missing input data to be considered valid<br />
+<code><i>          </i></code> (<code><i>pct</i></code> is optional and only relevant when used with <code>aave</code> and <code>amean</code> and must be between 0 and 100; default is 50%)
+<H3>Usage Notes</H3>
+<P>The lterp function works only with gridded data. The returned result  is a grid expression on the same grid as <code><i>dest</i></code>. 
+<P>The <code><i>source</i></code> and <code><i>dest</i></code> expressions   must have the same varying dimensions, which may be X, Y, or T. Interpolation is not performed in the Z or E dimension. 
+  <P>The <code><i>source</i></code> and <code><i>dest</i></code> expressions may vary in 1 or 2 dimensions, unless you are using the <code>aave</code> or <code>amean</code> methods, in which case the grids must be 2-D with X and Y as the varying dimensiions.   
+<P>If the domain of 
+  <code><i>source</i></code> is larger than the domain of <code><i>dest</i></code>, the returned result  will have an expanded grid to cover the requested domain.    
+
+<P>For interpolation in the time dimension, you may interpolate  (A) between monthly and yearly time axes, or (B) between minute, hourly, and daily time axes.
+<P>For the <code>bilin</code> method, each of the grid points in the <code><i>dest</i></code> grid contains the  average of  the nearest four grid points in the <code><i>source</i></code> grid, weighted by their distance from the destination grid point.  If any of the four surrounding input grid points contain missing data, the interpolated value will  be flagged as missing. 
+<P>(<span class="red">Version 2.0.2 or later</span>) The <code>bessel</code> method is adapted from the  regrid user defined function. It uses a bessel interpolation routine developed at Fleet Numerical
+  Meteorology and Oceanography Center (courtesy of D. Hensen).  
+The <code>bilin</code> method of  interpolation is performed at all points to
+  produce a "first guess."  Improvements to the  "first
+  guess" are made using the higher-order terms in the bessel
+  interpolator. Bessel interpolation uses not just the nearst 4 grid boxes in the <code><i>source</i></code> grid, but also the secondary ring of grid points that form a 4x4 matrix around the destination grid point. If  any of the grid boxes in the outer ring of the 4x4 matrix 
+  contain missing data, the output grid is assigned the <code>bilin</code> value. The <code>bessel</code> method may produce a closer fit to the <code><i>source</i></code> data
+  in regions where there are large gradients (e.g., around low pressure centers).
+<P>(<span class="red">Version 2.0.2 or later</span>) For the <code>aave</code> and <code>amean</code> methods, a spatial average using <code><i>source</i></code> data is calculated  in the area outlined by each grid box in the <code><i>dest</i></code> grid. 
+Note that in GrADS the boundaries of all grid boxes are the midpoints between their centers. If a grid box in the <code><i>source</i></code> grid partially overlaps the area of a <code><i>dest</i></code> grid box, its contribution to the spatial average is weighted by the fraction of area within the <code><i>dest</i></code> grid box domain. When the <code><i>source</i></code> grid contains missing data, the <code><i>pct</i></code> argument may be used to specify a threshold for the perce [...]
+<h3>Examples</h3>
+<p><code>* This shows how to use the new features in version 2.0.2 to interpolate between fine and coarse grids.<br />
+open fine.ctl<br />
+open coarse.ctl<br />
+d lterp(fine,coarse.2,aave)<br />
+d lterp(fine,coarse.2,aave,100)<br />
+d lterp(coarse.2,fine,bessel)</code><code><br />
+  </code><code><br />
+  *
+  This script interpolates a 1-D timeseries of hourly station data to a 3hourly grid<br />
+  open hourly_station_data.ctl<br />
+  open 3hourly_grid_data.ctl<br />
+  set x 1 <br />
+  set y 1<br />
+  set time 00z1jan 00z1feb<br />
+  d lterp(s2g1d(var.1(stid=kbwi)),var.2(lon=-77,lat=39))
+</code>
+<code>
+<p>* This script interpolates  2-D lat/lon grids<br />
+  'open obs.ctl'<br />
+  'open model.ctl'<br />
+  * define the source grid<br />
+'set dfile 2'<br />
+'q file'<br />
+line5 = sublin(result,5)<br />
+sx = subwrd(line5,3)<br />
+sy = subwrd(line5,6)<br />
+'set x 1 'sx<br />
+'set y 1 'sy<br />
+'set t 1'<br />
+'define data = model'<br />
+  * define the destination grid<br />
+  'set dfile 1'<br />
+  'q file'<br />
+  line5 = sublin(result,5)<br />
+  dx = subwrd(line5,3)<br />
+  dy = subwrd(line5,6)<br />
+  'set x 1 'dx<br />
+  'set y 1 'dy<br />
+  'set t 1'<br />
+  'define grid = obs'<br />
+* interpolate model data to obs grid <br />
+'d lterp(data,grid)'</code>
+<p>
+<p>
diff --git a/doc/gradfuncmag.html b/doc/gradfuncmag.html
new file mode 100644
index 0000000..eb8aa01
--- /dev/null
+++ b/doc/gradfuncmag.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>mag </b></h2><p>
+
+<code>mag(<i>uexpr,vexpr</i>) </code><p>
+
+Performs the calculation:
+<code>sqrt(<i>uexpr*uexpr+vexpr*vexpr</i>)</code>. May be used with
+gridded or station data. 
+
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncmaskout.html b/doc/gradfuncmaskout.html
new file mode 100644
index 0000000..4541fae
--- /dev/null
+++ b/doc/gradfuncmaskout.html
@@ -0,0 +1,45 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>maskout</b></h2><p>
+
+<code>maskout(<i>expr,mask</i>)</code><p> 
+
+Wherever the <code><i>mask</i></code> values are less than zero, the
+values in <code><i>expr</i></code> are set to the missing data value. <p>
+
+Works with gridded or station data. Where <code><i>mask</i></code> values
+are positive, the <code><i>expr</i></code> values are not modified. Thus
+the result of <code>maskout</code> is data with a possibly increased
+number of missing data values. The <code>maskout</code> function, in spite
+of its apparant simplicity, is extremely useful.  <p>
+
+<H3>Usage Notes</H3><P>
+
+<h3>Examples</h3><p> 
+
+<ol>
+<li>See the Examples for the <a
+href="gradfuncconst.html"><code>const</code></a> function for a
+description
+of using <code>maskout</code> to calculate the percentage of the globe
+covered by precipitation. <p>
+
+<li>The <code>maskout</code> function can be used to cause part of the
+data to be ignored while doing another calculation. For example, if we
+have a land-sea mask, where sea values are negative, and we want to take
+some areal average of a quantity only over land: <p>
+
+<dd><code>d aave(maskout(p,mask.2),lon=0,lon=360,lat=0,lat=90) </code><p>
+
+<li>People frequently have trouble using a mask grid, because it is often
+put into a seperate file, and given some arbitrary date/time and level.
+Thus, it is often necessary to <i>locally override</i> the dimension
+environment while using the mask grid: <p>
+
+<dd><code>d aave(maskout(p,mask.2(t=1)),lon=0,lon=360,lat=0,lat=90)
+</code><p>
+
+would probably be how Example 2 would have to be expressed in order to
+work, with the local override of <code>t=1</code> specified on the mask
+data. See the documentation on how GrADS evaluates expressions within the
+dimension environment for more information. 
diff --git a/doc/gradfuncmax.html b/doc/gradfuncmax.html
new file mode 100644
index 0000000..735b8b7
--- /dev/null
+++ b/doc/gradfuncmax.html
@@ -0,0 +1,52 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: max</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>max()</b></h2>
+<p>
+<code>max(<i>expr, dim1, dim2 <,tinc></i>)</code>
+<p>
+Returns the maximum of <code><i>expr</i></code> over the specified 
+dimension range. If the specified dimension is time, an
+optional time increment <code><i>tincr</i></code> may be specified.
+
+<p>
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>dim1</i>    </code>- the starting dimension expression<br>
+<code><i>dim2</i>    </code>- the ending dimension expression<br>
+<code><i>tinc</i>    </code>- optional time increment<br>
+</ul>
+
+<p>
+<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
+GrADS dimension expressions whose dimensions must match.
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>
+Related functions are: 
+<code><a href="gradfuncmaxloc.html">maxloc</a></code>, 
+<code><a href="gradfuncmin.html">min</a></code>, and
+<code><a href="gradfuncminloc.html">minloc</a></code>. <br>
+These functions will only work with GrADS version 1.8 or later.
+</ol>
+
+<p>
+<h3>Examples</h3>
+<ol>
+<li>To calculate the maximum value of the <code>precip</code> variable over the lon-lat domain, use nested <code>max</code> functions: 
+<p>
+<code>
+d max(max(precip,lon=0,lon=360),lat=-90,lat=90)
+</code>
+<p>
+
+</body>
+</html>
diff --git a/doc/gradfuncmaxloc.html b/doc/gradfuncmaxloc.html
new file mode 100644
index 0000000..3b127e6
--- /dev/null
+++ b/doc/gradfuncmaxloc.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: maxloc</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>maxloc()</b></h2>
+<p>
+<code>maxloc(<i>expr, dim1, dim2 <,tinc></i>)</code>
+<p>
+Returns the grid coordinate for the maximum of
+<code><i>expr</i></code> over the specified dimension range. If the
+specified dimension is time, an optional time increment
+<code><i>tincr</i></code> may be specified.
+
+<p>
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>dim1</i>    </code>- the starting dimension expression<br>
+<code><i>dim2</i>    </code>- the ending dimension expression<br>
+<code><i>tinc</i>    </code>- optional time increment<br>
+</ul>
+
+<p>
+<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
+GrADS dimension expressions whose dimensions must match.
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>
+Related functions are: 
+<code><a href="gradfuncmax.html">max</a></code>, 
+<code><a href="gradfuncmin.html">min</a></code>, and
+<code><a href="gradfuncminloc.html">minloc</a></code>. <br>
+These functions will only work with GrADS version 1.8 or later.
+</ol>
+
+<p>
+<h3>Examples</h3>
+
+</body>
+</html>
diff --git a/doc/gradfuncmean.html b/doc/gradfuncmean.html
new file mode 100644
index 0000000..03f3ac4
--- /dev/null
+++ b/doc/gradfuncmean.html
@@ -0,0 +1,32 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: mean</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>mean()</b></h2>
+<p>
+<code>mean (<i>expr, dexpr1, dexpr2, <,tinc></i> <,-b>)</code>
+<p>
+This function is the same as <a
+href="gradfuncave.html"><code>ave</code></a> in all respects except
+one: means in the Y dimension <b><i>are not</i></b> weighted by latitude.
+The means <b><i>are</i></b> weighted by grid interval to account for 
+non-linear grid spacing.
+<p>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<p>
+See the <a href="gradfuncave.html"><code>ave</code></a> reference page for details. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncmin.html b/doc/gradfuncmin.html
new file mode 100644
index 0000000..ee92d43
--- /dev/null
+++ b/doc/gradfuncmin.html
@@ -0,0 +1,44 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: min</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>min()</b></h2>
+<p>
+<code>min(<i>expr, dim1, dim2 <,tinc></i>)</code>
+<p>
+Returns the minimum of <code><i>expr</i></code> over the specified 
+dimension range. If the specified dimension is time, an
+optional time increment <code><i>tincr</i></code> may be specified.
+
+<p>
+<ul>
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+<code><i>dim1</i>    </code>- the starting dimension expression<br>
+<code><i>dim2</i>    </code>- the ending dimension expression<br>
+<code><i>tinc</i>    </code>- optional time increment<br>
+</ul>
+
+<p>
+<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
+GrADS dimension expressions whose dimensions must match.
+
+<p>
+<h3>Usage Notes</h3>
+<p>
+<ol>
+<li>
+Related functions are: 
+<code><a href="gradfuncminloc.html">minloc</a></code>, 
+<code><a href="gradfuncmax.html">max</a></code>, and
+<code><a href="gradfuncmaxloc.html">maxloc</a></code>.<br>
+These functions will only work with GrADS version 1.8 or later.
+</ol>
+<p>
+<h3>Examples</h3>
+
+</body>
+</html>
diff --git a/doc/gradfuncminloc.html b/doc/gradfuncminloc.html
new file mode 100644
index 0000000..e343aaf
--- /dev/null
+++ b/doc/gradfuncminloc.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Function: minloc</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>minloc()</b></h2>
<p>
<code>minloc(<i>expr, dim1, dim2 <,tinc></i>)</code>
<p>
Returns the grid coordinate for the minimum of
<code><i>expr</i></code> over the specified dimension range. If the
specified dimension is time, an optional time increment
<code><i>tincr</i></code> may be specified.

<p>
<ul>
<code><i>expr</i>    </code>- any valid GrADS expression <br>
<code><i>dim1</i>    </code>- the starting dimension expression<br>
<code><i>dim2</i>    </code>- the ending dimension expression<br>
<code><i>tinc</i>    </code>- optional time increment<br>
</ul>

<p>
<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
GrADS dimension expressions whose dimensions must match.

<p>
<h3>Usage Notes</h3>
<p>
<ol>
<li>
Related functions are: 
<code><a href="gradfuncmin.html">min</a></code>, 
<code><a href="gradfuncmax.html">max</a></code>, and
<code><a href="gradfuncmaxloc.html">maxloc</a></code>. <br>
These functions will only work with GrADS version 1.8 or later.
</ol>


<p>
<h3>Examples</h3>
<p> </p>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradfuncoabin.html b/doc/gradfuncoabin.html
new file mode 100644
index 0000000..4b6166e
--- /dev/null
+++ b/doc/gradfuncoabin.html
@@ -0,0 +1,57 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: oabin</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>oabin()</b></h2>
+<p>
+<code>oabin (<i>gexpr, sexpr <,-flag></i>)</code>
+<p>
+This function bins station observations into grid cells based on their
+location.  If more than one station is located within a grid box, the
+observations are averaged together to produce the analyzed value.
+
+<p>
+<ul>
+<code><i>gexpr  &nbsp</i></code>a valid grid expression<br>
+<code><i>sexpr  &nbsp</i></code>a valid station data expression<br>
+</ul>
+<p>
+The optional <code><i>flag</i></code> may be one of the following:
+<p>
+<ul>
+<code>-f  &nbsp  &nbsp</code>set the value to the first observation that gets binned<br>
+<code>-c  &nbsp  &nbsp</code>output is the # of stations located within each grid cell
+</ul>
+<p>
+
+<h3>Usage Notes</h3>
+<ol>
+<li>The -f flag should be used when summing is not appropriate --
+e.g. surface type classification.
+<p>
+<li>See the related function <a href="gradfuncoacres.html"><code>oacres</code></a>.
+
+</ol>
+
+<p>
+<h3>Example</h3>
+<p>
+<pre>
+open grd_var.ctl
+open stn_var.ctl
+
+set gxout grfill
+d oabin(grd_var.1,stn_var.2)
+
+set gxout grid
+d oabin(grd_var.1,stn_var.2,-c)
+</pre>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncoacres.html b/doc/gradfuncoacres.html
new file mode 100644
index 0000000..fa9e396
--- /dev/null
+++ b/doc/gradfuncoacres.html
@@ -0,0 +1,84 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: oacres</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>oacres()</b></h2>
+<p>
+<code>oacres (<i>gexpr, sexpr &lt,radii&gt</i>)</code>
+
+<p> 
+A Cressman objective analysis is performed on the station data to arrive
+at a gridded result that represents the station data. 
+
+<p> 
+<ul>
+<code><i>gexpr</i>   </code>a valid grid expression<br>
+<code><i>sexpr</i>   </code>a valid station data expression<br>
+<code><i>radii</i>   </code>optional radii of influence. Defaults are: 10,7,4,2,1<br>
+</ul>
+<p>
+The Cressman Analysis scheme is described in a 1959 paper in Monthly
+Weather Review. Multiple passes are made through the grid with
+increasingly smaller radii of influence. At each pass, a new value is
+calculated for each grid point based on a correction factor that is
+determined by looking at each station within the radius of influence.
+<p>
+For each such station, an error is defined as the difference
+between the station value and a value arrived by interpolation from
+the grid to that station. The correction factor is based on a distance
+weighted formula applied to all such errors within the radius of
+influence. The correction factors are applied to each grid point
+before the next pass is made. 
+<p>
+Any grid boxes that do not have stations within the third specified
+radius are set to the missing data value.
+
+<p>
+<h3>Usage Notes </h3><p>
+
+<ol>
+<li>The <code>oacres</code> function can be quite slow to execute,
+depending on grid and station data density. 
+<p>
+<li>The actual values of the gridded expression are ignored, but 
+the grid itself is used as a template to perform the analysis. The scaling of
+the grid must be linear in lat-lon.
+<p>
+<li>The Cressman Analysis scheme can be unstable if the grid density is
+substantially higher than the station data density (ie, far more grid
+points than station data points). In such cases, the analysis can produce
+extrema in the grid values that are not realistic. It is thus suggested
+that you examine the results of <code>oacres</code> and compare them to
+the station data to insure they meet your needs. 
+<p>
+<li>Objective analysis is a complex topic, and many schemes for doing
+it have been developed over the years. The <code>oacres</code>
+function is more of a quick-look function rather than a rigorous
+analysis scheme. If you have specific analysis requirements, consider
+doing your objective analysis outside of GrADS with a <a
+href="udf.html">user-defined function</a>.
+<p>
+<li>See the related function <a href="gradfuncoabin.html"><code>oabin</code></a>.
+</ol>
+
+<h3>Examples </h3>
+<p>
+<ol>
+<li>The simplest case: 
+<p>
+<dd><code>oacres(ts,ts.2)</code>
+<p>
+<li>To specify your own radii of influence: 
+<p>
+<dd><code>oacres(ts,ts.2,12,8,5,4,3,2,1)</code>
+<p>
+</ol>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfuncpow.html b/doc/gradfuncpow.html
new file mode 100644
index 0000000..68583c8
--- /dev/null
+++ b/doc/gradfuncpow.html
@@ -0,0 +1,23 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>pow</b></h2><p>
+
+<code>pow(<i>expr1,expr2</i>)</code><p> 
+
+The <code>pow</code> function raises the values of
+<code><i>expr1</i></code> to the power of <code><i>expr2</i></code>. No
+error checking is performed for invalid values in the operands. This
+function works on both gridded and station data. <p>
+
+<H3>Usage Notes</H3><P>
+
+<h3>Examples</h3><p> 
+
+<ol>
+<li>To square some value: <p>
+<dd><code>pow(expr,2) </code><p>
+
+<li>To duplicate the operation of the mag function: <p>
+
+<dd><code>sqrt(pow(u,2)+pow(v,2)) </code>
+</ol>
diff --git a/doc/gradfuncs2g1d.html b/doc/gradfuncs2g1d.html
new file mode 100644
index 0000000..7ecb0e8
--- /dev/null
+++ b/doc/gradfuncs2g1d.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Function: s2g1d</title>
<link href="GrADS.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>s2g1d</b></h2>
<p> <code>s2g1d(<i>expr</i>)</code> 
  <title></title>
  <link href="GrADS.css" rel="stylesheet" type="text/css">
<p> This function converts a station data time series into a 1-dimensional grid. 
  This allows more graphics and analytical operations. 
<p> <code><i>expr</i></code>            
  A valid GrADS 1D station data expression in which time is the only varying dimension.<br>

<h3>Usage Notes</h3>
<p>The s2g1d function only works with 'display' and will not work with 'define'. You have to use 'set gxout fwrite' and write the data to a file if you want to save and reuse the 1D gridded time series. 
<h3>Examples</h3><p> 
   
<p><code>'set gxout bar'<br>
  'set barbase 0'<br>
  'set bargap 10'<br>
  '</code><code>display s2g1d(precip(stid=kdca))'</code> 
<p><code>'set gxout contour'<br>
  '</code><code>display smth9(s2g1d(t(stid=kord)))</code>' 
<p><code>'set gxout vector'<br>
  'display const(s2g1d(u(stid=ksux)),0);s2g1d(u(stid=ksux));s2g1d(v(stid=ksux))'</code>
\ No newline at end of file
diff --git a/doc/gradfuncscorr.html b/doc/gradfuncscorr.html
new file mode 100644
index 0000000..f11b46d
--- /dev/null
+++ b/doc/gradfuncscorr.html
@@ -0,0 +1,68 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Function: scorr</title>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>scorr()</b></h2>
+
+<p>
+This function calculates the spatial correlation between two variables
+over an X-Y domain. It returns a single number. The syntax is:
+
+<ul>
+<code>scorr(<i>expr1, expr2, xdim1, xdim2, ydim1, ydim2</i>)</code>
+</ul>
+
+<p>
+where:
+<p>
+<ul>
+<code><i>expr1</i>   </code>- any valid GrADS expression <br>
+<code><i>expr2</i>   </code>- any valid GrADS expression <br>
+<code><i>xdim1</i>   </code>- starting X dimension expression <br>
+<code><i>xdim2</i>   </code>- ending X dimension expression <br>
+<code><i>ydim1</i>   </code>- starting Y dimension expression <br>
+<code><i>ydim2</i>   </code>- ending Y dimension expression <br>
+</ul>
+
+<p>
+For global averaging, a shorthand may be used:
+<ul>
+<code>scorr(<i>expr1, expr2</i>, global)</code>  or<br>
+<code>scorr(<i>expr1, expr2</i>, g)</code>
+</ul>
+is the same as
+<ul>
+<code>scorr(<i>expr1, expr2</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul> 
+
+<p>
+<H3>Usage Note</H3>
+<p>
+<ol>
+<li><code>scorr</code> may be used in conjunction with <a
+href="gradfunctloop.html"><code>tloop</code></a> or <a
+href="gradcomddefine.html"><code>define</code></a> to create time
+series or time/height plots.
+<p>
+<li><code>scorr</code> assumes that the world coordinates are
+longitude in the X dimension and latitude in the Y dimension, and does
+weighting in the latitude dimension by the delta of the sin of the
+latitudes. Weighting is also performed appropriately for unequally
+spaced grids.
+</ol>
+<p>
+<H3>Examples</H3>
+<p>
+This example calculates the correlation between the surface temperature
+and the latent heat flux over the tropical Pacific:
+<p>
+<pre>
+set lat -10 10
+set lon 120 280
+d scorr(tsfc, lhtfl, lon=120, lon=280, lat=-10, lat=10)
+</pre>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/doc/gradfuncsin.html b/doc/gradfuncsin.html
new file mode 100644
index 0000000..9e353ba
--- /dev/null
+++ b/doc/gradfuncsin.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>sin</b></h2><p> 
+
+<code>sin(<i>expr</i>)</code><p> 
+
+Takes the sin of the provided expression. It is assumed the expression is
+in radiians. Result values are in the range -1 to 1. This function works
+on both gridded and station data.
+
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncskip.html b/doc/gradfuncskip.html
new file mode 100644
index 0000000..0ff782f
--- /dev/null
+++ b/doc/gradfuncskip.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Command: skip</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2><b>skip()</b></h2>
<p>

<code>skip (<i>expr, skipi, skipj</i>)</code>

<p> 
Sets alternating values of <code><i>expr</i></code> to the missing
data value. 

<p>
<ul>
<code><i>expr</i>     </code>A valid grid expression that may have 1 or 2 varying dimensions<br>
<code><i>skipi</i>    </code>Skip factor in the I dimension of <code><i>expr</i></code><br>
<code><i>skipj</i>    </code>Skip factor in the J dimension of <code><i>expr</i></code><br>
</ul>
<p>
<H3>Usage Notes</H3>
<P>
<ol>
<li>This function is often used while displaying wind <code>arrows</code> or <code>barbs</code> to thin the number of arrows or
barbs. It is not necessary to use the <code>skip</code> function on
both the U and V wind components; it is sufficient to populate only one
component with missing data values to suppress the plotting of the wind
<code>arrow</code> or <code>barb</code>.
</ol>
<p>
<h3>Examples </h3>

<ol>
<li>Suppose you have a time series of 3-hourly data, but you want to display values at 6-hourly time steps:<br>
   <br><ul><code>set x 1<br>
   set y 1<br>
   set t 1 last<br>
   d skip(var,2)</code><br>
  </ul><br>
<li>To display every other grid point in both the X and Y direction:<br>
  <br>
    <ul>
      <code>d skip(u,2,2);v</code>
    </ul>
  <br>
  <li>To display every grid point in the Y direction, but every 5th grid
point in the X direction:<br>
<br>
<ul><code>d skip(u,5,1);v</code></ul>
<br>
<li>This example script "d_uv.gs" written by Wesley Ebisuzaki
automatically sets the skip factor based on the plot dimensions.
<br>
<pre>
*
* This function does a d skip(ugrd,n);v
* where n is automatically set to an appropriate value
*
* usage: d_uv ugrd vgrd 
*
* v1.1 w. ebisuzaki
* v1.2 4/6/98 revised empirical formula for skip
*
function duv(arg)
u = subwrd(arg,1)
v = subwrd(arg,2)

* get lat/lon info
'query dims'
lons = sublin(result,2)
lats = sublin(result,3)
dx = subwrd(lons,13) - subwrd(lons,11)
dy = subwrd(lats,13) - subwrd(lats,11)

* Determine skip factor 
dn = dx
if (dy > dx) ; dn = dy ; endif
skip = dn / 50 + 0.5
if (skip < 1) ; skip=1 ; endif

* Display the plot
'd skip('u','skip');'v
</pre>
</ol> 

</body>
</html>

\ No newline at end of file
diff --git a/doc/gradfuncsmth9.html b/doc/gradfuncsmth9.html
new file mode 100644
index 0000000..78d5267
--- /dev/null
+++ b/doc/gradfuncsmth9.html
@@ -0,0 +1,28 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>smth9</b></h2><p> 
+
+<code>smth9(<i>expr</i>)</code><p>
+
+Performs a 9 point smoothing to the gridded result of the
+<code><i>expr</i></code>.<p> 
+
+<h3>Usage Notes</h3><p>
+
+<ol>
+<li>The result at each grid point is a weighted average of the grid point
+plus the 8 surrounding points. The center point receives a wieght of 1.0,
+the points at each side and above and below receive a weight of 0.5, and
+corner points receive a weight of 0.3.<p>
+
+<li>All 9 points are multiplied by their weights and summed, then divided
+by the total weight to obtain the smoothed value. Any missing data points
+are not included in the sum; points beyond the grid boundary are
+considered to be missing. Thus the final result may be the result of an
+averaging with less than 9 points. <p>
+
+<li>If the gridded data is 1-Dimensional, the result is a 3 point
+smoothing. 
+</ol>
+
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncsqrt.html b/doc/gradfuncsqrt.html
new file mode 100644
index 0000000..67a2242
--- /dev/null
+++ b/doc/gradfuncsqrt.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>sqrt</b></h2><p> 
+
+<code>sqrt(<i>expr</i>) </code><p>
+
+Takes the square root of the result of the <code><i>expr</i></code>. This
+function works on both gridded and station data. Values in
+<code><i>expr</i></code> that are less than zero are set to missing in the
+result. 
+
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncsregr.html b/doc/gradfuncsregr.html
new file mode 100644
index 0000000..1a21643
--- /dev/null
+++ b/doc/gradfuncsregr.html
@@ -0,0 +1,131 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: sregr</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>sregr()</b></h2>
+<p>
+<p>
+This function calculates the linear least-squares regression between two variables
+over an X-Y domain. It returns a single number. The syntax is:
+
+<ul>
+<code>sregr(<i>expr1, expr2, xdim1, xdim2, ydim1, ydim2</i>)</code>
+</ul>
+
+<p>
+where:
+<p>
+<ul>
+<code><i>expr1</i>   </code>- a valid GrADS expression varying in X and Y<br>
+<code><i>expr2</i>   </code>- a valid GrADS expression varying in X and Y<br>
+<code><i>xdim1</i>   </code>- starting X dimension expression <br>
+<code><i>xdim2</i>   </code>- ending X dimension expression <br>
+<code><i>ydim1</i>   </code>- starting Y dimension expression <br>
+<code><i>ydim2</i>   </code>- ending Y dimension expression <br>
+</ul>
+
+<p>
+To do the regression over the global domain, a shorthand may be used:
+<ul>
+<code>sregr(<i>expr1, expr2</i>, global)</code>  or<br>
+<code>sregr(<i>expr1, expr2</i>, g)</code>
+</ul>
+is the same as
+<ul>
+<code>sregr(<i>expr1, expr2</i>, lon=0, lon=360, lat=-90, lat=90)</code>
+</ul> 
+
+<p>
+The result from <code>sregr</code> is the expected value of
+the <code><i>expr2</i></code> departure given a 1 unit departure in
+<code><i>expr1</i></code>. 
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>
+<code><i>expr1</i></code> is the independent variable and
+<code><i>expr2</i></code> is the dependent variable.
+<p>
+<li>The regression is sensitive to the units of the input expressions. 
+In the examples below, the sensible heat flux (shtfl) is in units of W m^-2 and 
+the surface temperature (tsfc) is in units of K, so the regression coefficient 
+of shtfl on tsfc is in units of W m^-2 K^-1.
+<p>
+<li>
+<code>sregr</code> may be used in conjunction with <a
+href="gradfunctloop.html"><code>tloop</code></a> or <a
+href="gradcomddefine.html"><code>define</code></a> to create time series
+or time/height plots.
+<p>
+<li><code>sregr</code> assumes that the world coordinates are
+longitude in the X dimension and latitude in the Y dimension, and does
+weighting in the latitude dimension by the delta of the sin of the
+latitudes. Weighting is also performed appropriately for unequally
+spaced grids.
+<p>
+<li>The result of the least squares regression of Y on X is often
+expressed as a linear equation: 
+<p>
+<ul><code>Y = slope * X + intercept</code></ul>
+<p>
+where X is the independent variable, Y is the dependent variable, and
+the slope and intercept are calculated using complicated algebraic
+formulas. The calculation is simplified if the means are
+removed. If we define x and y to be the departures from the areal
+averages of X and Y:
+<p>
+<ul><code>x = X - Xave</code><br><code>y = Y - Yave</code></ul>
+<p>
+then the regression equation becomes:
+<p>
+<ul><code>y = <i>coefficient</i> * x</code></ul>
+<p>
+Where
+<p>
+<ul><code><i>coefficient</i> = (sum of x*y over area)/(sum of x*x over area)</code></ul>
+<p>
+This <code><i>coefficient</i></code> is the output from the <code>sregr</code> function.
+The second example below shows how to construct the regression estimate of Y based on X.
+<p>
+<li>Use the <a href="gradfunctregr.html"><code>tregr</code></a>
+function to do regression over the time domain.
+<p>
+</ol>
+
+<p>
+<h3>Example</h3>
+<ol>
+<li>This example calculates the expected departure from the mean of
+the sensible heat flux (shtfl) in the North Pacific given a unit
+departure from the mean surface temperature (tsfc). The units are W m^-2 K^-1.
+<p>
+<pre>
+set lon 120 250
+set lat 15 60
+define ivar = tsfc   ;* surface temperautre
+define dvar = shtfl  ;* sensible heat flux
+set z 1
+set t 1 
+d sregr(ivar, dvar, lon=120, lon=250, lat=15, lat=60)
+</pre>
+<p>
+<li>This example builds on the previous example by 
+calculating the regression estimate of sensible heat flux based on the
+surface temperature. 
+<p>
+<pre>
+define coeff = sregr(ivar, dvar, lon=120, lon=250, lat=15, lat=60)
+define dvarave = aave(dvar, lon=120, lon=250, lat=15, lat=60)
+define ivarave = aave(ivar, lon=120, lon=250, lat=15, lat=60)
+d coeff * (ivar - ivarave) + dvarave
+</pre>
+</ol>
+
+
+</body>
+</html>
diff --git a/doc/gradfuncstnave.html b/doc/gradfuncstnave.html
new file mode 100644
index 0000000..cfe0d1c
--- /dev/null
+++ b/doc/gradfuncstnave.html
@@ -0,0 +1,55 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>stnave</b></h2><p> 
+
+<code>stnave(<i>expr,dexpr1,dexpr2<,-m cnt></i>)</code><p>
+
+Takes an average of station data over time: <p>
+
+<code><i>expr</i></code>           
+A valid
+GrADS expression that gives a station data result. <br>
+<code><i>dexpr1</i></code>        A
+dimension expression giving
+the starting time for the average. <br>
+<code><i>dexpr2</i></code>        A
+dimension expression giving
+the ending time for the average.<br>
+<code><i>-m cnt</i></code>       
+Optional minimal data count
+for the average to be taken. If, in the time series, there are fewer
+available data points for a particular station than the cnt value, then
+the result for that station is the missing data value. The default cnt
+value is 1 (ie, even 1 valid station in a time series of even thousands of
+points would give a valid    result for that station).<p> 
+
+<h3>Usage Notes</h3><p> 
+
+<ol>
+<li>The times are looped through based on the time interval of the default
+file. It is thus very important to set the default file to that of the
+station data file, or a file with the same time interval, or not all
+station reports will be included in the average.<p> 
+
+<li>If there is more than one report per station for a particular time,
+those reports are averaged equally to arrive at a single value for that
+time. The final average consists of each report for each time being
+averaged, with missing times not included in the average. <p>
+
+<li>Reports from different times are considered to be for the same station
+when the station id, the latitude, and the longitude all match exactly.
+<p>
+</ol>
+
+<h3>Examples</h3><p> 
+
+<ol>
+<li>A typical usage of the stnave function would be: <p>
+
+<dd><code>stnave(ts,t=1,t=20,-m 10) </code><p>
+
+Here an average is taken over 20 times, and if there are fewer than 10
+reports for a station then that station will be missing in the final
+result. 
+</ol>
+
diff --git a/doc/gradfuncstnmax.html b/doc/gradfuncstnmax.html
new file mode 100644
index 0000000..77d622d
--- /dev/null
+++ b/doc/gradfuncstnmax.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>stnmax</b></h2><p> 
+
+<code>stnmax(<i>expr,dexpr1,dexpr2<,-m cnt</i>)</code><p> 
+
+Examines a time series of station data and returns the maximum value
+encountered for each station. Operands and usage are the same as the
+<a href="gradfuncstnave.html"><code>stnave</code></a> function. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncstnmin.html b/doc/gradfuncstnmin.html
new file mode 100644
index 0000000..2606f0f
--- /dev/null
+++ b/doc/gradfuncstnmin.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>stnmin</b></h2><p> 
+
+<code>stnmin(<i>expr,dexpr1,dexpr2<,-m cnt</i>)</code><p> 
+
+Examines a time series of station data and returns the minimum value
+encountered for each station. Operands and usage are the same as the
+<a href="gradfuncstnave.html"><code>stnave</code></a> function.
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncsum.html b/doc/gradfuncsum.html
new file mode 100644
index 0000000..6dfcb5c
--- /dev/null
+++ b/doc/gradfuncsum.html
@@ -0,0 +1,112 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+
+<head>
+
+<title>GrADS Function: sum</title>
+
+<link rel="stylesheet" href="GrADS.css" type="text/css">
+
+</head>
+
+<body bgcolor="e0f0ff" text="#000000">
+
+
+
+<h2><b>sum()</b></h2>
+
+<p> <code>sum (<i>expr, dim1, dim2, <,tinc></i> <,-b>)</code> 
+
+<p>
+
+<p> Sums the result of <code><i>expr</i></code> over the specified dimension range. 
+
+  If the summing dimension is time, an optional time increment <code><i>tincr</i></code> 
+
+  may be specified. 
+
+<p>
+
+<ul>
+
+<code><i>expr</i>    </code>- any valid GrADS expression <br>
+
+<code><i>dim1</i>    </code>- the start point for the sum<br>
+
+<code><i>dim2</i>    </code>- the end point for the sum<br>
+
+<code><i>tinc</i>    </code>- optional increment for time summing<br>
+
+<code>-b      </code>- use exact boundaries<br>
+
+</ul>
+
+
+
+<p>
+
+<code><i>dim1</i></code> and <code><i>dim2</i></code> are standard
+
+GrADS dimension expressions whose dimensions must match.
+
+
+
+<p>
+
+<h3>Usage Notes</h3><p>
+
+<p>
+
+<ol>
+
+  <li>The limits and intervals of the summing are set according to the grid coordinates 
+
+    of the default file. If <code><i>dim1</i></code> and <code><i>dim2</i></code> 
+
+    are specified in world coordinates, the coordinates are converted to the nearest 
+
+    integer grid coordinates based on the scaling of the default file. 
+
+    <p>
+
+<li>The end points are given normal weighting, unless the <code>-b</code>
+
+boundary flag is specified. The boundry flag indicates that the
+
+sum should be taken to the exact boundaries specified by
+
+<code><i>dim1</i></code> and <code><i>dim2</i></code>, rather than
+
+the nearest grid points. 
+
+<p>
+
+<li>In the Y dimension, when the boundary is beyond the pole, the
+
+<code>asum</code> function recognizes this and weights appropriately.
+
+To calculate an sum without any weighting, use the <code><a
+
+href="gradfuncsumg.html">sumg</a></code> function.
+
+<p>
+
+
+
+</ol>
+
+
+
+<p>
+
+<h3>Examples</h3>
+
+
+
+</body>
+
+</html>
+
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
diff --git a/doc/gradfuncsumg.html b/doc/gradfuncsumg.html
new file mode 100644
index 0000000..55970af
--- /dev/null
+++ b/doc/gradfuncsumg.html
@@ -0,0 +1,30 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: sumg</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>sumg()</b></h2>
+<p>
+<code>sumg (<i>expr, dexpr1, dexpr2, <,tinc></i> <,-b>)</code>
+<p>
+This function is the same as <a
+href="gradfuncsum.html"><code>sum</code></a> in all respects except
+one: the sums are calculated without any weighting at all. 
+<p>
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<p>
+See the <a href="gradfuncsum.html"><code>sum</code></a> reference page for details. 
+</ol>
+
+<p>
+<h3>Examples </h3>
+
+
+</body>
+</html>
+
diff --git a/doc/gradfunctan.html b/doc/gradfunctan.html
new file mode 100644
index 0000000..16a5cda
--- /dev/null
+++ b/doc/gradfunctan.html
@@ -0,0 +1,11 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>tan </b></h2><p>
+
+<code>tan(<i>expr</i>)</code><p> 
+
+Applies the trigonometric tangent function to the <code><i>expr</i></code>
+which is assumed to be in radians. Operates on both gridded and station
+data. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfunctcorr.html b/doc/gradfunctcorr.html
new file mode 100644
index 0000000..476f6db
--- /dev/null
+++ b/doc/gradfunctcorr.html
@@ -0,0 +1,68 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: tcorr</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>tcorr()</b></h2>
+<p>
+<code>tcorr (<i>expr1, expr2, tdim1, tdim2</i>)</code>
+
+<p>
+This function produces a spatial map of temporal correlation
+coefficients. 
+
+<p>
+<ul>
+<code><i>expr1</i>   </code>- 
+a valid GrADS expression that varies in time<br>
+<code><i>expr2</i>   </code>- 
+a valid GrADS expression that varies in time and may also vary in X and Y<br>
+<code><i>tdim1</i>   </code>- 
+starting time dimension expression <br>
+<code><i>tdim2</i>   </code>- 
+ending time dimension expression <br>
+</ul>
+
+<p>
+The <code><i>expr1</i></code> time series is correlated to the time
+series at each grid point in <code><i>expr2</i></code>. The result is
+a grid of correlation coefficients that matches the X and Y dimensions
+of <code><i>expr2</i></code>.
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If both <code><i>expr1</i></code> and <code><i>expr2</i></code>
+vary only in time, the output is a single value.
+<p>
+<li>Use the <a href="gradfuncscorr.html"><code>scorr</code></a>
+function to do correlation over the spatial domain.
+</ol>
+
+<p>
+<h3>Example</h3>
+<ol>
+<li>
+This example calculates the temporal correlation between sea level pressure
+and the defined variable elnino, an areal average of surface temperature 
+in the equatorial Pacific.
+<p>
+<pre>
+set x 1
+set y 1 
+set z 1 
+set t 1 100
+define elnino = aave(ts,lon=-160,lon=-80,lat=-10,lat=10)
+set lon -180 180
+set lat -90 90
+set z 1
+set t 1
+d tcorr(elnino, slp, t=1, t=100)
+</pre>
+</ol>
+
+</body>
+</html>
diff --git a/doc/gradfunctloop.html b/doc/gradfunctloop.html
new file mode 100644
index 0000000..7e6e4bc
--- /dev/null
+++ b/doc/gradfunctloop.html
@@ -0,0 +1,88 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>tloop</b></h2><p> 
+
+<code>tloop(<i>expr</i>)</code><p>
+
+When time is a varying dimension in the dimension environment, the
+<code>tloop</code> function evaluates the <code><i>expr</i></code> at
+fixed times, then reconstructs the time series to obtain a final result
+that is time varying. The <code>tloop</code> function is required due to
+the implementation of the GrADS expression evaluation rules, and the
+implementation of certain other functions. The <code>tloop</code> function
+can also improve performance for certain calculations. <p>
+
+The <code>tloop</code> function is provided as a way to obtain time series
+from functions that themselves are not implemented to be able to operate
+when time is a varying dimension. See the examples below. <p>
+
+<h3>Usage Notes </h3><p>
+
+<ol>
+<li>The <code>tloop</code> function loops through time based on the time
+increment of the default file; it is thus important to have the default
+file set appropriately. <p>
+
+<li>The <code>tloop</code> function and the <a
+href="gradcomddefine.html"><code>define</code></a> command
+work very similarly. In many cases, the <code>define</code> command can be
+used to obtain the same result as using <code>tloop</code>. In fact, the
+<code>define</code> command can be even more useful along
+those lines, since it also loops through the Z dimension, in effect
+creating a <code>zloop</code> function. See the define command for more
+information. <p>
+</ol>
+
+<h3>Examples</h3><p> 
+
+<ol>
+<li>A typical application of the <code>tloop</code> function is to obtain
+a time series of areal averages using the <a
+href="gradfuncaave.html"><code>aave</code></a> function.
+Since the <code>aave</code> function will not work when time is a varying
+dimension, the useof <code>tloop</code> is required:<p> 
+
+<dd><code>set x 1 
+<dd>set y 1 
+<dd>set t 1 31 
+<dd>d tloop(aave(ts,lon=0,lon=360,lat=-90,lat=90)) </code><p>
+
+Note that the dimension environment is set up to reflect the kind of plot
+desired, namely a <code>line</code> plot where time is the varying
+dimension. Thus it is necessary to fix the X and Y dimensions; the values
+of those dimensions in this case are not relevent.<p> 
+
+<li>The <code>tloop</code> function can be used to smooth in time: <p>
+
+<dd><code>set lon -180 0 
+<dd>set lat 40 
+<dd>set lev 500 
+<dd>set t 3 28 
+<dd>d tloop(ave(z,t-2,t+2)) </code><p>
+
+In this example, we are plotting a time-longitude cross section, where
+each time is a 5 time period mean centered at that time. <p>
+
+<li>If we wanted to display a time-longitude cross section (X and T
+varying), with the data being averaged over latitude, the 'standard' way
+to do this might be: <p>
+
+<dd><code>set lon -180 0 
+<dd>set lat 40 
+<dd>set lev 500 
+<dd>set t 1 31 
+<dd>d ave(z,lat=20,lat=40) </code><p>
+
+This calculation could be fairly time consuming, since to perform the
+average, a longitude-time section is obtained at each latitude. If the
+time period is long, then this would be a very inneficient operation, due
+to the ordering of data in a typical GrADS data set. The
+<code>tloop</code> function might substantially improve the performance of
+this calculation: <p>
+
+<dd><code>d tloop(ave(z,lat=20,lat=40)) </code><p>
+since the average is then done at each fixed time, and is thus just an
+average of X varying data over Y. Thus the <code>tloop</code> function
+here is simply being used to force a different ordering to the
+calculation, although the result is the same.
+</ol>
diff --git a/doc/gradfunctmave.html b/doc/gradfunctmave.html
new file mode 100644
index 0000000..886c503
--- /dev/null
+++ b/doc/gradfunctmave.html
@@ -0,0 +1,117 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: tmave</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>tmave()</b></h2>
+<p>
+This function does time averaging while applying a mask. The syntax is:
+<p>
+<ul><code>tmave(<i>maskexpr,expr,timexpr1,timexpr2</i>)</code></ul>
+<p>
+where:
+<p>
+<ul>
+<code><i>maskexpr</i>    </code>
+- the mask expression; when evaluated at a fixed time, it must give a single value<br>
+<code><i>expr</i>        </code>
+- the expression to be averaged<br>
+<code><i>timexpr1,2</i> &nbsp</code>
+- the limits of the time averaging domain<br>
+</ul>
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+
+<li>This function works similarly to the <a
+href="gradfuncave.html"><code>ave</code></a> function,
+except for the masking. Using <code>tmave</code> is much more efficient than using 
+<a href="gradfuncmaskout.html"><code>maskout</code></a> with 
+<a href="gradfuncave.html"><code>ave</code></a>). 
+
+<p>
+<li>The function loops through the specified time steps, and evaluates
+<code><i>maskexpr</i></code> at each fixed time.
+<code><i>maskexpr</i></code> must yeild a single value. If this value
+is the undefined/missing data value, then <code><i>expr</i></code> for
+that time is not included in the average.
+
+<p>
+<li>If <code><i>maskexpr</i></code> is not the undefined data value, it is
+used as the weight for <code><i>expr</i></code> in the average. So if
+you define <code><i>maskexpr</i></code> accordingly, you can use the
+<code>tmave</code> function to do weighted time averaging.
+
+<p>
+<li>The tricky aspect of using <code>tmave</code> is setting up
+<code><i>maskexpr</i></code>.  If <code><i>expr</i></code> is a grid
+with X and/or Y and/or Z varying, then <code><i>maskexpr</i></code>
+*MUST* refer to either a defined variable or a file with only time
+varying. In general, you have to set up <code><i>maskexpr</i></code>
+in advance.
+
+</ol>
+
+<p>
+<h3>Examples</h3>
+
+<ol>
+<li>
+Say you want to average <code>slp</code> over some time range 
+but only when <code>sst</code> over some region is above some value.  You can 
+do this by:
+<p>
+<ul>
+<pre>
+set x 1
+set y 1
+set t 1 last
+define sstmask = aave(sst,lon=-180,lon=-90,lat=-20,lat=20)
+define sstmask = const(maskout(sstmask,sstmask-25.0),1)
+</pre>
+</ul>
+
+<p>
+Now <code>sstmask</code> is a time series where the value is 1 when
+the <code>sst</code> areal average is above 25 and undefined when the
+value is below 25. <a
+href="gradfuncmaskout.html"><code>maskout</code></a> set the values
+below 25 to missing; <a
+href="gradfuncconst.html"><code>const</code></a> set the non-missing
+values to 1. We can now do our <code>tmave</code>:
+<p>
+<ul>
+<pre>
+set lon -180 -90
+set lat -20 20
+set t 1
+d tmave(sstmask,slp,t=1,t=last)
+</pre>
+</ul>
+
+<p>
+<li>The mask could also be written to a file with all dimensions
+nonvarying except for time. Here is what some of the records in the
+data descriptor file might look like:
+<p>
+<ul>
+<pre>
+dset <i>maskfilename</i>
+xdef 1 linear 1 1
+ydef 1 linear 1 1
+zdef 1 linear 1 1
+tdef 100 linear 
+....
+</pre>
+</ul>
+</ol>
+
+
+
+</body>
+</html>
+
diff --git a/doc/gradfunctregr.html b/doc/gradfunctregr.html
new file mode 100644
index 0000000..7edced7
--- /dev/null
+++ b/doc/gradfunctregr.html
@@ -0,0 +1,109 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Function: tregr</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>tregr()</b></h2>
+<p>
+<code>tregr (<i>expr1, expr2, tdim1, tdim2</i>)</code>
+
+<p>
+This function calculates the least-squares regression between two
+time-dependent variables. 
+
+<p>
+<ul>
+<code><i>expr1</i>   </code>- 
+a valid GrADS expression that varies in time<br>
+<code><i>expr2</i>   </code>- 
+a valid GrADS expression that varies in time and may also vary in X and Y<br>
+<code><i>tdim1</i>   </code>- 
+starting time dimension expression <br>
+<code><i>tdim2</i>   </code>- 
+ending time dimension expression <br>
+</ul>
+<p>
+The result is a grid that matches the X and Y dimensions of
+<code><i>expr2</i></code> where each grid point is the temporal
+regression of <code><i>expr2</i></code> (the dependent variable) onto
+<code><i>expr1</i></code> (the independent variable). 
+<code>tregr</code> gives the expected value of
+the <code><i>expr2</i></code> departure given a 1 unit departure in
+<code><i>expr1</i></code>. 
+
+<p>
+<h3>Usage Notes</h3>
+<ol>
+<li>If both <code><i>expr1</i></code> and <code><i>expr2</i></code>
+vary only in time, the output is a single value.
+<p>
+<li>The regression is sensitive to the units of the input expressions. 
+In the examples below, the variable SLP is in units of mb and 
+the variable elnino is in units of K, so the regression coefficient 
+of SLP upon elnino is in units of mb per K.
+<p>
+<li>The result of the least squares regression of Y on X is often
+expressed as a linear equation: 
+<p>
+<ul><code>Y = slope * X + intercept</code></ul>
+<p>
+where X is the independent variable, Y is the dependent variable, and
+the slope and intercept are calculated using complicated algebraic
+formulas. The calculation is simplified if the time means are
+removed. If we define x and y to be the departures from the time
+averages of X and Y:
+<p>
+<ul><code>x = X - Xave</code><br><code>y = Y - Yave</code></ul>
+<p>
+then the regression equation becomes:
+<p>
+<ul><code>y = <i>coefficient</i> * x</code></ul>
+<p>
+Where
+<p>
+<ul><code><i>coefficient</i> = (sum of x*y over time)/(sum of x*x over time)</code></ul>
+<p>
+This <code><i>coefficient</i></code> is the output from the <code>tregr</code> function.
+The second example below shows how to construct the regression estimate of Y based on X.
+<p>
+<li>Use the <a href="gradfuncsregr.html"><code>sregr</code></a>
+function to do regression over the spatial domain.
+<p>
+</ol>
+
+<p>
+<h3>Example</h3>
+<ol>
+<li>This example calculates the expected departure from the 
+slp mean given a unit departure in the defined variable elnino.
+<p>
+<pre>
+set y 1
+set z 1
+set t 1 100
+define elnino = aave(ts, lon=-160, lon=-80, lat=-20, lat=10)
+set lon 0 360
+set lat -90 90
+set z 1
+set t 1
+d tregr(elnino, slp, t=1, t=100)
+</pre>
+<p>
+<li>This example builds on the previous example by 
+calculating the regression estimate of slp based on the
+defined variable elnino. 
+<p>
+<pre>
+define coeff = tregr(elnino, slp, t=1, t=100)
+define slpave = ave(slp, t=1, t=100)
+define ninoave = ave(elnino, t=1, t=100)
+d coeff * (elnino - ninoave) + slpave
+</pre>
+</ol>
+
+
+</body>
+</html>
diff --git a/doc/gradfunctvrh2q.html b/doc/gradfunctvrh2q.html
new file mode 100644
index 0000000..6e7dcf7
--- /dev/null
+++ b/doc/gradfunctvrh2q.html
@@ -0,0 +1,52 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>tvrh2q</b></h2>
+
+<p>
+<code>tvrh2q(<i>tvexpr,rhexpr</i>)</code>
+
+<p> 
+Given virtual temperature and relative humidty, <code>tvrh2q</code>
+returns specific humidity, q, in g/g. Specifically: 
+
+<p>
+<code><i>tvexpr</i></code>     
+A GrADS expression that represents virtual temperature, in Kelvin. <br>
+<code><i>rhexpr</i></code>     
+A GrADS expression that represents relative humidty, in percent 
+(values from 0 to 100). 
+
+<p>
+This function works only on gridded data. 
+
+<p>
+<h3>Usage Notes </h3>
+
+<p>
+<ol>
+<li>The conversion formula requires a pressure in mb. <code>tvrh2q</code>
+assumes that the Z coordinate system is pressure in mb. If Z is a varying
+dimension, the pressure valid at each grid point is used. When Z is a
+fixed dimension, the Z value from the current dimension environment is
+used. 
+
+<p>
+Note that it is possible to provide values from an incorrect pressure
+level by overriding the current dimension environment: 
+
+<p>
+<code>
+<dd>set lev 500 
+<dd>d tvrh2q(tv(lev=850),rh(lev=850)) 
+</code>
+
+<p>
+In this case, the <code>tvrh2q</code> function assumes a pressure of
+500mb, which is the current setting for the Z dimension
+environment. However, <code><i>tvexpr</i></code> and
+<code><i>rhexpr</i></code> are providing data from the 850mb level, 
+so the function will produce incorrect results. 
+</ol>
+
+
+<H3>Examples</H3>
diff --git a/doc/gradfunctvrh2t.html b/doc/gradfunctvrh2t.html
new file mode 100644
index 0000000..58aaf30
--- /dev/null
+++ b/doc/gradfunctvrh2t.html
@@ -0,0 +1,13 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2><b>tvrh2t</b></h2> <p>
+
+<code>tvrh2t(<i>tvexpr,rhexpr</i>)</code><p> 
+
+Given virtual temperature and relative humidity, <code>tvrh2t</code>
+returns the temperature in degrees Kelvin. The operation of this function
+is the same as <a href="gradfunctvrh2q.html"><code>tvrh2q</code></a>;
+refer to the above description for
+more information. 
+<H3>Usage Notes</H3><P>
+<H3>Examples</H3><P>
diff --git a/doc/gradfuncvint.html b/doc/gradfuncvint.html
new file mode 100644
index 0000000..f4de208
--- /dev/null
+++ b/doc/gradfuncvint.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Function: vint</title>
</head>
<body bgcolor="#e0f0ff" text="#000000">
<h2><b>vint</b></h2><p> 

<code>vint(<i>psexpr,expr,top</i>)</code><p> 

This function performs a mass-weighted vertical integral in mb pressure coordinates. The three arguments to <code>vint</code> are: 

<p>
<code><i>psexpr</i>   </code>a GrADS expression for the
surface pressure, in mb, which bounds the integral on
the bottom. <br>
<code><i>expr</i>     </code>a GrADS expression 
representing the quantity to be integrated.<br>
<code><i>top</i>     </code>
the bounding top pressure, in mb. This value must be a constant and cannot be
provided as an expression. <p>

The calculation is a sum of the mass-weighted layers: 
<p>
<ul><code>f/g * sum(expr * Delta(level))</code></ul>

<p>
The bounds of the integration are the surface pressure and the
indicated <code><i>top</i></code> value. The scale factors are f=100
and g=9.8. The summation is done for each layer present that is
between the bounds. The layers are determined by the Z levels of the
default file. Each layer is considered to be from the midpoints
between the levels actually present, and is assumed to have the same
value throughout the layer, namely the value of the gridpoint at the
middle of the layer.

<p>
<h3>Usage Notes </h3><p>

<ol>
<li>The summation is done using the Z levels from the default file, so 
it is important that the default file have the same Z dimension
coordinates as <code><i>expr</i></code>.

<li>Data levels below and above the bounds of the summation are ignored.

<li>The Z dimension in world-coordinate units is assumed to be
pressure values given in millibars (mb).  The units of g are
such that when the expression integrated is specific humidity (q) in
units of g/g, the result is kg of water per square meter, or
precipitable water in mm. 

<li>It is usually a good idea to make the <code><i>top</i></code>
pressure value to be at the top of a layer, which is midway between
grid points. For example, if the default file (and the data) have
pressure levels of ...,500,400,300,250,... then a good value for
<code><i>top</i></code> might be 275, the value at the top of the
layer that extends from 350 to 275 mb. 

<li>The <code>vint</code> function operates only in an X-Y varying
dimension environment. 
<li>Be sure the units of the surface pressure (argument 1) are in millibars (mb).
  <p>
</ol>

<p>
<h3>Examples </h3><p>

<p>
1. This expression will integrate specific humidity to obtain
precipitable water, in mm:
<ul><code>vint(ps,q,275)</code>
</ul>

<p> 2. This is an artificial example that demonstrates a vertical integration 
from a fixed lower bound of 1000mb to the top of the atmosphere, and integrating a field of all 1's. 
This gives an answer of 10204.1 (or 100000/9.8) which is the mass of air (in kg) of a 1 meter squared column 
when the surface pressure is 1 bar and the accelleration due to gravity is assumed to be exactly 9.8m/sec**2 over the entire column.
<ul>
  <code>vint(const(ps,1000),const(t,1),0)</code>
</ul>
<p>
</body>
</html>
\ No newline at end of file
diff --git a/doc/gradutilbufrscan.html b/doc/gradutilbufrscan.html
new file mode 100644
index 0000000..8ee8730
--- /dev/null
+++ b/doc/gradutilbufrscan.html
@@ -0,0 +1,77 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Utilities: bufrscan</title>
+<link href="../../assets/NewIGES.css" rel="stylesheet" type="text/css">
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>bufrscan</b></h2>
+
+<p> <span class="plaintext">BUFR (Binary Universal Form for the Representation 
+  of meteorological data) is a World Meteorological Organization (WMO) standard 
+  for storing observational data (aka sequence or in-situ data). BUFR is self-describing 
+  data format and can store a large amount of data and metadata in a small amount 
+  of disk space by using look-up tables and bit-by-bit packing. Bufrscan is an 
+  external GrADS utility that reads BUFR messages and prints out ascii values. 
+  </span>
+<p class="plaintext">Individual elements of a BUFR message are uniquely described 
+  by three numbers: F, X, and Y. F is a type indicator and may be 0, 1, 2, or 
+  3. X is a class or category indicator and varies between 0 and 63. Y indicates 
+  an entry within an X class, and varies between 0 and 255. The F,X,Y trio provides 
+  the required decoder table reference, so that the data value may be retrieved 
+  from the BUFR element. A group of BUFR elements forms a subset; a group of subsets 
+  forms a message; any number of messages may be concatenated together to form 
+  a BUFR file.
+<p class="plaintext">The syntax for bufrscan is as follows: 
+<p><code>bufrscan [-h] [-d] <em>tablepath filename</em></code>
+<p>Where: 
+<ul>
+  <table width="664" border="0">
+    <tr>
+    <td width="97"><code>-h</code></td>
+      <td width="551" class="plaintext">Prints the BUFR message headers (default) 
+      </td>
+  </tr>
+  <tr>
+    <td><code>-d</code></td>
+      <td class="plaintext">Prints the BUFR message contents</td>
+  </tr>
+  <tr>
+      <td><code><em>tablepath</em></code></td>
+      <td class="plaintext">Directory containing BUFR decoding tables (e.g. /usr/local/grads/lib/tables)</td>
+  </tr>
+  <tr>
+      <td><code><em>filename</em></code></td>
+      <td class="plaintext">BUFR message file to be decoded</td>
+  </tr>
+</table>
+</ul>
+
+<p class="plaintext">When using the -h option to print out the headers, the output 
+  from bufrscan will list the F, X, Y values for each element as well as the type 
+  of information in the element (given in parentheses). For elements that are 
+  type 'numeric' or 'text', a variable name and description are also printed. 
+  (<a href="bufr.sample.headers">Example header output</a>) 
+<p class="plaintext">When using the -d option to print out the data, the output 
+  from bufrscan will list message number, subset number (in parentheses), replication 
+  factor [in square brackets], the F,X,Y values, and then the decoded data value. 
+  (<a href="bufr.sample.data">Example data output</a>) 
+<p class="plaintext">Many BUFR files also contain a lookup table that was designed 
+  to be used with the data in the file. The tables are packed into the BUFR format 
+  the same way the data are. If a BUFR file contains a decoding table, the information 
+  in that table will override the lookup values in the standard decoding tables 
+  underneath the <code><em>tablepath</em></code> directory. 
+<p class="plaintext">There is a GrADS interface for BUFR, which means that BUFR 
+  data can be read directly in their native format and are handled as a GrADS 
+  station data set with all the associated display an analysis capabilities. GrADS 
+  requires a specially-formatted descriptor file to read BUFR data; the output 
+  from bufrscan is used to compose the descriptor file. The document on the <a href="bufrformat.html"> 
+  BUFR Format</a> has more information on how to generate BUFR descriptor files. 
+<p class="plaintext"> 
+<p> 
+<p> 
+</body>
+</html>
+
diff --git a/doc/gradutilgrib2scan.html b/doc/gradutilgrib2scan.html
new file mode 100644
index 0000000..764b993
--- /dev/null
+++ b/doc/gradutilgrib2scan.html
@@ -0,0 +1,133 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Utilities: grib2scan</title>
+<style type="text/css">
+<!--
+.style1 {color: #006600}
+.style2 {color: #0033FF}
+.style3 {color: #996600}
+.style4 {color: #006666}
+.style5 {color: #993366}
+.style6 {color: #FF66FF}
+.style8 {color: #990000}
+.style11 {color: #00CC33}
+.style12 {color: #9900FF}
+.style13 {color: #FF6600}
+.style14 {
+	color: #990;
+}
+.style15 {
+	color: #F00;
+}
+.red {
+	color: #900;
+}
+-->
+</style>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>grib2scan</b></h2>
+
+<p>
+The <code>grib2scan</code> utility is used for finding out what is inside a GRIB2 data file. It scans each record in the file, and prints out relevant information about the data in the record. 
+The command sytax is:
+<ul>
+<code>grib2scan [-v] <i>fname</i></code></ul>
+<p>
+Where <code><i>fname</i></code>
+ is the input GRIB2 file name, and the <code>-v</code> option is used for verbose output. 
+<p>To assist in the interpretation of the grib2scan output, here are some links to GRIB2 documentation: <a href="http://www.wmo.int/pages/prog/www/WMOCodes/GRIB.html" target="_parent"><br>
+  WMO</a> (the official source)<a href="http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc.shtml" target="_parent"><br>
+NCEP</a> (unofficial, but with a user-friendly web interface). 
+<p>A GRIB2 file is a collection of records, each with a complete set of metadata to describe the data contained in the record. A GRIB2 record has 9 sections, some of which may occur more than once. The output from grib2scan is printed out as it scans each section of the record. Below are  examples of the  grib2scan output from   different GRIB2 records. An explanation of the output follows.
+<p><code>
+Record 1 starts at 0 of length <span class="style3">17242</span><br>
+    <span class="style2">Discipline=0</span> (Meteorological)
+  <br>
+  <span class="style1">  Reference Time</span> = 2007-10-09 00:00:00  
+  <span class="style4">Start of Forecast</span>  <br>
+   Field 1 <br>
+    <span class="style5">GDT=0</span> (Lat/Lon) nx*ny=10512
+   <br>
+     XDEF 144 linear 0.000000 2.500000
+  <br>
+     YDEF 73 linear 90.000000 2.500000
+  <br>
+    <span class="style6">PDT=1</span> Forecast Time = 0 Hour 
+  <br>
+     Parameter: <span class="style13">disc,cat,num</span> = 0,3,5  <br>
+     Level: <span class="style8">ltype,lval</span> = 100,20000   (sf,sval = 0 20000) 
+  <br>
+     Ens: <span class="style11">type,pert</span> = 3,1 (total=10) 
+  <br>
+    <span class="style12">DRT=40</span> (Grid Point Data - JPEG2000 Compression) (Lossless)<br>
+  <span class="style15"> ctl: var1.1   0,100,20000  0,3,5   description  </span><br>
+  <br>
+  Record 2 starts at 17242 of length <span class="style3">110483</span>  <br>
+    <span class="style2">Discipline=0</span> (Meteorological)
+  <br>
+    <span class="style1">Reference Time</span> = 2007-10-09 00:00:00  <span class="style4">Start of Forecast</span>  <br>
+   Field 1 
+  <br>
+   
+  <span class="style5">GDT=0</span> (Lat/Lon) nx*ny=259920
+   <br>
+     XDEF 720 linear 0.000000 0.500000
+     <br>
+     YDEF 361 linear 90.000000 0.500000
+  <br>
+    <span class="style6">PDT=8</span> 6 Hour Average EndTime = 2007-10-09 06:00 
+  <br>
+     Parameter: <span class="style13">disc,cat,num,sp</span> = 0,1,7,0
+  <br>
+     Level: <span class="style8">ltype,lval</span> = 1,0   (sf,sval = 0 0) 
+  <br>
+    <span class="style12">DRT=40</span> (Grid Point Data - JPEG2000 Compression) (Lossless)<br>
+   <span class="style15">ctl:  var2.1     0,1,0  0,1,7,0     description </span></code>
+<p><code>Record 3 starts at 16469 of length <span class="style3">2300 </span><br>
+  <span class="style2">  Discipline=0</span> (Meteorological)<br>
+    <span class="style1">Reference Time</span> = 2012-09-11 03:00:00  (Start of Forecast)<br>
+   Field 1 <br>
+    <span class="style5">GDT=30</span> (Lambert Conformal) nx*ny=23865<br>
+     nx=185 ny=129 lon1=226.541000 lat1=12.190000<br>
+     reflon=265.000000 dx=40635.000000 dy=40635.000000<br>
+     latin1=25.000000 latin2=25.000000 <br>
+    <span class="style6">PDT=5</span> 0 Hour Forecast  Valid Time = 2012-09-11 03:00 <br>
+     Parameter: <span class="style13">disc,cat,num</span> = 0,0,0<br>
+     Level: <span class="style8">ltype,lval</span> = 100,85000   (sf,sval = 0 85000)<br>
+     Prob: <span class="style14">type,lim</span> = 0,273  (Probability of event below 273)<br>
+    <span class="style12">DRT=40</span> (Grid Point Data - JPEG2000 Compression) (Lossless) <br>
+   <span class="style15">ctl:  var3.1     0,100,85000   a0,273   0,0,0     description </span><br>
+  <br>
+  Record 4 starts at 37355 of length <span class="style3">205 </span><br>
+  <span class="style2">Discipline=0</span> (Meteorological)<br>
+  <span class="style1">Reference Time</span> = 2012-07-25 00:00:00  (Start of Forecast)<br>
+ Field 1 <br>
+  <span class="style5">GDT=0</span> (Lat/Lon) nx*ny=65160<br>
+   XDEF 360 linear 0.000000 1.000000<br>
+   YDEF 181 linear 90.000000 1.000000<br>
+  <span class="style6">PDT=48</span> 0 Hour Forecast  Valid Time = 2012-07-25 00:00 <br>
+   Parameter: <span class="style13">disc,cat,num</span> = 0,20,12<br>
+   Level: <span class="style8">ltype,lval</span> = 10,0   (sf,sval = 0 0)<br>
+   Aerosol: <span class="style14">atyp,styp,s1,s2 </span>= 62001,0,2e-05,0  (size is < 2e-05) <br>
+  <span class="style12">DRT=40</span> (Grid Point Data - JPEG2000 Compression) (Lossless) <br>
+ <span class="style15">ctl:  var4.1     0,10,0   a62001,0,2e-05,0   0,20,12     description</span> </code>
+<p>Section 0, the Indicator Section, contains info grib2scan uses to confirm it is looking at a GRIB2 file. This section also contains the <span class="style2">Discipline</span>, as well as the <span class="style3">size of the entire record</span>. 
+<p>Section 1, the Identification Section,  contains characteristics that apply to all data in the record. Sections 0 and 1 are the only ones that may not be repeated in a GRIB2 record. From  section 1 we get the <span class="style1">Reference Time</span> printed in a YYYY-MM-DD HH:MM:SS format, plus the <span class="style4">significance of the reference time</span>.
+<p>Section 3, the Grid Definition Section,  contains the definition of the grid surface and geometry of the data values in the grid. The Grid Definition Template (<span class="style5">GDT</span>) value indicates the grid type -- in Record 1, the data are on a Lat/Lon grid at 2.5-degree resolution; Record 2 has a 0.5-degree Lat/Lon grid. For some <span class="style5">GDT</span> values, grib2scan in verbose mode will print out  helpful information for creating the XDEF and YDEF or PDEF ent [...]
+<p>Section 4, the Product Definition Section,  contains a lot of essential information about the nature of the data -- what the variable is called, its units, its vertical level, its valid time, whether it is part of an ensemble set, and whether it is an instantaneous value or statistically processed in some way. The Product Definition Template (<span class="style6">PDT</span>) value tells grib2scan  where to get the parameter category and number, which, along with the discipline, are re [...]
+If the parameter has been statistically processed (i.e. it is an average or an accumulation over a period of time), then a fourth number is required by GrADS to  indicate the kind of statistical process used to generate the parameter: the <span class="style13">discipline, category, number, and statistical process</span> must go into the descriptor file. In Record 2, the parameter is "Discipline 0: Meterological products, Parameter Category 1: Moisture, Parameter Number 7: Precipitat [...]
+Section 4 also give the parameter's <span class="style8">level type and value</span> -- 
+  
+  these comma-delimited numbers can also be copied from the grib2scan output into your descriptor file. In the first example, the level type is pressure, and the level value is 20000 Pascals (or 200 mb). Note that if a parameter occurs on more than one pressure level, you should use ZDEF to list the pressure level values and omit the level value in the variable declaration. Pressure values are converted back to millibars internally if you use the OPTIONS  keyword "pascals". In  [...]
+
+metadata also appears in section 4. Ensemble metadata is only relevant in Record 1, and appears as an <span class="style11">ensemble type and perturbation number</span>. Parameters that are derived from all ensemble members only require one code, a number that indicates the type of derived forecast (e.g. ensemble mean). These ensemble codes  belong in the exanded form of the EDEF declaration. 
+<p>Starting with <span class="red">GrADS Version 2.0.2</span>, support was added for GRIB2 products that require additional codes. These are for <span class="style6">PDT 5</span> and <span class="style6">9</span> (forecast probabilities) and <span class="style6">PDT 48</span> (aerosol properties). The <span class="style14">additional  codes</span> are listed after the <span class="style13">parameter</span> and <span class="style8">level </span>information. The <span class="style14">addit [...]
+<p>Section 5, the Data Representation Section,  contains information about how the data are represented. The Data Representation Template (<span class="style12">DRT</span>) number is not required in a GrADS descriptor file, but because it is sometimes useful to know how the data are formatted in the GRIB2 file, it is included in the grib2scan output. 
+
+<p>Starting with <span class="red">GrADS Version 2.0.2</span>, another new feature was added to the grib2scan output, a suggestion for a descriptor file entry for each field in the grib2 file. This is shown in<span class="style15"> red</span> at the bottom with the prefix "<span class="style15">ctl: </span>". 
+</body>
+</html>
diff --git a/doc/gradutilgribmap.html b/doc/gradutilgribmap.html
new file mode 100644
index 0000000..593ea36
--- /dev/null
+++ b/doc/gradutilgribmap.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Utilities: gribmap</title>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>
<body text="#000000" bgcolor="e0f0ff">

<h2><b>gribmap</b></h2>

<p>
The GrADS data descriptor file defines a grid structure into which
the data will fit -- it gives "shape" to the data by identifying its
spatial dimensions, the number of time steps, and the number of variables. 
<p>
If the data is in binary format, its <a
href="aboutgriddeddata.html#structure">structure</a> has already been
prescribed. If the data is in GRIB format, no consistent 
relationship exists between the data and the grid structure defined in the data
descriptor file. Hence, the need for the <code>gribmap</code> utility which "maps"
between the GRIB data and the GrADS data description.
<p>
As <code>gribmap</code> reads each field in the GRIB data file, the
parameters for that field (e.g. variable name, vertical level, time)
are compared to the information in the data descriptor file until 
a match is found. The process continues until all the GRIB elements have been 
"mapped" to their location within the GrADS grid structure.
<table width="680" border="0" cellpadding="5" cellspacing="5" class="plaintext">
  <tr bgcolor="c5d5ff">
    <td colspan="2" bordercolor="#F4F4F4" bgcolor="#E0F0FF"><p>The syntax for the <code>gribmap</code> command is as follows:</p>
      <p>      <code>���gribmap [<i>options</i>] </code></p>
      <p>Command line <code><i>options</i></code> are:<br>
      </p></td>
  </tr>
  
  <tr bgcolor="c5d5ff">
    <td width="100"><code>-0</code></td>
    <td>Ignores the forecast time when setting up a match, so that the base time is the valid time.</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="100"><code>-b</code></td>
    <td>Valid time for averages is set to be the beginning of the period rather than 
        the end. Default valid time is the end of the averaging period<code>.</code>    </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-big</code></td>
    <td>(<span class="style1">GrADS version 2.0.a8</span>) Required option if the GRIB1 or GRIB2 files are > 2 Gb. This option creates a bigger index file, which cannot be read by earlier versions of GrADS. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-e<br>
      -E</code></td>
    <td>Ignores extra bytes (that are not part of the GRIB1 msg) at end of file. Some ECMWF GRIB files require this option because 
      of blocking. 
      Using the <code>-E</code> option ignores extra bytes in middle and/or end of GRIB file. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="100"><code>-f<i>hr</i></code></td>
    <td>Matches only those grib records whose forecast time is <code><i>hr</i></code> hours. This is used to isolate a sequence of forecasts. For example, if you 
        wanted to sample all the 120-hour forecasts from the MRF ensemble runs, you 
        would use <code>gribmap -f120</code>.      </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-h<i>num</i></code></td>
    <td>Skips over <code><i>num</i></code> bytes before starting the scan process. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-help</code></td>
    <td>Prints out the list of options </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-i <i>fname</i></code></td>
    <td><code><i>fname</i></code> is the name of the data descriptor file. If 
      not specified, <code>gribmap</code> will prompt the user. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-m</code></td>
    <td>Use base time from descriptor file instead of GRIB header. This option only works with GRIB1.</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-min0</code></td>
    <td>Ignores the minutes code. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-N</code></td>
    <td>Does NOT write out the index file. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-q</code></td>
    <td> Quiet mode -- suppresses all messages except for errors. Default is off.</td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-s<i>num</i></code></td>
    <td>Skips over no more than<em><code> num </code></em>bytes between records. The 
      default is 1000. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-t0</code></td>
    <td>Matches only those grib records whose base time is the same as the initial 
      time in the data descriptor file. This is used to pull out a forecast sequence 
      (0, 12, 24, ... , 72 hours) starting a specific time. </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td width="100"><code>-u</code></td>
    <td><p>
    Updates existing gribmap if adding data files are being added to <a href="templates.html">templated</a> data set. This option has been (temporarily) disabled in GrADS version 2.0.     </td>
  </tr>
  <tr bgcolor="c5d5ff">
    <td><code>-v</code></td>
    <td> Verbose mode -- detailed output makes it easier to verify what is being mapped. 
      Default is off. </td>
  </tr>
</table>
<p>

</body>
</html>

\ No newline at end of file
diff --git a/doc/gradutilgribscan.html b/doc/gradutilgribscan.html
new file mode 100644
index 0000000..8b779f2
--- /dev/null
+++ b/doc/gradutilgribscan.html
@@ -0,0 +1,247 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Utilities: gribscan</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>gribscan</b></h2>
+
+<p>
+The <code>gribscan</code> utility is used for extracting grid info
+from GRIB data files. Its features include grid/product information,
+gridded output in ASCII, binary, and/or grib format, plus automatic
+"scanning" for GRIB records so that you don't have to know the
+physical layout of the data to scan it.
+
+<p>
+The command sytax is: 
+
+<p>
+<ul>
+<code>gribscan [-i <i>ifname</i>] [-o <i>ofname</i>] [-<i>file options</i>] [-<i>processing options</i>] [-<i>display options</i>]</code>
+</ul>
+<p>
+Where:
+<p>
+<ul>
+<code><i>ifname</i></code>
+<ul>
+This is the input grib file name. If <code>-i <i>ifname</i> </code> is
+omitted, <code>gribscan</code> will prompt the user for a file name.
+</ul>
+<p>
+<code><i>ofname</i></code>
+<ul>
+This is the output file name WITHOUT an extension. If <code>-o <i>ofname</i></code>
+is omitted, a default file name of
+<code>zy0x1w2.<i>type</i></code> is created where
+<code><i>type</i></code> is:<br>
+<code>asc</code> - ascii <br>
+<code>grb</code> - GRIB <br>
+<code>dat</code> - a stream of floats (GrADS format)
+</ul>
+</ul>
+<p>
+File Options:
+<p>
+<ul>
+<code>-og</code>
+<ul>
+<code>gribscan</code> will return output in GRIB format
+</ul>
+<p>
+<code>-oa</code>
+<ul>
+<code>gribscan</code> will return output in ASCII format (%8g in C-language syntax)
+</ul>
+<p>
+<code>-of</code>
+<ul>
+<code>gribscan</code> will return output as a stream of floats. This
+is machine dependent and is 64-bit on Crays and 32-bit elsewhere.
+</ul>
+</ul>
+
+<p>
+Processing Options:
+<p>
+<ul>
+<code>-s<i>NNN</i></code>
+<ul>
+Specifies the max number <code><i>NNN</i></code> of bytes between GRIB
+messages in the file. The default is 500 and it is assumed that you
+want to ignore junk (e.g., comm stuff) between data.
+</ul>
+<p>
+<code>-sp<i>NNN</i></code>
+<ul>
+Selects parameter # <code><i>NNN</i></code> 
+(e.g.,<code>-sp11</code> for temperature)
+</ul>
+<p>
+<code>-sl<i>NNN</i></code>
+<ul>
+Selects level # <code><i>NNN</i></code> 
+(e.g., <code>-sp500</code> to get 500 mb fields)
+</ul>
+<p>
+<code>-st<i>NNN</i></code>
+<ul>
+Selects tau # <code><i>NNN</i></code> 
+(e.g., <code>-st12</code> to get t=12 forecasts)
+</ul>
+<p>
+<code><i>-h<i>NNN</i></i></code>
+<ul>
+Specifies a fixed file header of <code><i>NNN</i></code>
+bytes. If omitted, the default is to seek the first GRIB
+message automatically, but if you know <code><i>NNN</i></code>, it is more
+efficient to specify it.
+</ul>
+
+<p>
+<i>Special note to NMC users:</i> The once "standard" 81-byte header
+in an NMC GRIB file contained the string "GRIB". Unfortunately, the
+same string is part of the GRIB indicator section itself!  Thus, an
+automatic scan for GRIB to demark the start of the data will fail if
+the 81-byte header is present! When in doubt (or failure) try using
+the <code>-h81</code> option.
+
+<p>
+<i>Note:</i> These processing options can be used simultaneously 
+to output a very narrow set of fields. 
+</ul>
+
+<p>
+Display options:
+<p>
+<ul>
+<code>-q&nbsp&nbsp&nbsp&nbsp</code>
+Quick output to extract stuff GrADS gribmap cares about<br>
+<code>-q1&nbsp&nbsp&nbsp</code>
+One-line quick output<br>
+<code>-d&nbsp&nbsp&nbsp&nbsp</code>
+Comma delimited mode<br>
+<code>-v&nbsp&nbsp&nbsp&nbsp</code>
+Verbose mode for diagnostics<br>
+<code>-bd&nbsp&nbsp&nbsp</code>
+Binary data section info<br>
+<code>-gv&nbsp&nbsp&nbsp</code>
+Uses the NMC GRIB variable table to output mnemonic, title, and units<br>
+<code>-gd&nbsp&nbsp&nbsp</code>
+Output info from the grid defn sec<br>
+<code>-S&nbsp&nbsp&nbsp&nbsp</code>
+Silent mode; NO standard output<br>
+</ul>
+
+<p>
+<h3>Examples</h3>
+<p>
+<ol>
+<li>A "quick" scan to get the info GrADS cares about:<p>
+<dd><code>gribscan -q -i eta.T12Z.PGrbF48 | grep 184</code>
+<p>
+Gives the result: 
+<p>
+<dd><code>184,F,135,108,100,0,100,0,1e+09,T,1994,8,29,12,0,1,48,0,G,104,BDTG,94082912</code>
+<p>
+Where:
+<p>
+<ul>
+<code>184     </code>
+field # in the file <br>
+<code>F       </code>
+field data <br>
+<code>135     </code>
+param #<br>
+<code>108     </code>
+level indicator <br>
+<code>100     </code>
+level <br>
+<code>0       </code>
+l1 byte 1 of level <br>
+<code>100     </code>
+l2 byte 2 of level <br>
+<code>0       </code>
+time range indicator <br>
+<code>1e+09   </code> 
+decimal scale factor <br>
+<code>T       </code>
+time data follows <br>
+<code>1994    </code>
+year <br>
+<code>8       </code>
+month <br>
+<code>29      </code>
+day <br>
+<code>12      </code>
+hour <br>
+<code>0       </code>
+min <br>
+<code>1       </code>
+forecast time unit (hour) <br>
+<code>48      </code>
+t=48 h forecast<br>
+<code>G       </code>
+grid param follows <br>
+<code>104     </code>
+NMC grid #104 <br>
+<code>BDTG    </code>
+Base date-time-group (yymmddhh) follows
+</ul>
+<p>
+<li>Comma delimited output:<p>
+<dd><code>gribscan -d -i eta.T12Z.PGrbF48  | grep 184 </code>
+<p>
+Gives the same results as the previous example but arranged differently:
+<p>
+<dd><code>PDS,184,104,135,108,100,0,100,1994,8,29,12,0,1,48,0,0,1e+09</code>
+<p>
+
+<li>A full listing:
+<p>
+<dd><code>gribscan -d -gv -bd -gd -i eta.T12Z.PGrbF48 | grep 184 </code>
+<p>
+Gives the following results:
+<p>
+<ul><code>
+PDS,184,104,135,108,100,0,100,1994,8,29,12,0,1,48,0,0,1e+09,mconv,Horizontal moisture divergence,[kg/kg/s],GDS,5,147,110,-139.475,90.755,0.354,-0.268,-105.000,33536.000,0,1,0,BDS,12,-646.844,16170,4825059,26366
+</code></ul>
+<p>
+Where:
+<p>
+<code>104         </code>
+grid id <br>
+<code>param #135   </code>
+mconv,Horizontal moisture divergence,[kg/kg/s] <br>
+<code>BDS         </code>
+binary data section <br>
+<code>646.844     </code>
+ref value 16170 - # of points <br>
+<code>4825059     </code>
+starting byte of the data <br>
+<code>26366       </code>
+length of the grib message<br>
+<p>
+Note that eliminating the <code>-d</code> option would result in 
+a fixed-column type output.
+<p>
+
+<li>Output a selected few fields in GRIB:
+<p>
+<dd><code>gribscan -og -sp135 -q -i eta.T12Z.PGrbF48 -o eta.135</code>
+<p>
+Writes out all GRIB message containing the 135 parameter to the
+file <code>eta.135.grb</code>. A subsequent execution of <code>gribscan</code> on
+<code>eta.135.grb</code> would return:
+<p>
+<code>1, F ,135,108,100,0,100,0,1e+09, T,1994,8,29,12,0,1,48,0, G ,104, BDTG, 94082912 
+2, F,135,108,21860,85,100,0,1e+09, T ,1994,8,29,12,0,1,48,0, G ,104, BDTG, 
+94082912</code>
+</ol>
+
+
+</body>
+</html>
diff --git a/doc/gradutilgxeps.html b/doc/gradutilgxeps.html
new file mode 100644
index 0000000..a870e68
--- /dev/null
+++ b/doc/gradutilgxeps.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<title>GrADS Utilities: gxeps</title>
<link rel="stylesheet" href="/assets/NewIGES.css">
<body bgcolor="#e0f0ff">
<h2><a name="gxeps">gxeps</a></h2>

<code>gxeps [ -<i>acdklrsv -i <infile> -o <outfile></i> 
] [<i><infile></i>]</code>
<p class="plaintext"> Converts the GrADS metacode format file to a PostScript 
  file. Where: 
<ul>
  <code>-i <i>fname</i>    </code> <span class="plaintext">identifies 
  input GrADS metacode file </span><br>
  <code>-o <i>fname</i>    </code> <span class="plaintext">identifies 
  output postscript file </span><br>
  <code>-b          </code> <span class="plaintext">prints 
  black and white plot</span><br>
  <code>-c          </code> <span class="plaintext">prints 
  color plot (default)</span><br>
  <code>-r          </code> <span class="plaintext">prints 
  on a black background</span> <br>
  <code>-d          </code> <span class="plaintext">appends 
  CTRL-D to the file, useful if printing on a HP1200C/PS color printer</span><br>
  <code>-1          </code> <span class="plaintext">use 
  PostScript Level 1 </span>(default)<br>
  <code>-2          </code> <span class="plaintext">use 
  PostScript Level 2 </span><br>
  <code>-a          </code> <span class="plaintext">Page 
  size A4 </span><br>
  <code>-l          </code> <span class="plaintext">Page 
  size US-Letter </span><br>
  <code>-L          </code> <span class="plaintext">Ask 
  for a label to be printed on the plot </span><br>
  <code>-n          </code> <span class="plaintext">Ask 
  for a note to include in PostScript file header </span><br>
  <code>-s          </code> <span class="plaintext">Add 
  a file and time stamp on the plot.</span><br>
  <code>-v          </code> <span class="plaintext">Verbose 
  mode.</span> 
</ul>

<p>
<b>Usage Notes</b>

<ol>
  <li><span class="plaintext"> The default behaviour of <code>gxeps</code>is to 
    create a grayscale plot on a white background. The GrADS default rainbow colors 
    (color numbers 2 to 14) are converted into appropriate grey shades. User-defined 
    colors (numbers above 15) are translated to greyscale intensity based on their 
    <i>green</i> content only. </span>
  <li><span class="plaintext"> For more information, see the section in the User's 
    Guide on <a href="imageoutput.html">Producing Image Output from GrADS</a>. 
    </span>
</ol>

<p>
<b>Examples</b>
<ol>
<li><code>gxeps -a</code>
<br>
    <span class="plaintext">Prompts user for the input and output file names and 
    convert to greyscale on white background with page size A4. </span>
  <li><code>gxeps -rc -i mytest.mf -o mytest.ps</code>

<br>
    <span class="plaintext">Converts GrADS metacode format file </span><code><i>mytest.mf</i></code> 
    <span class="plaintext">to a color plot on black background and outputs the 
    result to PostScript file </span><code><i>mytest.ps</i></code>. 
</ol>


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradutilgxps.html b/doc/gradutilgxps.html
new file mode 100644
index 0000000..4477cf1
--- /dev/null
+++ b/doc/gradutilgxps.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<title>GrADS Utilities: gxps</title>
<body>

<h2><a name="gxps">gxps</a></h2>
<p>
<code>gxps [ -<i>crd -i <infile> -o <outfile></i> ] ]</code>

<p>
<code>gxps</code> is a UNIX utility that converts the GrADS metacode format file to a
PostScript file. Command line arguments and switches are: 

<p>
<ul>
<code>-i <i>fname</i>    </code>
identifies input GrADS metacode file <br>
<code>-o <i>fname</i>    </code>
identifies output postscript file <br>
<code>-c          </code>
prints color plot <br> 
<code>-r          </code>
prints on a black background <br>
<code>-d          </code>
does not append CTRL-D to the file, useful if printing on a HP1200C/PS color printer<br>
</ul>

<b>Usage Notes</b> 

<ol>
<li>
The default behaviour of <code>gxps</code> is to create a grayscale
plot on a white background. The GrADS default rainbow colors (color
numbers 2 to 14) are converted into appropriate grey
shades. User-defined colors (numbers above 15) are translated to
greyscale intensity based on their <i>green</i> content only.

<li>
For more information, see the section in the User's Guide on 
<a href="imageoutput.html">Producing Image Output from GrADS</a>.
</ol>

<p>
<b>Example</b>

<ul>
<code>gxps -cr -i mytest.mf -o mytest.ps</code>
</ul>

<p>
Convert GrADS metacode format file <code>mytest.mf</code> to a color
plot on a black background and outputs the result to PostScript file
<code>mytest.ps</code>.


</body>
</html>
\ No newline at end of file
diff --git a/doc/gradutilgxtran.html b/doc/gradutilgxtran.html
new file mode 100644
index 0000000..3347553
--- /dev/null
+++ b/doc/gradutilgxtran.html
@@ -0,0 +1,51 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Utilities: gxtran</title>
+<body>
+
+<h2><a name="gxtran">gxtran</a></h2>
+
+<code>gxtran [ -<i>airg <infile></i> ]</code>
+
+<p>
+This utility is used to display GrADS meta files containing
+single frames or animations (multi frames). 
+
+<p>
+The options are:
+<ul>
+<code>-i <i>fname</i>   &nbsp</code>
+identifies input GrADS metacode file <br>
+<code>-a         &nbsp</code>
+animates the frames without user hitting return in the command window<br>
+<code>-r         &nbsp</code>
+reverses background/foreground colors<br>
+<code>-g <i>geom</i>    &nbsp</code>
+sets the geometry of the X window as in any other X
+application. <br>
+<code>            </code>
+<code><i>geom</i></code> has the form WWWxHHH+X+Y, giving a display window<br>
+<code>            </code>
+WWW pixels wide and HHH pixels tall starting at point X,Y on the screen.<br>
+</ul>
+
+<p>
+<b>Usage Notes</b> 
+<p>
+Without any options, <code>gxtran</code> prompts the user for the name
+of the GrADS meta file. To quit </code>gxtran</code>, hit
+return in the command window.
+
+<p> 
+<b>Examples</b>
+<p>
+<code>gxtran -a -g 800x600+0 -i mytest.mf</code>
+
+<p>
+This command would open a window of size 800x600 starting at the upper
+left corner of the screen and animate all frames (plots) in the file
+<code>mytest.mf</code>.
+
+</body>
+</html>
diff --git a/doc/gradutilncdump.html b/doc/gradutilncdump.html
new file mode 100644
index 0000000..14d54f9
--- /dev/null
+++ b/doc/gradutilncdump.html
@@ -0,0 +1,184 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<body>
+
+<h2><a name="ncdump">ncdump</a></h2>
+
+<code>ncdump [-c] [-h] [-v <i>var1</i>,...] [-b <i>lang</i>] [-f
+<i>lang</i>] [-l <i>len</i>]
+          [-n <i>name</i>] [-d <i>f_digits</i>[,<i>d_digits</i>]]
+<i>file</i></code><p>
+Where:
+<ul>
+<code>-c</code>
+<ul>Show the values of <i>coordinate</i> variables (variables that are
+also dimensions) as well as the declarations of all dimensions,
+variables, and attribute values.  Data values of non-coordinate
+variables are not included in the output.  This is the most suitable
+option to use for a brief look at the structure and contents of a
+netCDF file.
+</ul>
+<p>
+<code>-h</code> 
+<ul>
+Show only the
+<i>header</i> information in the output, that is the declarations of
+dimensions, variables, and attributes but no data values for any
+variables.  The output is identical to using the <code>-c</code>
+option except that the values of coordinate variables are not
+included.  (At most one of <code>-c</code> or <code>-h</code> options
+may be present.) 
+</ul>
+
+<p> 
+<code>-v    <i>var1,...,varn</i></code>
+<ul>
+The output will include data values for the specified variables, in
+addition to the declarations of all dimensions, variables, and
+attributes.  One or more variables must be specified by name in the
+comma-delimited list following this option.  The list must be a single
+argument to the command, hence cannot contain blanks or other white
+space characters.  The named variables must be valid netCDF variables
+in the input-file.  The default, without this option and in the
+absence of the <code>-c</code> or <code>-h</code> options, is to
+include data values for <i>all</i> variables in the output.
+</ul>
+
+<p>
+<code>-b <i>lang</i></code>
+<ul>
+A brief annotation in the form of a CDL comment (text beginning with
+the characters ``//'') will be included in the data section of the
+output for each `row' of data, to help identify data values for
+multidimensional variables.  If <code><i>lang</i></code> begins with
+<code>C</code> or <code>c</code>, then C language conventions will be
+used (zero-based indices, last dimension varying fastest).  If
+<code><i>lang</i></code> begins with <code>F</code> or <code>f</code>,
+then Fortran language conventions will be used (one-based indices,
+first dimension varying fastest).  In either case, the data will be
+presented in the same order; only the annotations will differ.  This
+option is useful for browsing through large volumes of
+multidimensional data. 
+</ul>
+
+<p>
+<code>-f <i>lang</i></code>
+<ul>
+Full annotations in the form of trailing CDL comments (text beginning
+with the characters ``//'') for every data value (except individual
+characters in character arrays) will be included in the data section.
+If <code><i>lang</i></code> begins with <code>C</code> or
+<code>c</code>, then C language conventions will be used (zero-based
+indices, last dimension varying fastest).  If <code><i>lang</i></code>
+begins with <code>F</code> or <code>f</code>, then Fortran language
+conventions will be used (one-based indices, first dimension varying
+fastest).  In either case, the data will be presented in the same
+order; only the annotations will differ.  This option may be useful
+for piping data into other filters, since each data value appears on a
+separate line, fully identified.
+</ul>
+
+<p>
+<code>-l <i>len</i></code>
+<ul>
+Changes the default maximum line length (80) used in formatting lists
+of non-character data values.  
+</ul>
+
+<p>
+<code>-n <i>name</i></code>
+<ul>
+CDL requires a name for a netCDF data set, for use by <a
+href="gradutilncgen.html"><code>ncgen -b</code></a> in generating a default
+netCDF file name. By default, <code>ncdump</code> constructs this name
+from the last component of the pathname of the input netCDF file by
+stripping off any extension it has.  Use the <code>-n</code> option to
+specify a different name.  Although the output file name used by <a
+href="gradutilncgen.html"><code>ncgen -b</code></a> can be specified, it may
+be wise to have <code>ncdump</code> change the default name to avoid
+inadvertantly overwriting a valuable netCDF file when using
+<code>ncdump</code>, editing the resulting CDL file, and using <a
+href="gradutilncgen.html"><code>ncgen -b</code></a> to generate a new netCDF
+file from the edited CDL file.
+</ul>
+
+<p>
+<code>-d <i>float_digits</i>[,</i>double_digits</i>]</code>
+<ul>
+Specifies default number of significant digits to use in displaying
+floating-point or double precision data values for variables that
+don't have a `C_format' attribute.  Floating-point data will be
+displayed with <code><i>float_digits</i></code> significant digits.
+If <code><i>double_digits</i></code> is also specified,
+double-precision values will be displayed with that many significant
+digits.  If a variable has a `C_format' attribute, that overrides any
+specified floating-point default.  In the absence of any
+<code>-d</code> specifications, floating-point and double- precision
+data are displayed with 7 and 15 significant digits respectively.  CDL
+files can be made smaller if less precision is required.  If both
+floating-point and double-presision precisions are specified, the two
+values must appear separated by a comma (no blanks) as a single
+argument to the command.  If you really want every last bit of
+precision from the netCDF file represented in the CDL file for all
+possible floating- point values, you will have to specify this with
+<code>-d 9,17</code>.
+</ul>
+</ul>
+
+
+<b>Usage Notes</b>
+<p>
+<code>ncdump</code> generates an ASCII representation of a specified
+netCDF file on standard output.  The ASCII representation is in a form
+called <code>CDL</code> (``network Common Data form Language'') that
+can be viewed, edited, or serve as input to <a
+href="gradutilncgen.html"><code>ncgen</code></a>.  <a
+href="gradutilncgen.html"><code>ncgen</code></a> is a companion program that
+can generate a binary netCDF file from a <code>CDL</code> file.  Hence
+<a href="gradutilncgen.html"><code>ncgen</code></a> and <code>ncdump</code>
+can be used as inverses to transform the data representation between
+binary and ASCII representations.  See <a
+href="gradutilncgen.html"><code>ncgen</code></a> for a description of CDL and
+netCDF representations.
+
+<p>
+<code>ncdump</code> defines a default format used for each type of
+netCDF data, but this can be changed if a `C_format' attribute is
+defined for a netCDF variable.  In this case, <code>ncdump</code> will
+use the `C_format' attribute to format each value.  For example, if
+floating-point data for the netCDF variable <code>Z</code> is known to
+be accurate to only three significant digits, it would be appropriate
+to use the variable attribute<p> <dd><code>Z:C_format =
+"%.3g"</code><p> <code>ncdump</code> may also be used as a simple
+browser for netCDF data files, to display the dimension names and
+sizes; variable names, types, and shapes; attribute names and values;
+and optionally, the values of data for all variables or selected
+variables in a netCDF file.
+
+<p>
+<b>Examples</b>
+<ol>
+Look at the  structure  of  the  data  in  the  netCDF  file
+<code>foo.nc</code>:<p>
+<dd><code>ncdump -c foo.nc</code><p>
+<li>Produce an annotated CDL version of the structure  and  data
+     in  the netCDF file <code>foo.nc</code>, using C-style indexing for
+the
+     annotations:<p>
+<dd><code>ncdump -b c foo.nc > foo.cdl</code><p>
+<li>Output data for only the variables <code>uwind</code> and
+<code>vwind</code> from
+     the  netCDF  file <code>foo.nc</code>, and show the floating-point
+data
+     with only three significant digits of precision:<p>
+<dd><code>ncdump -v uwind,vwind -d 3 foo.nc</code><p>
+<li>Produce a fully-annotated (one data value per line)  listing
+     of  the data for the variable <code>omega</code>, using Fortran
+conventions for indices, and changing the netCDF dataset  name  in
+     the resulting CDL file to <code>omega</code>:<p>
+<dd><code>ncdump -v omega -f fortran -n omega foo.nc > Z.cdl</code></ol>
+
+
+</body>
+</html>
diff --git a/doc/gradutilncgen.html b/doc/gradutilncgen.html
new file mode 100644
index 0000000..a390c69
--- /dev/null
+++ b/doc/gradutilncgen.html
@@ -0,0 +1,73 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<body>
+
+<h2><a name="ncgen">ncgen</a></h2>
+<code>ncgen [-b] [-c] [-f] [-n] [-o <i>output_file</i>]
+<i>input_file</i></code><p>
+Where:
+<ul>
+<code>-b</code>
+<ul>
+Create a (binary) netCDF file.  If the <code>-o</code> option is
+absent, a default file name will be constructed from the netCDF name
+(specified after the netcdf keyword in the input) by appending the
+<code>.nc</code> extension.  If a file already exists with the
+specified name, it will be overwritten.
+</ul>
+
+<p>
+<code>-c</code>
+<ul>
+Generate C source code that will create a netCDF file matching the
+netCDF specification.  The C source code is written to standard
+output.
+</ul>
+
+<p> 
+<code>-f</code> 
+<ul>
+Generate Fortran source code that will
+create a netCDF file matching the netCDF specification.  The Fortran
+source code is written to standard output.  
+</ul>
+
+<p> 
+<code>-o <i>outputfile</i></code>
+<ul>
+Name for the netCDF file created.  If this option is specified, it
+implies the <code>-b</code> option.  (This option is necessary because
+netCDF files cannot be written directly to standard output, since
+standard output is not seekable.)
+</ul>
+
+<p>
+<code>-n</code>
+<ul>
+Like <code>-b</code> option, except creates netCDF file with the
+obsolete <code>.cdf</code> extension instead of the <code>.nc</code>
+extension, in the absence of an output filename specified by the
+<code>-O</code> option.  This option is only supported for backward
+compatibility.
+</ul>
+</ul>
+
+<p>
+<b>Examples</b>
+<ol>
+<li>Check the syntax of the CDL file <code>foo.cdl</code>:<p>
+<dd><code>ncgen foo.cdl</code><p>
+<li>
+From the CDL file <code>foo.cdl</code>, generate an  equivalent  binary
+     netCDF file named <code>x.nc</code>:<p>
+<dd><code>ncgen -o x.nc foo.cdl</code><p>
+<li>
+From the CDL file <code>foo.cdl</code>, generate a C program containing
+     the  netCDF  function  invocations  necessary  to  create an
+     equivalent binary netCDF file named <code>x.nc</code>:<p>
+<dd><code>ncgen -c -o x.nc foo.cdl</code></ol>
+
+
+</body>
+</html>
diff --git a/doc/gradutilstnmap.html b/doc/gradutilstnmap.html
new file mode 100644
index 0000000..781b7d1
--- /dev/null
+++ b/doc/gradutilstnmap.html
@@ -0,0 +1,94 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<title>GrADS Utilities: stnmap</title>
+
+<body bgcolor="e0f0ff" text="000000">
+<h2><a name="stnmap">stnmap</a></h2>
+<code>stnmap [-i <i>fname</i>] [-0]</code>
+
+<p>
+<code>stnmap</code> is an external GrADS utility that writes out a
+hash table and/or link list information for station data that allows
+GrADS to access the data more efficiently. After a station data set
+has been written and the accompanying data descriptor file has been
+created, you must run the <code>stnmap</code> utility before you can
+look at the data in GrADS.
+
+<p>
+The <code>stnmap</code> options are as follows: 
+<ul>
+<code><i>fname</i></code>
+<ul>The name of the station data descriptor file. If not specified, 
+<code>stnmap</code> will prompt the user.</ul>
+<p>
+<code>-0</code>
+<ul>Allows processing of certain templated station data sets without 
+actually reading the data.</ul>
+</ul>
+
+<p>
+The output from <code>stnmap</code> goes into a file that is named in the
+<code>STNMAP</code> record of the data descriptor file. (See Usage Note #2).
+
+<p>
+<b>Usage Notes</b>
+<ol>
+<li>If you change the data file (perhaps by appending another time group),
+you will also have to change the descriptor file to reflect the
+changes and then rerun the <code>stnmap</code> utility.
+<p>
+<li>Note the difference between required records in a station descriptor
+file and a grid descriptor file:
+<p>
+<code>DTYPE</code>
+<ul>specifies a data type of: station</ul>
+<code>STNMAP</code>
+<ul>gives the file name of the station mapping file</ul>
+<code>XDEF, YDEF, ZDEF</code>
+<ul>these records are not specified in a station data control file</ul>
+<code>TDEF</code>
+<ul>describes the time grouping interval and the number of the time groups in the file</ul>
+<code>VARS</code>
+<ul>
+surface variables are listed first, and show a "0" for the
+number-of-levels field. Level-dependent variables are listed after the
+surface variables, and show a "1" in the number-of-levels
+field.
+</ul>
+</ol>
+<p>
+<b>Examples</b>
+<p>
+Here's a sample descriptor file <code>stat.ctl</code> for station data set <code>ua.reps</code>:
+<ul>
+<code>
+DSET   ^ua.reps<br>
+DTYPE  station<br>
+STNMAP ^ua.map<br>
+UNDEF  -999.0<br>
+TITLE  Real Time Upper air obs<br>
+TDEF   10 linear 12z18jan1992 12hr<br>
+VARS   8<br>
+  slp 0  99  SLP<br>
+  ts  0  99  Temps<br>
+  us  0  99  U Winds<br>
+  vs  0  99  V Winds<br>
+  z   1  99  Heightsa<br>
+  t   1  99  Temps<br>
+  u   1  99  U Winds<br>
+  v   1  99  V WInds<br>
+ENDVARS<br>
+</code>
+</ul>
+
+<p>
+Run the <code>stnmap</code> utility:
+<ul><code>stnmap -i stat.ctl</code></ul>
+<p>
+The station map file <code>ua.map</code> is a
+binary file, which includes the hash table and/or link list
+information.
+
+</body>
+</html>
diff --git a/doc/graphelem.html b/doc/graphelem.html
new file mode 100644
index 0000000..dbf46fd
--- /dev/null
+++ b/doc/graphelem.html
@@ -0,0 +1,46 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Drawing Basic Graphics Elements with GrADS</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>Drawing Basic Graphics Elements with GrADS</b></h2>
+
+<p>
+Various commands are provided to display and customize various basic
+graphics elements: strings, labels, lines, marks, rectangles,
+polygons, etc. These graphics commands enable you to enhance your data
+plot by adding customized "artwork". They may also be used
+to create a map-based diagram with no data plot involved.
+
+<p>
+<h3>Drawing Commands</h3>
+<ul>
+<a href="gradcomddrawmap.html">draw map</a><br>
+<a href="gradcomddrawxlab.html">draw xlab</a><br>
+<a href="gradcomddrawylab.html">draw ylab</a><br>
+<a href="gradcomddrawstring.html">draw string</a><br>
+<a href="gradcomddrawline.html">draw line</a><br>  
+<a href="gradcomddrawrec.html">draw rec</a><br>  
+<a href="gradcomddrawrecf.html">draw recf</a><br>
+<a href="gradcomddrawmark.html">draw mark</a><br>  
+<a href="gradcomddrawpolyf.html">draw polyf</a><br>
+<a href="gradcomddrawwxsym.html">draw wxsym</a><br>
+</ul>
+<p>
+<h3>Controlling drawing commands</h3>
+<ul>
+<a href="gradcomdsetfont.html">set font</a><br> 
+<a href="gradcomdsetline.html">set line</a><br> 
+<a href="gradcomdsetstring.html">set string</a><br> 
+<a href="gradcomdsetstrsiz.html">set strsiz</a><br> 
+<a href="gradcomdsetrgb.html">set rgb</a><br>
+<a href="gradcomdsetclip.html">set clip</a><br>
+</ul>
+
+
+</body>
+</html>
+
diff --git a/doc/graphics.html b/doc/graphics.html
new file mode 100644
index 0000000..993d15f
--- /dev/null
+++ b/doc/graphics.html
@@ -0,0 +1,48 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h1>Graphics Primitives</h1>
+
+Various commands are provided to allow control and display of
+various graphics primitives:  These enable you to enhance your
+data plot by adding customised "artwork".  Alternatively, you can
+use these commands to create, for example, a map-based diagram
+with no data plot involved.<p>
+
+<h2><u>Drawing Commands</u></h2>
+<ul>
+<a href="gradcomddrawmap.html">draw map</a><br>
+<a href="gradcomddrawxlab.html">draw xlab</a><br>
+<a href="gradcomddrawylab.html">draw ylab</a><br>
+<a href="gradcomddrawstring.html">draw string</a><br>
+<a href="gradcomddrawline.html">draw line</a><br>  
+<a href="gradcomddrawrec.html">draw rec</a><br>  
+<a href="gradcomddrawrecf.html">draw recf</a><br>
+<a href="gradcomddrawmark.html">draw mark</a><br>  
+<a href="gradcomddrawpolyf.html">draw polyf</a><br>
+<a href="gradcomddrawwxsym.html">draw wxsym</a><br></ul>
+<br>
+<h2><u>Controlling drawing commands</u></h2>
+<ul>
+<a href="gradcomdsetfont.html">set font</a><br> 
+<a href="gradcomdsetline.html">set line</a><br> 
+<a href="gradcomdsetstring.html">set string</a><br> 
+<a href="gradcomdsetstrsiz.html">set strsiz</a><br> 
+<a href="gradcomdsetrgb.html">set rgb</a><br></ul><br>
+
+<h2><u>Plot clipping</u></h2>
+<ul>
+You may specify a clipping area for drawing graphics primitives
+such as lines and strings.  When you do a <a
+href="gradcomddisplay.html"><code>display</code></a> command, GrADS
+sets the clipping region to the parea, draws the graphic, then
+sets the clipping region to the entire page.  Even if you have
+set the clipping region, a display command will reset it to the
+entire page.  To clip the display of the various draw commands:<p>
+
+<dd><code><a href="gradcomdsetclip.html">set clip</a> xlo xhi ylo yhi</code><p>
+
+where <code>xlo,xhi,ylo,yhi</code> are the clipping coordinates in real page
+inches.
+</ul>
+
+
diff --git a/doc/grib.html b/doc/grib.html
new file mode 100644
index 0000000..6a58589
--- /dev/null
+++ b/doc/grib.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
<style type="text/css">
<!--
.style1 {color: #009900}
.style3 {color: #006666}
.style4 {color: #CC6633}
.style5 {color: #9900FF}
.style6 {color: #FF0000}
.style9 {color: #FF6666}
.style10 {color: #FF9900}
.style13 {color: #3300FF}
.style15 {color: #993300}
body {
	background-color: #e0f0ff;
}
-->
</style>


<h2>Handling GRIB in GrADS</h2>
<h4>
  <a href="#what">What is GRIB?</a><br>
  <a href="#handling">How to read GRIB data with GrADS</a><br>
  <a href="#example">An Example</a><br>
  <a href="#grib2">Comments on GRIB2</a><br />
  <a href="#summary">Summary</a><br>
</h4>
<hr>
<h3><br>
</h3>
<h3>Introduction</h3>


One of the most powerful features of GrADS is its ability to work
directly with GRIB data, versions 1 and 2. Grads version 2.0 is required to handle GRIB2. The interfaces for GRIB and GRIB2 are similar, but not identical -- they are treated as separate data types. This documentation page will attempt to provide the required understanding to use
GRIB data in GrADS.
</ul>
<p>

<a name="what">
<h3>What is GRIB?</h3>
</a>

<p>GRIB (General Regularly-distributed Information in Binary form) is an international, public, binary format
  for the efficient storage of meteorological/oceanographic
  variables and the metadata that describe them.  GRIB2 is similar to GRIB, but has a more complex set of header fields for the metadata, and also offers data compression that can significantly reduce file size. A GRIB data file typically consists of a collection of records. Each GRIB record contains a  2-D
  (lon,lat) grid of data at a particular time and vertical level. A 4-D GRIB data set is a collection of 2-D records that span a range of times and vertical levels. GRIB2 records may also contain ensemble information, creating a 5-D data set. A GRIB record is a self-describing data object -- each record contains not only the data, but also the metadata to describe the spatial grid, the valid time, the vertical level, and any ensemble metadata (for GRIB2 only). GRIB records may be concaten [...]
<p>
<a name="handling">
<h3>How to read GRIB data with GrADS </h3>
</a>
 <p>In order to display GRIB data in GrADS, the collection of records must be sorted and placed into the internal 4- or 5-D gridded data model. This is accomplished by the use of a GrADS data descriptor file and a separate index file, which maps the position of the GRIB records in the data file into their proper place in the 4- or 5-D grid environment. The general idea is to scan through the metadata in all the records, collecting information about the lat/lon grid, the list of vertical l [...]
 <p>The scanning of the metadata in each record is done by the several external utilities: <a href="gradutilgribscan.html">gribscan</a> and <a href="gradutilgrib2scan.html">grib2scan</a> (which are supported by COLA, as part of GrADS) and <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib.html" target="_parent">wgrib</a> and <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/" target="_parent">wgrib2</a> (which are supported by Wesley Ebisuzaki at NOAA). The scanning ut [...]
 <p><a name="example" id="example"></a></p>
 <h3>An Example (for GRIB1)</h3>
 <code>
# wgrib <a href="sample.grib">sample.grib</a>   <br />
1:0:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=0:TimeU=1:1000 mb:<span class="style6">anl</span>:NAve=0<br />
2:81534:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=0:TimeU=1:1000 mb:<span class="style6">anl</span>:NAve=0<br />
3:154922:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=0:TimeU=1:850 mb:<span class="style6">anl</span>:NAve=0<br />
4:236456:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=0:TimeU=1:850 mb:<span class="style6">anl</span>:NAve=0<br />
5:317990:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=0:TimeU=1:500 mb:<span class="style6">anl</span>:NAve=0<br />
6:399524:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=0:TimeU=1:500 mb:<span class="style6">anl</span>:NAve=0<br />
7:489202:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=0:TimeU=1:200 mb:<span class="style6">anl</span>:NAve=0<br />
8:578880:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=0:TimeU=1:200 mb:<span class="style6">anl</span>:NAve=0<br />
9:660414:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=6:TimeU=1:1000 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
10:741948:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=6:TimeU=1:1000 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
11:815336:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=6:TimeU=1:850 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
12:896870:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=6:TimeU=1:850 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
13:978404:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=6:TimeU=1:500 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
14:1059938:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=6:TimeU=1:500 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
15:1141472:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=6:TimeU=1:200 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
16:1231150:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=6:TimeU=1:200 mb:<span class="style9">6hr fcst</span>:NAve=0<br />
17:1312684:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=12:TimeU=1:1000 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
18:1394218:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">1000</span>:TR=10:P1=0:P2=12:TimeU=1:1000 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
19:1467606:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=12:TimeU=1:850 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
20:1549140:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">850</span>:TR=10:P1=0:P2=12:TimeU=1:850 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
21:1630674:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=12:TimeU=1:500 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
22:1712208:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">500</span>:TR=10:P1=0:P2=12:TimeU=1:500 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
23:1793742:d=<span class="style5">04040200</span>:<span class="style1">UGRD</span>:kpds5=<span class="style1">33</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=12:TimeU=1:200 mb:<span class="style10">12hr fcst</span>:NAve=0<br />
24:1883420:d=<span class="style5">04040200</span>:<span class="style3">VGRD</span>:kpds5=<span class="style3">34</span>:kpds6=<span class="style13">100</span>:kpds7=<span class="style4">200</span>:TR=10:P1=0:P2=12:TimeU=1:200 mb:<span class="style10">12hr fcst</span>:NAve=0
</code>
 <p>The wgrib output reveals that the sample.grib file contains 24 records. There are  two variables: <span class="style1">UGRD</span> and <span class="style3">VGRD</span>; there are four pressure levels: <span class="style4">1000</span>, <span class="style4">850</span>, <span class="style4">500</span>, and <span class="style4">200</span>; there are three times: <span class="style6">00hr analysis</span>, <span class="style9">6hr forecast</span>, and <span class="style10">12hr forecast</sp [...]
 <p>
 <code>
# wgrib -V -d 1 sample.grib<br />
rec 1:0:date 2004040200 UGRD kpds5=33 kpds6=100 kpds7=1000 levels=(3,232) grid=3 1000 mb anl:<br />
UGRD=u wind [m/s]<br />
timerange 10 P1 0 P2 0 TimeU 1  nx 360 ny 181 GDS grid 0 num_in_ave 0 missing 0<br />
center 7 subcenter 0 process 81 Table 2<br />
latlon: lat  90.000000 to -90.000000 by 1.000000  nxny 65160<br />
long 0.000000 to -1.000000 by 1.000000, (<span class="style15">360</span> x <span class="style15">181</span>) scan 0 mode 128 bdsgrid 1<br />
min/max data -24.8 29.3  num bits 10  BDS_Ref -248  DecScale 1 BinScale 0
</code>
<p>Now we can use this information to put together  the  descriptor file (<a href="sample.ctl">sample.ctl</a>):
<p>  <code>
  dset ^sample.grib<br />
  index ^sample.idx<br />
  title sample grib file<br />
  dtype grib <br />
  options yrev<br />undef 9.999E+20<br />
  XDEF <span class="style15">360</span> linear 0.0 1.0<br />
  YDEF <span class="style15">181</span> linear -90.0 1<br />
  ZDEF 4 levels 1000 850 500 200<br />
  TDEF 3 linear 00Z02apr2004 6hr<br />
  VARS 2<br />
  u  4  <span class="style1">33</span>,<span class="style13">100</span>   u wind [m/s]<br />v  4  <span class="style3">34</span>,<span class="style13">100</span>   v wind [m/s]<br />
  ENDVARS
</code>
<p>Notes: <br />
The name of the index file name can be anything at all, here we choose a filename similar to the data file, but with a .idx extension. The options yrev is needed because the grid is written from north to south (90 to -90), but the GrADS default is the opposite, so we need to tell GrADS to turn the grid upside down. For GRIB, the undef value is arbitrary, but required by GrADS. The XDEF and YDEF entries are based on the info from the verbose wgrib output. The ZDEF and TDEF entries are base [...]
<p>The final step is to run gribmap to create the index file. Gribmap looks at the metadata in each and every record in the GRIB file and compares it to the information in the descriptor file. If the record contains a variable at a vertical level at a time that fits into the grid described by the descriptor file, then it is declared a "MATCH" and a the file position of that record is recorded: </p>
<p><code>
# gribmap -v -i sample.ctl <br />
grib1map:  opening GRIB file: sample.grib  <br />
!!!!! MATCH:      1        81534   0  3     1    0   33 100         1000              79   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      2      154922   0  3     1    0   34 100         1000        81613   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      3      236456   0  3     1    0   33 100          850       155001   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      4      317990   0  3     1    0   34 100          850       236535   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      5      399524   0  3     1    0   33 100          500       318069   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      6      489202   0  3     1    0   34 100          500       399603   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      7      578880   0  3     1    0   33 100          200       489281   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      8      660414   0  3     1    0   34 100          200       578959   0 btim: 2004040200:00 tau:       0 dtim: 2004040200:00<br/>
!!!!! MATCH:      9      741948   0  3     1    0   33 100         1000      660493   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    10      815336   0  3     1    0   34 100         1000      742027   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    11      896870   0  3     1    0   33 100          850       815415   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    12      978404   0  3     1    0   34 100          850       896949   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    13    1059938   0  3     1    0   33 100          500       978483   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    14    1141472   0  3     1    0   34 100          500     1060017   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    15    1231150   0  3     1    0   33 100          200     1141551   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    16    1312684   0  3     1    0   34 100          200     1231229   0 btim: 2004040200:00 tau:       6 dtim: 2004040206:00<br/>
!!!!! MATCH:    17    1394218   0  3     1    0   33 100         1000    1312763   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    18    1467606   0  3     1    0   34 100         1000    1394297   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    19    1549140   0  3     1    0   33 100          850     1467685   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    20    1630674   0  3     1    0   34 100          850     1549219   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    21    1712208   0  3     1    0   33 100          500     1630753   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    22    1793742   0  3     1    0   34 100          500     1712287   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    23    1883420   0  3     1    0   33 100          200     1793821   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
!!!!! MATCH:    24    1973098   0  3     1    0   34 100          200     1883499   0 btim: 2004040200:00 tau:     12 dtim: 2004040212:00<br/>
 grib1map:  reached end of files<br/>
 grib1map:  writing the map...
</code></p>
<p>

Success!  Each record in the GRIB file has been mapped
to a variable, level, and time in the descriptor file. Note that  failure to match will not lead to an error in GrADS; if a grib record at a particular time or level is missing,  GrADS will return a grid
with "undefined" values on display. 
<p><a name="grib2" id="grib2"></a>

<h3>Comments on GRIB2</h3>
<p>The procedure for handling GRIB2 in GrADS is essentially the same as it is for GRIB1. However, GRIB2 is treated as a separate data type, so you need to change the DTYPE entry in your descriptor file. There are some keywords for the OPTIONS entry that are only valid for GRIB2 (e.g. "pascals"), and the  "yrev" option is not necessary with GRIB2, since the north-south orientation of the grid is contained in the header metadata, so GrADS can figure that one out on its o [...]
<p><a name="summary" id="summary"></a>
<h3>
  
  Summary<br>
</h3>
<ol>
<li>Scan the GRIB files (with <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib.html" target="_parent">wgrib</a> / <a href="http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/" target="_parent">wgrib2</a> / <a href="gradutilgribscan.html">gribscan</a> / <a href="gradutilgrib2scan.html">grib2scan</a>) to see what's in them.
<li>Construct a descriptor file manually (or use <a href="http://www.cpc.ncep.noaa.gov/products/wesley/grib2ctl.html" target="_parent">grib2ctl</a> / <a href="http://www.cpc.ncep.noaa.gov/products/wesley/g2ctl.html" target="_parent">g2ctl</a>). 
<li>Run <a href="gradutilgribmap.html">gribmap</a> in
verbose
mode (<code>-v</code>) to map the GRIB records to the 4- or 5-D grid
structure in the descriptor file and create the index file.
</ol>

The work required for step #2 is not necessarily easy. But the advantage of reading GRIB data directly without converting it to another format is worth the effort. 
The output from grib2ctl / g2ctl may be a good first guess for your descriptor file that will need some tweaking (by examinging  the wgrib output) to make sure you match every record. Of course, there's also the option to describe only those variables (or levels) that are of interest to you, in which case you are not required to match every record.
\ No newline at end of file
diff --git a/doc/grib_levels.html b/doc/grib_levels.html
new file mode 100644
index 0000000..b041eac
--- /dev/null
+++ b/doc/grib_levels.html
@@ -0,0 +1,410 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GRIB Vertical Levels</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../../assets/NewIGES.css">
+</head>
+
+<body bgcolor="#FFFFFF">
+<p class="plaintextbold">TABLE 3: VERTICAL LEVELS</p>
+<table border="1" cellspacing="0" cellpadding="3">
+  <tr>
+    <td width="48" class="plaintext" valign="top">VALUE</td>
+    <td width="220" class="plaintext" valign="top">DESCRIPTION</td>
+    <td align="center" colspan="2" class="plaintext">REQUIRED PARAMETERS</td>
+    <td width="61" class="plaintext" valign="top">ABBREV.</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">0-99</td>
+    <td width="220" class="plaintext" valign="top">Special Codes </td>
+    <td align="center" colspan="2" class="plaintext">(See Table 3a below)</td>
+    <td width="61" class="plaintext" valign="top"> </td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">100</td>
+    <td width="220" class="plaintext" valign="top">Isobaric level</td>
+    <td align="center" colspan="2" class="plaintext">Pressure in hPa (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">ISBL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">101</td>
+    <td width="220" class="plaintext" valign="top">Layer between two isobaric 
+      levels</td>
+    <td width="167" align="center" class="plaintext">Pressure of top <br>
+      in kPa</td>
+    <td width="167" align="center" class="plaintext">Pressure of bottom <br>
+      in kPa</td>
+    <td width="61" class="plaintext" valign="top"> </td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">102</td>
+    <td width="220" class="plaintext" valign="top">Mean sea level</td>
+    <td align="center" width="167" class="plaintext">0</td>
+    <td align="center" width="167" class="plaintext">0</td>
+    <td width="61" class="plaintext" valign="top">MSL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">103</td>
+    <td width="220" class="plaintext" valign="top">Specified altitude above MSL</td>
+    <td align="center" colspan="2" class="plaintext">Altitude in meters</td>
+    <td width="61" class="plaintext" valign="top">GPML</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">104</td>
+    <td width="220" class="plaintext" valign="top">Layer between two specified 
+      altitudes above MSL</td>
+    <td align="center" width="167" class="plaintext">Altitude of top <br>
+      in hm</td>
+    <td align="center" width="167" class="plaintext">Altitude of bottom <br>
+      in hm</td>
+    <td width="61" class="plaintext" valign="top">GPMY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">105</td>
+    <td width="220" class="plaintext" valign="top">Specified height level above 
+      ground</td>
+    <td align="center" colspan="2" class="plaintext">Height in meters</td>
+    <td width="61" class="plaintext" valign="top">TGL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">106</td>
+    <td width="220" class="plaintext" valign="top">Layer between two specified 
+      height levels above ground</td>
+    <td align="center" class="plaintext" width="167">Height of top <br>
+      in hm</td>
+    <td align="center" class="plaintext" width="167">Height of bottom <br>
+      in hm</td>
+    <td width="61" class="plaintext" valign="top">HTGY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">107</td>
+    <td width="220" class="plaintext" valign="top">Sigma level</td>
+    <td align="center" colspan="2" class="plaintext">Sigma value in 1/10000 (2 
+      octets)</td>
+    <td width="61" class="plaintext" valign="top">SIGL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">108</td>
+    <td width="220" class="plaintext" valign="top">Layer between two sigma levels</td>
+    <td align="center" class="plaintext" width="167">Sigma value at top<br>
+      in 1/100</td>
+    <td align="center" class="plaintext" width="167">Sigma value at bottom <br>
+      in 1/100</td>
+    <td width="61" class="plaintext" valign="top">SIGY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">109</td>
+    <td width="220" class="plaintext" valign="top">Hybrid level</td>
+    <td align="center" colspan="2" class="plaintext">Level number (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">HYBL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">110</td>
+    <td width="220" class="plaintext" valign="top">Layer between two hybrid levels</td>
+    <td align="center" class="plaintext" width="167">Level number of top</td>
+    <td align="center" class="plaintext" width="167">Level number of bottom</td>
+    <td width="61" class="plaintext" valign="top">HYBY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">111</td>
+    <td width="220" class="plaintext" valign="top">depth below land surface</td>
+    <td align="center" colspan="2" class="plaintext">Depth in cm (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">DBLL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">112</td>
+    <td width="220" class="plaintext" valign="top">Layer between two depths below 
+      land surface</td>
+    <td align="center" class="plaintext" width="167"> 
+      <p>Depth of upper surface<br>
+        in cm</p>
+    </td>
+    <td align="center" class="plaintext" width="167"> 
+      <p>Depth of lower surface<br>
+        in cm</p>
+    </td>
+    <td width="61" class="plaintext" valign="top">DBLY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">113</td>
+    <td width="220" class="plaintext" valign="top">Isentropic (theta) level</td>
+    <td align="center" colspan="2" class="plaintext">Potential temperature in 
+      K</td>
+    <td width="61" class="plaintext" valign="top">THEL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">114</td>
+    <td width="220" class="plaintext" valign="top">Layer between two isentropic 
+      levels</td>
+    <td align="center" class="plaintext" width="167"> 
+      <p>475 K minus theta of top <br>
+        in K</p>
+    </td>
+    <td align="center" class="plaintext" width="167">475 K minus theta of bottom 
+      in K</td>
+    <td width="61" class="plaintext" valign="top">THEY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">115</td>
+    <td width="220" class="plaintext" valign="top">Level at specified pressure 
+      difference from ground</td>
+    <td align="center" colspan="2" class="plaintext">Pressure difference in hPa 
+      (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">SPDL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">116</td>
+    <td width="220" class="plaintext" valign="top">Layer between two levels at 
+      specified pressure difference from ground</td>
+    <td align="center" class="plaintext" width="167">Pressure difference from 
+      ground to top in hPa</td>
+    <td align="center" class="plaintext" width="167">Pressure difference from 
+      ground to bottom in hPa</td>
+    <td width="61" class="plaintext" valign="top">SPDY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">117</td>
+    <td width="220" class="plaintext" valign="top">Potential vorticity surface</td>
+    <td align="center" colspan="2" class="plaintext">Potential vorticity value 
+      in units of 10<sup>-6</sup> K m<sup>2</sup>/kg s</td>
+    <td width="61" class="plaintext" valign="top">PVL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">119</td>
+    <td width="220" class="plaintext" valign="top">ETA level</td>
+    <td align="center" colspan="2" class="plaintext">ETA value in 1/1000 (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">ETAL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">120</td>
+    <td width="220" class="plaintext" valign="top">Layer between two ETA levels</td>
+    <td align="center" class="plaintext" width="167">ETA value at top<br>
+      in 1/100</td>
+    <td align="center" class="plaintext" width="167">ETA value at bottom <br>
+      in 1/100</td>
+    <td width="61" class="plaintext" valign="top">ETAY</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">121</td>
+    <td width="220" class="plaintext" valign="top">Layer between two isobaric 
+      surfaces (high precision)</td>
+    <td align="center" class="plaintext" width="167">1100 minus pressure of <br>
+      top in hPa</td>
+    <td align="center" class="plaintext" width="167">1100 minus pressure of<br>
+      bottom in hPa</td>
+    <td width="61" class="plaintext" valign="top">IBYH</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">125</td>
+    <td width="220" class="plaintext" valign="top">Specified height level above 
+      ground (high precision) <br>
+    </td>
+    <td align="center" colspan="2" class="plaintext">Height in cm (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">HGLH</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">128</td>
+    <td width="220" class="plaintext" valign="top">Layer between two sigma levels 
+      (high precision) <br>
+    </td>
+    <td align="center" class="plaintext" width="167">1.1 minus sigma of top <br>
+      in 1/1000 of sigma</td>
+    <td align="center" class="plaintext" width="167">1.1 minus sigma of bottom 
+      <br>
+      in 1/1000 of sigma</td>
+    <td width="61" class="plaintext" valign="top">SGYH</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">141</td>
+    <td width="220" class="plaintext" valign="top">Layer between two isobaric 
+      surfaces (mixed precision)</td>
+    <td align="center" class="plaintext" width="167">Pressure of top in hPa</td>
+    <td align="center" class="plaintext" width="167">1100 minus pressure of bottom 
+      in hPa</td>
+    <td width="61" class="plaintext" valign="top">IBYM</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">160</td>
+    <td width="220" class="plaintext" valign="top">Depth below sea level</td>
+    <td align="center" colspan="2" class="plaintext">Depth in m (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">DBSL</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">200</td>
+    <td width="220" class="plaintext" valign="top">Entire atmosphere </td>
+    <td align="center" colspan="2" class="plaintext">0 (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">EATM</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">201</td>
+    <td width="220" class="plaintext" valign="top">Entire ocean</td>
+    <td align="center" colspan="2" class="plaintext">0 (2 octets)</td>
+    <td width="61" class="plaintext" valign="top">EOCN</td>
+  </tr>
+  <tr> 
+    <td width="48" class="plaintext" valign="top">204-244</td>
+    <td width="220" class="plaintext" valign="top">NCEP Special Levels & Layers</td>
+    <td align="center" colspan="2" class="plaintext">See Table 3a</td>
+    <td width="61" class="plaintext" valign="top"> </td>
+  </tr>
+</table>
+<p class="plaintextbold">TABLE 3a: SPECIAL VERTICAL LEVELS</p>
+<table width="486" border="1" cellspacing="0" cellpadding="2">
+  <tr>
+    <td width="47" class="plaintext">VALUE</td>
+    <td width="357" class="plaintext">DESCRIPTION</td>
+    <td width="62" class="plaintext">ABBREV.</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">00 </td>
+    <td width="357" class="plaintext">Reserved</td>
+    <td width="62" class="plaintext"> </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">01 </td>
+    <td width="357" class="plaintext">Ground or water surface </td>
+    <td width="62" class="plaintext">SFC </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">02 </td>
+    <td width="357" class="plaintext">Cloud base level </td>
+    <td width="62" class="plaintext">CBL</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">03</td>
+    <td width="357" class="plaintext">Cloud top level</td>
+    <td width="62" class="plaintext"> CTL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">04 </td>
+    <td width="357" class="plaintext">Level of 0 deg (C) isotherm </td>
+    <td width="62" class="plaintext">0DEG </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">05</td>
+    <td width="357" class="plaintext">Level of adiabatic condensation lifted from 
+      the surface </td>
+    <td width="62" class="plaintext">ADCL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext"> 06</td>
+    <td width="357" class="plaintext">Maximum wind level </td>
+    <td width="62" class="plaintext">MWSL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">07</td>
+    <td width="357" class="plaintext">Tropopause </td>
+    <td width="62" class="plaintext">TRO</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext"> 08 </td>
+    <td width="357" class="plaintext">Nominal top of atmosphere </td>
+    <td width="62" class="plaintext">NTAT </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">09</td>
+    <td width="357" class="plaintext">Sea bottom </td>
+    <td width="62" class="plaintext">SEAB </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">10-19 </td>
+    <td width="357" class="plaintext">Reserved </td>
+    <td width="62" class="plaintext"> </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">20 </td>
+    <td width="357" class="plaintext">Isothermal level (temperature in 1/100 K 
+      in octets 11 and 12) </td>
+    <td width="62" class="plaintext">TMPL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">21-99</td>
+    <td width="357" class="plaintext">Reserved </td>
+    <td width="62" class="plaintext"> </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">204</td>
+    <td width="357" class="plaintext">Highest tropospheric freezing level </td>
+    <td width="62" class="plaintext">HTFL</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">209 </td>
+    <td width="357" class="plaintext">Boundary layer cloud bottom level </td>
+    <td width="62" class="plaintext">BCBL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">210 </td>
+    <td width="357" class="plaintext">Boundary layer cloud top level </td>
+    <td width="62" class="plaintext">BCTL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">211 </td>
+    <td width="357" class="plaintext">Boundary layer cloud layer </td>
+    <td width="62" class="plaintext">BCY </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">212 </td>
+    <td width="357" class="plaintext">Low cloud bottom level </td>
+    <td width="62" class="plaintext">LCBL</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">213</td>
+    <td width="357" class="plaintext"> Low cloud top level </td>
+    <td width="62" class="plaintext">LCTL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">214 </td>
+    <td width="357" class="plaintext">Low cloud layer</td>
+    <td width="62" class="plaintext"> LCY </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">222</td>
+    <td width="357" class="plaintext">Middle cloud bottom level </td>
+    <td width="62" class="plaintext">MCBL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">223 </td>
+    <td width="357" class="plaintext">Middle cloud top level </td>
+    <td width="62" class="plaintext">MCTL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">224 </td>
+    <td width="357" class="plaintext">Middle cloud layer </td>
+    <td width="62" class="plaintext">MCY</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">232 </td>
+    <td width="357" class="plaintext">High cloud bottom level </td>
+    <td width="62" class="plaintext">HCBL</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">233</td>
+    <td width="357" class="plaintext">High cloud top level </td>
+    <td width="62" class="plaintext">HCTL</td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">234 </td>
+    <td width="357" class="plaintext">High cloud layer </td>
+    <td width="62" class="plaintext"> HCY </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">242 </td>
+    <td width="357" class="plaintext">Convective cloud bottom level </td>
+    <td width="62" class="plaintext">CCBL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">243 </td>
+    <td width="357" class="plaintext">Convective cloud top level </td>
+    <td width="62" class="plaintext">CCTL </td>
+  </tr>
+  <tr> 
+    <td width="47" class="plaintext">244</td>
+    <td width="357" class="plaintext">Convective cloud layer </td>
+    <td width="62" class="plaintext">CCY </td>
+  </tr>
+</table>
+<p> </p><p> </p>
+</body>
+</html>
diff --git a/doc/grib_parameters.html b/doc/grib_parameters.html
new file mode 100644
index 0000000..5e5f45b
--- /dev/null
+++ b/doc/grib_parameters.html
@@ -0,0 +1,1595 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GRIB Parameter Table</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="../../assets/NewIGES.css">
+</head>
+
+<body bgcolor="#FFFFFF">
+<p class="plaintextbold">TABLE 2: PARAMETERS & UNITS (Version 2) (PDS Octet 
+  9)</p>
+<table border="1" cellspacing="0" cellpadding="2">
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">VALUE</td>
+    <td width="385" class="plaintext">PARAMETER (<b><a href="#notes">*</a></b> 
+      means see <a href="#notes">Notes</a> at bottom of table)</td>
+    <td width="92" class="plaintext" valign="top">UNITS</td>
+    <td width="77" class="plaintext" valign="top">ABBREV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">000</td>
+    <td width="385" class="plaintext">Reserved</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top"> </td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">001</td>
+    <td width="385" class="plaintext">Pressure</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">PRES</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">002</td>
+    <td width="385" class="plaintext">Pressure Reduced to Mean Sea Level</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">PRMSL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">003</td>
+    <td width="385" class="plaintext">Pressure Tendency</td>
+    <td width="92" class="plaintext" valign="top">Pa/s</td>
+    <td width="77" class="plaintext" valign="top">PTEND</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">004</td>
+    <td width="385" class="plaintext">Potential Vorticity</td>
+    <td width="92" class="plaintext" valign="top">K m<sup>2</sup>/kg s</td>
+    <td width="77" class="plaintext" valign="top">PVORT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">005</td>
+    <td width="385" class="plaintext">ICAO Standard Atmosphere Reference Height</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">ICAHT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">006</td>
+    <td width="385" class="plaintext">Geopotential</td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">GP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">007</td>
+    <td width="385" class="plaintext">Geopotential Height</td>
+    <td width="92" class="plaintext" valign="top">gpm</td>
+    <td width="77" class="plaintext" valign="top">HGT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">008</td>
+    <td width="385" class="plaintext">Geometric Height</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">DIST</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">009</td>
+    <td width="385" class="plaintext">Standard Deviation of Height</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">HSTDV </td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">010</td>
+    <td width="385" class="plaintext">Total Ozone </td>
+    <td width="92" class="plaintext" valign="top">Dobson </td>
+    <td width="77" class="plaintext" valign="top">TOZNE </td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">011</td>
+    <td width="385" class="plaintext">Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TMP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">012</td>
+    <td width="385" class="plaintext">Virtual Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">VTMP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">013</td>
+    <td width="385" class="plaintext">Potential Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">POT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">014</td>
+    <td width="385" class="plaintext">Pseudo-Adiabatic Potential Temperature or 
+      <br>
+      Equivalent Potential Temperature </td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">EPOT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">015</td>
+    <td width="385" class="plaintext">Maximum Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TMAX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">016</td>
+    <td width="385" class="plaintext">Minimum Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TMIN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">017</td>
+    <td width="385" class="plaintext">Dew Point Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">DPT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">018</td>
+    <td width="385" class="plaintext">Dew Point Depression (or Deficit)</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">DEPR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">019</td>
+    <td width="385" class="plaintext">Lapse Rate</td>
+    <td width="92" class="plaintext" valign="top">K/m</td>
+    <td width="77" class="plaintext" valign="top">LAPR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">020</td>
+    <td width="385" class="plaintext">Visibility</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">VIS</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">021</td>
+    <td width="385" class="plaintext">Radar Spectra (1) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">RDSP1</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">022</td>
+    <td width="385" class="plaintext">Radar Spectra (2) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">RDSP2</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">023</td>
+    <td width="385" class="plaintext">Radar Spectra (3) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">RDSP3</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">024</td>
+    <td width="385" class="plaintext">Parcel Lifted Index (to 500 hPa)</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">PLI</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">025</td>
+    <td width="385" class="plaintext">Temperature Anomaly</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TMPA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">026</td>
+    <td width="385" class="plaintext">Pressure Anomaly</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">PRESA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">027</td>
+    <td width="385" class="plaintext">Geopotential Height Anomaly</td>
+    <td width="92" class="plaintext" valign="top">gpm</td>
+    <td width="77" class="plaintext" valign="top">GPA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">028</td>
+    <td width="385" class="plaintext">Wave Spectra (1) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">WVSP1</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">029</td>
+    <td width="385" class="plaintext">Wave Spectra (2) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">WVSP2</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">030</td>
+    <td width="385" class="plaintext">Wave Spectra (3) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">WVSP3</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">031</td>
+    <td width="385" class="plaintext">Wind Direction (from which blowing)</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">WDIR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">032</td>
+    <td width="385" class="plaintext">Wind Speed</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">WIND</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">033</td>
+    <td width="385" class="plaintext">U-Component of Wind <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">UGRD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">034</td>
+    <td width="385" class="plaintext">V-Component of Wind <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">VGRD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">035</td>
+    <td width="385" class="plaintext">Stream Function <b><a href="#notes">*</a></b> 
+    </td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s</td>
+    <td width="77" class="plaintext" valign="top">STRM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">036</td>
+    <td width="385" class="plaintext">Velocity Potential</td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s</td>
+    <td width="77" class="plaintext" valign="top">VPOT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">037</td>
+    <td width="385" class="plaintext">Montgomery Stream Function</td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">MNTSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">038</td>
+    <td width="385" class="plaintext">Sigma Coordinate Vertical Velocity</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">SGCVV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">039</td>
+    <td width="385" class="plaintext">Vertical Velocity (pressure)</td>
+    <td width="92" class="plaintext" valign="top">Pa/s</td>
+    <td width="77" class="plaintext" valign="top">VVEL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">040</td>
+    <td width="385" class="plaintext">Vertical Velocity (geometric</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">DZDT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">041</td>
+    <td width="385" class="plaintext">Absolute Vorticity</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">ABSV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">042</td>
+    <td width="385" class="plaintext">Absolute Divergence</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">ABSD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">043</td>
+    <td width="385" class="plaintext">Relative Vorticity</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">RELV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">044</td>
+    <td width="385" class="plaintext">Relative Divergence</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">RELD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">045</td>
+    <td width="385" class="plaintext">U-Component of Vertical Shear <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top"> 
+      <p>VUCSH</p>
+    </td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">046</td>
+    <td width="385" class="plaintext">V-Component of Vertical Shear <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">VVCSH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">047</td>
+    <td width="385" class="plaintext">Direction of Current</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">DIRC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">048</td>
+    <td width="385" class="plaintext">Speed of Current</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">SPC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">049</td>
+    <td width="385" class="plaintext">U-Component of Current <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">UOGRD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">050</td>
+    <td width="385" class="plaintext">V-Component of Current <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">VOGRD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">051</td>
+    <td width="385" class="plaintext">Specific Humidity</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">SPFH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">052</td>
+    <td width="385" class="plaintext">Relative Humidity</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">RH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">053</td>
+    <td width="385" class="plaintext">Humidity Mixing Ration</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">MIXR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">054</td>
+    <td width="385" class="plaintext">Precipitable Water</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">PWAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">055</td>
+    <td width="385" class="plaintext">Vapor Pressure</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">VAPP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">056</td>
+    <td width="385" class="plaintext">Saturation Deficit</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">SATD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">057</td>
+    <td width="385" class="plaintext">Evaporation</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">EVP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">058</td>
+    <td width="385" class="plaintext">Cloud Ice</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CICE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">059</td>
+    <td width="385" class="plaintext">Precipitation Rate</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup>/s</td>
+    <td width="77" class="plaintext" valign="top">PRATE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">060</td>
+    <td width="385" class="plaintext">Thunderstorm Probability</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">TSTM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">061</td>
+    <td width="385" class="plaintext">Total Precipitation</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">APCP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">062</td>
+    <td width="385" class="plaintext">Largs Scale Precipitation (non-convective)</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NCPCP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">063</td>
+    <td width="385" class="plaintext">Convective Precipitation</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">ACPCP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">064</td>
+    <td width="385" class="plaintext">Snowfall Rate Water Equivalent</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup>/s</td>
+    <td width="77" class="plaintext" valign="top">SRWEQ</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">065</td>
+    <td width="385" class="plaintext">Water Equivalent Accumulated Snow Depth</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">WEASD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">066</td>
+    <td width="385" class="plaintext">Snow Depth</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">SNOD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">067</td>
+    <td width="385" class="plaintext">Mixed Layer Depth</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">MIXHT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">068</td>
+    <td width="385" class="plaintext">Transient Thermocline Depth</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">TTHDP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">069</td>
+    <td width="385" class="plaintext">Main Thermocline Depth</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">MTHD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">070</td>
+    <td width="385" class="plaintext">Main Thermocline Anomaly</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">MTHA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">071</td>
+    <td width="385" class="plaintext">Total Cloud Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">TCDC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">072</td>
+    <td width="385" class="plaintext">Convective Cloud Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">CDCON</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">073</td>
+    <td width="385" class="plaintext">Low Cloud Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">LCDC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">074</td>
+    <td width="385" class="plaintext">Medium Cloud Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">MCDC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">075</td>
+    <td width="385" class="plaintext">Hight Cloud Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">HCDC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">076</td>
+    <td width="385" class="plaintext">Cloud Water</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CWAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">077</td>
+    <td width="385" class="plaintext">Best Lifted Index (to 500 hPa)</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">BLI</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">078</td>
+    <td width="385" class="plaintext">Convective Snow</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SNOC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">079</td>
+    <td width="385" class="plaintext">Large Scale Snow (non-convective)</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SNOL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">080</td>
+    <td width="385" class="plaintext">Water Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">WTMP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">081</td>
+    <td width="385" class="plaintext">Land Cover (land=1, Sea=0) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">fraction</td>
+    <td width="77" class="plaintext" valign="top">LAND</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">082</td>
+    <td width="385" class="plaintext">Deviation of Sea Level From Mean</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">DSLM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">083</td>
+    <td width="385" class="plaintext">Surface Roughness</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">SFCR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">084</td>
+    <td width="385" class="plaintext">Albedo</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">ALBDO</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">085</td>
+    <td width="385" class="plaintext">Soil Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TSOIL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">086</td>
+    <td width="385" class="plaintext">Soil Moisture Content</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SOILM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">087</td>
+    <td width="385" class="plaintext">Vegetation</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">VEG</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">088</td>
+    <td width="385" class="plaintext">Salinity</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">SALTY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">089</td>
+    <td width="385" class="plaintext">Density</td>
+    <td width="92" class="plaintext" valign="top">kg/m3</td>
+    <td width="77" class="plaintext" valign="top">DEN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">090</td>
+    <td width="385" class="plaintext">Water Runoff</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">WATR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">091</td>
+    <td width="385" class="plaintext">Ice Cover (ice=1, no ice=0) <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">fraction</td>
+    <td width="77" class="plaintext" valign="top">ICEC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">092</td>
+    <td width="385" class="plaintext">Ice Thickness</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">ICETK</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">093</td>
+    <td width="385" class="plaintext">Direction of Ice Drift</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">DICED</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">094</td>
+    <td width="385" class="plaintext">Speed of Ice Drift</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">SICED</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">095</td>
+    <td width="385" class="plaintext">U-Component of Ice Drift <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">UICE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">096</td>
+    <td width="385" class="plaintext">V-Component of Ice Drift <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">VICE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">097</td>
+    <td width="385" class="plaintext">Ice Growth Rate</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">ICEG</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">098</td>
+    <td width="385" class="plaintext">Ice Divergence</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">ICED</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">099</td>
+    <td width="385" class="plaintext">Snow Melt</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SNOM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">100</td>
+    <td width="385" class="plaintext">Significant Height of Combined Wind Waves 
+      and Swell</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup>m</td>
+    <td width="77" class="plaintext" valign="top">HTSGW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">101</td>
+    <td width="385" class="plaintext">Direction of Wind Waves (from which)</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">WVDIR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">102</td>
+    <td width="385" class="plaintext">Significant Height of Wind Waves</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">WVHGT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">103</td>
+    <td width="385" class="plaintext">Mean Period of Wind Waves</td>
+    <td width="92" class="plaintext" valign="top">s</td>
+    <td width="77" class="plaintext" valign="top">WVPER</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">104</td>
+    <td width="385" class="plaintext">Direction of Swell Waves</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">SWDIR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">105</td>
+    <td width="385" class="plaintext">Significant Height of Swell Waves</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">SWELL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">106</td>
+    <td width="385" class="plaintext">Mean Period of Swell Waves</td>
+    <td width="92" class="plaintext" valign="top">s</td>
+    <td width="77" class="plaintext" valign="top">SWPER</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">107</td>
+    <td width="385" class="plaintext">Primary Wave Direction</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">DIRPW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">108</td>
+    <td width="385" class="plaintext">Primary Wave Mean Period</td>
+    <td width="92" class="plaintext" valign="top">s</td>
+    <td width="77" class="plaintext" valign="top">PERPW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">109</td>
+    <td width="385" class="plaintext">Secondary Wave Direction</td>
+    <td width="92" class="plaintext" valign="top">deg true</td>
+    <td width="77" class="plaintext" valign="top">DIRSW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">110</td>
+    <td width="385" class="plaintext">Secondary Wave Mean Period</td>
+    <td width="92" class="plaintext" valign="top">s</td>
+    <td width="77" class="plaintext" valign="top">PERSW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">111</td>
+    <td width="385" class="plaintext">Net Short Wave Radiation at Surface <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NSWRS</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">112</td>
+    <td width="385" class="plaintext">Net Long Wave Radiation at Surface <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m2</td>
+    <td width="77" class="plaintext" valign="top">NLWRS</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">113</td>
+    <td width="385" class="plaintext">Net Short Wave Radiation at Top of Atmosphere 
+      <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NSWRT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">114</td>
+    <td width="385" class="plaintext">Net Long Wave Radiation at Top of Atmosphere 
+      <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NLWRT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">115</td>
+    <td width="385" class="plaintext">Long Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">LWAVR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">116</td>
+    <td width="385" class="plaintext">Short Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SWAVR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">117</td>
+    <td width="385" class="plaintext">Global Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">GRAD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">118</td>
+    <td width="385" class="plaintext">Brightness Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">BRTMP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">119</td>
+    <td width="385" class="plaintext">Radiance (with respect to Wave Number)</td>
+    <td width="92" class="plaintext" valign="top">W/m/sr</td>
+    <td width="77" class="plaintext" valign="top">LWRAD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">120</td>
+    <td width="385" class="plaintext">Radiance (with respect to Wave Length)</td>
+    <td width="92" class="plaintext" valign="top">W/m3/sr</td>
+    <td width="77" class="plaintext" valign="top">SWRAD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">121</td>
+    <td width="385" class="plaintext">Latent Heat Net Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">LHTFL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">122</td>
+    <td width="385" class="plaintext">Sensible Heat Net Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SHTFL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">123</td>
+    <td width="385" class="plaintext">Boundary Layer Dissipation</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">BLYDP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">124</td>
+    <td width="385" class="plaintext">U-Component of Momentum Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">N/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">UFLX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">125</td>
+    <td width="385" class="plaintext">V-Component of Momentum Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">N/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">VFLX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">126</td>
+    <td width="385" class="plaintext">Wind Mixing Energy</td>
+    <td width="92" class="plaintext" valign="top">J</td>
+    <td width="77" class="plaintext" valign="top">WMIXE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">127</td>
+    <td width="385" class="plaintext">Image Data</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">IMGD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">128</td>
+    <td width="385" class="plaintext">Mean Sea Level Pressure <br>
+      (Standard Atmosphere Reduction)</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">MSLSA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">129</td>
+    <td width="385" class="plaintext">Mean Sea Level Pressure<br>
+      (MAPS System Reduction)<br>
+    </td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">MSLMA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">130</td>
+    <td width="385" class="plaintext">Mean Sea Level Pressure<br>
+      (ETA Model Reduction)</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">MSLET</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">131</td>
+    <td width="385" class="plaintext">Surface Lifted Index</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">LFTX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">132</td>
+    <td width="385" class="plaintext">Best (4-Layer) Lifted Index</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">4LFTX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">133</td>
+    <td width="385" class="plaintext">K Index</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">KX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">134</td>
+    <td width="385" class="plaintext">SWEAT Index</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">SX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">135</td>
+    <td width="385" class="plaintext">Horizontal Moisture Divergence</td>
+    <td width="92" class="plaintext" valign="top">kg/kg/s</td>
+    <td width="77" class="plaintext" valign="top">MCONV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">136</td>
+    <td width="385" class="plaintext">Vertical Speed Shear</td>
+    <td width="92" class="plaintext" valign="top">/s</td>
+    <td width="77" class="plaintext" valign="top">VWSH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">137</td>
+    <td width="385" class="plaintext">3-hr Pressure Tendency<br>
+      (Standard Atmosphere Reduction)</td>
+    <td width="92" class="plaintext" valign="top">Pa/s</td>
+    <td width="77" class="plaintext" valign="top">TSLSA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">138</td>
+    <td width="385" class="plaintext">Brunt-Vaisala Frequency (squared)</td>
+    <td width="92" class="plaintext" valign="top">/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">BVF2</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">139</td>
+    <td width="385" class="plaintext">Potential Vorticity (density weighted)</td>
+    <td width="92" class="plaintext" valign="top">/s/m</td>
+    <td width="77" class="plaintext" valign="top">PVMW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">140</td>
+    <td width="385" class="plaintext">Categorical Rain (yes=1, no=0)</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">CRAIN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">141</td>
+    <td width="385" class="plaintext">Categorical Freezing Rain (yes=1, no=0)</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">CFRZR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">142</td>
+    <td width="385" class="plaintext">Categorical Ice Pellets (yes=1, no=0)</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">CICEP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">143</td>
+    <td width="385" class="plaintext">Categorical Snow (yes=1, no=0)</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">CSNOW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">144</td>
+    <td width="385" class="plaintext">Volumetric Soil Moisture Content</td>
+    <td width="92" class="plaintext" valign="top">fraction</td>
+    <td width="77" class="plaintext" valign="top">SOILW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">145</td>
+    <td width="385" class="plaintext">Potential Evaporation Rate</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">PEVPR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">146</td>
+    <td width="385" class="plaintext">Cloud Workfunction</td>
+    <td width="92" class="plaintext" valign="top">J/kg</td>
+    <td width="77" class="plaintext" valign="top">CWORK</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">147</td>
+    <td width="385" class="plaintext">Zonal Flux of Gravity Wave Stress</td>
+    <td width="92" class="plaintext" valign="top">N/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">UGWD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">148</td>
+    <td width="385" class="plaintext">Meridional Flux of Gravity Wave Stress</td>
+    <td width="92" class="plaintext" valign="top">N/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top"> VGWD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">149</td>
+    <td width="385" class="plaintext">Potential Vorticity</td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s/kg</td>
+    <td width="77" class="plaintext" valign="top">PV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">150</td>
+    <td width="385" class="plaintext">Covariance Between Meridional and Zonal 
+      Wind.<br>
+      Defined as [uv]-[u][v], where "[]" indicates the mean over the indicated 
+      time span. </td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">COVMZ</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">151</td>
+    <td width="385" class="plaintext">Covariance Between Temperature and Zonal 
+      Wind.<br>
+      Defined as [uT]-[u][T], <br>
+      where "[]" indicates the mean over the indicated time span. </td>
+    <td width="92" class="plaintext" valign="top">K m/s</td>
+    <td width="77" class="plaintext" valign="top">COVTZ</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">152</td>
+    <td width="385" class="plaintext">Covariance Between Temperature and Meridional 
+      Wind.<br>
+      Defined as [vT]-[v][T], <br>
+      where "[]" indicates the mean over the indicated time span. </td>
+    <td width="92" class="plaintext" valign="top">K m/s</td>
+    <td width="77" class="plaintext" valign="top">COVTM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">153</td>
+    <td width="385" class="plaintext">Cloud Water</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">CLWMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">154</td>
+    <td width="385" class="plaintext">Ozone Mixing Ratio</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">O3MR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">155</td>
+    <td width="385" class="plaintext">Ground Heat Flux</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">GFLUX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">156</td>
+    <td width="385" class="plaintext">Convective Inhibition</td>
+    <td width="92" class="plaintext" valign="top">J/kg</td>
+    <td width="77" class="plaintext" valign="top">CIN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">157</td>
+    <td width="385" class="plaintext">Convective Available Potential Energy</td>
+    <td width="92" class="plaintext" valign="top">J/kg</td>
+    <td width="77" class="plaintext" valign="top">CAPE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">158</td>
+    <td width="385" class="plaintext">Turbulent Kinetic Energy</td>
+    <td width="92" class="plaintext" valign="top">J/kg</td>
+    <td width="77" class="plaintext" valign="top">TKE</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">159</td>
+    <td width="385" class="plaintext">Condensation Pressure of Parcel Lifted from 
+      Indicated Surface</td>
+    <td width="92" class="plaintext" valign="top">Pa</td>
+    <td width="77" class="plaintext" valign="top">CONDP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">160</td>
+    <td width="385" class="plaintext">Clear Sky Upward Short Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CSUSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">161</td>
+    <td width="385" class="plaintext">Clear Sky Downward Short Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CSDSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">162</td>
+    <td width="385" class="plaintext">Clear Sky Upward Long Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CSULF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">163</td>
+    <td width="385" class="plaintext">Clear Sky Downward Long Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CSDLF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">164</td>
+    <td width="385" class="plaintext">Cloud Forcing Net Short Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CFNSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">165</td>
+    <td width="385" class="plaintext">Cloud Forcing Net Long Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CFNLF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">166</td>
+    <td width="385" class="plaintext">Visible Beam Downward Short Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">VBDSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">167</td>
+    <td width="385" class="plaintext">Visible Diffuse Downward Short Wave Flux 
+      <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">VDDSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">168</td>
+    <td width="385" class="plaintext">Near IR Beam Downward Short Wave Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NBDSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">169</td>
+    <td width="385" class="plaintext">Near IR Diffuse Downward Short Wave Flux 
+      <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">NDDSF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">170</td>
+    <td width="385" class="plaintext">Rain Water Mixing Ratio</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">RWMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">171</td>
+    <td width="385" class="plaintext">Snow Mixing Ratio</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">SNMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">172</td>
+    <td width="385" class="plaintext">Momentum Flux</td>
+    <td width="92" class="plaintext" valign="top">N/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">MFLX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">173</td>
+    <td width="385" class="plaintext">Mass Point Model Surface</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">LMH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">174</td>
+    <td width="385" class="plaintext">Velocity Point Model Surface</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">LMV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">175</td>
+    <td width="385" class="plaintext">Model Layer Number (from bottom up)</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">MLYNO</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">176</td>
+    <td width="385" class="plaintext">Latitude (-90 to +90)</td>
+    <td width="92" class="plaintext" valign="top">deg</td>
+    <td width="77" class="plaintext" valign="top">NLAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">177</td>
+    <td width="385" class="plaintext">East Longitude (0 to 360)</td>
+    <td width="92" class="plaintext" valign="top">deg</td>
+    <td width="77" class="plaintext" valign="top">ELON</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">178</td>
+    <td width="385" class="plaintext">Ice Mixing Ratio</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">ICMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">179</td>
+    <td width="385" class="plaintext">Graupel Mixing Ratio</td>
+    <td width="92" class="plaintext" valign="top">kg/kg</td>
+    <td width="77" class="plaintext" valign="top">GRMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">181</td>
+    <td width="385" class="plaintext">X-Gradient of Log Pressure</td>
+    <td width="92" class="plaintext" valign="top">/m</td>
+    <td width="77" class="plaintext" valign="top">LPSX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">182</td>
+    <td width="385" class="plaintext">Y-Gradient of Log Pressure</td>
+    <td width="92" class="plaintext" valign="top">/m</td>
+    <td width="77" class="plaintext" valign="top">LPSY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">183</td>
+    <td width="385" class="plaintext">X-Gradient of Height</td>
+    <td width="92" class="plaintext" valign="top">m/m</td>
+    <td width="77" class="plaintext" valign="top">HGTX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">184</td>
+    <td width="385" class="plaintext">Y-Gradient of Height</td>
+    <td width="92" class="plaintext" valign="top">m/m</td>
+    <td width="77" class="plaintext" valign="top">HGTY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">185</td>
+    <td width="385" class="plaintext">Turbulence SIGMET/AIRMET</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">TURB</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">186</td>
+    <td width="385" class="plaintext">Icing SIGMET/AIRMET</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">ICNG</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">187</td>
+    <td width="385" class="plaintext">Lightning</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">LTNG</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">189</td>
+    <td width="385" class="plaintext">Virtual Potential Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">VPTMP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">190</td>
+    <td width="385" class="plaintext">Storm Relative Helicity</td>
+    <td width="92" class="plaintext" valign="top">m<sup>2</sup>/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">HLCY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">191</td>
+    <td width="385" class="plaintext">Probability from Ensemble</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">PROB</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">192</td>
+    <td width="385" class="plaintext">Probability from Ensemble <br>
+      (Normalized w.r.t. Climate Expectancy)</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">PROBN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">193</td>
+    <td width="385" class="plaintext">Probability of Precipitation</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">POP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">194</td>
+    <td width="385" class="plaintext">Probability of Frozen Precipitation</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">CPOFP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">195</td>
+    <td width="385" class="plaintext">Probability of Freezing Precipitation</td>
+    <td width="92" class="plaintext" valign="top"> 
+      <p>%</p>
+    </td>
+    <td width="77" class="plaintext" valign="top">CPOZP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">196</td>
+    <td width="385" class="plaintext">U-Component of Storm Motion <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">USTM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">197</td>
+    <td width="385" class="plaintext">V-Component of Storm Motion <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">VSTM</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">198</td>
+    <td width="385" class="plaintext">Number Concentration for Ice Particles</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">NCIP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">199</td>
+    <td width="385" class="plaintext">Direct Evaporation from Bare Soil</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">EVBS</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">200</td>
+    <td width="385" class="plaintext">Canopy Water Evaporation</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">EVCW</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">201</td>
+    <td width="385" class="plaintext">Ice-Free Water Surface</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">ICWAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">204</td>
+    <td width="385" class="plaintext">Downward Short Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">DSWRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">205</td>
+    <td width="385" class="plaintext">Downward Long Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">DLWRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">206</td>
+    <td width="385" class="plaintext">Ultra Violet Index <br>
+      (1-hr integration centered at solar noon)</td>
+    <td width="92" class="plaintext" valign="top">J/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">UVI</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">207</td>
+    <td width="385" class="plaintext">Moisture Availability</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">MSTAV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">208</td>
+    <td width="385" class="plaintext">Exchange Coefficient</td>
+    <td width="92" class="plaintext" valign="top">(kg/m3)(m/s)</td>
+    <td width="77" class="plaintext" valign="top">SEEXC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">209</td>
+    <td width="385" class="plaintext">Number of Mixed Layers Next to Surface</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">MIXLY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">210</td>
+    <td width="385" class="plaintext">Transpiration</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">TRANS</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">211</td>
+    <td width="385" class="plaintext">Upward Short Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">USWRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">212</td>
+    <td width="385" class="plaintext">Upward Long Wave Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">ULWRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">213</td>
+    <td width="385" class="plaintext">Amount of Non-Convective Cloud</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">CDLYR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">214</td>
+    <td width="385" class="plaintext">Convective Precipitation Rate</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup>/s</td>
+    <td width="77" class="plaintext" valign="top">CPRAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">215</td>
+    <td width="385" class="plaintext">Temperature Tendency by all Physics</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">TTDIA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">216</td>
+    <td width="385" class="plaintext">Temperature Tendency by all Radiation</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">TTRAD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">217</td>
+    <td width="385" class="plaintext">Temperature Tendency by Non-Radiation Physics</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">TTPHY</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">218</td>
+    <td width="385" class="plaintext">Precipitaion Index (0 to 1) <b><a href="#notes">*</a></b><a href="#notes"> 
+      </a></td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">PREIX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">219</td>
+    <td width="385" class="plaintext">Standard Deviation of IR T over 1x1 Degree 
+      Area</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">TSD1D</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">220</td>
+    <td width="385" class="plaintext">Natural Log of Surface Pressure</td>
+    <td width="92" class="plaintext" valign="top">ln(kPa)</td>
+    <td width="77" class="plaintext" valign="top">NLGSP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">221</td>
+    <td width="385" class="plaintext">Planetary Bounday Layer Height</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">HPBL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">222</td>
+    <td width="385" class="plaintext">5-Wave Geopotential height</td>
+    <td width="92" class="plaintext" valign="top">gpm</td>
+    <td width="77" class="plaintext" valign="top">5WAVH</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">223</td>
+    <td width="385" class="plaintext">Plant Canopy Surface Water</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">CNWAT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">224</td>
+    <td width="385" class="plaintext">Soil Type (Zobler) (0 to 9)</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">SOTYP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">225</td>
+    <td width="385" class="plaintext">Vegetation Type (SiB) (0 to 13)</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">VGTYP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">226</td>
+    <td width="385" class="plaintext">Blackadar's Mixing Length Scale</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">BMIXL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">227</td>
+    <td width="385" class="plaintext">Asymptotic Mixing Length Scale</td>
+    <td width="92" class="plaintext" valign="top">m</td>
+    <td width="77" class="plaintext" valign="top">AMIXL</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">228</td>
+    <td width="385" class="plaintext">Potential Evaporation</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">PEVAP</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">229</td>
+    <td width="385" class="plaintext">Snow Phase-Change Heat Flux</td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SNOHF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">230</td>
+    <td width="385" class="plaintext">5-Wave Geopotential Height Anomaly</td>
+    <td width="92" class="plaintext" valign="top">gpm</td>
+    <td width="77" class="plaintext" valign="top">5WAVA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">231</td>
+    <td width="385" class="plaintext">Convective Cloud Mass Flux</td>
+    <td width="92" class="plaintext" valign="top">Pa/s</td>
+    <td width="77" class="plaintext" valign="top">MFLUX</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">232</td>
+    <td width="385" class="plaintext">Downward Total Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">DTRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">233</td>
+    <td width="385" class="plaintext">Upward Total Radiation Flux <b><a href="#notes">*</a></b></td>
+    <td width="92" class="plaintext" valign="top">W/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">UTRF</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">234</td>
+    <td width="385" class="plaintext">Baseflow-Groundwater Runoff</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">BGRUN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">235</td>
+    <td width="385" class="plaintext">Storm Surface Runoff</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">SSRUN</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">237</td>
+    <td width="385" class="plaintext">Total Ozone</td>
+    <td width="92" class="plaintext" valign="top">kg/m<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">O3TOT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">238</td>
+    <td width="385" class="plaintext">Snow Cover</td>
+    <td width="92" class="plaintext" valign="top">%</td>
+    <td width="77" class="plaintext" valign="top">SNOWC</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">239</td>
+    <td width="385" class="plaintext">Snow Temperature</td>
+    <td width="92" class="plaintext" valign="top">K</td>
+    <td width="77" class="plaintext" valign="top">SNOT</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">241</td>
+    <td width="385" class="plaintext">Large Scale Condensation Heating Rate</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">LRGHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">242</td>
+    <td width="385" class="plaintext">Deep Convective Heating Rate</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">CNVHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">243</td>
+    <td width="385" class="plaintext">Deep Convective Moistening Rate</td>
+    <td width="92" class="plaintext" valign="top">kg/kg/s</td>
+    <td width="77" class="plaintext" valign="top">CNVMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">244</td>
+    <td width="385" class="plaintext">Shallow Convective Heating Rate</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">SHAHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">245</td>
+    <td width="385" class="plaintext">Shallow Convective Moistening Rate</td>
+    <td width="92" class="plaintext" valign="top">kg/kg/s</td>
+    <td width="77" class="plaintext" valign="top">SHAMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">246</td>
+    <td width="385" class="plaintext">Vertical Diffusion Heating Rate</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">VDFHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">247</td>
+    <td width="385" class="plaintext">Vertical Diffusion Zonal Acceleration</td>
+    <td width="92" class="plaintext" valign="top">m/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">VDFUA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">248</td>
+    <td width="385" class="plaintext">Vertical Diffusion Meridional Acceleration</td>
+    <td width="92" class="plaintext" valign="top">m/s<sup>2</sup></td>
+    <td width="77" class="plaintext" valign="top">VDFVA</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">249</td>
+    <td width="385" class="plaintext">Vertical Diffusion Moistening Rate</td>
+    <td width="92" class="plaintext" valign="top">kg/kg/s</td>
+    <td width="77" class="plaintext" valign="top">VDFMR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">250</td>
+    <td width="385" class="plaintext"> 
+      <p>Short Wave Radiative Heating Rate</p>
+    </td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">SWHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">251</td>
+    <td width="385" class="plaintext">Long Wave Radiative Heating Rate</td>
+    <td width="92" class="plaintext" valign="top">K/s</td>
+    <td width="77" class="plaintext" valign="top">LWHR</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">252</td>
+    <td width="385" class="plaintext">Drag Coefficient</td>
+    <td width="92" class="plaintext" valign="top">-</td>
+    <td width="77" class="plaintext" valign="top">CD</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">253</td>
+    <td width="385" class="plaintext">Friction Velocity</td>
+    <td width="92" class="plaintext" valign="top">m/s</td>
+    <td width="77" class="plaintext" valign="top">FRICV</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">254</td>
+    <td width="385" class="plaintext">Richardson Number</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top">RI</td>
+  </tr>
+  <tr> 
+    <td width="49" class="plaintext" align="left" valign="top">255</td>
+    <td width="385" class="plaintext">Missing</td>
+    <td width="92" class="plaintext" valign="top"> </td>
+    <td width="77" class="plaintext" valign="top"> </td>
+  </tr>
+</table>
+
+<br>
+<table width="625" border="0" cellspacing="0" cellpadding="0">
+  <tr>
+    <td>
+      <p><span class="plaintext"><a name="notes"></a>Notes:</span></p>
+      <ol>
+        <li><span class="plaintext">By convention, downward net fluxes of radiation 
+          or other quantities are assigned negative values; upward net fluxes 
+          of radiation or other quantities are assigned positive values.</span></li>
+        <li><span class="plaintext">Unidirectional flux values, where the direction 
+          of flow is indicated in the name of the parameter <br>
+          (e.g., 204, 205, 211, and 212), shall all have positive values irrespective 
+          of the direction of flow. <br>
+          Net (vertical) fluxes shall be calculated by subtracting the downward 
+          flux values from the upward flux values.</span></li>
+        <li><span class="plaintext">The u and v components of vector quantities 
+          are defined with reference to GDS Octet 17 and Table 7. However, if 
+          the GDS is not included in a message, then any wind components are assumed 
+          to be resolved relative to the grid specified in the PDS with u and 
+          v defined as positive in the direction of increasing x and y (or i and 
+          j) coordinates respectively.</span></li>
+        <li><span class="plaintext">Provision is made for three types of spectra: 
+          <br>
+          1) Direction and Frequency <br>
+          2) Direction and radial number <br>
+          3) Radial number and radial number </span></li>
+        <li><span class="plaintext">Parameters 81 and 91 show the units as "fraction", 
+          thus allowing for a range of coverage. It is up to the user to employ 
+          the scaling (power of ten) to assure that the necessary precision is 
+          retained in the numeric values.</span></li>
+        <li><span class="plaintext">Precipitation index (parameter 218) is defined 
+          as the fraction of satellite observed pixels with temperatures < 235K 
+          over a 1x1 box, centered at the gridpoint.</span></li>
+      </ol>
+</td>
+  </tr>
+</table>
+<p> </p>
+</body>
+</html>
diff --git a/doc/gsf.html b/doc/gsf.html
new file mode 100644
index 0000000..83c469d
--- /dev/null
+++ b/doc/gsf.html
@@ -0,0 +1,152 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Script Functions</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+<h2>Dynamic Loading of Script Functions</h2> 
+
+<p>
+Script variables are generally local to the functions (scripts) they
+are contained in; they exist in memory only while the function is
+executing. If a variable name starts with an underscore (_), then it
+becomes a <i>global</i> script variable and keeps its value throughout
+the execution of the main script file. The drawback to global
+variables was that the functions they are defined in had to be
+included in the main script file. With a new capability that comes
+with GrADS version 1.8, that is no longer the case.
+
+<p>
+Dynamic loading of script functions means that when your main script
+calls a function (subscript), all global variables from that function
+will be retained in memory and can continue to be used by main
+script. Commonly used functions do not have to be copied into every script
+that calls them.
+
+<p>
+The names of GrADS script functions may now have 16 characters and include 
+the underscore, although they still must begin with an alphabetic character.
+Grads script function names are case sensitive.
+
+<p>
+Error messages will include the file name
+where the error ocurred -- in this case, the full path name of
+the file that was actually opened.
+
+<p>
+<h3>Using GrADS Script Functions</h3>
+
+<p>
+The tricks to using GrADS script functions are (1) to enable dynamic
+loading and (2) to teach GrADS how to find the script functions you
+call from your main script.
+
+<p>
+To enable the dynamic loading of script functions, put this at the top
+of your script:
+
+<p>
+<ul><code>rc = gsfallow("on")</code></ul>
+
+<p>
+To teach Grads how to find the script functions you call from your
+main script, you must first know how Grads searches for main
+script file names. 
+
+<p>
+<b><i>How GrADS searches for main script file names</i></b>
+
+<p>
+Let's assume the user wants to run a script called
+<code>do_eof.gs</code> and gives the Grads command:
+
+<p>
+<ul><code>ga-> do_eof</code></ul>
+
+<p>
+Grads will search in the currently directory for the script name, as
+provided. If it doesn't find the script, it appends .gs to the script
+name and tries again. If the script is still not found, then the
+environment variable GASCRP is examined. GrADS attemps to open the
+script file in all the directories listed in the GASCRP variable,
+first with the provided name, then with the .gs appended.
+
+<p>
+If GASCRP contains "<code>/usr/local/gradslib
+/usr/homes/myhome</code>", then GrADS will search for the script
+<code>do_eof</code> in the following order:
+
+<ul>
+<code>
+<li>do_eof
+<li>do_eof.gs
+<li>/usr/local/gradslib/do_eof
+<li>/usr/local/gradslib/do_eof.gs
+<li>/usr/homes/myhome/do_eof
+<li>/usr/homes/myhome/do_eof.gs
+</code>
+</ul>
+
+<p>
+GrADS uses the first file it finds. Once found, the directory that
+contains the script file is remembered as the "main function prefix".
+
+<p>
+<b><i>How GrADS searches for script function file names</i></b>
+
+<p>
+Continuing with our example, let's further assume that GrADS
+encounters a function in <code>do_eof.gs</code> that is not included
+in the stuff already loaded from the main script file. GrADS will look
+for a .gsf file to load, using the following search path:
+
+<p>
+<ul>
+<code>
+<li><main-function-prefix>/<function-name>.gsf
+<li><main-function-prefix>/<private-paths>/<function-name>.gsf
+<li><GASCRP-paths>/<function-name>.gsf
+</code>
+</ul>
+
+<p>
+The private path directory list is an optional list that 
+is provided via the <code>gsfpath</code> function:
+
+<p>
+<ul><code>rc = gsfpath("dirlist")</code></ul>
+
+If used, the declaration of the private path directory list should
+appear at the top of the main script just underneath the statement
+enabling the dynamic script loading.
+
+<p>
+For example, if our main script "do_eof.gs" is executed with the command:
+
+<p>
+<ul><code>run /usr/local/gradslib/do_eof</code></ul>
+
+<p>
+and this script file contains the following lines at the front:
+
+<p>
+<ul><code>
+rc = gsfallow("on")<br>
+rc = gsfpath("math1 string2")
+</code></ul>
+
+<p>
+and the script calls a function <code>str_chop</code> which is not found in
+the main script, then the search path would be:
+
+<p>
+<ol>
+<li>/usr/local/gradslib/str_chop.gsf
+<li>/usr/local/gradslib/math1/str_chop.gsf
+<li>/usr/local/gradslib/string2/str_chop.gsf
+</ol>
+
+</body>
+</html>
+
diff --git a/doc/imageoutput.html b/doc/imageoutput.html
new file mode 100644
index 0000000..35af36e
--- /dev/null
+++ b/doc/imageoutput.html
@@ -0,0 +1,143 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Image Output</title></head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>Producing Hardcopy and Image Output from GrADS</b></h2>
+
+<h3>Generating Image Files from GrADS</h3>
+
+There are several GrADS commands that will convert the
+contents of the graphics window into an image file. The differences
+between them are the image formats they support and the way they are
+implemented in GrADS. 
+<p>
+<b><i>printim</i></b>
+<p>
+The <a href="gradcomdprintim.html"><code>printim</code></a> command
+was introduced in version 1.8. It produces a PNG, GIF, or JPG formatted image file based on the current
+contents of the GrADS metabuffer, which is the stuff displayed in the
+graphics window, minus any widgets. <a
+href="gradcomdprintim.html"><code>printim</code></a> will work in
+batch mode. 
+<p><b><i>outxwd</i></b>
+<p> The <code><a href="gradcomdoutxwd.html">outxwd</a></code> command draws the contents of the graphics display window to a file in XWD (X window dump) format. It does not work in batch mode. 
+<p><b><i>wi</i></b>
+<p> The <code><a href="gradcomdwi.html">wi</a></code> command was deprecated long ago and is not included in version 1.9 or later. 
+<p>
+<h3>Generating GrADS metafiles</h3>
+
+<p>
+<b><i>1. Set-up the GrADS metafile</i></b>
+<p>
+The first step in creating hardcopy image output is to invoke the <code><a href="gradcomdenableprint.html">enable print</a></code> command -- this opens the output file<em><code> </code></em>and enables
+GrADS to direct image information to that file. If the file exists, it will be overwritten.
+
+<p>
+<b><i>2. Display the image</i></b>
+<p>
+The next step is to display the graphic that you want to print. When
+you have finished, issue the <code><a href="gradcomdprint.html">print</a></code>command. GrADS copies the vector instructions used to create the current
+display into the output file in a GrADS metacode format.
+
+ For multiple images in your metafile, use <code><a href="gradcomdclear.html">clear</a></code>, create the new image, and then <a href="gradcomdprint.html"><code>print</code></a> again.
+
+<p>
+<b><i>3. Close the GrADS metafile</i></b>
+<p>
+There are three way to close the output file:
+<br>
+<a href="gradcomddisableprint.html"><code>disable print</code></a><br>
+<a href="gradcomdreinit.html"><code>reinit</code></a><br>
+<a href="gradcomdquit.html"><code>quit</code></a><br>
+
+<p>
+<h3>Converting GrADS Metafiles to Postscript</h3>
+
+<p>
+GrADS metacode files may be translated into postscript using the GrADS
+external utilities <a href="gradutilgxps.html"><code>gxps</code></a> and <a
+href="gradutilgxeps.html"><code>gxeps</code></a>. Both utilities will
+prompt for input and output filenames, unless they
+are provided on the command line. The input filename should be the
+file created by the <a href="gradcomdenableprint.html"> <code>enable
+print</code></a> command. The output filename can be anything, but a
+".ps" extension is conventional. Any existing file with this name will
+be overwritten. Once the output file is created, you may print it
+using UNIX print commands. Please consult the references pages for 
+<a href="gradutilgxps.html"><code>gxps</code></a> and 
+<a href="gradutilgxeps.html"><code>gxeps</code></a> to see 
+all the command line arguments and options.
+
+<p>
+<a href="gradutilgxps.html"><code>gxps</code></a> and <a
+href="gradutilgxeps.html"><code>gxeps</code></a> are not
+GrADS commands. They must be executed from the UNIX command line, or
+preceded by a <a href="gradcomdshell.html"><code>!</code></a> and
+executed as a shell command from the GrADS command line.
+<p>
+
+<h3>Generating Postscript from  within GrADS </h3>
+<p> There is a shortcut for creating an encapsulated postscript (EPS) file directly from within a GrADS session: use the <a href="gradcomdprint.html"><code>print</code></a> command without invoking the <code><a href="gradcomdenableprint.html">enable print</a></code> command first. This shortcut allows the user to skip the steps of creating the GrADS metafile and invoking the external utility <a
+href="gradutilgxeps.html"><code>gxeps</code></a>. However, using this shortcut means there can only be one image per file, and none of the options available when invoking <a
+href="gradutilgxeps.html"><code>gxeps</code></a> directly can be used.
+
+<p>
+<h3>Displaying GrADS Metafiles</h3>
+
+<p>
+GrADS metacode files may be displayed using the GrADS external utility
+<a href="gradutilgxtran.html"><code>gxtran</code></a>. The input
+filename should be the file created by the <a
+href="gradcomdenableprint.html"> <code>enable print</code></a>
+command. If the GrADS metafile contains more than one image, <a
+href="gradutilgxtran.html"><code>gxtran</code></a> will animate them.
+The animation can be automatic or controlled by the user with carriage
+returns.  Please consult the <a
+href="gradutilgxtran.html"></code>gxtran</code> reference page</a> to
+see all the command line arguments and options.
+
+<p>
+<h3>Displaying GrADS Metafiles with Windows 95/NT</h3>
+
+<p>
+The GrADS metafile Viewer (GV) allows you to view and manipulate GrADS
+graphics output files using Windows 95/NT. There are two files to download:
+<ul>
+<li> <a href="ftp://cola.gmu.edu/grads/gv/gv32.exe">gv32.exe</a>
+<li> <a href="ftp://cola.gmu.edu/grads/gv/gv32.hlp">gv32.hlp</a>
+</ul>
+<p>
+To open the metafile simply double click on a file listed in the File
+Manager or Explorer, drag and drop the file onto GV, or use the
+standard <i>Open</i> dialog box. GV assumes that default extension of GRADS
+metafiles is GMF. If your file includes more than one picture you can
+browse through pages using the keyboard keys (PageDown and PageUp) or the
+toolbar buttons.
+<p>
+Use the <i>View</i> commands and the <i>View/Options</i>
+dialog box to customize the image -- display it as black-and-white or
+color, change the line thickness, or clip and enlarge any part of the
+image.  Use the right mouse button to access the most commonly used
+features.
+<p>
+There are two ways to save separate pages of a GRADS metafile as
+Windows Metafile (WMF): 1) use the <i>File/Save Page As</i>
+command, or 2) use the <i>Edit/Copy</i> command to copy the
+current page to the Windows Clipboard and then <i>Edit/Paste</i>
+it in your favorite Windows application that handles Windows
+Metafiles.
+<p>
+Use <i>File/Print</i> command to print a current document <b>to
+any printer</b> (you do not need a Postscript printer).  Use
+<i>File/Print Preview</i> to display the active metafile as it
+would appear when printed.
+<p>
+
+
+</body>
+</html>
+
+
diff --git a/doc/images/dot_10.gif b/doc/images/dot_10.gif
new file mode 100644
index 0000000..6ab9263
Binary files /dev/null and b/doc/images/dot_10.gif differ
diff --git a/doc/images/dot_11.gif b/doc/images/dot_11.gif
new file mode 100644
index 0000000..6055730
Binary files /dev/null and b/doc/images/dot_11.gif differ
diff --git a/doc/images/dot_12.gif b/doc/images/dot_12.gif
new file mode 100644
index 0000000..f9acf7e
Binary files /dev/null and b/doc/images/dot_12.gif differ
diff --git a/doc/images/dot_13.gif b/doc/images/dot_13.gif
new file mode 100644
index 0000000..32cce14
Binary files /dev/null and b/doc/images/dot_13.gif differ
diff --git a/doc/images/dot_14.gif b/doc/images/dot_14.gif
new file mode 100644
index 0000000..5637fcf
Binary files /dev/null and b/doc/images/dot_14.gif differ
diff --git a/doc/images/dot_15.gif b/doc/images/dot_15.gif
new file mode 100644
index 0000000..da25d73
Binary files /dev/null and b/doc/images/dot_15.gif differ
diff --git a/doc/images/dot_2.gif b/doc/images/dot_2.gif
new file mode 100644
index 0000000..2123dae
Binary files /dev/null and b/doc/images/dot_2.gif differ
diff --git a/doc/images/dot_3.gif b/doc/images/dot_3.gif
new file mode 100644
index 0000000..ae5ca65
Binary files /dev/null and b/doc/images/dot_3.gif differ
diff --git a/doc/images/dot_4.gif b/doc/images/dot_4.gif
new file mode 100644
index 0000000..425b678
Binary files /dev/null and b/doc/images/dot_4.gif differ
diff --git a/doc/images/dot_5.gif b/doc/images/dot_5.gif
new file mode 100644
index 0000000..8e4bb0d
Binary files /dev/null and b/doc/images/dot_5.gif differ
diff --git a/doc/images/dot_6.gif b/doc/images/dot_6.gif
new file mode 100644
index 0000000..5f540ae
Binary files /dev/null and b/doc/images/dot_6.gif differ
diff --git a/doc/images/dot_7.gif b/doc/images/dot_7.gif
new file mode 100644
index 0000000..36e39b1
Binary files /dev/null and b/doc/images/dot_7.gif differ
diff --git a/doc/images/dot_8.gif b/doc/images/dot_8.gif
new file mode 100644
index 0000000..77d730d
Binary files /dev/null and b/doc/images/dot_8.gif differ
diff --git a/doc/images/dot_9.gif b/doc/images/dot_9.gif
new file mode 100644
index 0000000..e810f06
Binary files /dev/null and b/doc/images/dot_9.gif differ
diff --git a/doc/images/dot_b.gif b/doc/images/dot_b.gif
new file mode 100644
index 0000000..5f28612
Binary files /dev/null and b/doc/images/dot_b.gif differ
diff --git a/doc/images/dot_clear.gif b/doc/images/dot_clear.gif
new file mode 100644
index 0000000..35d42e8
Binary files /dev/null and b/doc/images/dot_clear.gif differ
diff --git a/doc/images/dot_w.gif b/doc/images/dot_w.gif
new file mode 100644
index 0000000..da189c0
Binary files /dev/null and b/doc/images/dot_w.gif differ
diff --git a/doc/images/key.gif b/doc/images/key.gif
new file mode 100644
index 0000000..32b9172
Binary files /dev/null and b/doc/images/key.gif differ
diff --git a/doc/images/logom2.gif b/doc/images/logom2.gif
new file mode 100644
index 0000000..054948c
Binary files /dev/null and b/doc/images/logom2.gif differ
diff --git a/doc/images/tutorial_fig1.gif b/doc/images/tutorial_fig1.gif
new file mode 100644
index 0000000..8d5eb2b
Binary files /dev/null and b/doc/images/tutorial_fig1.gif differ
diff --git a/doc/images/tutorial_fig2.gif b/doc/images/tutorial_fig2.gif
new file mode 100644
index 0000000..bb84362
Binary files /dev/null and b/doc/images/tutorial_fig2.gif differ
diff --git a/doc/images/tutorial_fig3.gif b/doc/images/tutorial_fig3.gif
new file mode 100644
index 0000000..50627f2
Binary files /dev/null and b/doc/images/tutorial_fig3.gif differ
diff --git a/doc/images/tutorial_fig4.gif b/doc/images/tutorial_fig4.gif
new file mode 100644
index 0000000..1fd80b7
Binary files /dev/null and b/doc/images/tutorial_fig4.gif differ
diff --git a/doc/images/tutorial_fig5.gif b/doc/images/tutorial_fig5.gif
new file mode 100644
index 0000000..a8f18a8
Binary files /dev/null and b/doc/images/tutorial_fig5.gif differ
diff --git a/doc/images/tutorial_fig6.gif b/doc/images/tutorial_fig6.gif
new file mode 100644
index 0000000..bcf712c
Binary files /dev/null and b/doc/images/tutorial_fig6.gif differ
diff --git a/doc/images/tutorial_fig7.gif b/doc/images/tutorial_fig7.gif
new file mode 100644
index 0000000..a0fc9f4
Binary files /dev/null and b/doc/images/tutorial_fig7.gif differ
diff --git a/doc/images/tutorial_fig8.gif b/doc/images/tutorial_fig8.gif
new file mode 100644
index 0000000..a35cb32
Binary files /dev/null and b/doc/images/tutorial_fig8.gif differ
diff --git a/doc/images/tutorial_fig9.gif b/doc/images/tutorial_fig9.gif
new file mode 100644
index 0000000..bb4ce87
Binary files /dev/null and b/doc/images/tutorial_fig9.gif differ
diff --git a/doc/indexalpha.html b/doc/indexalpha.html
new file mode 100644
index 0000000..e154ae4
--- /dev/null
+++ b/doc/indexalpha.html
@@ -0,0 +1,48 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Documentation Index</title>
+</head>
+<body bgcolor="#e0f0ff" text="#000000">
+
+<table border=0 cellpadding=2 width=100%>
+<td align=left width=20% valign=top><font size=2><a href="../head.html" target="_top">GrADS Home</a></font></td>
+<td align=center width=60%>
+<font size=5><b><font color="7b2100">GrADS</font> Documentation Index</b></font></td>
+    <td align=right width=20% valign=top><font size=2><a href="gadoc.html" target="_top">GrADS 
+      Documentation</a></font></td>
+</table>
+
+<table border=0 align=center width=100%>
+<tr align=center>
+<td><a href="indexlist.html#indexa" target="list"><b>A</b></a></td> 
+<td><a href="indexlist.html#indexb" target="list"><b>B</b></a></td> 
+<td><a href="indexlist.html#indexc" target="list"><b>C</b></a></td> 
+<td><a href="indexlist.html#indexd" target="list"><b>D</b></a></td> 
+<td><a href="indexlist.html#indexe" target="list"><b>E</b></a></td> 
+<td><a href="indexlist.html#indexf" target="list"><b>F</b></a></td> 
+<td><a href="indexlist.html#indexg" target="list"><b>G</b></a></td> 
+<td><a href="indexlist.html#indexh" target="list"><b>H</b></a></td> 
+<td><a href="indexlist.html#indexi" target="list"><b>I</b></a></td> 
+<td><a href="indexlist.html#indexj" target="list"><b>J</b></a></td> 
+<td><a href="indexlist.html#indexk" target="list"><b>K</b></a></td> 
+<td><a href="indexlist.html#indexl" target="list"><b>L</b></a></td> 
+<td><a href="indexlist.html#indexm" target="list"><b>M</b></a></td> 
+<td><a href="indexlist.html#indexn" target="list"><b>N</b></a></td> 
+<td><a href="indexlist.html#indexo" target="list"><b>O</b></a></td> 
+<td><a href="indexlist.html#indexp" target="list"><b>P</b></a></td> 
+<td><a href="indexlist.html#indexq" target="list"><b>Q</b></a></td> 
+<td><a href="indexlist.html#indexr" target="list"><b>R</b></a></td> 
+<td><a href="indexlist.html#indexs" target="list"><b>S</b></a></td> 
+<td><a href="indexlist.html#indext" target="list"><b>T</b></a></td> 
+<td><a href="indexlist.html#indexu" target="list"><b>U</b></a></td> 
+<td><a href="indexlist.html#indexv" target="list"><b>V</b></a></td> 
+<td><a href="indexlist.html#indexw" target="list"><b>W</b></a></td> 
+<td><a href="indexlist.html#indexx" target="list"><b>X</b></a></td> 
+<td><a href="indexlist.html#indexy" target="list"><b>Y</b></a></td> 
+<td><a href="indexlist.html#indexz" target="list"><b>Z</b></a></td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/doc/indexlist.html b/doc/indexlist.html
new file mode 100644
index 0000000..f703828
--- /dev/null
+++ b/doc/indexlist.html
@@ -0,0 +1,770 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Documentation Index</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="GrADS.css" rel="stylesheet" type="text/css">
+</head>
+<body bgcolor="#e0f0ff" text="#000000">
+<a name="indexa">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>A</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradfuncaave.html" target="pages">aave()</a></code><br>
+<code><a href="gradfuncabs.html" target="pages">abs()</a></code><br>
+<code><a href="gradfuncacos.html" target="pages">acos()</a></code><br>
+<a href="templates.html" target="pages">aggregate data files</a><br>
+<code><a href="gradfuncamax.html" target="pages">amax()</a></code><br>
+<code><a href="gradfuncamaxlocx.html" target="pages">amaxlocx()</a></code><br>
+<code><a href="gradfuncamaxlocy.html" target="pages">amaxlocy()</a></code><br>
+<code><a href="gradfuncamean.html" target="pages">amean()</a></code><br>
+<code><a href="gradfuncamin.html" target="pages">amin()</a></code><br>
+<code><a href="gradfuncaminlocx.html" target="pages">aminlocx()</a></code><br>
+<code><a href="gradfuncaminlocy.html" target="pages">aminlocy()</a></code><br>
+<a href="animation.html" target="pages">animation</a><br>
+<code>set <a href="gradcomdsetannot.html" target="pages">annot</a></code><br>
+<code>set <a href="gradcomdsetarrlab.html" target="pages">arrlab</a></code><br>
+<code>set <a href="gradcomdsetarrowhead.html" target="pages">arrowhead</a></code><br>
+<code>set <a href="gradcomdsetarrscl.html" target="pages">arrscl</a></code><br>
+<code><a href="gradfuncasin.html" target="pages">asin()</a></code><br>
+<code><a href="gradfuncasum.html" target="pages">asum()</a></code><br>
+<code><a href="gradfuncasumg.html" target="pages">asumg()</a></code><br>
+<code><a href="gradfuncatan2.html" target="pages">atan2()</a></code><br>
+<a href="http://dao.gsfc.nasa.gov/software/grads/win32/latest/pc-dist/doc/gagui/gagui_intro.html" target="_top">athena widgets</a><br>
+<code><a href="gradfuncatot.html" target="pages">atot()</a></code><br>
+<code><a href="gradcomdqattr.html" target="pages">q </a>attr</code><br> 
+<code><a href="gradfuncave.html" target="pages">ave()</a></code><br>
+<p>
+<a name="indexb">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>B</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetbackground.html" target="pages">background</a></code><br>
+<code>set <a href="gradcomdsetbarbase.html" target="pages">barbase</a></code><br>
+<code>set <a href="gradcomdsetbargap.html" target="pages">bargap</a></code><br>
+<code>set <a href="gradcomdsetbaropts.html" target="pages">baropts</a></code><br>
+<a href="basic.html" target="pages">basic operation</a><br>
+<a href="aboutgriddeddata.html" target="pages">binary data sets</a><br>
+<code>set <a href="gradcomdsetblack.html" target="pages">black</a></code><br>
+  <a href="bufrformat.html" target="pages">BUFR format</a><br>
+<code><a href="gradutilbufrscan.html" target="pages">bufrscan</a></code>  <br>
+<a href="supplibs.html" target="pages">build  from source</a><br>
+<code>draw <a href="gradcomddrawbutton.html" target="pages">button</a></code><br>
+<code>redraw <a href="gradcomdredrawbutton.html" target="pages">button</a></code><br>
+<code>set <a href="gradcomdsetbutton.html" target="pages">button</a></code><br>
+<p>
+<a name="indexc">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>C</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradcomdquery.html" target="pages">q </a>cache</code><br> 
+<code><a href="gradcomdquery.html" target="pages">q</a> cachesf</code><br> 
+<code>set <a href="gradcomdsetcachesf.html" target="pages">cachesf</a></code><br>
+<a href="gradcomddrawdropmenu.html" target="pages">cascading dropmenus</a><br>
+<code>set <a href="gradcomdsetccolor.html" target="pages">ccolor</a></code><br>
+<code>set <a href="gradcomdsetccols.html" target="pages">ccols</a></code><br>
+<code><a href="gradfunccdiff.html" target="pages">cdiff()</a></code><br>
+<code><a href="templates.html#chsub" target="pages">chsub</a></code><br>
+<code>set <a href="gradcomdsetchunksize.html" target="pages">chunksize</a></code><br> 
+<code>set <a href="gradcomdsetcint.html" target="pages">cint</a></code><br> 
+<code>set <a href="gradcomdsetclab.html" target="pages">clab</a></code><br>
+<code><a href="gradcomdclear.html" target="pages">clear</a></code><br>
+<code>set <a href="gradcomdsetclevs.html" target="pages">clevs</a></code><br>
+<code>set <a href="gradcomdsetclip.html" target="pages">clip</a></code><br>
+<code>set <a href="gradcomdsetclopts.html" target="pages">clopts</a></code><br>
+<code><a href="gradcomdclose.html" target="pages">close</a></code><br>
+<code>set <a href="gradcomdsetclskip.html" target="pages">clskip</a></code><br>
+<code>set <a href="gradcomdsetcmark.html" target="pages">cmark</a></code><br>
+<code>set <a href="gradcomdsetcmax.html" target="pages">cmax</a></code><br>
+<code>set <a href="gradcomdsetcmin.html" target="pages">cmin</a></code><br>
+<code><a href="gradcomdcollect.html" target="pages">collect</a></code><br>
+<code><a href="gradfunccoll2gr.html" target="pages">coll2gr()</a></code><br>
+default <a href="16colors.html" target="pages">colors</a><br>
+controlling <a href="colorcontrol.html" target="pages">colors</a><br>
+<a href="commandline.html" target="pages">command line editing</a><br>
+<a href="commandsatt.html" target="pages">commands: attribute</a><br>
+<a href="compression.html" target="pages">compression</a><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> config</code><br> 
+<code><a href="gradfuncconst.html" target="pages">const()</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> contours</code><br> 
+<a href="descriptorfile.html" target="pages">control file</a><br>
+<a href="gradfuncscorr.html" target="pages">correlation, spatial</a><br>
+<a href="gradfunctcorr.html" target="pages">correlation, temporal</a><br>
+<code><a href="gradfunccos.html" target="pages">cos()</a></code><br>
+<code>set <a href="gradcomdsetcoslat.html" target="pages">coslat</a></code><br>
+<a href="usingstationdata.html#xsection" target="pages">cross sections</a><br>
+<code>set <a href="gradcomdsetcsmooth.html" target="pages">csmooth</a></code><br>
+<code>set <a href="gradcomdsetcstyle.html" target="pages">cstyle</a></code><br>
+<code>set <a href="gradcomdsetcterp.html" target="pages">cterp</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> ctlinfo</code><br> 
+<code>set <a href="gradcomdsetcthick.html" target="pages">cthick</a></code><br> 
+</font>
+
+<p>
+<a name="indexd">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>D</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+data descriptor files:<br>
+  <a href="descriptorfile.html" target="pages">elements</a><br>
+  <a href="bufrformat.html" target="pages">for BUFR data</a><br>
+  <a href="aboutgriddeddata.html#descriptor" target="pages">for gridded data</a><br>
+    <a href="SDFdescriptorfile.html" target="pages">for NetCDF/HDF files</a><br>
+  <a href="aboutstationdata.html#descriptor" target="pages">for station data</a><br>
+<a href="aboutgriddeddata.html" target="pages">data sets (gridded)</a><br>
+<a href="aboutstationdata.html" target="pages">data sets (station)</a><br>
+<code>set <a href="gradcomdsetdatawarn.html" target="pages">datawarn</a></code><br>
+<code>q <a href="gradcomdqdbf.html" target="pages">dbf</a></code><br>
+<code>set <a href="gradcomdsetdbuff.html" target="pages">dbuff</a></code><br>
+<code><a href="gradcomddefine.html" target="pages">define</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> define</code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> defval</code><br>
+<code>set <a href="gradcomdsetdefval.html" target="pages">defval</a></code><br>
+<a href="fontcontrol.html#overrides" target="pages">degree symbol</a><br>
+<code>set <a href="gradcomdsetdfile.html" target="pages">dfile</a></code><br>
+<code>q <a href="gradcomdqdialog.html" target="pages">dialog</a></code><br> 
+<code>set <a href="gradcomdsetdialog.html" target="pages">dialog</a></code><br> 
+<code>set <a href="gradcomdsetdignum.html" target="pages">dignum</a></code><br> 
+<code>set <a href="gradcomdsetdigsize.html" target="pages">digsiz</a></code><br> 
+<a href="dimenv.html" target="pages">dimension environment</a><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> dims</code><br>
+<code><a href="gradcomddisablefwrite.html" target="pages">disable fwrite</a></code><br>
+<code><a href="gradcomddisableprint.html" target="pages">disable print</a></code><br>
+<code><a href="gradcomddisplay.html" target="pages">display</a></code><br>
+<code>set <a href="gradcomdsetdisplay.html" target="pages">display</a></code><br> 
+<a href="display.html" target="pages">displaying data</a><br>
+<a href="imageoutput.html" target="pages">displaying metafiles</a><br>
+<code><a href="gradcomddrawbutton.html" target="pages">draw button</a></code><br>
+<code><a href="gradcomddrawdropmenu.html" target="pages">draw dropmenu</a></code><br>
+<code><a href="gradcomddrawline.html" target="pages">draw line</a></code><br>
+<code><a href="gradcomddrawmap.html" target="pages">draw map</a></code><br>
+<code><a href="gradcomddrawmark.html" target="pages">draw mark</a></code><br>
+<code><a href="gradcomddrawpolyf.html" target="pages">draw polyf</a></code><br>
+<code><a href="gradcomddrawrec.html" target="pages">draw rec</a></code><br>
+<code><a href="gradcomddrawrecf.html" target="pages">draw recf</a></code><br>
+<code><a href="gradcomddrawshp.html" target="pages">draw shp</a></code><br>
+<code><a href="gradcomddrawstring.html" target="pages">draw string</a></code><br> 
+<code><a href="gradcomddrawtitle.html" target="pages">draw title</a></code><br>
+<code><a href="gradcomddrawwxsym.html" target="pages">draw wxsym</a></code><br>
+<code><a href="gradcomddrawxlab.html" target="pages">draw xlab</a></code><br>
+<code><a href="gradcomddrawylab.html" target="pages">draw ylab</a></code><br>
+<code>draw <a href="gradcomddrawdropmenu.html" target="pages">dropmenu</a></code><br>
+<code>set <a href="gradcomdsetdropmenu.html" target="pages">dropmenu</a></code><br>
+<p>
+<a name="indexe">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>E</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetxyzte.html" target="pages">e</a></code><br>
+<code><a href="gradfunceloop.html" target="pages">eloop</a></code><br>
+<code><a href="gradcomdenableprint.html" target="pages">enable print</a></code><br>
+<code>q <a href="gradcomdqens.html" target="pages">ens</a></code><br> 
+<code>set <a href="gradcomdsetlatlonlevtimeens.html" target="pages">ens</a></code><br>
+<a href="ensembles.html" target="pages">ensemble dimension</a><br>
+<a href="gradcomdgrads.html#env" target="pages">environment variables</a><br>
+<code><a href="gradcomdexec.html" target="pages">exec</a></code><br>
+<code><a href="gradfuncexp.html" target="pages">exp()</a></code><br>
+<a href="expressions.html" target="pages">expressions</a><br>
+<a href="utilities.html" target="pages">external utilites</a><br>
+<p>
+<a name="indexf">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>F</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetfgvals.html" target="pages">fgvals</a></code><br> 
+<code><a href="gradcomdquery.html" target="pages">q</a> file(s)</code><br>
+<code><a href="gradcomdflush.html" target="pages">flush</a></code><br> 
+<code><a href="gradfuncfndlvl.html" target="pages">fndlvl()</a></code><br>
+<a href="fontcontrol.html" target="pages">font control</a><br>
+<a href="font.html" target="pages">font file</a><br>
+<code>set <a href="gradcomdsetfont.html" target="pages">font</a></code><br> 
+<code>set <a href="gradcomdsetframe.html" target="pages">frame</a></code><br> 
+<code>disable <a href="gradcomddisablefwrite.html" target="pages">fwrite</a></code><br>
+<code>q <a href="gradcomdqfwrite.html" target="pages">fwrite</a></code><br> 
+<code>set <a href="gradcomdsetfwrite.html" target="pages">fwrite</a></code><br>
+<a href="functions.html" target="pages">functions: alpha</a><br>
+<a href="functionsatt.html" target="pages">functions: attribute</a><br>
+<a href="mathfunctions.html" target="pages">math functions</a><br>
+<p>
+<a name="indexg">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>G</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetgeotiff.html" target="pages">geotiff</a></code><br>
+<code><a href="gradfuncgint.html" target="pages">gint()</a></code><br>
+<code><a href="gradfuncgr2stn.html" target="pages">gr2stn()</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> gr2w</code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> gr2xy</code><br>
+<code>set <a href="gradcomdsetgrads.html" target="pages">grads</a></code><br> 
+<code><a href="gradcomdgrads.html" target="pages">grads</a></code><br>
+<code><a href="gradcomdgrads.html" target="pages">gradsc</a></code><br>
+<code><a href="gradcomdgrads.html" target="pages">gradsdap</a></code><br>
+<code><a href="gradcomdgrads.html" target="pages">gradsdods</a></code><br>
+<code><a href="gradcomdgrads.html" target="pages">gradshdf</a></code><br>
+<code><a href="gradcomdgrads.html" target="pages">gradsnc</a></code><br>
+  <a href="grib.html" target="pages">GRIB format</a><br>
+<code><a href="gradutilgribmap.html" target="pages">gribmap</a></code><br>
+<code><a href="gradutilgribscan.html" target="pages">gribscan</a></code><br>
+<code><a href="gradutilgrib2scan.html" target="pages">grib2scan</a></code><br>
+<code>set <a href="gradcomdsetgrid.html" target="pages">grid</a></code><br>
+<code>set <a href="gradcomdsetgridln.html" target="pages">gridln</a></code><br>
+<code><a href="gsf.html" target="pages">gsfallow()</a></code><br>
+<code><a href="gsf.html" target="pages">gsfpath()</a></code><br>
+<code><a href="gradutilgxeps.html" target="pages">gxeps</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> gxinfo</code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> gxout</code><br>
+<code>set <a href="gradcomdsetgxout.html" target="pages">gxout</a></code><br>  
+<code><a href="gradutilgxps.html" target="pages">gxps</a></code><br>
+<code><a href="gradutilgxtran.html" target="pages">gxtran</a></code><br>
+</font>
+
+<p>
+<a name="indexh">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>H</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<a href="imageoutput.html" target="pages">hardcopy output</a><br>
+<code><a href="gradfunchcurl.html" target="pages">hcurl()</a></code><br>
+  <code><a href="SDFdescriptorfile.html" target="pages">HDF-SDS format</a></code><br>
+<code><a href="gradfunchdivg.html" target="pages">hdivg()</a></code><br>
+<code><a href="gradcomdhelp.html" target="pages">help</a></code><br>
+<code>set <a href="gradcomdsethempref.html" target="pages">hempref</a></code><br>
+
+<p class="plaintext">
+<a name="indexi">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>I</b></font></td></tr>
+</table>
+</a>
+<p class="plaintext">
+<a href="imageoutput.html" target="pages">image output</a><br>
+<code>set <a href="gradcomdsetimprun.html" target="pages">imprun</a></code><br>
+
+<p class="plaintext">
+<a name="indexj">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>J</b></font></td></tr>
+</table>
+</a>
+<p class="plaintext">
+
+<p class="plaintext"> 
+<a name="indexk">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>K</b></font></td></tr>
+</table>
+</a>
+<p class="plaintext">
+<code>set <a href="gradcomdsetkml.html" target="pages">kml</a></code><br>
+
+
+<p class="plaintext">
+<a name="indexl">
+</a></p>
+<table cellpadding=2 border=0 WIDTH=20>
+  <tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+  <font color="fffacd"><b>L</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetlatlonlevtimeens.html" target="pages">lat</a></code><br>
+<code>set <a href="gradcomdsetlatlonlevtimeens.html" target="pages">lev</a></code><br>
+<code>set <a href="gradcomdsetlfcols.html" target="pages">lfcols</a></code><br> 
+script <a href="library.html" target="pages">library</a><br>
+<code>draw <a href="gradcomddrawline.html" target="pages">line</a></code><br>
+<code>set <a href="gradcomdsetline.html" target="pages">line</a></code><br>
+<code><a href="gradfunclog.html" target="pages">log()</a></code><br>
+<code><a href="gradfunclog10.html" target="pages">log10()</a></code><br>
+<code>set <a href="gradcomdsetlog1d.html" target="pages">log1d</a></code><br>
+<code>set <a href="gradcomdsetlatlonlevtimeens.html" target="pages">lon</a></code><br>
+<code>set <a href="gradcomdsetloopdim.html" target="pages">loopdim</a></code><br>
+<code>set <a href="gradcomdsetlooping.html" target="pages">looping</a></code><br> 
+<code><a href="gradfunclterp.html" target="pages">lterp()</a></code><br> 
+</font>
+
+<p>
+<a name="indexm">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>M</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradfuncmag.html" target="pages">mag()</a></code><br>
+<a href="map.html" target="pages">map projections</a><br>
+<code>draw <a href="gradcomddrawmap.html" target="pages">map</a></code><br>
+<code>set <a href="gradcomdsetmap.html" target="pages">map</a></code><br>
+<code>draw <a href="gradcomddrawmark.html" target="pages">mark</a></code><br>
+<code><a href="gradfuncmaskout.html" target="pages">maskout()</a></code><br> 
+<a href="mathfunctions.html" target="pages">math functions</a><br>
+<code><a href="gradfuncmax.html" target="pages">max()</a></code><br>
+<code><a href="gradfuncmaxloc.html" target="pages">maxloc()</a></code><br>
+<code>set <a href="gradcomdsetmdlopts.html" target="pages">mdlopts</a></code><br>
+<code><a href="gradfuncmean.html" target="pages">mean()</a></code><br>
+<a href="imageoutput.html" target="pages">metafiles</a><br>
+<code><a href="gradfuncmin.html" target="pages">min()</a></code><br>
+<code><a href="gradfuncminloc.html" target="pages">minloc()</a></code><br>
+<code>set <a href="gradcomdsetmissconn.html" target="pages">missconn</a></code><br>
+<code><a href="gradcomdmodify.html" target="pages">modify</a></code><br>
+<code>set <a href="gradcomdsetmpdraw.html" target="pages">mpdraw</a></code><br>
+<code>set <a href="gradcomdsetmpdset.html" target="pages">mpdset</a></code><br>
+<code>set <a href="gradcomdsetmproj.html" target="pages">mproj</a></code><br>
+<code>set <a href="gradcomdsetmpt.html" target="pages">mpt</a></code><br>
+<code>set <a href="gradcomdsetmpvals.html" target="pages">mpvals</a></code><br>
+<a href="pagecontrol.html#multipanel" target="pages">multi-panel plots</a><br>
+</font>
+
+<p>
+<a name="indexn">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>N</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="SDFdescriptorfile.html" target="pages">NetCDF format</a></code><br>
+</font>
+
+<p>
+<a name="indexo">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>O</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradfuncoabin.html" target="pages">oabin()</a></code><br>
+<code><a href="gradfuncoacres.html" target="pages">oacres()</a></code><br>
+<code><a href="offt.html" target="pages">offt</a></code><br>
+<code><a href="gradcomdopen.html" target="pages">open</a></code><br>
+<code><a href="gradcomdoutxwd.html" target="pages">outxwd</a></code><br>
+</font>
+
+<p>
+<a name="indexp">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>P</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<a href="pagecontrol.html" target="pages">page control</a><br>
+<code>set <a href="gradcomdsetparea.html" target="pages">parea</a></code><br>
+  <a href="http://dao.gsfc.nasa.gov/software/grads/win32/latest/" target="_top">PC 
+  GrADS</a><br>
+<code><a href="pdef.html" target="pages">PDEF</a></code><br>
+<a href="pagecontrol.html#plotarea" target="pages">plot area</a><br>
+<code>set <a href="gradcomdsetpoli.html" target="pages">poli</a></code><br>
+<code>draw <a href="gradcomddrawpolyf.html" target="pages">polyf</a></code><br>
+<code>q <a href="gradcomdqpos.html" target="pages">pos</a></code><br> 
+<code><a href="gradfuncpow.html" target="pages">pow()</a></code><br>
+<code><a href="gradcomdprint.html" target="pages">print</a></code><br>
+<code>disable <a href="gradcomddisableprint.html" target="pages">print</a></code><br>
+<code>enable <a href="gradcomdenableprint.html" target="pages">print</a></code><br>  
+<code><a href="gradcomdprintim.html" target="pages">printim</a></code><br>
+<code>set <a href="gradcomdsetprnopts.html" target="pages">prnopts</a></code><br>
+</font>
+
+<p>
+<a name="indexq">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>Q</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradcomdquery.html" target="pages">q (query)</a></code><br>
+<code><a href="gradcomdqattr.html" target="pages">q attr</a></code><br> 
+<code><a href="gradcomdqdbf.html" target="pages">q dbf</a></code><br>
+<code><a href="gradcomdqdialog.html" target="pages">q dialog</a></code><br>
+<code><a href="gradcomdqens.html" target="pages">q ens</a></code><br> 
+<code><a href="gradcomdqfwrite.html" target="pages">q fwrite</a></code><br> 
+<code><a href="gradcomdqpos.html" target="pages">q pos</a></code><br> 
+<code><a href="gradcomdqsdfwrite.html" target="pages">q sdfwrite</a></code><br>
+<code><a href="gradcomdqshades.html" target="pages">q shades</a></code><br>
+<code><a href="gradcomdqshp.html" target="pages">q shp</a></code><br>
+<code><a href="gradcomdqshpopts.html" target="pages">q shpopts</a></code><br>
+<a href="reference_card.pdf" target="_top">quick: commands</a><br>
+<a href="reference_card_scl.pdf"target="_top">quick: scripts</a><br>
+<code><a href="gradcomdquit.html" target="pages">quit</a></code><br>  
+</font>
+
+<p>
+<a name="indexr">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>R</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetrband.html" target="pages">rband</a></code><br>
+<code>set <a href="gradcomdsetrbcols.html" target="pages">rbcols</a></code><br>
+<code>set <a href="gradcomdsetrbrange.html" target="pages">rbrange</a></code><br>
+<a href="pagecontrol.html#real" target="pages">real page</a><br>
+<code>draw <a href="gradcomddrawrec.html" target="pages">rec</a></code><br>
+<code>draw <a href="gradcomddrawrecf.html" target="pages">recf</a></code><br>
+<code><a href="gradcomdredrawbutton.html" target="pages">redraw button</a></code><br>
+<code><a href="gradcomdreset.html" target="pages">reset</a></code><br>   
+<code><a href="gradcomdreinit.html" target="pages">reinit</a></code><br>   
+<a href="reinitialization.html" target="pages">reinitialization</a><br>
+<code>set <a href="gradcomdsetrgb.html" target="pages">rgb</a></code><br>
+<code><a href="gradcomdrun.html" target="pages">run</a></code><br> 
+</font>
+
+<p>
+<a name="indexs">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>S</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradfuncs2g1d.html" target="pages">s2g1d()</a></code><br>
+<a href="scatterplot.html" target="pages">scatter plots</a><br>
+<code><a href="gradfuncscorr.html" target="pages">scorr()</a></code><br>
+<code><a href="gradcomdscreen.html" target="pages">screen</a></code><br>
+<a href="gsf.html" target="pages">script functions</a><br>
+<a href="library.html" target="pages">script library</a><br>
+<a href="script.html" target="pages">scripting language</a><br>
+<code><a href="gradcomdsdfopen.html" target="pages">sdfopen</a></code><br>
+<code><a href="gradcomdsdfwrite.html" target="pages">sdfwrite</a></code><br>
+<code>q <a href="gradcomdqsdfwrite.html" target="pages">sdfwrite</a></code><br>
+<code>set <a href="gradcomdsetsdfattr.html" target="pages">sdfattr</a></code><br>
+<code>set <a href="gradcomdsetsdfwrite.html" target="pages"> sdfwrite</a></code><br>
+<code><a href="gradcomdsetannot.html" target="pages">set annot</a></code><br>
+<code><a href="gradcomdsetarrlab.html" target="pages">set arrlab</a></code><br>
+<code><a href="gradcomdsetarrowhead.html" target="pages">set arrowhead</a></code><br>
+<code><a href="gradcomdsetarrscl.html" target="pages">set arrscl</a></code><br>
+<code><a href="gradcomdsetbackground.html" target="pages">set background</a></code><br>
+<code><a href="gradcomdsetbarbase.html" target="pages">set barbase</a></code><br>
+<code><a href="gradcomdsetbargap.html" target="pages">set bargap</a></code><br>
+<code><a href="gradcomdsetbaropts.html" target="pages">set baropts</a></code><br>
+<code><a href="gradcomdsetblack.html" target="pages">set black</a></code><br>
+<code><a href="gradcomdsetbutton.html" target="pages">set button</a></code><br>
+<code><a href="gradcomdsetcachesf.html" target="pages">set cachesf</a></code><br>
+<code><a href="gradcomdsetccolor.html" target="pages">set ccolor</a></code><br>
+<code><a href="gradcomdsetccols.html" target="pages">set ccols</a></code><br>
+<code><a href="gradcomdsetcint.html" target="pages">set cint</a></code><br>
+<code><a href="gradcomdsetchunksize.html" target="pages">set chunksize</a></code><br>  
+<code><a href="gradcomdsetclab.html" target="pages">set clab</a></code><br>
+<code><a href="gradcomdsetclevs.html" target="pages">set clevs</a></code><br>
+<code><a href="gradcomdsetclip.html" target="pages">set clip</a></code><br>
+<code><a href="gradcomdsetclopts.html" target="pages">set clopts</a></code><br>
+<code><a href="gradcomdsetclskip.html" target="pages">set clskip</a></code><br>
+<code><a href="gradcomdsetcmark.html" target="pages">set cmark</a></code><br>
+<code><a href="gradcomdsetcmax.html" target="pages">set cmax</a></code><br>
+<code><a href="gradcomdsetcmin.html" target="pages">set cmin</a></code><br>
+<code><a href="gradcomdsetcmin.html" target="pages">set cmin</a></code><br>
+<code><a href="gradcomdsetcoslat.html" target="pages">set coslat</a></code><br>
+<code><a href="gradcomdsetcstyle.html" target="pages">set cstyle</a></code><br>
+<code><a href="gradcomdsetcterp.html" target="pages">set cterp</a></code><br>
+<code><a href="gradcomdsetcthick.html" target="pages">set cthick</a></code><br>
+<code><a href="gradcomdsetdatawarn.html" target="pages">set datawarn</a></code><br>
+<code><a href="gradcomdsetdbuff.html" target="pages">set dbuff</a></code><br>
+<code><a href="gradcomdsetdefval.html" target="pages">set defval</a></code><br>
+<code><a href="gradcomdsetdfile.html" target="pages">set dfile</a></code><br>
+<code><a href="gradcomdsetdialog.html" target="pages">set dialog</a></code><br> 
+<code><a href="gradcomdsetdignum.html" target="pages">set dignum</a></code><br> 
+<code><a href="gradcomdsetdigsize.html" target="pages">set digsiz</a></code><br> 
+<code><a href="gradcomdsetdisplay.html" target="pages">set display</a></code><br> 
+<code><a href="gradcomdsetdropmenu.html" target="pages">set dropmenu</a></code><br>
+<code><a href="gradcomdsetlatlonlevtimeens.html" target="pages">set ens</a></code><br>
+<code><a href="gradcomdsetfgvals.html" target="pages">set fgvals</a></code><br> 
+<code><a href="gradcomdsetfont.html" target="pages">set font</a></code><br> 
+<code><a href="gradcomdsetframe.html" target="pages">set frame</a></code><br> 
+<code><a href="gradcomdsetfwrite.html" target="pages">set fwrite</a></code><br>
+<code><a href="gradcomdsetgrads.html" target="pages">set grads</a></code><br> 
+<code><a href="gradcomdsetgeotiff.html" target="pages">set geotiff</a></code><br> 
+<code><a href="gradcomdsetgrid.html" target="pages">set grid</a></code><br>
+<code><a href="gradcomdsetgridln.html" target="pages">set gridln</a></code><br>
+<code><a href="gradcomdsetgxout.html" target="pages">set gxout</a></code><br>  
+<code><a href="gradcomdsethempref.html" target="pages">set hempref</a></code><br>
+<code><a href="gradcomdsetimprun.html" target="pages">set imprun</a></code><br>
+<code><a href="gradcomdsetkml.html" target="pages">set kml</a></code><br>
+<code><a href="gradcomdsetlatlonlevtimeens.html" target="pages">set lat</a></code><br>
+<code><a href="gradcomdsetlatlonlevtimeens.html" target="pages">set lev</a></code><br>
+<code><a href="gradcomdsetlfcols.html" target="pages">set lfcols</a></code><br> 
+<code><a href="gradcomdsetline.html" target="pages">set line</a></code><br>
+<code><a href="gradcomdsetlog1d.html" target="pages">set log1d</a></code><br>
+<code><a href="gradcomdsetlatlonlevtimeens.html" target="pages">set lon</a></code><br>
+<code><a href="gradcomdsetloopdim.html" target="pages">set loopdim</a></code><br>
+<code><a href="gradcomdsetlooping.html" target="pages">set looping</a></code><br> 
+<code><a href="gradcomdsetmap.html" target="pages">set map</a></code><br>
+<code><a href="gradcomdsetmdlopts.html" target="pages">set mdlopts</a></code><br>
+<code><a href="gradcomdsetmissconn.html" target="pages">set missconn</a></code><br>
+<code><a href="gradcomdsetmpdraw.html" target="pages">set mpdraw</a></code><br>
+<code><a href="gradcomdsetmpdset.html" target="pages">set mpdset</a></code><br>
+<code><a href="gradcomdsetmproj.html" target="pages">set mproj</a></code><br>
+<code><a href="gradcomdsetmpt.html" target="pages">set mpt</a></code><br>
+<code><a href="gradcomdsetmpvals.html" target="pages">set mpvals</a></code><br>
+<code><a href="gradcomdsetparea.html" target="pages">set parea</a></code><br>
+<code><a href="gradcomdsetpoli.html" target="pages">set poli</a></code><br>
+<code><a href="gradcomdsetprnopts.html" target="pages">set prnopts</a></code><br>
+<code><a href="gradcomdsetrband.html" target="pages">set rband</a></code><br>
+<code><a href="gradcomdsetrbcols.html" target="pages">set rbcols</a></code><br>
+<code><a href="gradcomdsetrbrange.html" target="pages">set rbrange</a></code><br>
+<code><a href="gradcomdsetrgb.html" target="pages">set rgb</a></code><br>
+<code><a href="gradcomdsetsdfattr.html" target="pages">set sdfattr</a></code><br>
+<code><a href="gradcomdsetsdfwrite.html" target="pages">set sdfwrite</a></code><br>
+<code><a href="gradcomdsetshp.html" target="pages">set shp</a></code><br>
+<code><a href="gradcomdsetshpattr.html" target="pages">set shpattr</a></code><br>
+<code><a href="gradcomdsetshpopts.html" target="pages">set shpopts</a></code><br>
+<code><a href="gradcomdsetstat.html" target="pages">set stat</a></code><br>
+<code><a href="gradcomdsetstid.html" target="pages">set stid</a></code><br>
+<code><a href="gradcomdsetstnprint.html" target="pages">set stnprint</a></code><br>
+<code><a href="gradcomdsetstring.html" target="pages">set string</a></code><br>
+<code><a href="gradcomdsetstrmden.html" target="pages">set strmden</a></code><br>
+<code><a href="gradcomdsetstrmden.html" target="pages">set strmopts</a></code><br>
+<code><a href="gradcomdsetstrsiz.html" target="pages">set strsiz</a></code><br>
+<code><a href="gradcomdsetxyzte.html" target="pages">set t</a></code><br>
+<code><a href="gradcomdsetlatlonlevtimeens.html" target="pages">set time</a></code><br>
+<code><a href="gradcomdsettimelab.html" target="pages">set timelab</a></code><br>
+<code><a href="gradcomdsettlsupp.html" target="pages">set tlsupp</a></code><br>
+<code><a href="gradcomdsetundef.html" target="pages">set undef</a></code><br>
+<code><a href="gradcomdsetvpage.html" target="pages">set vpage</a></code><br>
+<code><a href="gradcomdsetvrange.html" target="pages">set vrange</a></code><br>
+<code><a href="gradcomdsetvrange2.html" target="pages">set vrange2</a></code><br>
+<code><a href="gradcomdsetwarn.html" target="pages">set warn</a></code><br>
+<code><a href="gradcomdsetwxcols.html" target="pages">set wxcols</a></code><br>
+<code><a href="gradcomdsetwxopt.html" target="pages">set wxopt</a></code><br>
+<code><a href="gradcomdsetxyzte.html" target="pages">set x</a></code><br>
+<code><a href="gradcomdsetxaxis.html" target="pages">set xaxis</a></code><br>
+<code><a href="gradcomdsetxflip.html" target="pages">set xflip</a></code><br>
+<code><a href="gradcomdsetxlab.html" target="pages">set xlab</a></code><br>
+<code><a href="gradcomdsetxlabs.html" target="pages">set xlabs</a></code><br>
+<code><a href="gradcomdsetxlevs.html" target="pages">set xlevs</a></code><br>
+<code><a href="gradcomdsetxlint.html" target="pages">set xlint</a></code><br>
+<code><a href="gradcomdsetxlopts.html" target="pages">set xlopts</a></code><br>
+<code><a href="gradcomdsetxlpos.html" target="pages">set xlpos</a></code><br>
+<code><a href="gradcomdsetxsize.html" target="pages">set xsize</a></code><br>
+<code><a href="gradcomdsetxyrev.html" target="pages">set xyrev</a></code><br>
+<code><a href="gradcomdsetxyzte.html" target="pages">set y</a></code><br>
+<code><a href="gradcomdsetyaxis.html" target="pages">set yaxis</a></code><br>
+<code><a href="gradcomdsetyflip.html" target="pages">set yflip</a></code><br>
+<code><a href="gradcomdsetylab.html" target="pages">set ylab</a></code><br>
+<code><a href="gradcomdsetylabs.html" target="pages">set ylabs</a></code><br>
+<code><a href="gradcomdsetylevs.html" target="pages">set ylevs</a></code><br>
+<code><a href="gradcomdsetylint.html" target="pages">set ylint</a></code><br>
+<code><a href="gradcomdsetylopts.html" target="pages">set ylopts</a></code><br>
+<code><a href="gradcomdsetylpos.html" target="pages">set ylpos</a></code><br>
+<code><a href="gradcomdsetxyzte.html" target="pages">set z</a></code><br>
+<code><a href="gradcomdsetzlog.html" target="pages">set zlog</a></code><br>
+<code>query <a href="gradcomdqshades.html" target="pages">shades</a></code><br>
+<a href="shapefiles.html" target="pages">shapefiles</a><br>
+<code><a href="gradcomdshell.html" target="pages">!shell</a></code><br>
+<code>draw <a href="gradcomddrawshp.html" target="pages">shp</a></code><br>
+<code>q <a href="gradcomdqshp.html" target="pages">shp</a></code><br>
+<code>set <a href="gradcomdsetshp.html" target="pages">shp</a></code><br>
+<code>q <a href="gradcomdqshpopts.html" target="pages">shpopts</a></code><br>
+<code>set <a href="gradcomdsetshpopts.html" target="pages">shpopts</a></code><br>
+<code><a href="gradfuncsin.html" target="pages">sin()</a></code><br>
+<code><a href="gradfuncskip.html" target="pages">skip()</a></code><br>
+<code><a href="gradfuncsmth9.html" target="pages">smth9()</a></code><br>
+<code><a href="gradfuncsqrt.html" target="pages">sqrt()</a></code><br>
+<code><a href="gradfuncsregr.html" target="pages">sregr()</a></code><br>
+<a href="start.html" target="pages">starting GrADS</a><br>
+<code>set <a href="gradcomdsetstat.html" target="pages">stat</a></code><br>
+about <a href="aboutstationdata.html" target="pages">station data</a><br>
+using <a href="usingstationdata.html" target="pages">station data</a><br>
+<code>set <a href="gradcomdsetstid.html" target="pages">stid</a></code><br>
+<code><a href="gradfuncstnave.html" target="pages">stnave()</a></code><br>
+<code><a href="gradfuncstnmin.html" target="pages">stnmin()</a></code><br>
+<code><a href="gradutilstnmap.html" target="pages">stnmap</a></code><br>
+<code><a href="gradfuncstnmax.html" target="pages">stnmax()</a></code><br>
+<code>set <a href="gradcomdsetstnprint.html" target="pages">stnprint</a></code><br>
+<a href="fontcontrol.html" target="pages">string formatting</a><br>
+<code>draw <a href="gradcomddrawstring.html" target="pages">string</a></code><br> 
+<code><a href="gradcomdquery.html" target="pages">q</a> string</code><br>
+<code>set <a href="gradcomdsetstring.html" target="pages">string</a></code><br>
+<code>set <a href="gradcomdsetstrmden.html" target="pages">strmden</a></code><br>
+<code>set <a href="gradcomdsetstrsiz.html" target="pages">strsiz</a></code><br>
+<code><a href="gradfuncsum.html" target="pages">sum()</a></code><br>
+<code><a href="gradfuncsumg.html" target="pages">sumg()</a></code><br>
+<a href="supplibs.html" target="pages">supplibs</a><br>
+<code><a href="gradcomdswap.html" target="pages">swap</a></code><br>
+</font>
+<p>
+<a name="indext">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>T</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetxyzte.html" target="pages">t</a></code><br>
+<code><a href="gradfunctan.html" target="pages">tan()</a></code><br>     
+<code><a href="gradfunctcorr.html" target="pages">tcorr()</a></code><br>
+<a href="templates.html" target="pages">templates</a><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> time</code><br>
+<code>set <a href="gradcomdsetlatlonlevtimeens.html" target="pages">time</a></code><br>
+<code>set <a href="gradcomdsettimelab.html" target="pages">timelab</a></code><br>
+<code>draw <a href="gradcomddrawtitle.html" target="pages">title</a></code><br>
+<code><a href="gradfunctloop.html" target="pages">tloop()</a></code><br>
+<code>set <a href="gradcomdsettlsupp.html" target="pages">tlsupp</a></code><br>
+<code><a href="gradfunctmave.html" target="pages">tmave()</a></code><br>
+<code><a href="gradfunctregr.html" target="pages">tregr()</a></code><br>
+<a href="tutorial.html" target="pages">Tutorial</a><br>
+<code><a href="gradfunctvrh2q.html" target="pages">tvrh2q()</a></code><br>
+<code><a href="gradfunctvrh2t.html" target="pages">tvrh2t()</a></code><br>
+</font>
+
+<p>
+<a name="indexu">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>U</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradcomdquery.html" target="pages">q</a> undef</code><br>
+<code>set <a href="gradcomdsetundef.html" target="pages">undef</a></code><br>
+<code><a href="gradcomdundefine.html" target="pages">undefine</a></code><br>
+<a href="udf.html" target="pages">user defined functions</a><br>
+<a href="users.html" target="pages">user's guide</a><br>
+external <a href="utilities.html" target="pages">utilites</a><br>
+</font>
+
+<p>
+<a name="indexv">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>V</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<a href="variable.html" target="pages">variables</a><br>
+<code><a href="gradfuncvint.html" target="pages">vint()</a></code><br>    
+<a href="pagecontrol.html#real" target="pages">virtual page</a><br>
+<code>set <a href="gradcomdsetvpage.html" target="pages">vpage</a></code><br>
+<code>set <a href="gradcomdsetvrange.html" target="pages">vrange</a></code><br>
+<code>set <a href="gradcomdsetvrange2.html" target="pages">vrange2</a></code><br>
+</font>
+
+<p>
+<a name="indexw">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>W</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code><a href="gradcomdquery.html" target="pages">q</a> w2gr</code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> w2xy</code><br>
+<code>set <a href="gradcomdsetwarn.html" target="pages">warn</a></code><br>
+<code><a href="gradcomdwi.html" target="pages">wi</a></code><br>
+<a href="script.html#widgets" target="pages">widgets</a><br>
+<code>set <a href="gradcomdsetwxcols.html" target="pages">wxcols</a></code><br>
+<code>set <a href="gradcomdsetwxopt.html" target="pages">wxopt</a></code><br>
+<code>draw <a href="gradcomddrawwxsym.html" target="pages">wxsym</a></code><br>
+</font>
+
+<p>
+<a name="indexx">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>X</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetxyzte.html" target="pages">x</a></code><br>
+<code>set <a href="gradcomdsetxaxis.html" target="pages">xaxis</a></code><br>
+<code><a href="gradcomdxdfopen.html" target="pages">xdfopen</a></code><br>
+<code>set <a href="gradcomdsetxflip.html" target="pages">xflip</a></code><br>
+<code>draw <a href="gradcomddrawxlab.html" target="pages">xlab</a></code><br>
+<code>set <a href="gradcomdsetxlab.html" target="pages">xlab</a></code><br>
+<code>set <a href="gradcomdsetxlabs.html" target="pages">xlabs</a></code><br>
+<code>set <a href="gradcomdsetxlevs.html" target="pages">xlevs</a></code><br>
+<code>set <a href="gradcomdsetxlint.html" target="pages">xlint</a></code><br>
+<code>set <a href="gradcomdsetxlopts.html" target="pages">xlopts</a></code><br>
+<code>set <a href="gradcomdsetxlpos.html" target="pages">xlpos</a></code><br>
+<code>set <a href="gradcomdsetxsize.html" target="pages">xsize</a></code><br>
+<code>set <a href="gradcomdsetxyrev.html" target="pages">xyrev</a></code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> xy2gr</code><br>
+<code><a href="gradcomdquery.html" target="pages">q</a> xy2w</code><br>
+</font>
+
+<p>
+<a name="indexy">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>Y</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetxyzte.html" target="pages">y</a></code><br>
+<code>set <a href="gradcomdsetyaxis.html" target="pages">yaxis</a></code><br>
+<code>set <a href="gradcomdsetyflip.html" target="pages">yflip</a></code><br>
+<code>draw <a href="gradcomddrawylab.html" target="pages">ylab</a></code><br>
+<code>set <a href="gradcomdsetylab.html" target="pages">ylab</a></code><br>
+<code>set <a href="gradcomdsetylabs.html" target="pages">ylabs</a></code><br>
+<code>set <a href="gradcomdsetylevs.html" target="pages">ylevs</a></code><br>
+<code>set <a href="gradcomdsetylint.html" target="pages">ylint</a></code><br>
+<code>set <a href="gradcomdsetylopts.html" target="pages">ylopts</a></code><br>
+<code>set <a href="gradcomdsetylpos.html" target="pages">ylpos</a></code><br>
+</font>
+
+<p>
+<a name="indexz">
+<table cellpadding=2 border=0 WIDTH=20>
+<tr><td bgcolor="7b2100" align=center valign=center WIDTH=20>
+<font color="fffacd"><b>Z</b></font></td></tr>
+</table>
+</a>
+
+<p class="plaintext">
+<code>set <a href="gradcomdsetxyzte.html" target="pages">z</a></code><br>
+<code>set <a href="gradcomdsetzlog.html" target="pages">zlog</a></code><br>
+</font>
+
+</body>
+</html>
diff --git a/doc/key.gif b/doc/key.gif
new file mode 100644
index 0000000..32b9172
Binary files /dev/null and b/doc/key.gif differ
diff --git a/doc/library.html b/doc/library.html
new file mode 100644
index 0000000..91e0934
--- /dev/null
+++ b/doc/library.html
@@ -0,0 +1,314 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Script Library</title>
+<link rel="stylesheet" href="GrADS.css">
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+-->
+</style>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+<center>
+  <h2 class="banner18">GrADS Script Library</h2>
+</center>
+<p>
+<table border=1 bordercolor=#6699ff cellpadding=3>
+  <tr> 
+    <td valign=top border=1 class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/basemap.gs">basemap.gs</a>    </td>
+    <td class="plaintext">Overlays a land or ocean mask that exactly fits the 
+      coastal outlines. Requires the following supplemental data files:<br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/lpoly_lowres.asc">lpoly_lowres.asc</a> 
+      and <a href="ftp://cola.gmu.edu/grads/scripts/lpoly_mres.asc">lpoly_mres.asc</a> 
+      and <a href="ftp://cola.gmu.edu/grads/scripts/lpoly_hires.asc">lpoly_hires.asc</a><br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/opoly_lowres.asc">opoly_lowres.asc</a> 
+      and <a href="ftp://cola.gmu.edu/grads/scripts/opoly_mres.asc">opoly_mres.asc</a> 
+      and <a href="ftp://cola.gmu.edu/grads/scripts/opoly_hires.asc">opoly_hires.asc</a><br>  
+      See instructions in script header for using <a href="ftp://cola.gmu.edu/grads/scripts/lpoly_US.asc">lpoly_US.asc</a> 
+      to mask out non-US areas. </td>
+  </tr>
+  <tr>
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/box_and_whisker.gs">box_and_whisker.gs</a></td>
+    <td class="plaintext">Demonstrates  how to use gxout bar and errbar to draw a box and whisker plot</td>
+  </tr>
+  <tr> 
+
+    <td valign=top class="plaintext"> <p><a href="ftp://cola.gmu.edu/grads/scripts/cbar.gs">cbar.gs</a> 
+      
+      and <br>
+      
+      <a href="ftp://cola.gmu.edu/grads/scripts/cbarn.gs">cbarn.gs</a> 
+            <br>
+            <a href="ftp://cola.gmu.edu/grads/scripts/cbarm.gs">cbarm.gs</a></p>      </td>
+
+    <td class="plaintext">Scripts to draw a long rectangular color legend next 
+
+      to shaded plots. <br>
+      cbar.gs is the original version -- just the filled rectangles with labels<br>
+      cbarn has some added features and arguments -- it draws outlines and triangular 
+
+      endpoints<br>
+      cbarm will look better if using 30+ colors -- labels are drawn at appropriate intervals</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/cbarc.gs">cbarc.gs</a>    </td>
+
+    <td class="plaintext">Draws a small fan-shaped color legend in the corner 
+
+      of shaded plots.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/cbar_l.gs">cbar_l.gs</a> 
+      <br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/cbar_line.gs">cbar_line.gs</a> 
+      <br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/cbar_line2.gs">cbar_line2.gs      </a><br> </td>
+
+    <td class="plaintext">Scripts to draw a legend for line graphs.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/cmap.gs">cmap.gs</a><br>    </td>
+
+    <td class="plaintext">Creates a color table. See additional <a href="ftp://cola.gmu.edu/grads/scripts/cmapdoc">documentation</a>.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/connect_the_dots.gs">connect_the_dots.gs</a><br>    </td>
+
+    <td class="plaintext">Draws a line connecting user's mouse clicks.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/define_colors.gs">define_colors.gs</a><br>    </td>
+
+    <td class="plaintext">Defines a variety of colors using the <a href="gradcomdsetrgb.html"><span class="code">set 
+
+      rgb</span></a> command.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/defval_demo.gs">defval_demo.gs</a><br>    </td>
+
+    <td class="plaintext">Illustrates the use of <a href="gradcomdquery.html"><span class="code">q 
+
+      defval</span></a> and <a href="gradcomdsetdefval.html"><span class="code">set 
+
+      defval</span></a> commands. </td>
+  </tr>
+
+  <tr>
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/draw_pdsi.gs">draw_pdsi.gs</a></td>
+    <td class="plaintext">Demonstrates a  way to use the shapefile interface in GrADS by drawing the Palmer Drought Severity Index (PDSI) values for U.S. climate divisions.</td>
+  </tr>
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/font.gs">font.gs</a><br>    </td>
+
+    <td class="plaintext">Displays all the characters in a font set.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/isen.gs">isen.gs</a><br>    </td>
+
+    <td class="plaintext">Displays a field interpolated to a specified isentropic 
+
+      level.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/lats4d.gs">lats4d.gs</a><br>    </td>
+
+    <td class="plaintext">Writes NetCDF, HDF-SDS or GRIB files from GrADS. See 
+
+      additional <a href="http://dao.gsfc.nasa.gov/software/grads/lats4d/">documentation</a>.</td>
+  </tr>
+
+  <tr>
+
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/makebg.gs">makebg.gs</a></td>
+
+    <td class="plaintext">Creates a background map image that shows topographic 
+
+      texture. It requires a DODS-enabled version of GrADS and also uses the external 
+
+      ImageMagick utility "combine".</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/map.gs">map.gs</a><br>    </td>
+
+    <td class="plaintext">Automates settings for a variety of useful map projections.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/mconv.gs">mconv.gs</a><br>    </td>
+
+    <td class="plaintext">Calculates moisture convergence.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top border=1 class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/meteogram_eta.gs">meteogram_eta.gs</a><br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/meteogram_gfs.gs">meteogram_gfs.gs</a><br>
+      <a href="ftp://cola.gmu.edu/grads/scripts/meteogram_gfsb.gs">meteogram_gfsb.gs</a></td>
+
+    <td class="plaintext">These scrips draw meteograms based on NCEP forecast 
+      data, which is accessed through the GrADS-DODS Server. You must use a DODS-enabled 
+      version of GrADS for these scripts to work. </td>
+  </tr>
+
+  <tr>
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/narropen.gs">narropen.gs</a></td>
+    <td class="plaintext">This script uses command line arguments to build a data descriptor file   to open  pre-projected (lambert conformal) NARR netCDF data in GrADS (version 1.9b4 or later). </td>
+  </tr>
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/panels.gsf">panels.gsf</a> 
+
+      and<br>
+
+      <a href="ftp://cola.gmu.edu/grads/scripts/panels_demo.gs">panels_demo.gs</a>    </td>
+
+    <td class="plaintext">Scripts to create global variables that contain the 
+
+      'set vpage' commands for a multi-panel plot. These also illustrate the <a href="gsf.html">dynamic 
+
+      loading of script functions</a>.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/script_math_demo.gs">script_math_demo.gs</a><br>    </td>
+
+    <td class="plaintext">Illustrates the use of the scripting language math funcitons.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/pinterp.gs">pinterp.gs</a><br>    </td>
+
+    <td class="plaintext">Displays a field interpolated to a specified pressure 
+
+      level.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/plotskew.gs">plotskew.gs</a><br>    </td>
+
+    <td class="plaintext">Draws a SkewT/LogP Diagram.</td>
+  </tr>
+
+  <tr>
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/rgb255.gs">rgb255.gs</a></td>
+    <td class="plaintext"><span class="style1">(Version 2.0.a6) </span>Defines a set of rainbow colors and draws a demo plot; uses <a href="ftp://cola.gmu.edu/grads/scripts/cbarm.gs">cbarm.gs</a> to draw a color bar</td>
+  </tr>
+  <tr>
+    <td valign=top class="plaintext"><a href="ftp://cola.gmu.edu/grads/scripts/sdfopent.gs">sdfopent.gs</a></td>
+    <td class="plaintext">This script simulates the old 3-arg sdfopen for templating</td>
+  </tr>
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/stack.gs">stack.gs</a><br>    </td>
+
+    <td class="plaintext">Delays display while command sequence is entered by 
+
+      user, then executes all at once.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/string.gs">string.gs</a><br>    </td>
+
+    <td class="plaintext">Draws a string located at position of user's mouse click.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/sweat_index.gs">sweat_index.gs</a><br>    </td>
+
+    <td class="plaintext">Calculates the SWEAT Index given relative humidity, 
+
+      temperature, and wind components.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/traj.gs">traj.gs</a><br>    </td>
+
+    <td class="plaintext">Draws forward and backward trajectories in the horizontal 
+
+      plane.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/use.gs">use.gs</a><br>    </td>
+
+    <td class="plaintext">Similar to <a href="gradcomdopen.html"><span class="code">open</span></a> 
+
+      except it checks the list of current files to see if the specified file 
+
+      has already been opened. If it has been opened, it changes the default file 
+
+      number to the previously opened file instead of opening the same data file 
+
+      again. </td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/wxsym.gs">wxsym.gs</a><br>    </td>
+
+    <td class="plaintext">Displays available weather symbols.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/xanim.gs">xanim.gs</a><br>    </td>
+
+    <td class="plaintext">Controls an animated display.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/zinterp.gs">zinterp.gs</a><br>    </td>
+
+    <td class="plaintext">Displays a field interpolated to a specified height 
+
+      level.</td>
+  </tr>
+
+  <tr> 
+
+    <td valign=top class="plaintext"> <a href="ftp://cola.gmu.edu/grads/scripts/zoom.gs">zoom.gs</a><br>    </td>
+
+    <td class="plaintext">A simple way to zoom into a plot. </td>
+  </tr>
+</table>
+
+
+
+</body>
+
+</html>
+
+
+
+
+
diff --git a/doc/map.html b/doc/map.html
new file mode 100644
index 0000000..f7a238f
--- /dev/null
+++ b/doc/map.html
@@ -0,0 +1,1044 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h1>Using Map Projections in GrADS</h1>
+
+It is important to understand the distinction between the two
+uses of map projections when creating GrADS displays of your
+data:<p>
+
+<ul>
+<li>projection of the data (preprojected grids);<br>
+<li>projection of the display.</ul><p>
+
+GrADS supports two types of data grids:<p>
+<ul>
+<li><code>lon/lat</code> grids (and not necessarily regular,
+e.g., gaussian);<br>
+<li>preprojected grids.</ul><p>
+<ul>
+<a href="#pre">Using Preprojected Grids</a><br>
+<a href="#proj">GrADS Display Projections</a><br>
+<a href="#summary">Summary and Plans</a></ul><br>
+<hr>
+<p>
+
+<a name="pre"><h2><u>Using Preprojected Grids</u></h2></a>
+<ul>
+<a href="#polar">Polar Stereo Preprojected Data</a><br>
+<a href="#lambert">Lambert Conformal Preprojected Data</a><br>
+<a href="#eta">NMC Eta model</a><br>
+<a href="#nmc">NMC high accuracy polar stereo for SSM/I 
+data</a><br>
+<a href="#csu">CSU RAMS Oblique Polar Stereo Grids</a><br>
+<a href="#pit">Pitfalls when using preprojected
+data</a></ul><br>
+<br>
+<ul><b>Preprojected</b> data are data <b>already</b> on a map
+projection. GrADS
+supports four types of preprojected data:<p>
+
+<ol>
+<li>N polar stereo (NMC model projection); 
+<li>S polar stereo (NMC model projection) ; 
+<li>Lambert Conformal (originally for Navy NORAPS model); 
+<li>NMC eta model (unstaggered). 
+<li>More precise N and S polar stereo (hi res SSM/I data) 
+<li>Colorado State University RAMS model (oblique polar stereo;
+beta)</ol><p>
+
+When preprojected grids are opened in GrADS, bilinear
+interpolation constants are calculated and all date are displayed
+on an internal GrADS lat/lon grid defined by the
+<code>xdef</code> and <code>ydef</code>
+card in the data description or <code>.ctl</code> file (that's
+why it takes
+longer to "open" a preprojected grid data set).<p>
+
+It is very important to point out that the internal GrADS grid
+can be any grid as it is completely independent of the
+preprojected data grid.  Thus, there is nothing
+stopping you
+displaying preprojected data on a very high res
+lon/lat grid
+(again, defined in the <code>.ctl</code> by <code>xdef</code> 
+and <code>ydef</code>). In fact, you
+could create and open multiple .ctl files with different
+resolutions and/or regions which pointed to the same
+preprojected
+data file.<p>
+
+When you do a <a
+href="gradcomddisplay.html"><code>display</code></a>
+(i.e., get a grid of data), the
+preprojected data are bilinearly interpolated to
+the GrADS
+internal lat/lon grid.  For
+preprojected
+scalar fields (e.g., 500
+mb heights), the display is adequate and the precision of the
+interpolation can be controlled by <code>xdef</code> and
+<code>ydef</code> to define a
+higher spatial resolution grid.<p>
+
+The big virtue of this approach is that all built in GrADS
+analytic functions (e.g., <a
+href="gradfuncaave.html"><code>aave</code></a>,
+<a href="gradfunchcurl.html"><code>hcurl</code></a>...)
+continue to work even
+though the data were not originally on a lon/lat grid.  The
+downside is that you are not looking directly at your data on a
+geographic map.  However, one could always define a .ctl file
+which simply opened the data file as i,j data and displayed
+without the map (<a href="gradcomdsetmpdraw.html"><code>set
+mpdraw</a> off</code>). So, in my opinion, this
+compromise is not that limiting even if as a modeller you wanted
+to look at the grid--you just don't get the map background.<p>
+
+<code>Preprojected vector fields</code> are a little trickier,
+depending on
+whether the vector is defined relative to the data grid or
+relative to the Earth.  For example, NMC polar stereo grids use
+winds relative to the data grid and thus must be rotated to the
+internal GrADS lat/lon grid (again defined in the
+<code>.ctl</code> file by
+the <code>xdef</code> and <code>ydef</code> cards).<p>
+
+The only potential problem with working with preprojected data
+(e.g., Lambert Conformal model data) is defining the projection
+for GrADS. This is accomplished using a <code>pdef</code> card
+in the data
+descriptor <code>.ctl</code> file.
+</ul><br><br>
+
+<a name="polar"><b><i>Polar Stereo Preprojected Data (coarse
+accuracy for NMC
+Models)</i></b><p>
+<ul>
+Preprojected data on a polar stereo projection (N and S) is
+defined as at NMC.  For the NCEP model GRIB data distributed
+via anon ftp from ftp.ncep.noaa.gov, the <code>pdef</code> card
+is:<p>
+<ul>
+<code>
+pdef isize jsize projtype ipole jpole lonref gridinc<br>
+pdef 53 45 nps 27 49 -105 190.5
+</code>
+</ul><p>
+
+where,<p>
+
+<ul><code>ipole</code> and <code>jpole</code> are the (i,j) of
+the pole referenced from the lower left corner at (1,1) and <code>gridinc</code> is the dx
+in km.</ul><p>
+
+The relevant GrADS source is:<p>
+
+<code>
+void w3fb04 (float alat, float along, float xmeshl, float
+orient,
+float *xi, float *xj) {<br>
+ /* <br>
+C <br>
+C SUBPROGRAM: W3FB04     LATITUDE, LONGITUDE TO GRID
+COORDINATES <br>
+C   AUTHOR: MCDONELL,J.   
+  ORG: W345       DATE: 90-06-04 <br>
+C <br>
+C ABSTRACT: CONVERTS THE
+COORDINATES OF A LOCATION ON EARTH FROM THE <br>
+C   NATURAL
+COORDINATE SYSTEM OF LATITUDE/LONGITUDE TO THE GRID (I,J) <br>
+C  
+COORDINATE SYSTEM OVERLAID ON A POLAR STEREOGRAPHIC MAP PRO
+<br>
+C  
+JECTION TRUE AT 60 DEGREES N OR S LATITUDE. W3FB04 IS THE
+REVERSE<br>
+C   OF W3FB05. <br>
+C <br>
+C PROGRAM HISTORY LOG: <br>
+C   77-05-01  J.
+MCDONELL<br>
+C   89-01-10  R.E.JONES   CONVERT TO MICROSOFT FORTRAN 4.1
+<br>
+C  
+90-06-04  R.E.JONES   CONVERT TO SUN FORTRAN 1.3 <br>
+C
+93-01-26 B.
+Doty     converted to <br>
+C <br>C <br>C USAGE:  CALL W3FB04 (ALAT,
+ALONG,
+XMESHL, ORIENT, XI, XJ) <br>C <br>C   INPUT VARIABLES: <br>C
+NAMES 
+INTERFACE DESCRIPTION OF VARIABLES AND TYPES <br>C     ------
+--------- ----------------------------------------------- <br>C    
+ALAT   ARG LIST  LATITUDE IN DEGREES (<0 IF SH) <br>C     ALONG
+ARG
+LIST  WEST LONGITUDE IN DEGREES <br>C     XMESHL ARG LIST  MESH
+LENGTH OF GRID IN KM AT 60 DEG LAT(<0 IF SH) <br>C                  
+(190.5 LFM GRID, 381.0 NH PE GRID,-381.0 SH PE GRID) <br>C
+ORIENT
+ARG LIST  ORIENTATION WEST LONGITUDE OF THE GRID <br>C                
+  (105.0 LFM GRID, 80.0 NH PE GRID, 260.0 SH PE GRID) <br>C
+<br>C  
+OUTPUT VARIABLES: <br>C     NAMES  INTERFACE DESCRIPTION OF
+VARIABLES
+AND TYPES <br>C     ------ ---------
+----------------------------------------------- <br>C     XI
+ARG
+LIST  I OF THE POINT RELATIVE TO NORTH OR SOUTH POLE <br>C
+XJ    
+ARG LIST  J OF THE POINT RELATIVE TO NORTH OR SOUTH POLE <br>C
+<br>C  
+SUBPROGRAMS CALLED: <br>C     NAMES                                   
+               LIBRARY <br>C    
+------------------------------------------------------- --------
+<br>C     COS SIN                                                
+SYSLIB <br>C <br>C   REMARKS: ALL PARAMETERS IN THE CALLING
+STATEMENT
+MUST BE <br>C     REAL. THE RANGE OF ALLOWABLE LATITUDES IS
+FROM A
+POLE TO <br>C     30 DEGREES INTO THE OPPOSITE HEMISPHERE.
+<br>C THE
+GRID USED IN THIS SUBROUTINE HAS ITS ORIGIN (I=0,J=0) <br>C
+AT
+THE POLE IN EITHER HEMISPHERE, SO IF THE USER'S GRID HAS ITS
+<br>C    
+ORIGIN AT A POINT OTHER THAN THE POLE, A TRANSLATION IS NEEDED
+<br>C  
+  TO GET I AND J. THE GRIDLINES OF I=CONSTANT ARE PARALLEL TO A
+<br>C 
+   LONGITUDE DESIGNATED BY THE USER. THE EARTH'S RADIUS IS TAKEN
+C     TO BE 6371.2 KM. <br>C <br>C ATTRIBUTES: <br>C
+LANGUAGE: SUN FORTRAN
+1.4 C   MACHINE:  SUN SPARCSTATION 1+ <br>C*/ 
+<br>static float
+radpd =
+0.01745329; <br>
+static float earthr = 6371.2;<p>
+
+float re,xlat,wlong,r; <br>
+   re    = (earthr * 1.86603) / xmeshl;<br>
+   xlat
+=  alat * radpd; <br>
+   if (xmeshl>0.0) { <br>
+      wlong =
+(along + 180.0 -
+orient) * radpd; <br>
+         r     =
+(re * cos(xlat)) / (1.0 +
+sin(xlat));
+<br>
+         *xi    =
+r * sin(wlong); <br>
+         *xj = r *
+cos(wlong);<p>
+
+   } else { <br>
+      re    = -re; <br>
+      xlat =
+-xlat;
+<br>
+      wlong = (along - orient) *
+radpd; <br>
+         r     =
+(re * cos(xlat)) / (1.0+ sin(xlat)); <br>
+         *xi =
+r *
+sin(wlong); <br>
+         *xj   =
+-r * cos(wlong); <br>
+   } <br>
+}
+</code></ul>
+<br>
+<br>
+
+<a name="lambert"><b><i>Lambert Conformal Preprojected
+Data</i></b></a><p>
+<ul>
+
+The Lambert Conformal projection (lcc) was implemented for the
+U.S. Navy's limited area model NORAPS.  Thus, to work with your
+lcc data you must express your grid in the context of the Navy
+lcc grid.  NMC has been able to do this for their AIWIPS grids
+and the Navy definition should be general enough for others.<p>
+
+A typical NORAPS Lambert-Conformal grid is described below,
+including the C code which sets up the internal
+interpolation.<p>
+
+The <code>.ctl</code> file is:<p>
+
+<ul>
+<code>
+dset ^temp.grd <br>
+title NORAPS DATA TEST <br>
+undef 1e20 <br>
+pdef 103 69 lcc 30 -88 51.5 34.5 20 40 -88 90000 90000 <br>
+xdef 180 linear -180 1.0<br>
+ydef 100 linear  -10 1.0 <br>
+zdef  16 levels 1000 925 850 700 500 400 300 250 200 150 100 70
+50 30 20 10 <br>
+tdef   1 linear 00z1jan94 12hr<br>
+vars 1 <br>
+   t 16 0 temp <br>
+endvars</code></ul><p>
+
+where,<p>
+
+<ul>
+<code>103   </code>= #pts in x <br>
+<code>69    </code>= #pts in y <br>
+<code>lcc   </code>= Lambert-Conformal <br>
+<code>30    </code>= lat of ref point <br>
+<code>88    </code>= lon of ref point (E is positive, W is negative) <br>
+<code>51.5  </code>= i of ref point <br>
+<code>34.5  </code>= j of ref point <br>
+<code>20    </code>= S true lat <br>
+<code>40    </code>= N true lat <br>
+<code>88    </code>= standard lon <br>
+<code>90000&nbsp</code>= dx in M <br>
+<code>90000&nbsp</code>= dy in M
+</ul><p>
+
+Otherwise, it is the same as other GrADS files.<p>
+
+<b>Note</b> - the <code>xdef/ydef</code> apply to the
+<code>lon/lat</code> grid GrADS internally interpolates to and
+can be anything...<p>
+
+The GrADS source which maps <code>lon/lat</code> of the GrADS
+internal <code>lon/lat</code>
+grid to <code>i,j</code> of the preprojected grid is:<p>
+
+<code>
+<pre>
+/* Lambert Conformal conversion */
+void ll2lc (float *vals, float grdlat, float grdlon, 
+float *grdi, float *grdj) {
+/*  Subroutine to convert from lat-lon to Lambert Conformal i,j.
+Provided by NRL Monterey; converted to C 6/15/94.
+c                SUBROUTINE: ll2lc
+c
+c                PURPOSE: To compute i- and j-coordinates of a specified
+c                         grid given the latitude and longitude points. 
+c                         All latitudes in this routine start 
+c                         with -90.0 at the south pole and increase 
+c                         northward to +90.0 at the north pole.  The 
+c                         longitudes start with 0.0 at the Greenwich 
+c                         meridian and increase to the east, so that 
+c                         90.0 refers to 90.0E, 180.0 is the inter- 
+c                         national dateline and 270.0 is 90.0W. 
+c
+c                INPUT VARIABLES: 
+c 
+c   vals+0         reflat: latitude at reference point (iref,jref) 
+c
+c   vals+1         reflon: longitude at reference point (iref,jref) 
+c 
+c   vals+2         iref:   i-coordinate value of reference point 
+c 
+c   vals+3         jref:   j-coordinate value of reference point 
+c 
+c   vals+4         stdlt1: standard latitude of grid 
+c 
+c   vals+5         stdlt2: second standard latitude of grid (only required 
+c                  if igrid = 2, lambert conformal) 
+c 
+c   vals+6         stdlon: standard longitude of grid (longitude that 
+c                          points to the north) 
+c 
+c   vals+7         delx:   grid spacing of grid in x-direction 
+c                          for igrid = 1,2,3 or 4, delx must be in meters 
+c                          for igrid = 5, delx must be in degrees 
+c 
+c   vals+8         dely:   grid spacing (in meters) of grid in y-direction 
+c                          for igrid = 1,2,3 or 4, delx must be in meters 
+c                          for igrid = 5, dely must be in degrees 
+c 
+c                  grdlat: latitude of point (grdi,grdj) 
+c 
+c                  grdlon: longitude of point (grdi,grdj)
+c 
+c                  grdi:   i-co ordinate(s) that this routine will generate 
+c                          information for 
+c 
+c                  grdj:   j-coordinate(s) that this routine will generate 
+c                          information for 
+c 
+*/
+
+   float pi, pi2, pi4, d2r, r2d, radius, omega4; 
+   float gcon,ogcon,ahem,deg,cn1,cn2,cn3,cn4,rih,xih,yih,rrih,check; 
+   float alnfix,alon,x,y; 
+   pi = 4.0*atan(1.0); 
+   pi2 = pi/2.0; 
+   pi4 = pi/4.0;
+   d2r = pi/180.0; 
+   r2d = 180.0/pi; 
+   radius = 6371229.0; 
+   omega4 = 4.0*pi/86400.0;
+
+/*mf -------------- mf*/ 
+/*case where standard lats are the same */ 
+  if(*(vals+4) == *(vals+5)) { 
+    gcon = sin(*(vals+4)*d2r); 
+  } else { 
+    gcon = (log(sin((90.0-*(vals+4))*d2r))
+    log(sin((90.0-*(vals+5))*d2r)))
+    /(log(tan((90.0-*(vals+4))*0.5*d2r))
+    log(tan((90.0-*(vals+5))*0.5*d2r))); 
+  } 
+/*mf -------------- mf*/
+  ogcon = 1.0/gcon; 
+  ahem = fabs(*(vals+4))/(*(vals+4)); 
+  deg = (90.0-fabs(*(vals+4)))*d2r; 
+  cn1 = sin(deg); 
+  cn2 = radius*cn1*ogcon;
+  deg = deg*0.5; 
+  cn3 = tan(deg); 
+  deg = (90.0-fabs(*vals))*0.5*d2r;
+  cn4 = tan(deg); 
+  rih = cn2*pow((cn4/cn3),gcon); 
+  deg = (*(vals+1)-*(vals+6))*d2r*gcon; 
+  xih = rih*sin(deg); 
+  yih = -rih*cos(deg)*ahem; 
+  deg = (90.0-grdlat*ahem)*0.5*d2r; 
+  cn4 = tan(deg); 
+  rrih = cn2*pow((cn4/cn3),gcon); 
+  check = 180.0-*(vals+6); 
+  alnfix = *(vals+6)+check; 
+  alon = grdlon+check;
+  while (alon<0.0) alon = alon+360.0; 
+  while (alon>360.0) alon = alon-360.0; 
+  deg = (alon-alnfix)*gcon*d2r; 
+  x = rrih*sin(deg); 
+  y = -rrih*cos(deg)*ahem; 
+  *grdi = *(vals+2)+(x-xih)/(*(vals+7)); 
+  *grdj = *(vals+3)+(y-yih)/(*(vals+8)); 
+}
+</pre></code></ul>
+<br>
+<br><a name="eta"><b><i>NMC Eta model (unstaggered
+grids)</i></b></a><p>
+<ul>
+
+The NMC eta model "native" grid is awkward to work with because
+the variables are on staggered (e.g., the grid for winds is not
+the same as the grid for mass points) <i>and</i> non rectangular (number
+of points in i is <i>not</i> constant with j) grids.  Because any
+contouring of irregularly gridded data involves interpolation at
+some point, NMC creates "unstaggered"  eta model fields for
+practical application programs such as GrADS.  In the unstaggered
+grids all variables are placed on a common <i>and</i> rectangular grid
+(the mass points).<p>
+
+Wind rotation has also been added so that vector data will be
+properly displayed.<p>
+
+The pdef card for a typical eta model grid is:<p>
+
+<ul>
+<code>pdef 181 136 eta.u -97.0 41.0 0.38888888 0.37037037</code><p>
+
+<code>181</code>         = #pts in x <br>
+<code>136</code>            = #pts in y <br>
+<code>eta.u</code>      = eta grid, unstaggered<br>
+<code>-97.0</code>      = lon of ref point (E is positive in GrADS, W
+is negative)
+[deg] <br>
+<code>41.0</code>       = lat of ref point [deg] <br>
+<code>0.3888</code>   = dlon [deg] <br>
+<code>0.37037</code> = dlat [deg]</ul><p>
+
+The source code in GrADS for the lon,lat -> i,j mapping is:<p>
+<pre>
+void ll2eg (int im, int jm, float *vals,  float grdlon, float grdlat,
+      float *grdi, float *grdj, float *alpha) {
+
+/*  Subroutine to convert from lat-lon to NMC eta i,j.
+
+    Provided by Eric Rogers NMC; converted to C 3/29/95 by Mike Fiorino.
+
+c                SUBROUTINE: ll2eg 
+c 
+c                PURPOSE: To compute i- and j-coordinates of a specified 
+c                         grid given the latitude and longitude points.
+c                         All latitudes in this routine start 
+c                         with -90.0 at the south pole and increase 
+c                         northward to +90.0 at the north pole.  The 
+c                         longitudes start with 0.0 at the Greenwich 
+c                         meridian and increase to the east, so that 
+c                         90.0 refers to 90.0E, 180.0 is the inter- 
+c                         national dateline and 270.0 is 90.0W. 
+c 
+c                INPUT VARIABLES: 
+c 
+c   vals+0         tlm0d: longitude of the reference center point 
+c 
+c   vals+1         tph0d: latitude of the reference center point 
+c 
+c   vals+2         dlam:  dlon grid increment in deg 
+c 
+c   vals+3         dphi:  dlat grid increment in deg 
+c 
+c 
+c                  grdlat: latitude of point (grdi,grdj) 
+c 
+c                  grdlon: longitude of point (grdi,grdj) 
+c 
+c                  grdi:   i-coordinate(s) that this routine will generate 
+c                          information for 
+c 
+c                  grdj:   j-coordinate(s) that this routine will generate 
+c                          information for 
+c
+
+*/
+
+   float pi,d2r,r2d, earthr;   float tlm0d,tph0d,dlam,dphi;  
+   float 
+    phi,lam,lame,lam0,phi0,lam0e,cosphi,sinphi,sinphi0,cosphi0,sinlam r,cos 
+    lamr;
+   float x1,x,y,z,bigphi,biglam,cc,num,den,tlm,tph;
+
+   int idim,jdim;
+
+   pi=3.141592654;
+
+   d2r=pi/180.0;   
+   r2d=1.0/d2r;   
+   earthr=6371.2;
+
+   tlm0d=-*(vals+0); /* convert + W to + E, the grads standard for
+    longitude */   
+   tph0d=*(vals+1);   
+   dlam=(*(vals+2))*0.5;  
+   dphi=(*(vals+3))*0.5;
+
+   /* grid point and center of eta grid trig */
+
+   /* convert to radians */
+
+   phi    = grdlat*d2r;   
+   lam    = -grdlon*d2r; /* convert + W to + E, the grads standard for 
+    longitude */   
+   lame   = (grdlon)*d2r;
+
+   phi0   = tph0d*d2r;   
+   lam0   = tlm0d*d2r;   
+   lam0e  = ( 360.0 + *(vals+0) )*d2r;
+
+   /* cos and sin */
+
+   cosphi = cos(phi);   
+   sinphi = sin(phi);
+
+   sinphi0 = sin(phi0);   
+   cosphi0 = cos(phi0);
+
+   sinlamr=sin(lame-lam0e);   
+   coslamr=cos(lame-lam0e);
+
+   x1     = cosphi*cos(lam-lam0);   
+   x      = cosphi0*x1+sinphi0*sinphi;   
+   y      = -cosphi*sin(lam-lam0);   
+   z      = -sinphi0*x1+cosphi0*sinphi;
+
+   /* params for wind rotation alpha */
+
+   cc=cosphi*coslamr;   
+   num=cosphi*sinlamr;  
+   den=cosphi0*cc+sinphi0*sinphi;
+
+   tlm=atan2(num,den);
+
+   /* parms for lat/lon -> i,j */
+
+   bigphi = atan(z/(sqrt(x*x+y*y)))*r2d;   
+   biglam = atan(y/x)*r2d;
+
+   idim = im*2-1;   
+   jdim = jm*2-1 ;
+
+   *grdi  = (biglam/dlam)+(idim+1)*0.5;   
+   *grdj  = (bigphi/dphi)+(jdim+1)*0.5;   
+   *grdi  = (*grdi+1)*0.5-1;   
+   *grdj  = (*grdj+1)*0.5-1;
+
+   *alpha = asin( ( sinphi0*sin(tlm)) / cosphi ) ;
+ 
+/*   printf("qqq %6.2f %6.2f %6.2f %6.2f %g %g %g %g\n",    
+       grdlon,grdlat,*grdi,*grdj,*alpha,tlm*r2d,cosphi,sinphi0); 
+*/
+
+}
+</code></pre></ul>
+<br>
+<br>
+
+<a name="nmc"><b><i>NMC high accuracy polar stereo for SSM/I
+data</i></b></a><p>
+<ul>
+The polar stereo projection used by the original NMC models is
+not very precise because it assumes the earth is round
+(eccentricity = 0).  While this approximation was reasonable for
+coarse resolution NWP models, it is inadequate to work with
+higher resolution data such as SSM/I.<p>
+
+<i>Wind rotation has not been implemented!!!  Use only for scalar
+fields.</i><p>
+
+<ul><code>pdef ni nj pse slat slon polei polej dx dy sgn</code><p>
+
+<code>ni</code>           = # points in x
+<br>
+<code>nj</code>          = # points in y <br>
+<code>slat</code>      = absolute value of the standard latitude
+<br>
+<code>slon</code>      = absolute value of the standard longitude
+<br>
+<code>pse</code>         = polar stereo,
+"eccentric"<br>
+<code>polei</code>     = x index position of the pole (where (0,0) is the
+index of the first point vice the more typical (1,1) ) <br>
+<code>polej</code>     = y index position of the pole (where (0,0) is the
+index of the first point vice the more typical (1,1) ) <br>
+<code>dx</code>          = delta x in km <br>
+<code>dy</code>          = delta y in km <br>
+<code>sgn</code>        = 1 for N polar stereo and -1
+for S polar
+stereo</ul><p>
+
+Source code in GrADS for the lon,lat -> i,j mapping:<p>
+<pre>
+</code>
+void ll2pse (int im, int jm, float *vals, float lon, float lat,   
+       float *grdi, float *grdj) {
+
+   /* Convert from geodetic latitude and longitude to polar stereographic      
+      grid coordinates.  Follows mapll by V. J. Troisi.         */   
+   /* Conventions include that slat and lat must be absolute values */   
+   /* The hemispheres are controlled by the sgn parameter */   
+   /* Bob Grumbine 15 April 1994. */
+
+   const rearth = 6738.273e3;   
+   const eccen2 = 0.006693883;  
+   const float pi = 3.141592654;
+
+   float cdr, alat, along, e, e2;
+   float t, x, y, rho, sl, tc, mc;
+   float slat,slon,xorig,yorig,sgn,polei,polej,dx,dy;
+
+   slat=*(vals+0);
+   slon=*(vals+1);
+   polei=*(vals+2);  
+   polej=*(vals+3);
+   dx=*(vals+4)*1000;
+   dy=*(vals+5)*1000;  
+   sgn=*(vals+6);
+
+   xorig = -polei*dx;
+   yorig = -polej*dy;
+
+   /*printf("ppp %g %g %g %g %g %g
+   %g\n",slat,slon,polei,polej,dx,dy,sgn);*/
+
+   cdr   = 180./pi;
+   alat  = lat/cdr;
+   along = lon/cdr;
+   e2    = eccen2;
+   e     = sqrt(eccen2);
+
+   if ( fabs(lat) > 90.)  {
+     *grdi = -1;
+     *grdj = -1;    
+     return;
+   }
+   else {
+     t = tan(pi/4. - alat/2.) /
+       pow( (1.-e*sin(alat))/(1.+e*sin(alat)) , e/2.);
+
+     if ( fabs(90. - slat) < 1.E-3) {
+       rho = 2.*rearth*t/
+     pow( pow(1.+e,1.+e) * pow(1.-e,1.-e) , e/2.);
+       }
+       else {
+         sl = slat/cdr;
+         tc = tan(pi/4.-sl/2.) /
+         pow( (1.-e*sin(sl))/(1.+e*sin(sl)), (e/2.) );
+         mc = cos(sl)/ sqrt(1.-e2*sin(sl)*sin(sl) );
+         rho = rearth * mc*t/tc;
+       }
+
+       x = rho*sgn*cos(sgn*(along+slon/cdr));
+       y = rho*sgn*sin(sgn*(along+slon/cdr));
+
+       *grdi = (x - xorig)/dx+1;
+       *grdj = (y - yorig)/dy+1;
+
+       /*printf("ppp (%g %g) (%g %g %g) %g
+     %g\n",lat,lon,x,y,rho,*grdi,*grdj);*/
+
+       return;
+   }
+
+}
+</code></pre></ul>
+<br>
+<br>
+
+<a name="csu"><b><i>CSU RAMS Oblique Polar Stereo
+Grids</i></b></a><p>
+<ul>
+
+The CSU RAMS model uses an oblique polar stereo projection.  This
+projection is still being tested...<p>
+
+<ul>
+<code>
+pdef 26 16 ops 40.0 -100.0 90000.0 90000.0 14.0 9.0 180000.0
+180000.0</code><p>
+
+<code>26</code>             
+= #pts in x <br>
+<code>16</code>             
+= #pts in y <br>
+<code>ops</code>              =
+oblique polar
+stereo<br>
+<code>40.0</code>           = lat of ref
+point (14.0, 9.0) <br>
+<code>-100.0</code>      = lon of ref point (14.0, 9.0 (E is
+positive in
+GrADS, W is negative) <br>
+<code>90000.0</code>    = xref offset [m] <br>
+<code>90000.0</code>     = yref offset [m]<br>
+<code>14.0</code>          = i of ref point
+<br>
+<code>9.0</code>            = j of
+ref
+point <br>
+<code>180000.0</code>   = dx [m] <br>
+<code>180000.0</code>   = dy [m]</ul><p>
+
+<i>Wind rotation has not been implemented!!!  Use only for scalar
+fields.</i><p>
+
+Source code in GrADS for the lon,lat -> i,j mapping:<p>
+<pre>
+<code>
+void ll2ops(float *vals, float lni, float lti, float *grdi, float *grdj) 
+   {
+
+   const float radius = 6371229.0 ;   
+   const float pi = 3.141592654;
+
+   float stdlat, stdlon, xref, yref, xiref, yjref, delx , dely;
+
+   float plt,pln;   
+   double pi180,c1,c2,c3,c4,c5,c6,arg2a,bb,plt1,alpha,
+   pln1,plt90,argu1,argu2;
+
+   double hsign,glor,rstdlon,glolim,facpla,x,y;
+
+   stdlat = *(vals+0);
+   stdlon = *(vals+1);
+   xref = *(vals+2);  
+   yref = *(vals+3);
+   xiref = *(vals+4);
+   yjref = *(vals+5);  
+   delx = *(vals+6);
+   dely = *(vals+7);
+
+   c1=1.0 ;
+   pi180 = asin(c1)/90.0;
+
+/* 
+c 
+c     set flag for n/s hemisphere and convert longitude to <0 ; 360> 
+   interval 
+c 
+*/
+   if(stdlat >= 0.0) {
+     hsign= 1.0 ;  
+   } else {
+     hsign=-1.0 ;
+   } 
+/* 
+c 
+c     set flag for n/s hemisphere and convert longitude to <0 ; 360> 
+   interval 
+c 
+*/  
+   glor=lni ;
+   if(glor <= 0.0) glor=360.0+glor ;
+   rstdlon=stdlon;  
+   if(rstdlon < 0.0) rstdlon=360.0+stdlon;
+
+/* 
+c 
+c     test for a n/s pole case 
+c 
+*/
+   if(stdlat == 90.0) {   
+     plt=lti ;
+     pln=fmod(glor+270.0,360.0) ;
+     goto l2000;
+   }
+
+  if(stdlat == -90.0) {
+     plt=-lti ;    
+     pln=fmod(glor+270.0,360.0) ;
+     goto l2000;
+   }
+
+/* 
+c 
+c     test for longitude on 'greenwich or date line' 
+c 
+*/  
+   if(glor == rstdlon) {
+     if(lti > stdlat) {      
+       plt=90.0-lti+stdlat;
+       pln=90.0;
+     } else {
+       plt=90.0-stdlat+lti;
+       pln=270.0;;
+     }   
+     goto l2000;
+   }
+
+   if(fmod(glor+180.0,360.0) == rstdlon) {    
+     plt=stdlat-90.0+lti;
+     if(plt < -90.0) {
+       plt=-180.0-plt;  
+       pln=270.0;
+     } else {
+       pln= 90.0;
+     }
+     goto l2000;
+   }
+
+/* 
+c 
+c     determine longitude distance relative to rstdlon so it belongs to 
+c     the absolute interval 0 - 180 
+c 
+*/
+   argu1 = glor-rstdlon;
+   if(argu1 > 180.0) argu1 = argu1-360.0;
+   if(argu1 < -180.0) argu1 = argu1+360.0;
+
+/* 
+c 
+c     1. get the help circle bb and angle alpha (legalize arguments) 
+c 
+*/
+
+   c2=lti*pi180 ;
+   c3=argu1*pi180 ;
+   arg2a = cos(c2)*cos(c3) ;  
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = max1(arg2a,-c1)  */  
+   if(  c1 < arg2a ) arg2a = c1 ; /* min1(arg2a, c1)         */
+   bb = acos(arg2a) ;
+
+   c4=hsign*lti*pi180 ;
+   arg2a = sin(c4)/sin(bb) ;
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a = c1  ; /* arg2a = dmin1(arg2a, c1) */
+   alpha = asin(arg2a) ; 
+/* 
+c 
+c     2. get plt and pln (still legalizing arguments) 
+c 
+*/
+   c5=stdlat*pi180 ;
+   c6=hsign*stdlat*pi180 ;  
+   arg2a = cos(c5)*cos(bb) + sin(c6)*sin(c4) ;
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a = c1  ; /* arg2a = dmin1(arg2a, c1) */
+   plt1   = asin(arg2a) ;
+
+   arg2a = sin(bb)*cos(alpha)/cos(plt1) ;
+
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */  
+   pln1   = asin(arg2a) ;
+
+/* 
+c 
+c    test for passage of the 90 degree longitude (duallity in pln) 
+c         get plt for which pln=90 when lti is the latitude 
+c 
+*/   
+   arg2a = sin(c4)/sin(c6);
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+   plt90 = asin(arg2a) ;
+
+/* 
+c  
+c         get help arc bb and angle alpha 
+c 
+*/
+   arg2a = cos(c5)*sin(plt90) ;
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+   bb    = acos(arg2a) ;
+
+   arg2a = sin(c4)/sin(bb) ;
+   if( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+   if(  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+   alpha = asin(arg2a) ;
+
+/* 
+c 
+c         get glolim - it is nesc. to test for the existence of solution 
+c 
+*/
+   argu2  = cos(c2)*cos(bb) / (1.-sin(c4)*sin(bb)*sin(alpha)) ;
+   if( fabs(argu2) > c1 ) {    
+     glolim = 999.0;
+   } else {
+     glolim = acos(argu2)/pi180;
+   }
+
+/* 
+c 
+c
+     modify (if nesc.) the pln solution 
+c 
+*/
+   if( ( fabs(argu1) > glolim && lti <= stdlat ) || ( lti > stdlat ) ) {   
+     pln1 = pi180*180.0 - pln1;
+   } 
+/* 
+c 
+c     the solution is symmetric so the direction must be if'ed 
+c 
+*/
+   if(argu1 < 0.0) { 
+     pln1 = -pln1;
+   } 
+/* 
+c 
+c     convert the radians to degrees
+c 
+*/
+   plt = plt1/pi180 ;
+   pln = pln1/pi180 ;
+
+/* 
+c
+c     to obtain a rotated value (ie so x-axis in pol.ste. points east) 
+c     add 270 to longitude 
+c 
+*/  
+   pln=fmod(pln+270.0,360.0) ;
+
+ l2000:
+
+/* 
+c 
+c     this program convert polar stereographic coordinates to x,y ditto 
+c     longitude:   0 - 360  ; positive to the east 
+c     latitude : -90 -  90  ; positive for northern hemisphere 
+c     it is assumed that the x-axis point towards the east and 
+c     corresponds to longitude = 0 
+c 
+c     tsp 20/06-89 
+c 
+c     constants and functions 
+c 
+*/
+   facpla = radius*2.0/(1.0+sin(plt*pi180))*cos(plt*pi180);   
+   x = facpla*cos(pln*pi180) ;   
+   y = facpla*sin(pln*pi180)  ;
+
+   *grdi=(x-xref)/delx + xiref;
+   *grdj=(y-yref)/dely + yjref;
+
+   return;
+
+}
+</pre></code></ul>
+<br>
+<br>
+
+<a name="pit"><b><i>Pitfalls when using preprojected
+data</i></b></a><p>
+<ul>
+
+There are a few <i>gotchas</i> with using preprojected data:<p>
+
+<ol>
+<li>the units in the variable definition for the <code>u</code> and <code>v</code>
+components <b>must</b> be <code>33</code> and <code>34K</code> (the GRIB standard)
+respectively, e.g.,<p>
+
+<ul>
+<code>u 15 33</code>     u component of the wind at 15 pressure levels
+<br>
+<code>v 15 34</code>    v component of the wind at 15 pressure
+levels</ul><p>
+
+<li>wind rotation is handled for polar stereo (N and S)
+preprojected data, but <i>not</i> for Lambert Conformal, as the Navy
+rotates the winds relative to earth.  This will have to be added
+later......
+
+<li>the <code>eta.u</code> <b>and</b> <code>ops</code> projection are still
+experimental...</ol>
+</ul>
+<br>
+<br>
+
+<a name="proj"><h2><u>GrADS Display Projections</u></h2></a>
+<ul>
+Now that you hopefully understand GrADS data grids, it is time to
+discuss display projections. Graphics in GrADS are calculated
+relative to the internal GrADS data grid <code>i,j</code> space, transformed
+to the display device coordinates (e.g., the screen) and then
+displayed.  That is, the i,j of the graphic element is converted
+to <code>lat/lon</code> and then to <code>x,y</code> on the screen via a map
+projection.<p>
+
+GrADS currently supports four <code>display projections</code>:<p>
+
+<ul>
+<li>lat/lon (or spherical);
+<li>N polar stereo (<a href="gradcomdsetmproj.html"><code>set mproj</a> nps</code>);
+<li>S polar stereo (<a href="gradcomdsetmproj.html"><code>set mproj</a> sps</code>);
+<li>the Robinson projection (set lon -180 180, set lat -90 90,
+set mproj robinson).</ul><p>
+
+As you can probably appreciate, the i,j-to-lon/lat-to-screen x,y
+for <code>lon/lat</code> displays is very simple and is considerably more
+complicated for N and S <code>polar stereo</code> projections.<p>
+
+In principle, a Lambert Conformal display projection could be
+implemented.  It just takes work and a simple user interface for
+setting up that display projection.  Actually, the user interface
+(i.e., "set" calls) is the most difficult problem...
+</ul>
+<br>
+<br>
+
+<a name="summary"><h2><u>Summary and Plans</u></h2></a>
+
+<ul>
+GrADS handles map projections in two different ways.  The first
+is preprojected data where the fields are <i>already</i> on a projection
+(e.g., Lambert Conformal).  It is fairly straightforward to
+implement other preprojected data projections and we will be
+fully implementing the NMC eta grid both staggered and
+unstaggered, "thinned" gaussian grids and the CSU RAMS oblique
+polar stereo projection.  The second is in how i,j graphics
+(calculated in "grid" space) are displayed on a map background. 
+Currently, only a few basic projections (lon/lat, polar stereo
+and robinson) are supported, but perhaps the development group
+will tackle this problem.</ul>
+
+
diff --git a/doc/mathfunctions.html b/doc/mathfunctions.html
new file mode 100644
index 0000000..14a52c8
--- /dev/null
+++ b/doc/mathfunctions.html
@@ -0,0 +1,195 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Scripting Language Math Functions</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2><b>GrADS Scripting Language Math Functions</b></h2>
+<p>
+A set of math functions has been developed for use within the GrADS
+scripting language. Their use is somewhat self-explanatory, based on
+the following descriptions of the arguments and return codes.
+
+<p> <br>
+  else if (cmpwrd(name,"math_sqrt")) rc = gsfmath(pcmn,8);<br>
+  else if (cmpwrd(name,"math_abs")) rc = gsfmath(pcmn,9);<br>
+<p><code>rc = math_<i>trigfunc</i>(<i>angle <,angle2> </i>)</code> 
+<ul>
+  <code><i>trigfunc</i>  </code> sin, cos, tan, asin, acos, atan, atan2, 
+  sinh, cosh, tanh, asinh, acosh, or atanh<br>
+  <code><i>angle</i>     </code> must be given in radians 
+  <br>
+  <code><i>angle2</i>    </code> (only used for atan2) <br>
+  <code>rc        </code> the result of 
+  the trig function calculation 
+</ul>
+
+<p>
+<code>rc = math_format(<i>format,num</i>)</code>
+<ul>
+  <code><i>format</i>    </code> a C-language style format 
+  statement for a floating point number, e.g. <code>%5.2f</code><br>
+  <code><i>num</i>       </code> the number 
+  to be formatted<br>
+  <code>rc        </code> the formatted 
+  number
+</ul>
+<code>rc = math_nint(<i>num</i>)</code>
+<ul>
+  <code><i>num</i>       </code> a real number 
+  in decimal form<br>
+  <code>rc        </code> <code><i>num</i></code> 
+  rounded up or down to the nearest integer
+</ul>
+<code>rc = math_int(<i>num</i>)</code>
+<ul>
+  <code><i>num</i>       </code> a real number 
+  in decimal form<br>
+  <code>rc        </code> the integer 
+  part of <code><i>num</i></code> not greater than <code><i>num</i></code>
+</ul>
+<code>rc = math_log(<i>num</i>);</code> 
+<ul>
+  <code><i>num</i>       </code> any number 
+  > 0<br>
+  <code>rc        </code> natural logarithm 
+  of <code><i>num</i></code> 
+</ul>
+<code></code><code>rc = math_log10(<i>num</i>);</code> 
+<ul>
+  <code><i>num</i>       </code> any number 
+  > 0.0<br>
+  
+  <code>rc        </code> base 10 logarithm of <code><i>num</i></code> 
+  
+</ul>
+<code></code><code></code><code>rc = math_pow(<i>num,exponent</i>);</code> 
+<ul>
+  <p><code><i>num</i>       </code> any number<br>
+    <code><i>exponent</i>  </code> any number<br>
+    <code>rc        </code> <code><i>num</i></code> 
+    raised to the power <code><i>exponent</i></code> </p>
+</ul>
+<p><code>rc = math_sqrt(<i>num</i>)</code> </p>
+<ul>
+  <code><i>num</i>       </code> any number<br>
+  <code>rc        </code> the square root 
+  of <code><i>num</i></code> 
+</ul>
+<p><code>rc = math_abs(<i>num</i>)</code> </p>
+<ul>
+  <code><i>num</i>       </code> any number<br>
+  <code>rc        </code> the absolute 
+  value of <code><i>num</i></code> 
+</ul>
+<p><code>rc = math_exp(<i>num</i>)</code> </p>
+<ul>
+  <code><i>num</i>       </code> any number<br>
+  <code>rc        </code> the result of 
+  the exponential function; <code>e</code> raised to the power <code><i>num</i></code>
+</ul>
+<code></code><code>rc = math_fmod(<i>num1,num2</i>);</code> 
+<ul>
+  <code><i>num1</i>      </code> any number<br>
+  <code><i>num2</i>      </code> any number not 
+  equal to zero<br>
+  <code>rc        </code> the remainder 
+  when <code><i>num1</i></code> is divided by <code><i>num2</i></code> 
+</ul>
+<code>rc = math_mod(<i>num1,num2</i>);</code> 
+<ul>
+  <code><i>num1</i>      </code> any number<br>
+  <code><i>num2</i>      </code> any number not 
+  equal to zero<br>
+  <code>rc        </code> the integer 
+  part of the remainder when <code><i>num1</i></code> is divided by <code><i>num2</i></code> 
+</ul>
+<code>rc = math_strlen(<i>string</i>)</code>
+<ul>
+<code><i>string</i>    </code>
+any string variable<br>
+<code>rc        </code>
+the length of <code><i>string</i></code>
+</ul>
+<code>rc = valnum(<i>string</i>)</code>
+<ul>
+  <code><i>string</i>    </code> any string variable<br>
+  <code>rc         0 - <i>string</i></code> 
+  is not a number<br>
+  <code>           1 - 
+  <i>string</i></code> is an integer<br>
+  <code>           2 - 
+  <i>string</i></code> is not an integer
+</ul>
+
+<code>rc = wrdpos(<i>string,int</i>)</code>
+ <ul>
+<code><i>string</i>    </code>
+any string, usually contains more than one word<br>
+<code><i>int</i>       </code>
+an integer<br>
+<code>rc        </code>
+word #<code><i>int</i></code of ><code><i>string</i></code> starts at this character #<br>
+</ul>
+
+
+<p>
+<h3>Usage Notes</h3>
+
+<p>
+These math functions will only work with GrADS version 1.8 (or higher). 
+
+<p>
+<h3>Examples </h3>
+
+<p> These script records were taken from a sample script called "<a href="ftp://cola.gmu.edu/grads/scripts/script_math_demo.gs">script_math_demo.gs</a>". 
+<p>
+<code>
+v = 3.1456<br>
+fmt = '%-6.1f'<br>
+rc = math_format(fmt,v)<br>
+say fmt' of 'v' = 'rc<br>
+<br>
+pi = 3.1415926<br>
+d2r = pi/180<br>
+angd = 45<br>
+ang = angd * d2r<br>
+cos = math_cos(ang)<br>
+say 'cos of 'angd' = 'cos<br>
+<br>
+num = '3.1455'<br>
+rc = valnum(num)<br>
+if (rc = 0) ; say num' is not a number' ; endif<br>
+if (rc = 1) ; say num' is an integer' ; endif<br>
+if (rc = 2) ; say num' is not an integer' ; endif<br>
+<br>
+v = 3.0<br>
+while(v < 4.0) <br>
+  rc1 = math_nint(v)<br>
+  rc2 = math_int(v)<br>
+  print 'nint of 'v' = 'rc1'  int of 'v' = 'rc2<br>
+  v = v + 0.1<br>
+endwhile<br>
+<br>
+pow = math_pow(2,0.5);<br>
+print '2 raised to the power 0.5 = 'pow<br>
+<br>
+num = math_exp(1)<br>
+print 'exp(1) = 'num<br>
+<br>
+fmod = math_fmod(5,2)<br>
+print '5 modulo 2 (the remainder when 5 is divided by 2) = 'fmod<br>
+<br>
+s = 'this is a test'<br>
+rc = math_strlen(s)<br>
+print 'length of the string "'s'" = 'rc
+p = 2<br>
+rc = wrdpos(s,p)<br>
+print 'word 'p' of the string "'s'" starts at character 'rc<br>
+<br>
+</code>
+</body>
+</html>
+
diff --git a/doc/ncdump.html b/doc/ncdump.html
new file mode 100644
index 0000000..e17f493
--- /dev/null
+++ b/doc/ncdump.html
@@ -0,0 +1,189 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>ncdump</h2>
+<code>ncdump [-c] [-h] [-v <i>var1</i>,...] [-b <i>lang</i>] [-f
+<i>lang</i>] [-l <i>len</i>]
+          [-n <i>name</i>] [-d <i>f_digits</i>[,<i>d_digits</i>]]
+<i>file</i></code><p>
+Where:<p>
+<ul>
+<code>-c</code>        Show the values of
+<i>coordinate</i> variables (variables that
+          are also dimensions) as well as the declarations of all
+          dimensions,  variables,  and  attribute  values.   Data
+          values  of non-coordinate variables are not included in
+          the output.  This is the most suitable  option  to  use
+          for  a  brief  look  at the structure and contents of a
+          netCDF file.<p>
+
+<code>-h</code>        Show only the
+<i>header</i>
+information in the output, that is
+          the  declarations  of dimensions, variables, and attributes but no data values for any variables.  The output
+          is  identical  to  using  the <code>-c</code> option except
+that the
+          values of coordinate variables are not  included.   (At
+          most one of <code>-c</code> or <code>-h</code> options may be
+present.) <p>
+<code>-v</code>     
+<code><i>var1,...,varn</i></code><br>
+<ul>
+          The output will include data values for  the  specified
+          variables,  in  addition to the declarations of all dimensions, variables, and attributes.  One or more variables  must be specified by name in the comma-delimited
+          list following this option.  The list must be a  single
+          argument to the command, hence cannot contain blanks or
+          other white space characters.  The named variables must
+          be  valid  netCDF variables in the input-file.  The default, without this option and in the absence of the
+<code>-c</code>
+          or  <code>-h</code> options, is to include data values for
+<i>all</i> variables in the output.</ul><p>
+
+<code>-b <i>lang</i></code><br>
+<ul>
+          A brief annotation in the form of a CDL  comment  (text
+          beginning  with the characters ``//'') will be included
+          in the data section of the output  for  each  `row'  of
+          data, to help identify data values for multidimensional
+          variables.  If <code><i>lang</i></code> begins with
+<code>C</code> or <code>c</code>, then C
+          language  conventions will be used (zero-based indices,
+          last dimension varying fastest).  If <code><i>lang</i></code> 
+begins
+with
+          <code>F</code>  or  <code>f</code>, then Fortran language
+conventions will be
+          used  (one-based  indices,  first   dimension   varying
+          fastest).   In  either case, the data will be presented
+          in the same order; only the  annotations  will  differ.
+          This  option  is  useful  for  browsing  through  large
+          volumes of multidimensional data. </ul><p>    
+
+<code>-f <i>lang</i></code><p>
+<ul>
+Full annotations in the form of trailing  CDL  comments
+          (text  beginning  with the characters ``//'') for every
+          data value (except individual characters  in  character
+          arrays)  will be included in the data section.  If
+<code><i>lang</i></code>
+          begins with <code>C</code> or <code>c</code>,  then  C
+language conventions
+          will  be used (zero-based indices, last dimension varying
+fastest).  If <code><i>lang</i></code> begins with  <code>F</code>  or
+<code>f</code>, then
+          Fortran  language  conventions  will be used (one-based
+          indices, first dimension varying fastest).   In  either
+          case,  the  data  will  be presented in the same order;
+          only the annotations will differ.  This option  may  be
+          useful  for  piping data into other filters, since each
+          data value appears on a separate  line,  fully
+identified.</ul><p>
+
+<code>-l <i>len</i></code><br>
+<ul>
+Changes the default maximum line
+length (80) used
+in
+          formatting lists of non-character data values.     </ul><p>
+
+<code>-n <i>name</i></code><br>
+<ul>
+          CDL requires a name for a netCDF data set, for  use  by
+          <a href="ncgen.html"><code>ncgen -b</code></a> 
+in generating a default netCDF file name. By
+          default, <code>ncdump</code> constructs this name from the
+last component  of  the  pathname  of  the input netCDF file by
+          stripping off any extension it has.  Use the <code>-n</code> 
+option
+          to  specify a different name.  Although the output file
+          name used by <a href="ncgen.html"><code>ncgen -b</code></a> 
+can be specified, it may be wise
+          to  have  <code>ncdump</code> change the default name to avoid
+inadvertantly overwriting a valuable netCDF file when using
+          <code>ncdump</code>, editing the resulting CDL file, and using
+<a href="ncgen.html"><code>ncgen
+          -b</code></a> to generate a new netCDF file from  the  edited
+CDL
+file.</ul><p>
+
+<code>-d <i>float_digits</i>[,</i>double_digits</i>]</code><p>
+<ul>
+Specifies default number of significant digits  to  use
+          in  displaying  floating-point or double precision data
+          values for variables that don't have a  `C_format'  attribute.   Floating-point  data  will be displayed with
+          <code><i>float_digits</i></code> significant digits.  If
+<code><i>double_digits</i></code> is
+          also   specified,   double-precision   values  will  be
+          displayed with that  many  significant  digits.   If  a
+          variable has a `C_format' attribute, that overrides any
+          specified floating-point default.  In  the  absence  of
+          any   <code>-d</code>  specifications,  floating-point  and
+double-
+          precision data are displayed with 7 and 15  significant
+          digits  respectively.  CDL files can be made smaller if
+          less precision is required.  If both floating-point and
+          double-presision  precisions  are  specified,  the  two
+          values must appear separated by a comma (no blanks)  as
+          a  single  argument to the command.  If you really want
+          every last  bit  of  precision  from  the  netCDF  file
+          represented  in the CDL file for all possible floating-
+          point values, you will have to  specify  this  with  <code>-d
+          9,17</code>.</ul></ul>
+
+
+<h3>Usage Notes</h3>
+<code>ncdump</code> generates an  ASCII  representation  of  a
+specified
+     netCDF file on standard output.  The ASCII representation is
+     in a form called <code>CDL</code> (``network Common Data form
+Language'')
+     that  can  be  viewed,  edited,  or serve as input to <a
+href="ncgen.html"><code>ncgen</code></a>.
+     <a href="ncgen.html"><code>ncgen</code></a> is a companion program
+that can generate a binary
+     netCDF  file from a <code>CDL</code> file.  Hence <a
+href="ncgen.html"><code>ncgen</code></a> and <code>ncdump</code> can
+be
+     used  as  inverses  to  transform  the  data  representation
+     between  binary  and ASCII representations.  See <a
+href="ncgen.html"><code>ncgen</code></a> for a
+     description of CDL and netCDF representations.<p>
+
+<code>ncdump</code> defines a default format used for each type of
+netCDF
+     data,  but  this can be changed if a `C_format' attribute is
+     defined for a netCDF variable.  In this  case,  <code>ncdump</code> 
+will
+     use  the `C_format' attribute to format each value.  For example,
+if floating-point data for the netCDF variable <code>Z</code> is
+     known  to  be  accurate to only three significant digits, it
+     would be appropriate to use the variable attribute<p>
+          <dd><code>Z:C_format = "%.3g"</code><p>
+<code>ncdump</code> may also be used as a simple browser for netCDF
+data
+     files,  to  display  the dimension names and sizes; variable
+     names, types, and shapes; attribute names  and  values;  and
+     optionally, the values of data for all variables or selected
+     variables in a netCDF file.<p>
+
+<h3>Examples</h3>
+<ol>
+Look at the  structure  of  the  data  in  the  netCDF  file
+<code>foo.nc</code>:<p>
+<dd><code>ncdump -c foo.nc</code><p>
+<li>Produce an annotated CDL version of the structure  and  data
+     in  the netCDF file <code>foo.nc</code>, using C-style indexing for
+the
+     annotations:<p>
+<dd><code>ncdump -b c foo.nc > foo.cdl</code><p>
+<li>Output data for only the variables <code>uwind</code> and
+<code>vwind</code> from
+     the  netCDF  file <code>foo.nc</code>, and show the floating-point
+data
+     with only three significant digits of precision:<p>
+<dd><code>ncdump -v uwind,vwind -d 3 foo.nc</code><p>
+<li>Produce a fully-annotated (one data value per line)  listing
+     of  the data for the variable <code>omega</code>, using Fortran
+conventions for indices, and changing the netCDF dataset  name  in
+     the resulting CDL file to <code>omega</code>:<p>
+<dd><code>ncdump -v omega -f fortran -n omega foo.nc > Z.cdl</code></ol>
+
diff --git a/doc/ncgen.html b/doc/ncgen.html
new file mode 100644
index 0000000..56e3cd6
--- /dev/null
+++ b/doc/ncgen.html
@@ -0,0 +1,52 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>ncgen</h2>
+<code>ncgen [-b] [-c] [-f] [-n] [-o <i>output_file</i>]
+<i>input_file</i></code><p>
+Where:<p>
+<ul>
+<code>-b</code>   Create a (binary) netCDF file.  If the <code>-o</code> 
+option is absent,  a default file name will be constructed from the
+          netCDF name (specified after the netcdf keyword in  the
+          input) by appending the <code>.nc</code> extension.  If a file
+already exists  with  the  specified  name,  it  will  be
+          overwritten.<p>
+
+<code>-c</code>   Generate C source code that will create a  netCDF
+file
+          matching  the  netCDF specification.  The C source code
+          is written to standard output.<p>
+<code>-f</code>   Generate Fortran source code that will create a
+netCDF
+          file  matching  the  netCDF specification.  The Fortran
+          source code is written to standard output.     <p>
+<code>-o
+<i>outputfile</i></code><br>
+<ul>
+Name for the netCDF file created.  If  this  option  is
+          specified, it implies the <code>-b</code> option.  (This
+option is
+          necessary  because  netCDF  files  cannot  be   written
+          directly  to  standard output, since standard output is
+          not seekable.)</ul><p>
+
+<code>-n</code>   Like <code>-b</code> option, except creates netCDF
+file with the obsolete <code>.cdf</code> extension instead of the
+<code>.nc</code> extension,
+          in the absence of an output filename specified  by  the
+          <code>-O</code>  option.  This option is only supported for
+backward
+          compatibility.</ul></ul><p>
+<h3>Examples</h3>
+<ol>
+<li>Check the syntax of the CDL file <code>foo.cdl</code>:<p>
+<dd><code>ncgen foo.cdl</code><p>
+<li>
+From the CDL file <code>foo.cdl</code>, generate an  equivalent  binary
+     netCDF file named <code>x.nc</code>:<p>
+<dd><code>ncgen -o x.nc foo.cdl</code><p>
+<li>
+From the CDL file <code>foo.cdl</code>, generate a C program containing
+     the  netCDF  function  invocations  necessary  to  create an
+     equivalent binary netCDF file named <code>x.nc</code>:<p>
+<dd><code>ncgen -c -o x.nc foo.cdl</code></ol>
diff --git a/doc/offt.html b/doc/offt.html
new file mode 100644
index 0000000..d57b320
--- /dev/null
+++ b/doc/offt.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>Expression Evaluation Using "offt" Dimension Override</title>
<link href="../../assets/NewIGES.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style1 {color: #990000}
body {
	background-color: #e0f0ff;
}
-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></head>
<body
 text="#000000">


<h2>Expression Evaluation Using "offt" Dimension Override</h2>
<h4>
<a href="#intro">Motivation</a><br>
<a href="#syntax">Syntax</a><br>
  <a href="#tfixed">A Diagonal Slice</a><br>
  <a href="#tvarying">A Time-Varying Diagonal Slice</a><br>
  <a href="#func">Applying a Function Over a Time-Varying Diagonal Slice</a><br>

  <br>
</h4>
<hr>

<h3><a name="intro"></a>Motivation</h3>
<p>The time axis in the GrADS environment is a simple, linear, one-dimensional object, defined by its start time, a time increment, and its length. The ensemble axis in the GrADS environment is also a linear, one-dimensional object, but it can become complicated when the metadata for individual ensemble members is time axis related. Such is the case when individual ensemble members have a start time and a length that is different from the defined time axis. For these kinds of data sets, t [...]
<h3><a name="syntax"></a>Syntax</h3>
<p>Beginning with version 2.0.a7, GrADS has a new interface for making the clarification between absolute time axis indices and indices that are offsets from an ensemble member's initial time. It has been implemented in the expression syntax as part of a <a href="variable.html#names">complete variable declaration</a>, which has three components: </p>
<ul>
  <p><code>abbrev.file#(dimexpr,dimexpr,...)</code>    where: </p>

  <ul>
    <code>abbrev   </code>is the abbreviation for the variable as
    specified in the
    data descriptor file
    <br />
    <code>file#    </code>is the file number that contains
      this variable.  If <code>file#</code> is absent, GrADS assumes the default file number. <br />
      <code>dimexpr  </code>is a dimension expression that locally
      modifies the current dimension environment.
</ul>
</ul>
<p>The new interface allows a <code>dimexpr</code> that specifies an offset
from the variable's initial time (which may be different for each ensemble member). The syntax is "<code>offt</code>" followed by "<code>=/+/-</code>" followed by an offset value. </p>
<p>The  "<code>offt</code>" dimension override is currently supported only for variables associated with a data file -- it will not work with defined variables or for dimension expressions given as arguments to functions such as <code><a href="gradfuncave.html">ave</a></code> or <code><a href="gradfuncsum.html">sum</a></code>. </p>
<h3><a name="tfixed"></a>A Diagonal Slice </h3>
<p>For the purposes of explaining how to use expressions that employ the "<code>offt</code>" dimension override, we use a lag ensemble data set that contains 10 members. Each member is a 96-hour forecast, with output every 6 hours, and initialized at 12-hour intervals. The figure below illustrates the coverage of all 10 members in the Time-Ensemble domain; the rainbow colored boxes represent indivual time steps in each member. 
<p>Suppose you want to extract the 12-hour precipitation forecast from each ensemble member -- this is the third time step from the initial time of each forecast, which would be a diagonal slice through the domain, highlighted in the figure below with a solid black outline:
<p><img src="offt_diag.png" alt="edemo1">

<p>The first step is to set the time dimension to a fixed value by using 'set time' or 'set t' and set the ensemble dimension to include all the desired members:<br>
<code>   'set t 1'<br>
   'set e 1 10'</code>
<p>Next, determine the offset value that will give you the time index you desire. In this example, we want the third time step, which is an offset of two from the initial time, so our offset value is 2. (If you want the first time step of each member, the offset value would be zero.) Now display the variable, using parentheses attached to the variable name to override the time dimension value,  specifying "<code>offt=</code>" with the offset value:<br>
<code>   'd p(offt=2)'</code>
<p> GrADS will retrieve the third valid time step from each ensemble member (GrADS knows the start time of each member because that information is provided in the EDEF entry of the data descriptor file). GrADS then aligns all the retrieved values into a single column and returns a result grid with a fixed T  and a varying E dimension:
<p><img src="offt_1D_t1.png" alt="offt_t1">
<p>Note that the original valid time of the precipitation value from each member is not  retained ... the new valid time associated with this result is taken from the current dimension environment. In this example, the new valid time is first time step in the data set, since the time dimension had been fixed with the <code>'set t 1'</code> command.
<p>
<h3><a name="tvarying"></a>A Time-Varying Diagonal Slice</h3>
<p>Now we expand our data request to include more than one time step. Suppose you want to extract the precipitation values over  the first 24 hours of each ensemble member -- you need the second, third, fourth, and fifth time step from each forecast. This request would be a time-varying diagonal slice through the domain, highlighted in the figure below with a solid black outline:
<p><img src="offtv_diag.png" alt="offtv_diag">
<p>This is accomplished by using the <code><a href="gradfunctloop.html">tloop</a></code> function with an expression that contains the   "<code>offt</code>" dimension override. Begin by setting time to be a varying dimension in the dimension environment. The ensemble dimension is also set to include all desired members: <br>
<code>    'set t 1 4'<br>
    'set e 1 10'</code>
<p>The <code><a href="gradfunctloop.html">tloop</a></code> function will evaluate the expression at fixed times, then reconstruct the time series to obtain a final result that is time varying.
At each step, when <code><a href="gradfunctloop.html">tloop</a></code> is evaluating the expression at a fixed time, it will override the time dimension value with a time offset value instead. The tricky part is creating the   "<code>offt</code>" dimension override expression, which must be relative to the T index of the dimension environment. In our example, want the second, third, fourth, and fifth time steps which correspond to offset values of 1, 2, 3, and 4. Thus, our offse [...]
<code>    'd tloop(p(offt+0))'</code>
<p>The dimension override expression, in this case   "<code>offt+0</code>", is a kind of formula for calculating the offset value using the current t value of the dimension environment. In this case, when t=1, the offset value will be t+0 or 1; when t=2, the offset value will be t+0 or 2; etc. This will achieve the desired result -- as <code><a href="gradfunctloop.html">tloop</a></code> builds the time-varying result, it steps through the desired offset values, retrieving the se [...]
<p><img src="offtv_1D.png" alt="offtv_1d">

<p>Note that if the dimension override expression contained   "<code>offt=0</code>", then this would indicate a straightforward assignment of the time offset value that does not depend on the current dimension environment. When using <code><a href="gradfunctloop.html">tloop</a></code> to retrieve a time-varying diagonal slice, the   "<code>offt</code>" dimension override must be a relative expression (i.e. "+/-value") instead of an assignment expression (i.e. [...]
<h3><a name="func" id="func"></a>Applying a Function Over a Time-Varying Diagonal Slice</h3>
<p>Now we take our time-varying example one step further. Suppose you want to calculate the accumulated precipitation  over  the first 24 hours of each ensemble member -- you need to add the second, third, fourth, and fifth time step from each forecast, which would require summing over the time-varying diagonal slice discussed in the previous section. One way to do this is to create a defined variable that contains the time-varying aligned grid with <code><a href="gradfunctloop.html">tloo [...]
  <code>   'set t 1 4'<br>
   'set e 1 10'</code><br>
<code>   'define pnew = tloop(p(offt+0))'<br>
   'set t 1'<br>
   'd sum(pnew,t=1,t=4)'</code><br>
<p>A more elegant and economical way to achieve the same result is to let the  <code><a href="gradfuncsum.html">sum</a></code> function do the work that the <code><a href="gradfunctloop.html">tloop</a></code> function would do -- <code><a href="gradfuncsum.html">sum</a></code> loops over each time evaluating the expression at a fixed time and returns the sum of all values: <br>
  <code>   'set t 1'<br>
   'set e 1 10'</code><code><br>
   'd sum(p(offt+0),t=1,t=4)'</code>
<p>Remember that the  "<code>offt</code>" dimension override is  supported only for variables associated with a data file -- it will not work with defined variables or for dimension expressions given as arguments to functions such as <code><a href="gradfuncave.html">ave</a></code> or <code><a href="gradfuncsum.html">sum</a></code>. The following expression will return an error message:<br>
<code>   'd sum(p,offt=1,offt=4)' <span class="style1"><=== THIS IS INCORRECT</span></code>
<p>
<p>

<p>

</body>
</html>

\ No newline at end of file
diff --git a/doc/offt_1D_t1.png b/doc/offt_1D_t1.png
new file mode 100644
index 0000000..5b23d01
Binary files /dev/null and b/doc/offt_1D_t1.png differ
diff --git a/doc/offt_diag.png b/doc/offt_diag.png
new file mode 100644
index 0000000..06a2c01
Binary files /dev/null and b/doc/offt_diag.png differ
diff --git a/doc/offtv_1D.png b/doc/offtv_1D.png
new file mode 100644
index 0000000..29b952a
Binary files /dev/null and b/doc/offtv_1D.png differ
diff --git a/doc/offtv_diag.png b/doc/offtv_diag.png
new file mode 100644
index 0000000..d73fb90
Binary files /dev/null and b/doc/offtv_diag.png differ
diff --git a/doc/pagecontrol.html b/doc/pagecontrol.html
new file mode 100644
index 0000000..9feb989
--- /dev/null
+++ b/doc/pagecontrol.html
@@ -0,0 +1,162 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Page Control in GrADS</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2><b>Page Control in GrADS</b></h2>
+<p>
+
+<h3><a name="real">Real and virtual pages</a></h3>
+<p>
+The "real" page is an 8.5x11 page in the landscape or portrait
+orientation.  The orientation is specified when you first startup <a
+href="gradcomdgrads.html">grads</a>. The graphics output window is a
+representation of the real page on your computer screen. The graphics
+window can be any size at all. You can set the dimensions explicitly
+(in pixel coordinates) using the <a href="gradcomdsetxsize.html">set
+xsize</a> command, or you can simply resize the graphics window using
+your mouse. When it comes time to print the contents of the graphics
+window to a real page, the screen coordinates (in pixels) will be
+scaled so the graphics will fit in the real page in the same way they
+fit in the graphics window.
+<p>
+The "virtual" page is a page-within-a-page that fits within the limits
+of the real page. By default, the virtual page is the same as the real
+page, so that real page coordinates are exactly the same as virtual
+page coordinates. All graphics are drawn on the virtual page. The
+limits of the virtual page may be changed by using the following
+command:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetvpage.html">set vpage</a> <i>xmin xmax ymin ymax</i>
+</code>
+</ul>
+
+<p>
+After entering a <a href="gradcomdsetvpage.html"><code>set
+vpage</code></a> command, GrADS will return the size of the virtual
+page in inches. Any arguments to graphics commands that require page
+coordinates in inches are to be given in virtual page
+coordinates. For example, to draw a plot in the lower left quadrant 
+of the real page, use the following command:
+<p>
+<ul>
+<code><a href="gradcomdsetvpage.html">set vpage</a> 0 5.5 0 4.25</code>
+</ul>
+
+<p>
+GrADS will return the following virtual page dimensions: 
+
+<p>
+<ul>
+<code>Virtual page size = 11 8.5</code>
+</ul>
+
+<p>
+If the virtual page has the same aspect ratio as the real page, Grads 
+will give it the same dimensions as the real page -- in this case the virtual page is a mini version of an 11"x8.5" page. Here's another example where the virtual page is a centered square: 
+
+<p>
+<ul>
+<code><a href="gradcomdsetvpage.html">set vpage</a> 4 7 2.75 5.75</code>
+</ul>
+
+<p>
+GrADS will return the following virtual page dimensions: 
+
+<p>
+<ul>
+<code>Virtual page size = 8.5 8.5</code>
+</ul>
+
+<p>
+On the <i>real page</i> the plot will be within a 3" square, but on
+the <i>virtual page</i> in Grads the plot will be within an 8.5"
+square. Remember that any arguments to graphics commands that require
+page coordinates in inches are to be given in virtual page
+coordinates.
+
+<p>
+To return to the default state where the virtual page equals the
+real page, enter:
+<p>
+<ul>
+<a href="gradcomdsetvpage.html"><code>set vpage off</code></a>
+</ul>
+
+<p>
+<h3><a name="plotarea">Controlling the plot area</a></h3>
+<p>
+It is possible to control the area within the virtual page where GrADS
+draws contour plots, maps, or line graphs. The command is:
+<p>
+<ul>
+<code>
+<a href="gradcomdsetparea.html">set parea</a> <i>xmin xmax ymin ymax</i>
+</code>
+</ul>
+
+<p>
+This area does not include axis labels, titles, color bars, etc., so
+be sure to provide for adequate margins in order to see these
+features. Note that the plot area is specified in terms of virtual
+page units.
+
+<p>
+GrADS chooses an appropriate default plotting area depending on
+the type of graphics output. To return to this default, enter:
+
+<p>
+<ul>
+<code><a href="gradcomdsetparea.html">set parea</a> off</code>
+</ul>
+
+<p>
+Line graphs and contour plots that don't contain a map will be scaled
+to fill the entire plot area. Any plot that contains a map projection
+will be scaled to fit within the plotting area while maintaining a
+correct lat/lon aspect ratio. Thus, the map may not fill the entire
+plotting area except under certain lat/lon ranges.  This feature may
+be turned off by setting the map projection to "scaled". See the
+reference page for <a href="gradcomdsetmproj.html">set mproj</a> for
+additional map projection options.
+
+<p>
+<h3><a name="multipanel">Drawing Multi-Panel Plots</a></h3>
+
+<p>
+For drawing multi-panel plots, use <a
+href="gradcomdsetvpage.html"><code>set vpage</code></a> to define
+several virtual pages that fit within the limits of the real page. 
+Virtual pages may overlap.
+The sample script called 
+<a href="ftp://cola.gmu.edu/grads/scripts/panels_demo.gs">
+<code>panels_demo.gs</code></a> demonstrates how to set up virtual
+page coordinates for a multi-panel plot with a specified number of
+rows and columns. It uses a <a href="gsf.html">GrADS script function</a>
+called <a href="ftp://cola.gmu.edu/grads/scripts/panels.gsf">
+<code>panels.gsf</code></a>. 
+
+<p>
+If you want to place a label or some other graphic element in each panel, 
+the position is given in virtual page coordinates. These coordinates
+will be the same no matter which panel you're in. This makes it easy
+to shift the labels in one direction or another to accomodate the
+graphics.
+
+<p>
+Do not use <a href="gradcomdsetparea.html"><code>set parea</code></a>
+to draw multiple plots on one page. That is not what
+<code>parea</code> was designed for.  It is far better (and easier!) to
+use the <a href="gradcomdsetvpage.html"><code>set vpage</code></a>
+command as described above.
+
+
+</body>
+</html>
+
diff --git a/doc/pages.html b/doc/pages.html
new file mode 100644
index 0000000..0df2946
--- /dev/null
+++ b/doc/pages.html
@@ -0,0 +1,12 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<body bgcolor="e0f0ff" text="#000000">
+
+<center>
+Click on one of the letters above or click on any entry in the Index. 
+</center>
+
+</body>
+</html>
+
diff --git a/doc/pdef.html b/doc/pdef.html
new file mode 100644
index 0000000..a4e06ba
--- /dev/null
+++ b/doc/pdef.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>PDEF - Displayng Pre-Projected Data in GrADS</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="GrADS.css" rel="stylesheet" type="text/css">
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>
</head>

<body bgcolor="e0f0ff">
<p class="banner18">Use PDEF For Displaying Pre-Projected Data With GrADS</p>
<p class="plaintext"><a href="#about">Display pre-projected data with PDEF</a><br>
  <a href="#syntax">PDEF Syntax</a><br>
  <a href="#interp">How grid interpolation works</a><br>
  <a href="#rotation">How wind rotation works</a><br>
  <a href="#bilin">PDEF BILIN option</a><br>
  <a href="#file">PDEF GENERAL option</a><br>
  <a href="#file">PDEF FILE option</a></p>
<table width="650" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td><p class="plaintext"><a name="about" class="item12bold">Display Pre-Projected 
        Data with PDEF</a></p>
      <p class="plaintext">Gridded data that are mapped onto a particular map 
        projection are called 'pre-projected.' An example of pre-projected data 
        is the output from a weather forecast model that is mapped onto a north 
        polar stereographic grid. </p>
      <p class="plaintext">In order to display pre-projected data on a map in 
        GrADS, the descriptor file must contain a PDEF entry. A descriptor file 
        that contains a PDEF record describes two different grids. The first grid 
        is described by the PDEF record itself and is the "native" grid 
        for the pre-projected data in the file. The second 
        grid described in the desctiptor file is a rectilinear lat/lon grid, which 
        is defined by the XDEF and YDEF records. The PDEF record describes the 
        size of the native grid, and then describes how to convert from i/j of the native grid to the lat/lon values of the rectilinear grid described by XDEF and YDEF. The information in the PDEF entry describes the 
        projection of the grid along with the projection constants or providing 
        the mapping to the native grid in a supplementary data file. The rectilinear grid is used 
        by GrADS internally and can be any size or resolution -- it is completely 
        independent of the pre-projected or native grid. GrADS uses the information 
        about the two grids to interpolate from the PDEF-described native grid 
        to the XDEF/ YDEF-described rectilinear grid. All displays and analyses 
        are done using the interpolated data on the rectilinear grid. The virtue 
        of this approach is that all built in GrADS analytic functions (e.g., 
        <a
href="/grads/gadoc/gradfuncaave.html">aave</a>, <a href="/grads/gadoc/gradfunchcurl.html">hcurl</a>...) 
        will work even though the data were not originally on a lon/lat grid. 
        The downside is that you are looking at interpolated data. </p>
      <p class="plaintext">It is possible to view the pre-projected data on its 
        native grid. To do this, you omit the PDEF entry from the descriptor file, 
        and use the XDEF and YDEF entries to describe the shape of the native 
        grid. In this case, your displays must be drawn in i/j space without a 
        map projection (<a href="/grads/gadoc/gradcomdsetmpdraw.html">set mpdraw</a> 
        off). </p>
      <p class="plaintext">When you do a <a
href="/grads/gadoc/gradcomddisplay.html">display</a> of a pre-projected vector 
        field, you must know whether the original vector components are defined 
        relative to the data grid or relative to the Earth. If the data are grid-relative, 
        they must be rotated to Earth-relative coordinates in order for the interpolation 
        to work properly. See the "Notes" under each particular projection 
        type for further information.</p>
      <p class="item12bold"><a name="syntax"></a>PDEF Syntax</p>
      <ul>
        <table width="600" border="0" cellpadding="0" cellspacing="4" class="plaintext">
          <tr bgcolor="#CCCCCC"> 
            <td colspan="3"> <strong>PDEF <em>isize jsize</em> NPS<em> ipole jpole 
              lonref gridinc</em><br>
              PDEF <em>isize jsize</em> SPS<em> ipole jpole lonref gridinc</em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td width="50" align="right">Example:</td>
            <td colspan="2">PDEF 53 45 nps 27 49 -105 190.5</td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top">Args: </td>
            <td colspan="2"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr class="plaintext"> 
                  <td width="60" valign="top"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>ipole</em></td>
                  <td>the i coordinate of the pole referenced from the lower left 
                    corner, assumed to be at (1,1)</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jpole</em></td>
                  <td>the j coordinate of the pole referenced from the lower left 
                    corner, assumed to be at (1,1)</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>lonref</em></td>
                  <td>reference longitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>gridinc</em></td>
                  <td>distance between gripoints in km</td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Notes: </td>
            <td colspan="2">Polar stereographic projections (N and S) are defined 
              as at NCEP. Wind rotation has also been added so that vector data 
              will be properly displayed. </td>
          </tr>
          <tr> 
            <td> </td>
            <td colspan="2"> </td>
          </tr>
          <tr bgcolor="#CCCCCC"> 
            <td colspan="3"><strong>PDEF <em>isize jsize</em> LCCR <em>latref 
              lonref iref jref Struelat Ntruelat slon dx dy<br>
              </em>PDEF <em>isize jsize</em> LCC <em>latref lonref iref jref Struelat 
              Ntruelat slon dx dy</em><em> </em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right">Example:</td>
            <td colspan="2">PDEF 103 69 lccr 30 -88 51.5 34.5 20 40 -88 90000 
              90000</td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top" bgcolor="b8c8d7">Args: </td>
            <td colspan="2"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr class="plaintext"> 
                  <td width="60" valign="top"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>latref</em></td>
                  <td>reference latitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>lonref</em></td>
                  <td>reference longitude (in degrees, E is positive, W is negative)                  </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>iref</em></td>
                  <td>i of ref point </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jref</em></td>
                  <td>j of ref point </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>Struelat</em></td>
                  <td>S true lat </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>Ntruelat</em></td>
                  <td>N true lat </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>slon</em></td>
                  <td>standard longitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>dx</em></td>
                  <td>grid X increment in meters</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>dy</em></td>
                  <td>grid Y increment in meters</td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top" bgcolor="ccdceb">Notes: </td>
            <td colspan="2">Starting with version 1.9b4, the LCCR option supplements 
              the use of PDEF with data on the Lambert Conformal projection. With 
              LCCR, wind rotation has been implemented for data files with grid-relative 
              winds instead of Earth-relative winds. Use LCC if your vector components 
              are already Earth-relative. </td>
          </tr>
          <tr> 
            <td> </td>
            <td width="9%"> </td>
            <td width="82%"> </td>
          </tr>
          <tr bgcolor="#CCCCCC"> 
            <td colspan="3"><strong>PDEF <em>isize jsize </em>ETA.U<em> lonref 
              latref dlon dlat</em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right">Example:</td>
            <td colspan="2">PDEF 181 136 eta.u -97.0 41.0 0.38888888 0.37</td>
          </tr>
          <tr> 
            <td align="right" valign="top" bgcolor="b8c8d7">Args: </td>
            <td colspan="2" bgcolor="b8c8d7"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr class="plaintext"> 
                  <td width="60" valign="top"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">lonref</td>
                  <td>reference longitude (in degrees, E is positive, W is negative)                  </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">latref</td>
                  <td>reference latitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">dlon</td>
                  <td>grid longitude increment in degrees</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">dlat</td>
                  <td>grid latitude increment in degrees</td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Notes: </td>
            <td colspan="2">The eta model native grid is awkward to work with 
              because the variables are on staggered <i>and</i> non-rectangular 
              grids. NCEP created "unstaggered" eta model fields, in which the 
              variables are placed on a common rectangular grid. Wind rotation 
              has also been added so that vector data will be properly displayed.            </td>
          </tr>
          <tr> 
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr bgcolor="#CCCCCC"> 
            <td colspan="3"><strong>PDEF <em>isize jsize</em> PSE <em>slat slon 
              ipole jpole dx dy sign</em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Example:</td>
            <td colspan="2"> </td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top">Args: </td>
            <td colspan="2"> <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr class="plaintext"> 
                  <td width="60" valign="top"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top"><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">slat</td>
                  <td>absolute value of the standard latitude </td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">slon</td>
                  <td>absolute value of the standard longitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">ipole</td>
                  <td>the i coordinate of the pole referenced from the lower left 
                    corner, assumed to be at (0,0)</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">jpole</td>
                  <td>the j coordinate of the pole referenced from the lower left 
                    corner, assumed to be at (0,0)</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">dx</td>
                  <td>grid X increment in km</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">dy</td>
                  <td>grid Y increment in km</td>
                </tr>
                <tr class="plaintext"> 
                  <td valign="top">sign</td>
                  <td>1 for NH; -1 for SH</td>
                </tr>
              </table></td>
          </tr>
          <tr> 
            <td align="right" valign="top" bgcolor="ccdceb">Notes: </td>
            <td colspan="2" bgcolor="ccdceb">The polar stereo projection used 
              by the original NMC models is not very precise because it assumes 
              the earth is round (eccentricity = 0). While this approximation 
              was reasonable for coarse resolution NWP models, it is inadequate 
              to work with higher resolution data such as SSM/I. <i>Wind rotation 
              has not been implemented!!! Use only for scalar fields.</i></td>
          </tr>
          <tr> 
            <td> </td>
            <td> </td>
            <td> </td>
          </tr>
          <tr bgcolor="#CCCCCC"> 
            <td colspan="3"><strong>PDEF <em>isize jsize</em> OPS <em> latref 
              lonref xoff yoff iref jref dx dy </em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right">Example:</td>
            <td colspan="2">PDEF 26 16 ops 40.0 -100.0 90000.0 90000.0 14.0 9.0 
              180000.0 180000.0 </td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top" bgcolor="b8c8d7">Args: </td>
            <td colspan="2"> <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
                <tr class="plaintext"> 
                  <td width="60"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td>latref</td>
                  <td>reference latitude</td>
                </tr>
                <tr class="plaintext"> 
                  <td>lonref</td>
                  <td>reference longitude (in degrees, E is positive, W is negative)                  </td>
                </tr>
                <tr class="plaintext"> 
                  <td>xoff</td>
                  <td>lonref offset in meters</td>
                </tr>
                <tr class="plaintext"> 
                  <td>yoff</td>
                  <td>latref offset in meters</td>
                </tr>
                <tr class="plaintext"> 
                  <td>iref</td>
                  <td>the i coordinate of the reference point</td>
                </tr>
                <tr class="plaintext"> 
                  <td>jref</td>
                  <td>the j coordinate of the reference point</td>
                </tr>
                <tr class="plaintext"> 
                  <td>dx</td>
                  <td>grid X increment in km</td>
                </tr>
                <tr class="plaintext"> 
                  <td>dy</td>
                  <td>grid Y increment in km</td>
                </tr>
                <tr class="plaintext"> 
                  <td>dy</td>
                  <td>grid Y increment in km</td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Notes: </td>
            <td colspan="2">The CSU RAMS model uses an oblique polar stereo projection. 
              <i>Wind rotation has not been implemented!!! Use only for scalar 
              fields.</i></td>
          </tr>
          <tr bgcolor="ccdceb">
            <td align="right" valign="top" bgcolor="#FFFFFF"> </td>
            <td colspan="2" bgcolor="#FFFFFF"> </td>
          </tr>
          <tr bgcolor="#CCCCCC">
            <td colspan="3"><strong>PDEF <em>isize jsize</em> ROTLL<em> lonpol latpol dlon dlat lonll latll <br>
            </em>PDEF <em>isize jsize</em> ROTLLR<em> lonpol latpol dlon dlat lonll latll </em></strong></td>
          </tr>
          <tr bgcolor="#CCCCCC"></tr>
          <tr bgcolor="ccdceb">
            <td align="right">Example:</td>
            <td colspan="2">PDEF 500 330 rotllr -170.0  43.0   0.02   0.02  -5.5 -3.8</td>
          </tr>
          <tr bgcolor="b8c8d7">
            <td align="right" valign="top" bgcolor="b8c8d7">Args: </td>
            <td colspan="2"><table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
                <tr class="plaintext">
                  <td width="60"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext">
                  <td><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr class="plaintext">
                  <td>lonpol</td>
                  <td>Longitude of the rotated pole in degrees</td>
                </tr>
                <tr class="plaintext">
                  <td>latpol</td>
                  <td>Latitude of the rotated pole in degrees</td>
                </tr>
                <tr class="plaintext">
                  <td>dlon</td>
                  <td>grid spacing in longitudinal direction of the rotated grid in degrees</td>
                </tr>
                <tr class="plaintext">
                  <td>dlat</td>
                  <td>grid spacing in latitudinal direction of the rotated grid in degrees</td>
                </tr>
                <tr class="plaintext">
                  <td>lonll</td>
                  <td>longitude of the lower left corner, given in rotated space in degree</td>
                </tr>
                <tr class="plaintext">
                  <td>latll</td>
                  <td>latitude of the lower left corner, given in rotated space in degree</td>
                </tr>

            </table></td>
          </tr>
          <tr bgcolor="ccdceb">
            <td align="right" valign="top">Notes: </td>
            <td colspan="2" bgcolor="ccdceb"><p>(<font color="#990000">GrADS version 2.0</font>) The rotated lat/lon grid projection is described in the  <a href="http://www.cosmo-model.org/public/documentation.htm">COSMO documentation</a>, Part 1, chapter 3.3. The lower left corner, i.e. the first element in the data array, has to be the southwest corner.  It is  not possible to use a mirrored grid by setting dlon or dlat to a negative value.</p>            </td>
          </tr>
          
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top" bgcolor="#FFFFFF"> </td>
            <td colspan="2" bgcolor="#FFFFFF"> </td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td colspan="3" align="left" valign="top" bgcolor="#CCCCCC"> <p><strong>PDEF<em> 
                isize jsi</em>ze BILIN <em>format byteorder fname</em></strong></p></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Example:</td>
            <td colspan="2">PDEF 100 100 BILIN sequential binary-big ^mygrid.interp.values            </td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top" bgcolor="b8c8d7">Args:</td>
            <td colspan="2"> <table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
                <tr class="plaintext"> 
                  <td width="60"><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr class="plaintext"> 
                  <td><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr> 
                  <td><em>format</em></td>
                  <td>Must be either STREAM (direct access) or SEQENTIAL (fortran 
                    formatted)</td>
                </tr>
                <tr> 
                  <td valign="top"><em>byteorder</em></td>
                  <td>If set to BINARY, byte odering is assumed to be same as 
                    local machine<br>
                    If set to BINARY-BIG, byte ordering is assumed to be big-endian<br>
                    If set to BINARY-LITTLE, byte ordering is assumed to be little-endian</td>
                </tr>
                <tr> 
                  <td valign="top"><em>fname</em></td>
                  <td>The name of the supplementary file </td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Notes:</td>
            <td colspan="2">The supplementary file contains three lat-lon floating-point 
              grids: i values, j values, and wind rotation values. The native grid  is assumed to have a corner (i,j) value of (1,1). The size of 
              these grids must match the XDEF and YDEF entries in the descriptor 
              file. </td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top" bgcolor="#FFFFFF"> </td>
            <td colspan="2" bgcolor="#FFFFFF"> </td>
          </tr>
          <tr align="left" bgcolor="#CCCCCC">
            <td colspan="3" valign="top"><strong>PDEF<em> isize jsize</em> GENERAL <em>num 
              format byteorder fname</em></strong></td>
          </tr>
          <tr bgcolor="ccdceb">
            <td align="right" valign="top">Example:</td>
            <td colspan="2">PDEF 182 149  general 4 sequential binary-big ^mygrid.interp.values<br>
              PDEF 15238 1 general 1 stream binary ^gtd.filepdef</td>
          </tr>
          <tr bgcolor="b8c8d7">
            <td align="right" valign="top">Args:</td>
            <td colspan="2"><table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
                <tr>
                  <td><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr>
                  <td><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                <tr>
                  <td width="60"><em>num</em></td>
                  <td>number of sets of interpolation grids supplied</td>
                </tr>
                <tr>
                  <td><em>format</em></td>
                  <td>Must be either STREAM (direct access) or SEQENTIAL (fortran 
                    formatted)</td>
                </tr>
                <tr>
                  <td valign="top"><em>byteorder</em></td>
                  <td>If set to BINARY, byte odering is assumed to be same as 
                    local machine<br>
                    If set to BINARY-BIG, byte ordering is assumed to be big-endian<br>
                    If set to BINARY-LITTLE, byte ordering is assumed to be little-endian</td>
                </tr>
                <tr>
                  <td valign="top"><em>fname</em></td>
                  <td>The name of the supplementary file; it may be mixed case. </td>
                </tr>
            </table></td>
          </tr>
          <tr bgcolor="ccdceb">
            <td align="right" valign="top" bgcolor="ccdceb">Notes:</td>
            <td colspan="2" bgcolor="ccdceb"><p>(<span class="style1">GrADS version 2.0.a3 and later</span>) The syntax and behavior of PDEF GENERAL is exactly like PDEF FILE, except that the convention for the native grid offset values in the pdef file is the same for all data formats. The offsets should be 1-based; the first grid point is assumed to have (i,j) values of (1,1), and  valid offset values are > 0 and <= <em>isize</em>*<em>jsize</em> .</p>
              <p>Native grid offset values of -999 indicate not to use 
        an input point for that portion of the calculation (thus you can apply 
        less than the "<em>num</em>" number of interpolation points for some 
        of the points). </p>
              <p>See additional notes in the paragraphs below.</p></td>
          </tr>
          <tr align="left" bgcolor="#CCCCCC">
            <td colspan="3" valign="top" bgcolor="#FFFFFF"> </td>
          </tr>
          
          <tr align="left" bgcolor="#CCCCCC"> 
            <td colspan="3" valign="top"><strong>PDEF<em> isize jsize</em> FILE <em>num 
              format byteorder fname</em></strong></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Example:</td>
            <td colspan="2">PDEF 182 149 file 4 sequential binary-big ^mygrid.interp.values<br>
              PDEF 15238 1 file 1 stream binary ^gtd.filepdef</td>
          </tr>
          <tr bgcolor="b8c8d7"> 
            <td align="right" valign="top">Args:</td>
            <td colspan="2"><table width="100%" border="0" cellpadding="0" cellspacing="0" class="plaintext">
                <tr>
                  <td><em>isize</em></td>
                  <td>The size of the native grid in the x direction </td>
                </tr>
                <tr>
                  <td><em>jsize</em></td>
                  <td>The size of the native grid in the y direction </td>
                </tr>
                
                <tr> 
                  <td width="60"><em>num</em></td>
                  <td>number of sets of interpolation grids supplied</td>
                </tr>
                <tr> 
                  <td><em>format</em></td>
                  <td>Must be either STREAM (direct access) or SEQENTIAL (fortran 
                    formatted)</td>
                </tr>
                <tr> 
                  <td valign="top"><em>byteorder</em></td>
                  <td>If set to BINARY, byte odering is assumed to be same as 
                    local machine<br>
                    If set to BINARY-BIG, byte ordering is assumed to be big-endian<br>
                    If set to BINARY-LITTLE, byte ordering is assumed to be little-endian</td>
                </tr>
                <tr> 
                  <td valign="top"><em>fname</em></td>
                  <td>The name of the supplementary file; it may be mixed case.                  </td>
                </tr>
              </table></td>
          </tr>
          <tr bgcolor="ccdceb"> 
            <td align="right" valign="top">Notes:</td>
            <td colspan="2" bgcolor="ccdceb"><p>For GrADS v2.0.a2 and earlier, <em>jsize</em> was fixed to be 1, and <em>isize</em> was the size of the native grid expressed as a vector (i.e., all gridpoints in the x-y grid). This mode for describing the native grid will continue to work with v2.0.a3+, but only if the native grid is in GRIB or binary format. For NetCDF and HDF formats, the <em>isize</em> and <em>jsize</em> args must match the X and Y dimensions of the native grid. </p>
            <p><span class="style1">WARNING: The use of PDEF FILE may be incorrect!</span> A long-standing bug and incomplete documentation has led to different conventions for the native grid offset values in the pdef file for GRIB and non-GRIB data formats. For GRIB (1&2), the offsets must be 0-based; the first grid point is assumed to have (i,j) values of (0,0). For all other data types, the offsets must be 1-based; the first grid point is assumed to have (i,j) values of (1,1). Thus:<br>
                   for GRIB format: valid offset values are >= 0 and < <em>isize</em>*<em>jsize</em><br>
                   for other formats: valid offset values are > 0 and <= <em>isize</em>*<em>jsize</em><br>
              To maintain backward compatibility, the bug will remain in GrADS as a feature, but the use of PDEF FILE has been deprecated as of version 2.0.a3 and a warning message will be displayed when a data set is opened that uses PDEF FILE. Note that if you use <a href="http://www.cpc.ncep.noaa.gov/products/wesley/grib2ctl.html">grib2ctl</a> or <a href="http://www.cpc.ncep.noaa.gov/products/wesley/g2ctl.html">g2ctl </a>to generate your pdef file, the offsets are correct. </p>
            <p>Native grid offset values of -999 indicate not to use 
        an input point for that portion of the calculation (thus you can apply 
        less than the "<em>num</em>" number of interpolation points for some 
        of the points). </p>
            <p>See additional notes in the paragraphs below.</p></td>
          </tr>
        </table>
      </ul>
      <p class="item16"> <span class="item12bold"><strong><a name="interp"></a>How 
        PDEF Grid Interpolation Works</strong></span><br>
        <span class="plaintext">To illustrate how the data is interpolated from 
        the native grid to the rectilinear grid, let's consider an example. Here 
        are a set of relevant records from a descriptor file: <br>
        PDEF 100 100 nps ...<br>
        XDEF 181 linear -180 1<br>
        YDEF 90 linear 0 1<br>
        These three entries describe data on a native 100x100 North Polar stereographic 
        projection and a rectilinear lat/lon grid that is 181 by 90 and has an 
        interval of 1 degree in both lat and lon. Consider one point within the 
        rectilinear grid, the point -90,40. GrADS calls an internal routine to 
        calculate the i and j values in the native grid that correspond to this 
        lat/lon point. Let's say we get i,j values of 31.24 and 67.88. To do the 
        interpolation to the lat/lon point -90,40, GrADS uses the data values 
        from the following four native grid points: 31,67 - 31,68 - 32,67 - 32,68. 
        Bi-linear interpolation is used within this grid box to get down to the 
        position 31.24,67.88. The interpolation is linear within the i,j grid. 
        When a descriptor file is opened that contains a PDEF record, GrADS calculates 
        the i/j values in the native grid that correspond to the lat/lon pair 
        for each gridpoint in the rectilinear grid. </span></p>
      <p class="item16"> <span class="item12bold"><strong><a name="rotation"></a>How 
        PDEF Wind Rotation Works</strong></span><br>
        <span class="plaintext">There is a third value calculated for every lat/lon 
        point, and that is the wind rotation value. With some "pre-projected" 
        or native grids, the winds are given relative to the i/j space and not 
        the lat/lon space. To insure correct interpolation, the winds must be 
        rotated to lat/lon space. This is done by determining a rotation amount 
        for each lat/lon point. When u or v wind components are displayed, the 
        values are not just interpolated but also rotated. </span></p>
      <p class="plaintext">To do the wind rotation properly, GrADS requires both 
        the u and v components. Even if you are just displaying u, GrADS has to 
        retrieve (internally) both the u and v component in order to do the rotation 
        calculation. GrADS determines how to match u and v variables by checking 
        the<em> units</em> field of the variable record in the descriptor file. 
        The u variable must have a <em>units</em> value of 33, and the v variable 
        must have a <em>units</em> value of 34. (This is the GRIB convention). 
        If there are more than one u/v pairs, secondary <em>units</em> values 
        are used. For example: 
      <ul>
        <table width="600" border="0" cellpadding="0" cellspacing="0" class="plaintext">
          <tr> 
            <td width="30">u</td>
            <td width="15" align="right">18</td>
            <td width="50" align="center"> <p>33,100</p></td>
            <td > U-Wind Components on Pressure Levels</td>
          </tr>
          <tr> 
            <td>v</td>
            <td align="right">18</td>
            <td align="center">34,100</td>
            <td> V-Wind Components on Pressure Levels</td>
          </tr>
          <tr> 
            <td>u10</td>
            <td align="right">0</td>
            <td align="center"> 33,105</td>
            <td>10 Meter U Wind</td>
          </tr>
          <tr> 
            <td>v10</td>
            <td align="right">0</td>
            <td align="center">34,105</td>
            <td>10 Meter V Wind</td>
          </tr>
        </table>
      </ul>
      <p class="plaintext">might be some variable records in the descriptor file. 
        If wind rotation is called for, u and v would be paired, and u10 and v10 
        would be paired (since the secondary values would be checked, ie, the 
        105,100 values). </p>
      <p class="item16"><span class="item12bold"><strong><a name="bilin"></a>The 
        PDEF BILIN Option</strong></span><br>
        <span class="plaintext">When a descriptor file is opened that contains 
        a PDEF record, we have explained that GrADS internally generates three 
        grids, each one the size of the rectilinear lat/lon grid. The first two 
        grids contain the i and j values (respectively) from the native grid that 
        correspond to each grid point in the rectilinear grid; the third grid 
        contains wind rotation values. But this only works for a small set of 
        well-defined native grids. GrADS will generate these three internal grids 
        automatically for polar stereographic, lamber conformal, and some eta 
        grids. If the native grid for your data is not one of the predefined projections, 
        it is still possible for GrADS to handle the data. All you have to do 
        is supply these three grids to GrADS with a supplementary data file and 
        use the bilin option in your PDEF record. </span></p>
      <p class="plaintext">The supplementary file will contains three lat-lon 
        floating-point grids sized according to the XDEF and YDEF records in the 
        descriptor file.The three grids contain: i values, j values, and wind 
        rotation values. A value of -999 in the i-value grid indicates not to 
        interpolate to that lat-lon point (will end up missing on output) and 
        a value of -999 in the wind-rotation grid indicates not to do wind rotation 
        for that point. If the wind-rotation grid is all -999 values, no rotation 
        is ever done and a flag is set not to even attempt rotation.</p>
      <p class="item16"><span class="item12bold"><strong><a name="file"></a>The 
        PDEF GENERAL Option (and the PDEF FILE option)</strong></span><br>
        <span class="plaintext">All of the PDEF examples discussed so far involve 
        the same method for grid interpolation: a grid point value in the rectilinear 
        grid is calculated by finding the four neighboring grid points in the 
        native grid and averaging them, with weights applied bi-linearly according 
        to their proximity to the to rectilinear grid point. The PDEF GENERAL option 
        and the PDEF FILE option generalize this method so that an arbitrary number of native grid point 
        values and their weights are averaged to generate the interpolated rectilinear 
        grid point values. The index values for the native grid values that are 
        to be used and their weights are specified by the user in a supplementary 
        data file (<em>fname</em>). The  FILE and GENERAL options are identical except for one detail: they have different conventions for the native grid offset values in the supplementary file (see the "Notes" in the syntax tables above for specifics). <br>
        </span></p>
      <p class="plaintext">The <em>num</em> argument in the PDEF FILE entry specifies 
        the number of native grid points that will be used to calcuate each interpolated 
        rectilinear grid point value. For each <em>num, </em>the supplementary 
        data file will contain two grids -- both will be the size of the rectilinear 
        grid (as defined by XDEF and YDEF). The first grid contains the index 
        or offset values that point to the native grid value that will be used 
        in the interpolation; the second grid contains the weights for those native 
        grid values. The first grid contains integer values, the second grid contains 
        floating-point values. Finally, the supplementary data file must also 
        contain one grid of floating-point wind rotation values. Thus if <em>num</em> 
        equals 1, there will be 3 grids in <em>fname</em>. If <em>num</em> equals 
        3, there will be 7 grids in <em>fname</em> (3 sets of 2 grids plus the 
        wind rotation grid). </p>
      <p class="plaintext">To do the grid interpolation, GrADS will first read 
        the data in the native grid (vector) along with the values in the supplementary 
        grids. To calculate the interpolated value for a particular lat-lon point, 
        GrADS will get <em>num</em> native grid point values, multiply each by 
        their weight, sum over all the weighted native grid points, and divide 
        by the sum of the weights. </p>
      <p class="plaintextbold">An Example: </p>
      <p class="plaintext">The original data are set up as a vector of land points 
        only, taken from a 1-degree lat/lon grid. There are 15238 land points 
        in the native grid (vector). We use the PDEF FILE option to repopulate 
        a rectilinear lat/lon grid with the land values, leaving the ocean grid 
        points as missing. In this case, ther eis no interpolation done. The PDEF 
        option is used simply to convert a vector of land points into a 2D grid 
        with ocean points missing. The descriptor file looks like this: 
      <ul>
        <span class="plaintext"> DSET ^gswp_vegetation_parameters.nc<br>
        DTYPE netcdf <br>
        TITLE Monthly Vegetation parameters at 1x1 degree<br>
        UNDEF 1.e+20<br>
        PDEF 15238 1 file 1 stream binary ^gswp.filepdef<br>
        XDEF 360 linear -179.5 1<br>
        YDEF 150 linear -59.5 1<br>
        ZDEF 1 linear 1 1<br>
        TDEF 204 linear 00Z01jan1982 1mo<br>
        VARS 1<br>
        NDVI=>ndvi 0 t,x Monthly vegetation index<br>
        ENDVARS</span> 
      </ul>
      <p class="plaintext">The supplementary file gtd.filepdef contains three 
        grids -- the first contains the index values that associate each location 
        in the lat/lon grid with it's point in the vector. All of the ocean points 
        will have a missing value of -999. The second grid will contain the weights, 
        which will be 1 for land points, 0 for ocean points. The third grid will 
        contain all missing values since wind rotation is not a issue in this 
        example. Here is a descriptor file for the supplementary data file (a 
        useful strategy for making sure you've got everything written out correctly):</p>
      <ul>
        <p class="plaintext">DSET ^gswp.filepdef<br>
          TITLE PDEF file for GSWP Vegetation Parameters<br>
          UNDEF -999<br>
          XDEF 360 linear -179.5 1<br>
          YDEF 150 linear -59.5 1<br>
          ZDEF 1 linear 1 1 <br>
          TDEF 1 linear 00z01jul1982 3hr<br>
          VARS 3<br>
          i 0 -1,40,4 Index Values<br>
          w 0 99 Weights<br>
          r 0 99 Wind Rotation Values<br>
          ENDVARS</p>
        <p></p>
        <p> </p>
      </ul>

</td>
  </tr>
</table>
<p class="plaintext"> </p>
</body>
</html>
\ No newline at end of file
diff --git a/doc/pdsi.png b/doc/pdsi.png
new file mode 100644
index 0000000..cf6e004
Binary files /dev/null and b/doc/pdsi.png differ
diff --git a/doc/preprojectedgrids.html b/doc/preprojectedgrids.html
new file mode 100644
index 0000000..7856655
--- /dev/null
+++ b/doc/preprojectedgrids.html
@@ -0,0 +1,302 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+
+<link rel="stylesheet" href="/assets/NewIGES.css">
+
+<body bgcolor="#e0f0ff">
+<h1><u>Using Preprojected Grids</u></h1>
+<ul>
+  <span class="plaintext"><a href="#polar">Polar Stereo Preprojected Data</a><br>
+  <a href="#lambert">Lambert Conformal Preprojected Data</a><br>
+  <a href="#eta">NMC Eta model</a><br>
+  <a href="#nmc">NMC high accuracy polar stereo for SSM/I data</a><br>
+  <a href="#csu">CSU RAMS Oblique Polar Stereo Grids</a><br>
+  <a href="#pit">Pitfalls when using preprojected data</a> </span> 
+</ul>
+<br>
+<br>
+<ul>
+  <b><span class="plaintext">Preprojected</span></b><span class="plaintext"> data 
+  are data <b>already</b> on a map projection. GrADS supports four types of preprojected 
+  data: </span> 
+  <p> 
+  <ol>
+    <li class="plaintext">N polar stereo (NMC model projection); 
+    <li class="plaintext">S polar stereo (NMC model projection) ; 
+    <li class="plaintext">Lambert Conformal (originally for Navy NORAPS model); 
+    <li class="plaintext">NMC eta model (unstaggered). 
+    <li class="plaintext">More precise N and S polar stereo (hi res SSM/I data) 
+    <li class="plaintext">Colorado State University RAMS model (oblique polar 
+      stereo; beta)<br>
+      When preprojected grids are opened in GrADS, bilinear interpolation constants 
+      are calculated and all date are displayed on an internal GrADS lat/lon grid 
+      defined by the <code>xdef</code> and <code>ydef</code> card in the data 
+      description or <code>.ctl</code> file (that's why it takes longer to "open" 
+      a preprojected grid data set). 
+      <p class="plaintext"> It is very important to point out that the internal 
+        GrADS grid can be any grid as it is completely independent of the preprojected 
+        data grid. Thus, there is nothing stopping you displaying preprojected 
+        data on a very high res lon/lat grid (again, defined in the <code>.ctl</code> 
+        by <code>xdef</code> and <code>ydef</code>). In fact, you could create 
+        and open multiple .ctl files with different resolutions and/or regions 
+        which pointed to the same preprojected data file. 
+      <p class="plaintext"> When you do a <a
+href="gradcomddisplay.html"><code>display</code></a> (i.e., get a grid of data), 
+        the preprojected data are bilinearly interpolated to the GrADS internal 
+        lat/lon grid. For preprojected scalar fields (e.g., 500 mb heights), the 
+        display is adequate and the precision of the interpolation can be controlled 
+        by <code>xdef</code> and <code>ydef</code> to define a higher spatial 
+        resolution grid. 
+      <p class="plaintext"> The big virtue of this approach is that all built 
+        in GrADS analytic functions (e.g., <a
+href="gradfuncaave.html"><code>aave</code></a>, <a href="gradfunchcurl.html"><code>hcurl</code></a>...) 
+        continue to work even though the data were not originally on a lon/lat 
+        grid. The downside is that you are not looking directly at your data on 
+        a geographic map. However, one could always define a .ctl file which simply 
+        opened the data file as i,j data and displayed without the map (<a href="gradcomdsetmpdraw.html"><code>set 
+        mpdraw</code></a><code> off</code>). So, in my opinion, this compromise 
+        is not that limiting even if as a modeller you wanted to look at the grid--you 
+        just don't get the map background. 
+      <p> <span class="plaintext"><code>Preprojected vector fields</code> are 
+        a little trickier, depending on whether the vector is defined relative 
+        to the data grid or relative to the Earth. For example, NMC polar stereo 
+        grids use winds relative to the data grid and thus must be rotated to 
+        the internal GrADS lat/lon grid (again defined in the <code>.ctl</code> 
+        file by the <code>xdef</code> and <code>ydef</code> cards). </span>
+      <p class="plaintext"> The only potential problem with working with preprojected 
+        data is defining the projection for GrADS. This is accomplished using 
+        a <code>pdef</code> card in the data descriptor <code>.ctl</code> file. 
+  </ol>
+</ul>
+<span class="plaintext"><br>
+</span> <br>
+<span class="plaintextbold"><a name="polar"></a>Polar Stereographic Preprojected 
+Data</span> 
+<p> 
+<ul>
+  <span class="plaintext">Preprojected data on polar stereographic projections 
+  (N and S) is defined as at NMC. For the NCEP model GRIB data distributed via 
+  anon ftp from ftp.ncep.noaa.gov, the <code>pdef</code> card is: </span> 
+  <p> 
+  <ul>
+    <span class="plaintext"><code> pdef isize jsize projtype ipole jpole lonref 
+    gridinc<br>
+    pdef 53 45 nps 27 49 -105 190.5 </code> </span> 
+  </ul>
+  <p class="plaintext"> where, 
+  <p> 
+  <ul>
+    <span class="plaintext"><code>ipole</code> and <code>jpole</code> are the 
+    (i,j) of the pole referenced from the lower left corner at (1,1) and <code>gridinc</code> 
+    is the dx in km. </span> 
+  </ul>
+  <p>  
+  <p><br>
+    <br>
+    <a name="lambert"><b><i>Lambert Conformal Preprojected Data</i></b></a> 
+</ul>
+<p> 
+<ul>
+  The Lambert Conformal projection (lcc) was implemented for use with data from 
+  the U.S. Navy's limited area model NORAPS. Thus, to work with your lcc data 
+  you must express your grid in the context of the Navy lcc grid. 
+  <p> A typical NORAPS Lambert-Conformal grid is described below, including the 
+    C code which sets up the internal interpolation. 
+  <p> The<code> pdef record for a typical NORAPS Lambert-Conformal grid might 
+    be:</code><code> <br>
+    pdef 103 69 lcc 30 -88 51.5 34.5 20 40 -88 90000 90000 <br>
+    </code> </p>
+  <p> where, 
+  <p> 
+  <ul>
+    <code>103   </code>= #pts in x <br>
+    <code>69    </code>= #pts in y <br>
+    <code>lcc   </code>= Lambert-Conformal <br>
+    <code>30    </code>= lat of ref point <br>
+    <code>88    </code>= lon of ref point (E is positive, 
+    W is negative) <br>
+    <code>51.5  </code>= i of ref point <br>
+    <code>34.5  </code>= j of ref point <br>
+    <code>20    </code>= S true lat <br>
+    <code>40    </code>= N true lat <br>
+    <code>88    </code>= standard lon <br>
+    <code>90000&nbsp</code>= dx in M <br>
+    <code>90000&nbsp</code>= dy in M 
+  </ul>
+  <p> <br>
+    <br>
+    <a name="eta"><b><i>NMC Eta model (unstaggered grids)</i></b></a> 
+</ul>
+<p> 
+<ul>
+  The NMC eta model "native" grid is awkward to work with because the variables 
+  are on staggered (e.g., the grid for winds is not the same as the grid for mass 
+  points) <i>and</i> non rectangular (number of points in i is <i>not</i> constant 
+  with j) grids. Because any contouring of irregularly gridded data involves interpolation 
+  at some point, NMC creates "unstaggered" eta model fields for practical application 
+  programs such as GrADS. In the unstaggered grids all variables are placed on 
+  a common <i>and</i> rectangular grid (the mass points). 
+  <p> Wind rotation has also been added so that vector data will be properly displayed. 
+  <p> The pdef card for a typical eta model grid is: 
+  <p> 
+  <ul>
+    <code>pdef 181 136 eta.u -97.0 41.0 0.38888888 0.37037037</code> 
+    <p> <code>181</code>         = #pts 
+      in x <br>
+      <code>136</code>         = #pts 
+      in y <br>
+      <code>eta.u</code>     = eta grid, unstaggered<br>
+      <code>-97.0</code>     = lon of ref point (E is positive 
+      in GrADS, W is negative) [deg] <br>
+      <code>41.0</code>       = lat of ref point 
+      [deg] <br>
+      <code>0.3888</code>   = dlon [deg] <br>
+      <code>0.37037</code> = dlat [deg] 
+  </ul>
+  <p>  
+</ul>
+<br>
+<br>
+<a name="nmc"><b><i>NMC high accuracy polar stereo for SSM/I data</i></b></a>
+<p> 
+<ul>
+  The polar stereo projection used by the original NMC models is not very precise 
+  because it assumes the earth is round (eccentricity = 0). While this approximation 
+  was reasonable for coarse resolution NWP models, it is inadequate to work with 
+  higher resolution data such as SSM/I. 
+  <p> <i>Wind rotation has not been implemented!!! Use only for scalar fields.</i> 
+  <p> 
+  <ul>
+    <code>pdef ni nj pse slat slon polei polej dx dy sgn</code> 
+    <p> <code>ni</code>          
+      = # points in x <br>
+      <code>nj</code>          = 
+      # points in y <br>
+      <code>slat</code>      = absolute value of the 
+      standard latitude <br>
+      <code>slon</code>      = absolute value of the 
+      standard longitude <br>
+      <code>pse</code>        = polar stereo, 
+      "eccentric"<br>
+      <code>polei</code>    = x index position of the pole (where 
+      (0,0) is the index of the first point vice the more typical (1,1) ) <br>
+      <code>polej</code>    = y index position of the pole (where 
+      (0,0) is the index of the first point vice the more typical (1,1) ) <br>
+      <code>dx</code>          = 
+      delta x in km <br>
+      <code>dy</code>          = 
+      delta y in km <br>
+      <code>sgn</code>        = 1 for N polar 
+      stereo and -1 for S polar stereo 
+  </ul>
+  <p> Source code in GrADS for the lon,lat -> i,j mapping: 
+  <p> 
+  <pre> 
+
+
+</pre>
+</ul>
+<br>
+<br>
+<a name="csu"><b><i>Oblique Polar Stereo Grids</i></b></a> 
+<p> 
+<ul>
+  The CSU RAMS model uses an oblique polar stereo projection. <i>Wind rotation 
+  has not been implemented!!! Use only for scalar fields.</i> 
+  <p> 
+  <ul>
+    <code> pdef 26 16 ops 40.0 -100.0 90000.0 90000.0 14.0 9.0 180000.0 180000.0</code> 
+    <p> <code>26</code>              
+      = #pts in x <br>
+      <code>16</code>              
+      = #pts in y <br>
+      <code>ops</code>            
+      = oblique polar stereo<br>
+      <code>40.0</code>          
+      = lat of ref point (14.0, 9.0) <br>
+      <code>-100.0</code>      = lon of ref point (14.0, 
+      9.0 (E is positive in GrADS, W is negative) <br>
+      <code>90000.0</code>    = xref offset [m] <br>
+      <code>90000.0</code>    = yref offset [m]<br>
+      <code>14.0</code>          
+      = i of ref point <br>
+      <code>9.0</code>            
+      = j of ref point <br>
+      <code>180000.0</code>  = dx [m] <br>
+      <code>180000.0</code>  = dy [m] 
+  </ul>
+  <p>  
+  <p>  
+</ul>
+<br>
+<br>
+<a name="pit"><b><i>Pitfalls when using preprojected data</i></b></a>
+<p> 
+<ul>
+  There are a few <i>gotchas</i> with using preprojected data:
+  <p> 
+  <ol>
+    <li>the units in the variable definition for the <code>u</code> and <code>v</code> 
+      components <b>must</b> be <code>33</code> and <code>34</code> (the GRIB 
+      standard) respectively, e.g., 
+      <p> 
+      <ul>
+        <code>u 15 33</code>    u component of the wind at 15 pressure 
+        levels <br>
+        <code>v 15 34</code>    v component of the wind at 15 pressure 
+        levels
+      </ul>
+      <p> 
+    <li>wind rotation is handled for polar stereo (N and S) preprojected data, 
+      but <i>not</i> for Lambert Conformal, as the Navy rotates the winds relative 
+      to earth. 
+    <li>the <code>eta.u</code> <b>and</b> <code>ops</code> projection are still 
+      experimental...
+  </ol>
+</ul>
+<br>
+<br>
+<a name="proj">
+<h2><u>GrADS Display Projections</u></h2>
+</a> 
+<ul>
+  Now that you hopefully understand GrADS data grids, it is time to discuss display 
+  projections. Graphics in GrADS are calculated relative to the internal GrADS 
+  data grid <code>i,j</code> space, transformed to the display device coordinates 
+  (e.g., the screen) and then displayed. That is, the i,j of the graphic element 
+  is converted to <code>lat/lon</code> and then to <code>x,y</code> on the screen 
+  via a map projection.
+  <p> GrADS currently supports four <code>display projections</code>:
+  <p> 
+  <ul>
+    <li>lat/lon (or spherical); 
+    <li>N polar stereo (<a href="gradcomdsetmproj.html"><code>set mproj</code></a><code> 
+      nps</code>); 
+    <li>S polar stereo (<a href="gradcomdsetmproj.html"><code>set mproj</code></a><code> 
+      sps</code>); 
+    <li>the Robinson projection (set lon -180 180, set lat -90 90, set mproj robinson).
+  </ul>
+  <p> As you can probably appreciate, the i,j-to-lon/lat-to-screen x,y for <code>lon/lat</code> 
+    displays is very simple and is considerably more complicated for N and S <code>polar 
+    stereo</code> projections.
+  <p> In principle, a Lambert Conformal display projection could be implemented. 
+    It just takes work and a simple user interface for setting up that display 
+    projection. Actually, the user interface (i.e., "set" calls) is the most difficult 
+    problem... 
+</ul>
+<br>
+<br>
+<a name="summary">
+<h2><u>Summary and Plans</u></h2>
+</a> 
+<ul>
+  GrADS handles map projections in two different ways. The first is preprojected 
+  data where the fields are <i>already</i> on a projection (e.g., Lambert Conformal). 
+  It is fairly straightforward to implement other preprojected data projections 
+  and we will be fully implementing the NMC eta grid both staggered and unstaggered, 
+  "thinned" gaussian grids and the CSU RAMS oblique polar stereo projection. The 
+  second is in how i,j graphics (calculated in "grid" space) are displayed on 
+  a map background. Currently, only a few basic projections (lon/lat, polar stereo 
+  and robinson) are supported, but perhaps the development group will tackle this 
+  problem.
+</ul>
diff --git a/doc/reference.html b/doc/reference.html
new file mode 100644
index 0000000..44ef28e
--- /dev/null
+++ b/doc/reference.html
@@ -0,0 +1,27 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Documentation Index</title>
+</head>
+<frameset rows="110,*">
+  <frame name="alpha" src="indexalpha.html" target="list">
+  <frameset cols="165,*" border=0>
+    <frame name="list" src="indexlist.html" target="pages">
+    <frame name="pages" src="pages.html">
+  </frameset>
+</frameset>
+
+<noframes>
+<body bgcolor="#e0f0ff" text="#000000">
+<p>
+Your browser does not support frames. Your options are: 
+<p>
+1. Curse the universe for having to work with obsolete gear, then upgrade.
+<p>
+2. View the <a href="indexlist.html" target="_top">index list</a> without frames.
+</body>
+
+</noframes>
+</body>
+</html>
diff --git a/doc/reference_card.pdf b/doc/reference_card.pdf
new file mode 100644
index 0000000..10fcecb
Binary files /dev/null and b/doc/reference_card.pdf differ
diff --git a/doc/reference_card_scl.pdf b/doc/reference_card_scl.pdf
new file mode 100644
index 0000000..4c53fac
Binary files /dev/null and b/doc/reference_card_scl.pdf differ
diff --git a/doc/reinitialization.html b/doc/reinitialization.html
new file mode 100644
index 0000000..87789de
--- /dev/null
+++ b/doc/reinitialization.html
@@ -0,0 +1,62 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Reinitialization</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+
+<h2>Reinitialization of GrADS</h2>
+
+<p>
+Two commands are available for resetting or reinitializing the state of GrADS:
+
+<p>
+<b><i>Reinit</i></b>
+
+<p>
+The <a href="gradcomdreinit.html"><code>reinit</code></a> command
+returns GrADS to its initial state.  <a
+href="gradcomdreinit.html"><code>reinit</code></a> closes all open
+files, releases all defined variables, and resets all graphics
+settings to their defaults.
+
+<p>
+<b><i>Reset</i></b>
+<p>
+The <a href="gradcomdreset.html"><code>reset</code></a> command
+returns GrADS to its initial state with the following exceptions:
+
+<p>
+<ol>
+<li>No files are closed
+<li>No defined variables are released
+<li>The <a href="gradcomdsetdisplay.html"><code>set display</code></a> settings
+are not modified
+</ol>
+
+<p>
+If files are open, the default file is set to 1, and the
+dimension environment is set to X,Y varying and Z and T set to 1
+(as though file 1 were just opened).
+
+<p>
+The <a href="gradcomdreset.html"><code>reset</code></a> command may be
+qualified so that only certain aspects of GrADS are returned to their
+initial state. The qualifiers are as follows:
+
+<p>
+<ul>
+<code><a href="gradcomdreset.html">reset</a> events    </code>
+resets the events buffer (e.g., mouse clicks) <br>
+<code><a href="gradcomdreset.html">reset</a> graphics  </code>
+resets the graphics, but not the widgets <br>
+<code><a href="gradcomdreset.html">reset</a> hbuff     </code>
+resets the display buffer when in double buffer mode <br>
+<code><a href="gradcomdreset.html">reset</a> norset    </code>
+resets the X events only
+</ul>
+
+</body>
+</html>
diff --git a/doc/sample.ctl b/doc/sample.ctl
new file mode 100644
index 0000000..c968cbe
--- /dev/null
+++ b/doc/sample.ctl
@@ -0,0 +1,15 @@
+dset ^sample.grib
+index ^sample.idx
+title sample grib file
+dtype grib 
+options yrev
+undef 9.999E+20
+XDEF 360 linear 0.0 1.0
+YDEF 181 linear -90.0 1
+ZDEF 4 levels 1000 850 500 200
+TDEF 3 linear 00Z02apr2004 6hr
+VARS 2
+u 4 33,100 u wind [m/s]
+v 4 34,100 v wind [m/s]
+ENDVARS
+
diff --git a/doc/sample.grib b/doc/sample.grib
new file mode 100644
index 0000000..31c7ce2
Binary files /dev/null and b/doc/sample.grib differ
diff --git a/doc/sample.ncdump b/doc/sample.ncdump
new file mode 100644
index 0000000..3984734
--- /dev/null
+++ b/doc/sample.ncdump
@@ -0,0 +1,179 @@
+netcdf sample.nc {
+dimensions:
+	xt = 240 ;
+	yt = 134 ;
+	zt = 25 ;
+	xu = 240 ;
+	yu = 134 ;
+	zw = 25 ;
+	Surface = 1 ;
+	Time = UNLIMITED ; // (1 currently)
+variables:
+	float xt(xt) ;
+		xt:long_name = "Longitude of T points" ;
+		xt:units = "degrees_E" ;
+		xt:cartesian_axis = "X" ;
+	float yt(yt) ;
+		yt:long_name = "Latitude of T points" ;
+		yt:units = "degrees_N" ;
+		yt:cartesian_axis = "Y" ;
+	float zt(zt) ;
+		zt:long_name = "Depth of T grid point" ;
+		zt:units = "m" ;
+		zt:cartesian_axis = "Z" ;
+		zt:positive = "down" ;
+	float xu(xu) ;
+		xu:long_name = "Longitude of U points" ;
+		xu:units = "degrees_E" ;
+		xu:cartesian_axis = "X" ;
+	float yu(yu) ;
+		yu:long_name = "Latitude of U points" ;
+		yu:units = "degrees_N" ;
+		yu:cartesian_axis = "Y" ;
+	float zw(zw) ;
+		zw:long_name = "Depth of T cell bottom" ;
+		zw:units = "m" ;
+		zw:cartesian_axis = "Z" ;
+		zw:positive = "down" ;
+	float Surface(Surface) ;
+		Surface:long_name = "Depth of surface" ;
+		Surface:units = "m" ;
+		Surface:cartesian_axis = "Z" ;
+		Surface:positive = "down" ;
+	double Time(Time) ;
+		Time:long_name = "Time since initial condition" ;
+		Time:units = "days since 1925-01-01 00:00:00.0" ;
+		Time:cartesian_axis = "T" ;
+	float temp(Time, zt, yt, xt) ;
+		temp:long_name = "potential temperature" ;
+		temp:units = "deg C" ;
+		temp:valid_range = -5.f, 50.f ;
+		temp:missing_value = -1.e+34f ;
+		temp:_FillValue = -1.e+34f ;
+	float u(Time, zt, yu, xu) ;
+		u:long_name = "Zonal velocity" ;
+		u:units = "cm/s" ;
+		u:missing_value = -1.e+34f ;
+	float v(Time, zt, yu, xu) ;
+		v:long_name = "Meridional velocity" ;
+		v:units = "cm/s" ;
+		v:missing_value = -1.e+34f ;
+	float w(Time, zw, yt, xt) ;
+		w:long_name = "W at T cell bottom" ;
+		w:units = "cm/s" ;
+		w:missing_value = -1.e+34f ;
+	float taux(Time, Surface, yu, xu) ;
+		taux:long_name = "Zonal windstress" ;
+		taux:units = "dyn/cm**2" ;
+		taux:missing_value = -1.e+34f ;
+	float tauy(Time, Surface, yu, xu) ;
+		tauy:long_name = "Meridional windstress" ;
+		tauy:units = "dyn/cm**2" ;
+		tauy:missing_value = -1.e+34f ;
+	float hflx(Time, Surface, yt, xt) ;
+		hflx:long_name = "Surface heat flux" ;
+		hflx:units = "cal/cm**2/s" ;
+		hflx:missing_value = -1.e+34f ;
+	float sflx(Time, Surface, yt, xt) ;
+		sflx:long_name = "Surface salt flux" ;
+		sflx:units = "g/cm**2/s" ;
+		sflx:missing_value = -1.e+34f ;
+	float eta(Time, yt, xt) ;
+		eta:long_name = "Surface height" ;
+		eta:units = "cm" ;
+		eta:missing_value = -1.e+34f ;
+
+data:
+
+ xt = 0.75, 2.25, 3.75, 5.25, 6.75, 8.25, 9.75, 11.25, 12.75, 14.25, 15.75, 
+    17.25, 18.75, 20.25, 21.75, 23.25, 24.75, 26.25, 27.75, 29.25, 30.75, 
+    32.25, 33.75, 35.25, 36.75, 38.25, 39.75, 41.25, 42.75, 44.25, 45.75, 
+    47.25, 48.75, 50.25, 51.75, 53.25, 54.75, 56.25, 57.75, 59.25, 60.75, 
+    62.25, 63.75, 65.25, 66.75, 68.25, 69.75, 71.25, 72.75, 74.25, 75.75, 
+    77.25, 78.75, 80.25, 81.75, 83.25, 84.75, 86.25, 87.75, 89.25, 90.75, 
+    92.25, 93.75, 95.25, 96.75, 98.25, 99.75, 101.25, 102.75, 104.25, 105.75, 
+    107.25, 108.75, 110.25, 111.75, 113.25, 114.75, 116.25, 117.75, 119.25, 
+    120.75, 122.25, 123.75, 125.25, 126.75, 128.25, 129.75, 131.25, 132.75, 
+    134.25, 135.75, 137.25, 138.75, 140.25, 141.75, 143.25, 144.75, 146.25, 
+    147.75, 149.25, 150.75, 152.25, 153.75, 155.25, 156.75, 158.25, 159.75, 
+    161.25, 162.75, 164.25, 165.75, 167.25, 168.75, 170.25, 171.75, 173.25, 
+    174.75, 176.25, 177.75, 179.25, 180.75, 182.25, 183.75, 185.25, 186.75, 
+    188.25, 189.75, 191.25, 192.75, 194.25, 195.75, 197.25, 198.75, 200.25, 
+    201.75, 203.25, 204.75, 206.25, 207.75, 209.25, 210.75, 212.25, 213.75, 
+    215.25, 216.75, 218.25, 219.75, 221.25, 222.75, 224.25, 225.75, 227.25, 
+    228.75, 230.25, 231.75, 233.25, 234.75, 236.25, 237.75, 239.25, 240.75, 
+    242.25, 243.75, 245.25, 246.75, 248.25, 249.75, 251.25, 252.75, 254.25, 
+    255.75, 257.25, 258.75, 260.25, 261.75, 263.25, 264.75, 266.25, 267.75, 
+    269.25, 270.75, 272.25, 273.75, 275.25, 276.75, 278.25, 279.75, 281.25, 
+    282.75, 284.25, 285.75, 287.25, 288.75, 290.25, 291.75, 293.25, 294.75, 
+    296.25, 297.75, 299.25, 300.75, 302.25, 303.75, 305.25, 306.75, 308.25, 
+    309.75, 311.25, 312.75, 314.25, 315.75, 317.25, 318.75, 320.25, 321.75, 
+    323.25, 324.75, 326.25, 327.75, 329.25, 330.75, 332.25, 333.75, 335.25, 
+    336.75, 338.25, 339.75, 341.25, 342.75, 344.25, 345.75, 347.25, 348.75, 
+    350.25, 351.75, 353.25, 354.75, 356.25, 357.75, 359.25 ;
+
+ yt = -74.25, -72.75, -71.25, -69.75, -68.25, -66.75, -65.25, -63.75, 
+    -62.25, -60.75, -59.25, -57.75, -56.25, -54.75, -53.25, -51.75, -50.25, 
+    -48.75, -47.25, -45.75, -44.25, -42.75, -41.25, -39.75, -38.25, -36.75, 
+    -35.25, -33.75, -32.25, -30.75, -29.25, -27.75616, -26.28063, -24.83512, 
+    -23.43062, -22.07706, -20.78317, -19.55618, -18.40167, -17.32345, 
+    -16.32345, -15.40167, -14.55617, -13.78317, -13.07706, -12.43062, 
+    -11.83512, -11.28063, -10.75616, -10.25, -9.75, -9.25, -8.75, -8.25, 
+    -7.75, -7.25, -6.75, -6.25, -5.75, -5.25, -4.75, -4.25, -3.75, -3.25, 
+    -2.75, -2.25, -1.75, -1.25, -0.75, -0.25, 0.25, 0.75, 1.25, 1.75, 2.25, 
+    2.75, 3.25, 3.75, 4.25, 4.75, 5.25, 5.75, 6.25, 6.75, 7.25, 7.75, 8.25, 
+    8.75, 9.25, 9.75, 10.25, 10.75616, 11.28063, 11.83512, 12.43062, 
+    13.07706, 13.78317, 14.55617, 15.40167, 16.32345, 17.32345, 18.40167, 
+    19.55618, 20.78317, 22.07706, 23.43062, 24.83512, 26.28063, 27.75616, 
+    29.25, 30.75, 32.25, 33.75, 35.25, 36.75, 38.25, 39.75, 41.25, 42.75, 
+    44.25, 45.75, 47.25, 48.75, 50.25, 51.75, 53.25, 54.75, 56.25, 57.75, 
+    59.25, 60.75, 62.25, 63.75, 65.25 ;
+
+ zt = 7.5, 22.5, 37.5, 52.5, 67.5, 82.5, 97.5, 112.5, 127.5, 142.5, 
+    158.058, 175.1405, 194.3055, 215.553, 238.325, 261.655, 336.655, 463.325, 
+    624.1221, 882.1049, 1285.536, 1860.536, 2607.105, 3499.122, 4488.325 ;
+
+ xu = 1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 
+    24, 25.5, 27, 28.5, 30, 31.5, 33, 34.5, 36, 37.5, 39, 40.5, 42, 43.5, 45, 
+    46.5, 48, 49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, 66, 
+    67.5, 69, 70.5, 72, 73.5, 75, 76.5, 78, 79.5, 81, 82.5, 84, 85.5, 87, 
+    88.5, 90, 91.5, 93, 94.5, 96, 97.5, 99, 100.5, 102, 103.5, 105, 106.5, 
+    108, 109.5, 111, 112.5, 114, 115.5, 117, 118.5, 120, 121.5, 123, 124.5, 
+    126, 127.5, 129, 130.5, 132, 133.5, 135, 136.5, 138, 139.5, 141, 142.5, 
+    144, 145.5, 147, 148.5, 150, 151.5, 153, 154.5, 156, 157.5, 159, 160.5, 
+    162, 163.5, 165, 166.5, 168, 169.5, 171, 172.5, 174, 175.5, 177, 178.5, 
+    180, 181.5, 183, 184.5, 186, 187.5, 189, 190.5, 192, 193.5, 195, 196.5, 
+    198, 199.5, 201, 202.5, 204, 205.5, 207, 208.5, 210, 211.5, 213, 214.5, 
+    216, 217.5, 219, 220.5, 222, 223.5, 225, 226.5, 228, 229.5, 231, 232.5, 
+    234, 235.5, 237, 238.5, 240, 241.5, 243, 244.5, 246, 247.5, 249, 250.5, 
+    252, 253.5, 255, 256.5, 258, 259.5, 261, 262.5, 264, 265.5, 267, 268.5, 
+    270, 271.5, 273, 274.5, 276, 277.5, 279, 280.5, 282, 283.5, 285, 286.5, 
+    288, 289.5, 291, 292.5, 294, 295.5, 297, 298.5, 300, 301.5, 303, 304.5, 
+    306, 307.5, 309, 310.5, 312, 313.5, 315, 316.5, 318, 319.5, 321, 322.5, 
+    324, 325.5, 327, 328.5, 330, 331.5, 333, 334.5, 336, 337.5, 339, 340.5, 
+    342, 343.5, 345, 346.5, 348, 349.5, 351, 352.5, 354, 355.5, 357, 358.5, 
+    360 ;
+
+ yu = -73.5, -72, -70.5, -69, -67.5, -66, -64.5, -63, -61.5, -60, -58.5, 
+    -57, -55.5, -54, -52.5, -51, -49.5, -48, -46.5, -45, -43.5, -42, -40.5, 
+    -39, -37.5, -36, -34.5, -33, -31.5, -30, -28.50308, -27.01839, -25.55788, 
+    -24.13287, -22.75384, -21.43012, -20.16967, -18.97892, -17.86256, 
+    -16.82345, -15.86256, -14.97892, -14.16967, -13.43012, -12.75384, 
+    -12.13287, -11.55788, -11.01839, -10.50308, -10, -9.5, -9, -8.5, -8, 
+    -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, 
+    -0.5, 1.776357e-15, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 
+    7, 7.5, 8, 8.5, 9, 9.5, 10, 10.50308, 11.01839, 11.55788, 12.13287, 
+    12.75384, 13.43012, 14.16967, 14.97892, 15.86256, 16.82345, 17.86256, 
+    18.97892, 20.16967, 21.43012, 22.75384, 24.13287, 25.55788, 27.01839, 
+    28.50308, 30, 31.5, 33, 34.5, 36, 37.5, 39, 40.5, 42, 43.5, 45, 46.5, 48, 
+    49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, 66 ;
+
+ zw = 15, 30, 45, 60, 75, 90, 105, 120, 135, 150.279, 166.5993, 184.723, 
+    204.9293, 226.939, 249.99, 299.155, 399.99, 543.7236, 753.1135, 1083.821, 
+    1573.036, 2233.821, 3053.114, 3993.724, 4999.99 ;
+
+ Surface = 0 ;
+
+ Time = 47449.9583333333 ;
+
+}
diff --git a/doc/sample_sfc.ctl b/doc/sample_sfc.ctl
new file mode 100644
index 0000000..caf4755
--- /dev/null
+++ b/doc/sample_sfc.ctl
@@ -0,0 +1,28 @@
+DSET ^sample.nc
+DTYPE netcdf
+TITLE Ocean Surface Variables
+UNDEF -1.e+34
+XDEF 240 linear 0.75 1.5 
+YDEF 134 levels -74.25 -72.75 -71.25 -69.75 -68.25 -66.75 -65.25 -63.75 
+    -62.25 -60.75 -59.25 -57.75 -56.25 -54.75 -53.25 -51.75 -50.25 
+    -48.75 -47.25 -45.75 -44.25 -42.75 -41.25 -39.75 -38.25 -36.75 
+    -35.25 -33.75 -32.25 -30.75 -29.25 -27.75616 -26.28063 -24.83512 
+    -23.43062 -22.07706 -20.78317 -19.55618 -18.40167 -17.32345 
+    -16.32345 -15.40167 -14.55617 -13.78317 -13.07706 -12.43062 
+    -11.83512 -11.28063 -10.75616 -10.25 -9.75 -9.25 -8.75 -8.25 
+    -7.75 -7.25 -6.75 -6.25 -5.75 -5.25 -4.75 -4.25 -3.75 -3.25 
+    -2.75 -2.25 -1.75 -1.25 -0.75 -0.25 0.25 0.75 1.25 1.75 2.25 
+    2.75 3.25 3.75 4.25 4.75 5.25 5.75 6.25 6.75 7.25 7.75 8.25 
+    8.75 9.25 9.75 10.25 10.75616 11.28063 11.83512 12.43062 
+    13.07706 13.78317 14.55617 15.40167 16.32345 17.32345 18.40167 
+    19.55618 20.78317 22.07706 23.43062 24.83512 26.28063 27.75616 
+    29.25 30.75 32.25 33.75 35.25 36.75 38.25 39.75 41.25 42.75 
+    44.25 45.75 47.25 48.75 50.25 51.75 53.25 54.75 56.25 57.75 
+    59.25 60.75 62.25 63.75 65.25
+ZDEF 1 levels 0
+TDEF 1 linear 01dec2054 1mo
+VARS 3
+hflx   1  t,z,y,x  Surface Heat Flux (cal/cm**2/s)
+sflx   1  t,z,y,x  Surface Salt Flux (g/cm**2/s)
+eta    0  t,y,x    Surface height (cm)
+ENDVARS
diff --git a/doc/sample_tau.ctl b/doc/sample_tau.ctl
new file mode 100644
index 0000000..77ef792
--- /dev/null
+++ b/doc/sample_tau.ctl
@@ -0,0 +1,24 @@
+DSET ^sample.nc
+DTYPE netcdf
+TITLE 3-D Ocean Variables: Wind Stress Components
+UNDEF -1.e+34
+xdef 240 linear 1.5 1.5
+ydef 134 levels -73.5 -72 -70.5 -69 -67.5 -66 -64.5 -63 -61.5 -60 -58.5 
+    -57 -55.5 -54 -52.5 -51 -49.5 -48 -46.5 -45 -43.5 -42 -40.5 
+    -39 -37.5 -36 -34.5 -33 -31.5 -30 -28.50308 -27.01839 -25.55788 
+    -24.13287 -22.75384 -21.43012 -20.16967 -18.97892 -17.86256 
+    -16.82345 -15.86256 -14.97892 -14.16967 -13.43012 -12.75384 
+    -12.13287 -11.55788 -11.01839 -10.50308 -10 -9.5 -9 -8.5 -8 
+    -7.5 -7 -6.5 -6 -5.5 -5 -4.5 -4 -3.5 -3 -2.5 -2 -1.5 -1 
+    -0.5 1.776357e-15 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 
+    7 7.5 8 8.5 9 9.5 10 10.50308 11.01839 11.55788 12.13287 
+    12.75384 13.43012 14.16967 14.97892 15.86256 16.82345 17.86256 
+    18.97892 20.16967 21.43012 22.75384 24.13287 25.55788 27.01839 
+    28.50308 30 31.5 33 34.5 36 37.5 39 40.5 42 43.5 45 46.5 48 
+    49.5 51 52.5 54 55.5 57 58.5 60 61.5 63 64.5 66
+ZDEF 1 levels 0
+TDEF 1 linear 01dec2054 1mo
+VARS 2
+taux   1  t,z,y,x  Zonal Wind Stress (dyn/cm**2)
+tauy   1  t,z,y,x  Meridional Wind Stress (dyn/cm**2)
+ENDVARS
diff --git a/doc/sample_temp.ctl b/doc/sample_temp.ctl
new file mode 100644
index 0000000..5c094bb
--- /dev/null
+++ b/doc/sample_temp.ctl
@@ -0,0 +1,29 @@
+DSET ^sample.nc
+DTYPE netcdf
+TITLE 4-D Ocean Variables: Potential Temperature
+UNDEF -1.e+34
+XDEF 240 linear 0.75 1.5 
+YDEF 134 levels -74.25 -72.75 -71.25 -69.75 -68.25 -66.75 -65.25 -63.75 
+    -62.25 -60.75 -59.25 -57.75 -56.25 -54.75 -53.25 -51.75 -50.25 
+    -48.75 -47.25 -45.75 -44.25 -42.75 -41.25 -39.75 -38.25 -36.75 
+    -35.25 -33.75 -32.25 -30.75 -29.25 -27.75616 -26.28063 -24.83512 
+    -23.43062 -22.07706 -20.78317 -19.55618 -18.40167 -17.32345 
+    -16.32345 -15.40167 -14.55617 -13.78317 -13.07706 -12.43062 
+    -11.83512 -11.28063 -10.75616 -10.25 -9.75 -9.25 -8.75 -8.25 
+    -7.75 -7.25 -6.75 -6.25 -5.75 -5.25 -4.75 -4.25 -3.75 -3.25 
+    -2.75 -2.25 -1.75 -1.25 -0.75 -0.25 0.25 0.75 1.25 1.75 2.25 
+    2.75 3.25 3.75 4.25 4.75 5.25 5.75 6.25 6.75 7.25 7.75 8.25 
+    8.75 9.25 9.75 10.25 10.75616 11.28063 11.83512 12.43062 
+    13.07706 13.78317 14.55617 15.40167 16.32345 17.32345 18.40167 
+    19.55618 20.78317 22.07706 23.43062 24.83512 26.28063 27.75616 
+    29.25 30.75 32.25 33.75 35.25 36.75 38.25 39.75 41.25 42.75 
+    44.25 45.75 47.25 48.75 50.25 51.75 53.25 54.75 56.25 57.75 
+    59.25 60.75 62.25 63.75 65.25
+ZDEF 25 levels 7.5 22.5 37.5 52.5 67.5 82.5 97.5 112.5 127.5 142.5 
+    158.058 175.1405 194.3055 215.553 238.325 261.655 336.655 463.325 
+    624.1221 882.1049 1285.536 1860.536 2607.105 3499.122 4488.325
+TDEF 1 linear 01dec2054 1mo
+VARS 1
+temp   25  t,z,y,x  Potential Temperature (deg C)
+ENDVARS
+
diff --git a/doc/sample_uv.ctl b/doc/sample_uv.ctl
new file mode 100644
index 0000000..52dc8cf
--- /dev/null
+++ b/doc/sample_uv.ctl
@@ -0,0 +1,26 @@
+DSET ^sample.nc
+DTYPE netcdf
+TITLE 4-D Ocean Variables: Velocity Components
+UNDEF -1.e+34 
+XDEF 240 linear 1.5 1.5
+YDEF 134 levels -73.5 -72 -70.5 -69 -67.5 -66 -64.5 -63 -61.5 -60 -58.5 
+    -57 -55.5 -54 -52.5 -51 -49.5 -48 -46.5 -45 -43.5 -42 -40.5 
+    -39 -37.5 -36 -34.5 -33 -31.5 -30 -28.50308 -27.01839 -25.55788 
+    -24.13287 -22.75384 -21.43012 -20.16967 -18.97892 -17.86256 
+    -16.82345 -15.86256 -14.97892 -14.16967 -13.43012 -12.75384 
+    -12.13287 -11.55788 -11.01839 -10.50308 -10 -9.5 -9 -8.5 -8 
+    -7.5 -7 -6.5 -6 -5.5 -5 -4.5 -4 -3.5 -3 -2.5 -2 -1.5 -1 
+    -0.5 1.776357e-15 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 
+    7 7.5 8 8.5 9 9.5 10 10.50308 11.01839 11.55788 12.13287 
+    12.75384 13.43012 14.16967 14.97892 15.86256 16.82345 17.86256 
+    18.97892 20.16967 21.43012 22.75384 24.13287 25.55788 27.01839 
+    28.50308 30 31.5 33 34.5 36 37.5 39 40.5 42 43.5 45 46.5 48 
+    49.5 51 52.5 54 55.5 57 58.5 60 61.5 63 64.5 66
+ZDEF 25 levels 7.5 22.5 37.5 52.5 67.5 82.5 97.5 112.5 127.5 142.5 
+    158.058 175.1405 194.3055 215.553 238.325 261.655 336.655 463.325 
+    624.1221 882.1049 1285.536 1860.536 2607.105 3499.122 4488.325
+TDEF 1 linear 01dec2054 1mo
+VARS 2
+u     25  t,z,y,x  Zonal Velocity (cm/s)
+v     25  t,z,y,x  Meridional Velocity (cm/s)
+ENDVARS
diff --git a/doc/sample_w.ctl b/doc/sample_w.ctl
new file mode 100644
index 0000000..486bd56
--- /dev/null
+++ b/doc/sample_w.ctl
@@ -0,0 +1,28 @@
+DSET ^sample.nc
+DTYPE netcdf
+TITLE 4-D Ocean Variables: Omega
+UNDEF -1.e+34
+XDEF 240 linear 0.75 1.5 
+YDEF 134 levels -74.25 -72.75 -71.25 -69.75 -68.25 -66.75 -65.25 -63.75 
+    -62.25 -60.75 -59.25 -57.75 -56.25 -54.75 -53.25 -51.75 -50.25 
+    -48.75 -47.25 -45.75 -44.25 -42.75 -41.25 -39.75 -38.25 -36.75 
+    -35.25 -33.75 -32.25 -30.75 -29.25 -27.75616 -26.28063 -24.83512 
+    -23.43062 -22.07706 -20.78317 -19.55618 -18.40167 -17.32345 
+    -16.32345 -15.40167 -14.55617 -13.78317 -13.07706 -12.43062 
+    -11.83512 -11.28063 -10.75616 -10.25 -9.75 -9.25 -8.75 -8.25 
+    -7.75 -7.25 -6.75 -6.25 -5.75 -5.25 -4.75 -4.25 -3.75 -3.25 
+    -2.75 -2.25 -1.75 -1.25 -0.75 -0.25 0.25 0.75 1.25 1.75 2.25 
+    2.75 3.25 3.75 4.25 4.75 5.25 5.75 6.25 6.75 7.25 7.75 8.25 
+    8.75 9.25 9.75 10.25 10.75616 11.28063 11.83512 12.43062 
+    13.07706 13.78317 14.55617 15.40167 16.32345 17.32345 18.40167 
+    19.55618 20.78317 22.07706 23.43062 24.83512 26.28063 27.75616 
+    29.25 30.75 32.25 33.75 35.25 36.75 38.25 39.75 41.25 42.75 
+    44.25 45.75 47.25 48.75 50.25 51.75 53.25 54.75 56.25 57.75 
+    59.25 60.75 62.25 63.75 65.25
+ZDEF 25 levels 15 30 45 60 75 90 105 120 135 150.279 166.5993 184.723 
+    204.9293 226.939 249.99 299.155 399.99 543.7236 753.1135 1083.821 
+    1573.036 2233.821 3053.114 3993.724 4999.99
+TDEF 1 linear 01dec2054 1mo
+VARS 1
+w  25  t,z,y,x   W at T cell bottom (cm/s)
+ENDVARS
diff --git a/doc/scatterplot.html b/doc/scatterplot.html
new file mode 100644
index 0000000..27d32c6
--- /dev/null
+++ b/doc/scatterplot.html
@@ -0,0 +1,57 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Command: set gxout</title>
+
+
+<style type="text/css">
+.Red {
+	color: #900;
+}
+.italic {
+	color: #900;
+}
+.red {
+	color: #900;
+}
+body {
+	background-color: #e0f0ff;
+}
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body text="#000000">
+
+<h2><b>Scatter Plots</b></h2>
+<p class="plaintext">
+
+This section describes how to draw a scatter plot and refine the display with controls over colors and axis labels. The commands are:
+<p><code>set gxout scatter<br>
+  display exp1;exp2<span class="italic"><;exp3></span></code>
+<p class="plaintext">
+Where:
+<ul>
+
+<code>exp1   </code>
+<span class="plaintext">A grid expression that determines the position of the scatter points on the X axis</span><br>
+
+<code>exp2   </code>
+<span class="plaintext">A grid expression that determines the position of the scatter points on the Y axis</span><br>
+
+<code>exp3   </code>
+<span class="plaintext">A grid expression that determines the color of the points in the scatter plot (</span><span class="red">GrADS version 2.0.2+</span>)<br>
+</ul>
+<h3>Usage Notes</h3>
+<ol>
+  <p class="fineprint"><span class="plaintext">The third argument to control the colorization of the points in the scatter diagram is new in GrADS version 2.0.2. </span>Use <code><a href="gradcomdsetclevs.html">set clevs</a></code> and <code><a href="gradcomdsetccols.html">set ccols</a></code> to control the range of values and color for each level. When using colorization of the scatter plot, if any of the color numbers is < 0, no points will be drawn for that level.</p>
+  <p class="fineprint"><span class="plaintext">After a display of a scatter plot, GrADS will return four numbers: the
+    min and max   of the X axis values, followed by the min and max of the Y axis values.</span></p>
+  <p class="fineprint"><span class="plaintext">Use the <a href="gradcomdsetvrange.html"><code>set vrange</code></a> command to specificy the min and max of the X axis values  if you do not wish to use the defaults that GrADS selects. <br>
+    Use the <a href="gradcomdsetvrange2.html"><code>set vrange2</code></a> command to specificy the min and max of the Y axis values  if you do not wish to use the defaults that GrADS selects.    <br>
+  </span></p>
+  <p>  </p>
+</ol>
+</body>
+</html>
+
diff --git a/doc/script.html b/doc/script.html
new file mode 100644
index 0000000..5b608c3
--- /dev/null
+++ b/doc/script.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<title>GrADS Scripting Language</title>
<body bgcolor="e0f0ff" text="#000000">
<h1>GrADS Scripting Language</h1>
<p>
<a href="#intro">Introduction to GrADS scripts</a><br>
<a href="#elements">Elements of the Language:</a><br>
      <a href="#comment">comment</a><br>
      <a href="#statement">statement</a><br>
      <a href="#assignment">assignment</a><br>
      <a href="#standardio">say / prompt / pull</a><br>
      <a href="#ifendif">if / else / endif</a><br>
      <a href="#while">while / endwhile</a><br>
      <a href="#variables">variables</a><br>
      <a href="#operators">operators</a><br>
      <a href="#expressions">expressions</a><br>
      <a href="#functions">Functions</a><br>
      <a href="#intrinsic">Intrinsic Functions</a><br>
<a href="#commands">Commands that complement the scripting language</a><br>
<a href="#widgets">Widgets</a><br>
<a href="library.html">Script Library</a><br>
<a href="reference_card_scl.pdf">Scripting Language Reference Card</a>
<font size=-1>
(Requires <a href="http://www.adobe.com/products/acrobat/readstep.html">
Adobe Acrobat Reader</a>)</font>

<p>
<hr>
<p>

<h2><a name="intro"><u>Introduction to GrADS Scripts</u></a></h2>

<p>
Scripts offer users the facility to program GrADS operations.
Although it is relatively easy for users to produce sophisticated
GrADS graphics without ever writing a script, there are occasions
where the programming capability makes things even easier. This
section explains the general capabilities of scripts, how to run them,
and suggests a strategy for users who may wish to write their own.

<p>
<i><b>What scripts can do</b></i>

<p>
The GrADS scripting language, used via the GrADS <code><a
href="gradcomdrun.html">run</a></code> command, provides a similar
capability to the <code><a href="gradcomdexec.html">exec</a></code>
command, except that scripts also have flow control, defined
variables, and access to GrADS command output. Scripts may be written
to perform a variety of functions, such as allowing a user to interact
with Grads via point and click interface, animating any desired
quantities, and annotating plots with information obtained from GrADS
query commands.

<p>
The scripting language is similar to REXX in implementation. All
variables are of type STRING. Mathematical operations are supported on
script variables. Flow control is achieved via
<code>if/else/endif</code> and <code>while/endwhile</code>
constructs. Loop flow may be modified by the <code>continue</code> or
<code>break</code> commands. Strings contained in variables or
generated via an expression may be issued to GrADS as commands. The
output from those commands (i.e., the text that GrADS would have
output to the terminal) is put into a variable and made available to
the script. The language includes support for functions.

<p>
Before writing your own scripts, it is recommended that you read the
rest of this section and then try to run some of the scripts in the <a
href="library.html">library</a>. Study these example
scripts, referring to this page for information on syntax etc., and
you will soon be equipped to write scripts of your own.<p>

<p>
<i><b>Running scripts</b></i>

<p>
The command to execute a script is the 
<code><a href="gradcomdrun.html">run</a></code> command:

<p>
<ul><code>
<a href="gradcomdrun.html">run</a> <i>filename &ltarguments&gt</i>
</code></ul>

<p>
This command runs the script contained in the named file, which
generally has a <code>".gs"</code> tag at the end. Optional
<code><i>arguments</i></code> are passed to the script as a string
variable. You may issue any GrADS command from a script, including the
<code>run</code> command. When calling scripts recursively, be sure
that you can back out of the recursion and return to your main script.


<p>
<i><b>Automatic script execution</b></i>

<p>
You may have a simple script automatically executed before every
<code><a href="gradcomddisplay.html">display</a></code> command:

<p>
<ul><code>
<a href="gradcomdsetimprun.html">set imprun</a> <i>script-name</i>
</code></ul>

<p>
This script would typically be used to set an option that by
default gets reset after each <code><a href="gradcomddisplay.html">display</a></code> 
command, for example:

<p>
<ul><code><a href="gradcomdsetgrads.html">set grads</a> off</code></ul>

<p>
You can issue any GrADS command from this script, but the interactions
are not always clear.  For example, if you issued a <code><a
href="gradcomddisplay.html">display</a></code> command from this
script, you could easily enter an infinite recursion loop.

<p>
The argument to the script is the expression from the <code><a
href="gradcomddisplay.html">display</a></code>
command.

<p>
<i><b><a name="storing">Storing GrADS scripts</a></b></i>

<p>
It is convenient to put all your GrADS "utility" scripts in one
directory (e.g., <code>/usr/local/grads/lib/scripts</code>).

<p>
To simplify running these scripts, GrADS first looks in the
current directory for the script and then, if it can't find it,
appends the "<code>.gs</code>" extension and tries again.  For example,
suppose you are working on a test script called <code>t.gs</code>.  You would
run it in GrADS by,

<p>
<ul><code>run t</code></ul>

<p>
If after the first two tries, the script still can't be located,
then GrADS looks in the directory defined by the environment
variable <code>GASCRP</code>.  In the <code>t(csh)</code>, for example,

<p>
<ul><code>setenv GASCRP /home1/grads/lib</code></ul>

<p>
or in <code>ksh</code>,

<p>
<ul><code>export GASCRP=/home1/grads/lib</code></ul>

<p>
Note the if the <code>/</code> is not added to the end of the
directory name, it is automatically added by UNIX. However, it'll
still work if you type<p>

<ul><code>setenv GASCRP /home1/grads/lib/</code></ul>

<p>
If the script cannot be found, then <code>.gs</code> is appended and GrADS
tries yet again.  Thus,

<p>
<ul><code>d slp <br> run /home1/grads/lib/cbarn.gs</code></ul>

<p>
simplifies to,

<p>
<ul><code>d slp <br> run cbarn</code></ul>


<hr>

<h2><a name="elements"><u>Elements of the Language</u></a></h2>

<p>
A script file is made up of records. The end of a script record is
determined by either a newline character or a semicolon (where the
semicolon is not contained within a constant string).<p>

Each script record may be one of the following types:<p>
<ul>
<li>comment<br>
<li>statement<br>
<li>assignment<br>
<li>say / prompt / pull<br>
<li>if / else / endif<br>
<li>while / endwhile / break / continue<br>
<li>function header / return<br>
</ul>

<p>
Many of the above record types will contain expressions.  Script
expressions are composed of operands and operators. Operands
are strings constants, variables, or function calls; operators
are mathematical, logical, or concatenation operations. Further
discussion of these record types and the expressions they may
contain is given below.

<p>
<i><b><a name="comment">Comment</a></b></i>

<p>
Comments in GrADS scripts must contain an asterisk (*) in the first column. 

<p>
<i><b><a name="statement">Statement</a></b></i>

<p>
The statement record consists only of an expression:
<p>
<ul><code><i>expression</i></code></ul>

<p>
The expression is evaluated, and the resulting string is then
submitted to GrADS as a command for execution. The script variable
<code>rc</code> will contain the return code from the GrADS command
(this will always be an integer value). In addition, any text output
from GrADS in response to the command is put in the variable
<code>result</code> for examination by the script. A GrADS error
resulting from an invalid command WILL NOT terminate execution of the
script.

<p>
The simplest type of expression is a string constant, which is just a
character string enclosed in single or double quotes. Here's an
example of simple script containing a comment plus statements
comprised of string constants:

<p>
<ul>
<code>
* this is a sample script <br>
'open my_sst_dataset.ctl' <br>
'set lat -30 30' <br>
'set lon 90 300' <br>
'display sst' <br>
</code>
</ul>


<p>
<i><b><a name="assignment">Assignment</a></b></i>

<p>
Assignment records are used to define variables and assign them
values. The format of the assignment record is:
<p>
<ul><code>variable = <i>expression</i></code></ul>

<p>
The expression is evaluated, and the result is assigned to be the
value of the indicated variable. The same example from above can be
rewritten to include assignment statements. Note the use of explicit
and implied concatenation:

<p>
<ul>
<code>
'open my_sst_dataset.ctl' <br>
minlat = -30 <br>
maxlat = minlat + 60 <br>
minlon =  90 <br>
maxlon = 300 <br>
'set lat 'minlat%' '%maxlat <br>
'set lon 'minlon' 'maxlon <br>
'display sst' <br>
</code>
</ul>

<p>
<i><b><a name="standardio">say / prompt</a></b></i>

<p>
To present information or questions to the GrADS user via the terminal
(standard output), use the <code>say</code> or <code>prompt</code>
commands:
<p>
<ul><code>
say <i>expression</i><br>
prompt <i>expression</i><br>
</code></ul>
<p>
The result of the <code><i>expression</i></code> is written to the
terminal. The <code>prompt</code> command works the same way as the
<code>say</code> command but does not append a carriage return. It is
possible to combine variables and string constants when writing to
standard output:
<p>
For example:<p>
<ul><code>
line = "Peter Pan, the flying one" <br>
say line<br>
say `She said it is `line<br>
</code></ul>
<p>
gives:
<p>
<ul><code>
Peter Pan, the flying one<br>
She said it is Peter Pan, the flying one
</code></ul>


<p>
<i><b>pull</b></i>

<p>
To retrieve information provided by the GrADS user via the terminal
(standard input), use the <code>pull</code> command:<p>
<ul><code>pull <i>variable</i></code></ul>
<p>
The script will pause for user input from the keyboard (ending with
the carriage return), and then the string entered by the user is
assigned to the indicated variable name. To elaborate on a
previous example:

<p>
<ul><code>
'open my_sst_dataset.ctl' <br>
prompt 'Enter min and max latitudes: ' <br>
pull minlat maxlat <br>
prompt 'Enter min and max longitudes: ' <br>
pull minlon maxlon <br>
'set lat 'minlat%' '%maxlat <br>
'set lon 'minlon' 'maxlon <br>
'display sst' <br>
</code></ul>


<p>
<i><b><a name="ifendif">if / else / endif</a></b></i>

<p>
One way to control the flow of script execution is via the <code>if/else/endif</code> 
construct. The format is as follows:<p>
<ul>
<code>
if expression<br>
   script record<br>
   script record<br>
   . <br>
   . <br>
else<br>
   script record<br>
   . <br> 
   . <br>
endif<br>
</code>
</ul>

<p>
The <code>else</code> block is optional, but the <code>endif</code>
record must be present. The script records following <code>if
expression</code> are executed if the expression evaluates to a string
containing the character 1. If the expression evaluates to 0, then the
script records in the <code>if</code> block are not executed and the
script continues with the <code>else</code> block (if it is present)
or the record following <code>endif</code>. The <code>if
expression</code> record must be separated from the script records
that follow it. For example, the following script record would be
invalid:
<p>
<ul><code>if (i = 10) j = 20 </code></ul>
<p>
The correct syntax requires three separate script records. This is
achieved by putting each record on one line:
<p> 
<ul><code> if (i = 10)<br> 
   j = 20 <br> endif<br> </code></ul>
<p>
Alternatively, the three records could be on the same line separated 
by a semicolon:
<p>
<ul><code>if (i = 10) ; j = 20 ; endif</code></ul>
<p>
N.B. There is no <code>elseif</code> construct in GrADS.


<p>
<i><b><a name="while">while / endwhile</a></b></i>

<p>
Another method for controlling the flow of script execution is the <code>while/endwhile</code> construct. The format is as follows:
<p>
<ul>
<code>
while expression<br>
   script record<br>
   script record <br>
   . <br>
   . <br>
endwhile<br>
</code>
</ul>

<p>
The script records following <code>while expression</code> are
executed if the expression evaluates to a string containing the
character 1. If the expression evaluates to 0, then the script records
in the <code>while</code> block are not executed and the script continues
with the record following <code>endwhile</code>. The <code>while
expression</code> record must be separated from the script records
that follow it.

<p>
Two additional script commands may be used to modify the
<code>while</code> loop execution: <code><b>break</b></code> and
<code><b>continue</b></code>. Inserting the <code>break</code> statement will
immediately end execution of the loop and the script will move on to
the records following <code>endwhile</code>. The <code>continue</code>
statement will immediately end execution of the loop, but the script
will then branch immediately back to the top of the loop, and the
expression will be re-evaluated.<p>

While loops are often used as counters. For example:<p>
<ul>
  <code> count = 1 <br>
  while (count < 10) <br>
     'set t 'count <br>
     'display z' <br>
     if (rc != 0) ; break ; endif <br>
     count = count + 1 <br>
  endwhile<br>
  </code>
</ul>


<p>
<i><b><a name="variables">Variables</a></b></i>

<p>
The contents of a script variable is always a character string.
However, if the contents of a variable represent a number in the
correct format, certain operators may perform numeric operations on
that variable, giving a string result which will also be a number.
<p>
Variable names can have from 1 to 8 characters, beginning with an
alphabetic character and containing letters or numbers only. The name
is case sensitive. If a variable has not yet been assigned, its value
is its name.
<p>
String variables or string constants are enclosed in either single or
double quotes. An example of an assignment statement that defines a
string variable is as follows:
<p>
<ul><code>name = `Peter Pan' <br> name = "Peter Pan"</code></ul>
<p>
Numeric variables may be entered without quotes, but are still
considered strings.
<p>
<ul><code>number = -99.99</code></ul>


<p>
<i><b>Predefined script variables</b></i>
<p>
Some variable names are predefined; it is a good idea to avoid
assigning values to these variables. The following are predefined
script variables -- their values will change with every execution of a
GrADS command from the script:
<p>
<ul><code>rc <br> result </code></ul>

<p>
<code>lat, lon, lev,</code> and <code>time </code>are also used
as predefined variables in GrADS. Although using them within a script
is okay, in order to avoid confusion it is not recommended.

<p>
<i><b>Global string variables</b></i>
<p>
String variables are usually local to the functions they are contained
in. Global string variables are also available.  They are specified
via the variable name. Any variable name starting with an
underscore (_) will be assumed to be a global variable, and will keep
its value throughout an entire script file. An example of an
assignment statement that defines a global string variable is as
follows:
<p>
<ul><code>_var1 = "global variable 1"</code></ul>
<p>
<i>N.B.</i> Global variables cannot be used in function headers. For example:
<p>
<ul><code>function dostuff(_var)</code></ul>
<p>
wouldn't make sense, since <code>_var</code> is a global variable, and would
be invalid if it were the only argument.

<p>
<i><b>Compound string variables</b></i>
<p>
Compound variables are used to construct arrays in scripts. A compound
variable has a variable name with segments separated by periods. For
example:
<p>
<ul><code>varname.i.j</code></ul>
<p>
In this case, when the variable contents are accessed,
<code>i</code> and <code>j</code> will be looked up to see if they are
also variables (non-compound). If they are, the <code>i</code> and
<code>j</code> will be replaced by the string values of <code>i</code>
and <code>j</code>. For example:
<p>
<ul><code>i = 10 <br> j = 3 <br> varname.i.j = 343</code></ul>
<p>
In the above example, the assignment is equivalent to:
<p>
<ul><code>varname.10.3 = 343</code></ul>
<p>
Note that the string values of <code>i</code> and <code>j</code> may
be anything, but the variable name specification in the script must
follow the rules for variable names: letters or numbers, with a
leading letter. The variable name after substitution may be any
string:
<p>
<ul><code>i = 'a#$xx' <br> varname.i = 343</code></ul>
<p>
The above is valid.  However, we cannot refer to this variable
name directly:
<p>
<ul><code>varname.a#$xx = 343</code></ul>
<p>
would be invalid.
<p>
Variable names may <i>not</i> be longer than 16 characters, either
before or after substitution.
<p>
Note that the GrADS scripting language is not particularly
efficient in handling large numbers of variables.  Thus compound
variables should not be used to create large arrays:
<p>
<ul><code>
i = 1 <br> 
while (i < 10000) <br> 
&nbsp&nbsp var.i = i <br>
&nbsp&nbsp i = i + 1 <br>
endwhile
</code></ul>
<p>
The above loop will create 10000 distinct variable names. Such
a large number of variables in the variable chain will slow the
script down a lot. 
</ul>


<p>
<i><b><a name="operators">Operators</a></b></i>

<p>
The following operators are implemented in the scripting language:<p>
<ul>
<code>|          </code> logical OR <br>
<code>&      </code> logical AND <br>
<code>!          </code> unary NOT <br>
<code>-          </code> unary minus <br>
<code>=          </code> equal <br>
<code>!=        </code> not equal <br>
<code>>       </code> greater than <br>
<code>>=     </code> greater than or equal <br>
<code><       </code> less than <br>
<code><=     </code> less than or equal <br> 
<code>%          </code> concatenation <br>
<code>+          </code> addition <br>
<code>-          </code> subtraction <br>
<code>*          </code> multiplication <br>
<code>/          </code> division<br>
</ul>

<p>
The following operators will perform a numeric operation if the
operands are numeric:<p>

<ul><code>=, !=, >, >=, <, <=, +, -, *, /</code></ul>

<p>
If any of the following operations are attempted with non-numeric
operands, an error will result:<p>

<ul><code>+, -, *, /</code></ul>

<p>
Arithmetical operations are done in floating point. If the result is
integral, the result string will be an integer. Logical operations
will give a character <code>0</code> (zero) if the result is FALSE,
and a character <code>1</code> (one) if the result is TRUE.


<p>
<i><b><a name="expressions">Expressions</a></b></i>

<p>
Script expressions consist of any combination of operands, operators,
and parentheses. Operands may be string constants, variables, 
or function calls. The precedence of the operators is:
<p>
<ul><code>
-, !  (Unary) <br>
/, * <br>
+, - <br>
% <br>
=, !=, >, >=, <, <= <br>
& <br>
| <br>
</code></ul>

<p>
Within the same precedence level, operations are performed left
to right. Parentheses modify the order of operation according to
standard convention.

<p>
All script expressions, including all function calls, etc. are
evaluated and the resulting string is what gets executed as a
command. For example:
<p>
<ul><code>
var1 = -1 ; var2 = 10 <br>
if (var1*var2 < 10 & var1 > 0) <br>
   say 'both statements are true' <br>
else <br>
   say 'it is not the case that both statements are true' <br>
endif <br>
</code></ul>
<p>
For the expression following <code>if</code>, both sides of the
logical operation must be evaluated before the entire expression can
be simplified into a true or false result. In this case, the
subexpression on the left is true, but the subexpression on the left
is not, so the whole expressions resolves to 0 (zero) and the script
will print:
<p>
<ul><code>it is not the case that both statements are true</code></ul>

<p>
<b><i>Concatenation</i></b>
<p>
In some espressions, the concatenation operator may be implied. The <code>%</code>
operator may be omitted whenever the two operands are a string
constant and a variable name. With implied concatentation, intervening
blanks will be ignored.
<p>
For example, the following expressions have the same effect:
<p>
<ul>
<code>'set lat 'minlat%' '%maxlat      </code>
uses the concatenation operator % <br>
<code>'set lat 'minlat' 'maxlat       </code>
concatenation is implied <br>
</ul>

<p>
Assuming two previous statements, <code>minlat = -30 </code> and
<code> maxlat = 30</code>, the resulting expression would be:
<p>
<ul><code>'set lat -30 30'</code></ul>
<p>
Keep in mind the order of precedence when using the concatenation operator.

<p>
<i><b><a name="functions">Functions</a></b></i>
<p>
Function calls take the form of:
<p>
<ul><code>name(arg,arg,arg,...)</code></ul>

<p>
where the function name follows the same rules as for variable names, and
the arguments may be any expression.

Functions may either be contained within the script file itself,
or the may be intrinsic functions. Functions contained within
other script files are not supported as yet (other script files
may be executed via the GrADS run command).<p>

In either case, functions are invoked as a script expression is
being evaluated.  Script functions always have a single string
result, but may have one or more string arguments.  Functions are
invoked by:<p>

<dd><code>name(arg,arg,arg...)</code><p>

If the function has no arguments, you must still provide the
parentheses:<p>

<dd><code>name()</code><p>

You may provide your own functions from within your script file
by using the <code>function</code> definition record:<p>

<dd><code>function name(variable, variable, ...)</code><p>

To return from a function, use the <code>return</code> command:<p>

<dd><code>return <i>expression</i></code><p>

The <code><i>expression</i></code> is optional; if not provided, a NULL string will
be returned.  (A null string is: '')  The result of the function
is the result of the expression specified on the return command.<p>

When a function is invoked, the arguments are evaluated, then
flow of control is transferred to the function.  The variables
contained in the list within the function definition record are
initialized   to the values of the passed arguments.  If too few
arguments where passed for the variables specified, the trailing
variables are uninitialized.  If too many arguments are passed,
the extra arguments are discarded.<p>

You may modify the variables from the function definition record
without modifying the variables from the calling routine.<p>

Scope of variables is normally local to the function, but can be
global.<p>

When a script file is first invoked (via the <code>run</code> command), 
execution starts at the beginning of the file.  A function
definition record may optionally be provided at the beginning. 
If it is, it should specify one variable name.  This variable
will be initialized to any <code>run</code> command options.  If no options
were given, the variable will be initialized to NULL.<p>

<p>
<i><b><a name="intrinsic">Intrinsic Functions</a></b></i>
<p>
<ul>
<b><code>strlen (<i>string</i>)</code></b>
<br>
This function returns the length (number of characters) of  
<code><i>string</i></code>.

<p><b><code>sublin (<i>string, n</i>)</code></b>
<br>
This function gets a single line from a string containing several
lines. The result is the <code><i>nth</i></code> line of
<code><i>string</i></code>.  If the string has too few lines, the
result is NULL.  <code><i>n</i></code> must be an integer.

<p>
<b><code>subwrd (<i>string, n</i>)</code></b>
<br>
This functions gets a single word from a string. 
The result is the <code><i>nth</i></code> word of <code><i>string</i></code>.  
If the string is too short, the result is NULL. 
<code><i>n</i></code> must be an integer.

<p>
<b><code>substr (<i>string, start, length</i>)</code></b>
<br>
This function gets part of a string. 
The sub-string of <code><i>string</i></code> starting at location
<code><i>start</i></code> for length <code><i>length</i></code> will be returned.  
If the string is too short, the result will be short or NULL. 
<code><i>start</i></code> and <code><i>length</i></code> must be integers.

<p>
<b><code>read (<i>filename</i>)</code></b>
<br>
This functions reads individual records from file <code><i>filename</i></code>.
Repeated calls must be made to read consecutive records. The result is
a string containing two lines: the first line is the return code, the 
2nd line is the record read from the file. The record may be a maximum 
of 80 characters. Use the <code>sublin</code> function to separate the
result. Return codes are:<br>

<ul>
<code>0 - </code>ok <br>
<code>1 - </code>open error <br>
<code>2 - </code>end of file <br>
<code>8 - </code>file open for write <br>
<code>9 - </code>I/O error<br>
</ul>

Files are opened when the first call to read is made for a 
particular file name. Files are closed when the execution of the
script file terminates (note that files remain open between
function calls, etc).

<p>
<b><code>write (<i>filename, record</i> <, append>)</code></b>
<br>
This functions writes records to output file <code>filename</code>.  

On the first call to write for a particular file, the file is opened
in write mode.  This will destroy an existing file!  If you use the
optional append flag, the file will be opened in append mode, and all
writes will be appended to the end of the file.  Return codes are:<br>
<ul>
<code>0</code> - ok <br>
<code>1</code> - open error <br>
<code>8</code> - file open for read</ul>

<p>
<b><code>close (<i>name</i>)</code></b>
<br>

This function closes the named file.  This must be done if you wish to
read from a file you have been writing to.  This can also be used to
rewind a file.  Return codes are:<br>
<ul>
<code>0</code> - ok <br>
<code>1</code> - file not open</ul><p>
</ul>

<h2><a name="commands"><u>Commands that complement the scripting language</u></a></h2>
<p>
There are some GrADS commands that, although not designed
exclusively for scripts, are most useful in script applications. 
These include:

<p>
<b><code><a href="gradcomdquery.html">query</a> <<i>option</i>></code></b> or 
<b><code><a href="gradcomdquery.html">q</a> <<i>option</i>></code></b>
<ul>
<p>
To see the list of available options, issue the <code><a
href="gradcomdquery.html">query</a></code> command by itself. A
description of the <code><a href="gradcomdquery.html">query</a></code>
options that are most useful for script applications follows.

<p>
<b><code><a href="gradcomdquery.html">q</a> define</code></b> --
Lists all defined variables

<p>
<b><code><a href="gradcomdquery.html">q</a> defval <i>ival
jval</i></code></b> -- Gives defined grid value at <i>ival, jval</i>
<p>
To interactively modify grid point values for a <code>defined</code>
variable, <code><a href="gradcomdquery.html">q</a> defval</code>
can be used in conjunction with <code><a
href="gradcomdsetdefval.html">set defval</a></code>. For example, the
code shown below queries the value of sst at gridpoint(i,j), then
tests to see if the value is less than -1.6, and if it is, sets the
sst to a bad value.<p>
<ul>
<code>
'q defval sst 'i' 'j <br>
val = subwrd(result,3) <br>
if (val < -1.6)  <br>
&nbsp&nbsp'set defval sst 'i' 'j' 'bad_value <br>
endif <br>
</code>
</ul>

<p>
<b><code><a href="gradcomdquery.html">q</a> dims</code></b> --
Gives the current dimension environment

<p>
<b><code><a href="gradcomdquery.html">q</a> file
<i>n</i></code></b> -- Gives info on file number <i>n</i>

<p>
<b><code><a href="gradcomdquery.html">q</a> files</code></b> --
Lists open files

<p>
<b><code><a href="gradcomdquery.html">q</a> fwrite</code></b> --
Gives the name of the file used for fwrite operations

<p>
<b><code><a href="gradcomdquery.html">q</a> gxinfo</code></b> --
Lists graphics settings

<p>
This option is handy when trying to find the plot area. The output
from <code><a href="gradcomdquery.html">q</a> gxinfo</code> might
look like this:

<p>
<code>
<ul>
Last Graphic = Line <br>
Page Size = 11 by 8.5 <br>
X Limits = 2 to 10.5 <br>
Y Limits = 0.75 to 7.75 <br>
Xaxis = Lon  Yaxis = Val <br>
Mproj = 2<br>
</ul>
</code>

<p>
The first line indicates that the output is a line plot. The second line
gives the page dimensions -- in this case GrADS is in landscape
mode. The third and fourth lines give the x and y boundaries of the
plot. In this case the plot has 1-inch margins in the x direction and
0.75-inch margins in the y direction.  The fifth line tells what kind
of axes you have, and the sixth line identifies the map projection:
<br>
<ul>
<code>1    </code>Scaled (no preservation of aspect ratio)<br>
<code>2    </code>Latlon (2-D horizontal fields) <br>
<code>3    </code>Northern polar stereographic <br>
<code>4    </code>Southern polar stereographic <br>
<code>5    </code>Robinson (lon range must be -180 to
180 and lat range must be -90 to 90)<br>
</ul>

<p>
<b><code><a href="gradcomdqpos.html">q pos</a></code></b> -- Waits for mouse click, returns position<br>

<p>
<b><code><a href="gradcomdquery.html">q</a> shades</code></b> -- Gives colors and levels of shaded contours<br>

<p>
<b><code><a href="gradcomdquery.html">q</a> time</code></b> - gives time range of current open file<br>

<p>
<b><code><a href="gradcomdquery.html">q</a> <i>transform coord1 coord2</i></code></b> -- Coordinate transformations 

<ul>
<p>
where <code><i>transform</i></code> is one of: <br>
<code>xy2w       </code>XY coords to world coords <br>
<code>xy2gr      </code>XY coords to grid coords <br>
<code>w2xy       </code>world coords to XY coords <br>
<code>w2gr       </code>world coords to grid coords <br>
<code>gr2w       </code>grid coords to world coords <br>
<code>gr2xy      </code>grid coords to XY coords <br>
</ul>

<p>
<i>XY coords</i> are inches on the page (screen) where the page is
11x8.5 inches or 8.5x11 inches, depending on how GrADS was started.

<p>
<i>World coords</i> are lat, lon, lev, time or val, depending on what
the dimension environment is when the grid was displayed. Note that
time is displayed (and must be specified) in GrADS absolute date/time
format. val is the value coordinate for a 1-D plot (linegraph).

<p>
<i>Grid coordinates</i> are the i,j indices the grid being
displayed. For station data sets, grid and world coordinates are
equivalent except for the time dimension. Note that if you display a
grid from a 'wrapped' data set, the grid numbers may be out of range
of the actual file grid numbers. (A 'wrapped' data set is a data set
that covers the earth in the longitude direction. Wrapping takes place
automatically). The conversions are done consistently, but you may
want to be sure you can handle the wrapping case if your data set is
global.

<p>
N.B. Coordinate transform queries are only valid after something has
been displayed, and the transformations apply only to the most recent
item that has been displayed.
</ul>

<p>
<b><code><a name="scriptfindstn">set gxout findstn</a></code></b>
<p>
When using the graphics output type <code><a href="gradcomdsetgxout.html">set gxout findstn</a></code>, three
arguments must be provided with the <a
href="gradcomddisplay.html"><code>display</code></a> command. The
first argument is a station data expression. The 2nd and 3rd arguments
are the X and Y screen coordinates of the of the desired search
location.  GrADS will find the station closest to the specified X and
Y position, and print its stid, lon, and lat.  This graphics output
type should only be used when X and Y are the varying dimensions and
AFTER a regular display command (that results in graphics output) is
entered.
<p>
<b><code>set dbuff on|off</code></b>
<p>
This command sets double buffer mode <code>on</code> or
<code>off</code>. This allows animation to be controlled from a
script. The <a href="gradcomdclear.html"><code>clear</code></a>
command also sets double buffer mode <code>off</code>.

<p>
<b><code>swap</code></b>

<p>
Swaps buffers, when double buffer mode is <code>on</code>. If double
buffer mode is <code>off</code>, this command has no effect.

<p>
The usual usage of these commands would be:<p>

<ul>
<code>
set dbuff on <br>
start looping <br>
&nbsp&nbsp display <i>something</i><br>
&nbsp&nbsp swap <br>
endloop <br>
set dbuff off<br>
</code>
</ul>

<p>
<a name="widgets"><h2><u>Widgets</u></h2></a>
<p>
GrADS has the capability to implement a graphical user interface. This
interface is used to draw widgets (buttons and pull down menus) that
allow a "point and click" interface between the Grads user and the
scripting language.

<p>
<h3>Buttons</h3>
<p>
Here is a sample from a script illustrating how to draw a button:

<p>
<ul>
<pre>
set rgb 90 100 100 100
set rgb 91  50  50  50
set rgb 92 200 200 200
set button 2 90 91 92 3 90 92 91 6
draw button 1 5.5 1 2 0.5 This is a Button
</pre>
</ul>

<p>
The reference pages for <a href="gradcomdsetbutton.html"><code>set
button</code></a> and <a href="gradcomddrawbutton.html"><code>draw
button</code></a> contain information on how to specify the button
characteristics and position.

<p>
A button's initial "state" is <code>ON</code>. If a user clicks on a
button following a <a href="gradcomdqpos.html"><code>q pos</code></a>
command, then the button state will switch from <code>ON (1)</code> to
<code>OFF (0)</code>. A second <a href="gradcomdqpos.html"><code>q
pos</code></a> followed by a mouse click on the button will return it
to the <code>ON</code> state. The button state may also be changed
with the <a href="gradcomdredrawbutton.html"><code>redraw
button</code></a> command.

<p>
The output from the <a href="gradcomdqpos.html"><code>q pos</code></a> command 
is what makes the button widgets so useful. Here is a template of what 
<a href="gradcomdqpos.html"><code>q pos</code></a> returns after a mouse click
on a button:

<p>
<code>
Position = <i>xpos ypos mousebutton widgetclass buttonnumber buttonstate </i></code>

<p>
where:
<ul>
<code><i>xpos, ypos</i>&nbsp&nbsp&nbsp&nbsp</code>
- coordinates of the mouse click in virtual page units <br>
<code><i>mousebutton</i>&nbsp&nbsp&nbsp</code>
- either 1, 2, or 3 for the left, center, or right mouse button <br>
<code><i>widgetclass</i>&nbsp&nbsp&nbsp</code>
- 1 is the widget class number for buttons  <br>
<code><i>buttonnumber</i>&nbsp&nbsp</code>
- the number assigned to the button when it was originally drawn <br>
<code><i>buttonstate</i>&nbsp&nbsp&nbsp</code>
- either 0 (meaning "off") or 1 (meaning "on")
</ul>

<p>
If the user did not click on a button, then <code><i>widgetclass</i></code>
will be 0 and there will be no output for
<code><i>buttonnumber</i></code> or <code><i>buttonstate</i></code>.


<p>
<h3>Drop Menus</h3>
<p>
As with button widgets, dropmenus provide a "point-and-click"
interface between scripts and the GrADS user. The reference pages for
<a href="gradcomdsetdropmenu.html"><code>set dropmenu</code></a> and
<a href="gradcomddrawdropmenu.html"><code>draw dropmenu</code></a>
contain information on how to specify the dropmenu characteristics and
position.
<p>
The output from <a href="gradcomdqpos.html"><code>q pos</code></a>
after a click on a dropmenu is similar to that described above for
buttons.  Here is a template of what is returned by <a
href="gradcomdqpos.html"><code>q pos</code></a> after a mouse click
on a dropmenu:

<p>
<code>Position = <i>xpos ypos mousebutton widgetclass menunumber inum</i></code>

<p>
where:
<ul>
<code><i>xpos, ypos</i>&nbsp&nbsp&nbsp&nbsp</code>
- coordinates of the mouse click in the menu base in virtual page units <br>
<code><i>mousebutton</i>&nbsp&nbsp&nbsp</code>
- either 1, 2, or 3 for the left, center, or right mouse button <br>
<code><i>widgetclass</i>&nbsp&nbsp&nbsp</code>
- 3 is the widget class number for dropmenus  <br>
<code><i>menunumber</i>&nbsp&nbsp&nbsp&nbsp</code>
- the number assigned to the dropmenu when it was originally drawn <br>
<code><i>inum</i>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</code>
-  the menu item number selected from the menu list
</ul>

<p>
If no menu item is selected, then <code><i>menunumber</i></code> and <code><i>inum</i></code> will
both be -1.


<p>
Here is a script sample illustrating how to use a dropmenu:

<p>
<pre>
'reset events'
'set rgb 90 100 100 100'
'set rgb 91 150 150 150'
'set rgb 92 200 200 200'
'set dropmenu 1 91 90 92 0 91 90 92 1 91 90 92 90 92 6'
'draw dropmenu 1 1 8 1.5 0.5 Select a Variable | Wind | Temperature | Height | SLP '
noselect = 1
while (noselect)
  'q pos'
  menunum  = subwrd(result,7)
  menuitem = subwrd(result,8)
  if (menunum = 1)
    if menuitem = 1 ; newbase = 'Variable = Wind'   ; endif
    if menuitem = 2 ; newbase = 'Variable = Temp'   ; endif
    if menuitem = 3 ; newbase = 'Variable = Height' ; endif
    if menuitem = 4 ; newbase = 'Variable = SLP'    ; endif
    'draw dropmenu 1 1 8 1.5 0.5 'newbase' | Wind | Temperature | Height | SLP '
    noselect = 0
  endif
endwhile
</pre>
<p>
Here is another script sample illustrating how to use cascading dropmenus:
<p>
<pre>
'clear'
'set rgb 90 100 100 100'
'set rgb 91 150 150 150'
'set rgb 92 200 200 200'
'set button 1 91 -1 -1 1 91 90 92 12'
'draw button 1 1 8 1 0.5 quit'
'set dropmenu 1 91 -1 -1 1 91 90 92 1 91 90 92 90 92 6'
'draw dropmenu 1 1.5 7.5 2 0.5  Menu Base | Space | Earth >05> | Sun | Moon'
'draw dropmenu 5 cascade Ocean | Land | Atmosphere >11> | Biosphere'
'draw dropmenu 11 cascade Snow | Rain | Mist | Tornado '

while (1)
  'q pos'
  say result
  ev = subwrd(result,6)
  if (ev!=3); break; endif;
endwhile
</pre>
<p>
It is left to the GrADS script writer (that means you!) to run the demo and 
interpret the output of <a href="gradcomdqpos.html"><code>q pos</code></a>
when clicking on all the options in the cascade of dropmenus. 

<p>
<h3>Rubber banding</h3>

<p>
GrADS has a widget type called <code>rband</code> for rubber banding.  There
are two <code>rband</code> modes: <code>box</code> and <code>line</code>.
To set up the <code>rband</code> widget, use the following command:
<p>
<ul><code>
<a href="gradcomdsetrband.html">set rband</a> <i>num mode x1 y1 x2 y2</i>
</code></ul>

<p>
where:
<p>
<ul>
<code><i>num</i>   </code>
- widget number<br>
<code><i>mode</i>  </code>
- may be either <code>box</code> or <code>line</code><br>
<code><i>x1</i>    </code>
- lowest X point where the widget will be active (in virtual page units)<br>
<code><i>y1</i>    </code>
- lowest Y point where the widget will be active (in virtual page units)<br>
<code><i>x2</i>    </code>
- highest X point where the widget will be active (in virtual page units)<br> 
<code><i>y2</i>    </code>
- highest Y point where the widget will be active (in virtual page units)<br>
</ul>

<p>
In <code>box</code> mode, as the user clicks and drags the mouse in
the active rband area a box is drawn with one corner located at the
initial click and the opposite corner located at the release point. In
<code>line</code> mode, a line is drawn between these two points.

<p>
For example, suppose you  want to set up a
<code>box</code> rubber band widget in the plot region only.

<p>
First, execute <a href="gradcomdquery.html"><code>q gxinfo</code></a>
to get the X and Y limits of the plot area. The result from <a
href="gradcomdquery.html"><code>q gxinfo</code></a> might look like
this:

<ul>
<pre>
Last Graphic = Line
Page Size = 11 by 8.5
X Limits = 2 to 10.5
Y Limits = 0.75 to 7.75
Xaxis = Lon  Yaxis = Val
Mproj = 2
</pre>
</ul>

<p>
Second, set up the widget with <a
href="gradcomdsetrband.html"><code>set rband</code></a> using the dimensions
grabbed from the result of <a href="gradcomdquery.html"><code>q gxinfo</code></a>:
<p>
<ul>
<pre>
xlims = sublin(result,3)
ylims = sublin(result,4)
x1 = subwrd(xlims,4)
x2 = subwrd(xlims,6)
y1 = subwrd(ylims,4)
y2 = subwrd(ylims,6)
'set rband 21 box 'x1' 'y1' 'x2' 'y2
</pre>
</ul>

<p>
Finally, use <a href="gradcomdqpos.html"><code>q pos</code></a> 
to activate the widget.

<p>
<ul><code>ga-> q pos</code></ul>

<p>
This freezes the system until the user clicks, drags, and 
then releases the mouse somewhere within the active rband area. 
Here is a template for the output you would get from GrADS after
a mouse click and drag in the rband area:<p>

<ul>
<code>Position = <i>xpos1 ypos1 mousebutton widgetclass widgetnumber xpos2 ypos2</i></code>
</ul>

<p>
where:
<ul>
<code><i>xpos1, ypos1</i>&nbsp&nbsp&nbsp</code>
- coordinates of the initial mouse click in virtual page units <br>
<code><i>mousebutton</i>&nbsp&nbsp&nbsp&nbsp</code>
- either 1, 2, or 3 for the left, center, or right mouse button <br>
<code><i>widgetclass</i>&nbsp&nbsp&nbsp&nbsp</code>
- 2 is the widget class number for rbands  <br>
<code><i>widgetnumber</i>&nbsp&nbsp&nbsp</code>
- the number assigned to the
rband widget when it was set up  <br>
<code><i>xpos2, ypos2</i>&nbsp&nbsp&nbsp</code>
- coordinates of the mouse release point in virtual page units <br>
</ul>

<p>
The page coordinates can be then be used to draw a box (or a line)
where the user specified, or parsed and used in the coordinate
transform <a href="gradcomdquery.html"><code>q xy2w</code></a> to
recover the lat/lon region selected by the user.

</body>
</html>
\ No newline at end of file
diff --git a/doc/shapefiles.html b/doc/shapefiles.html
new file mode 100644
index 0000000..0343e57
--- /dev/null
+++ b/doc/shapefiles.html
@@ -0,0 +1,80 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><title>Shapefiles</title>
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+-->
+</style>
+<H2><strong>The Shapefile</strong> Interface in GrADS</H2>
+<p><strong>
+<a href="#intro">Introduction</a><br />
+<a href="#whatis">What is a shapefile?</a><br />
+<a href="#draw">Drawing shapefiles</a><br />
+<a href="#query">Querying shapefiles</a><br />
+<a href="#envv">Relevant Environment Variables</a><br />
+<a href="#writing">Writing shapefiles</a><br />
+<a href="#examples">Examples</a><br />
+<a href="#caveat">Caveat</a></strong></p>
+<p><img src="../../assets/colaline.gif" alt="line" width="600" height="4" />
+<p><em><strong><a name="intro" id="intro"></a>Introduction</strong></em><br />
+  GrADS version 2.0.a8 introduced the new  capability to  <strong>draw</strong> and <strong>query</strong> the contents of a shapefile; version 2.0.a9 added the capability to <strong>create</strong> new shapefiles from GrADS gridded or station data sets. This documentation page serves as an overview of the GrADS shapefile inteface, providing guidance on what shapefiles are, how to find out what they contain, how to draw their contents, and how to create new shapefiles. 
+<P><em><strong><a name="whatis" id="whatis"></a>What is a Shapefile?</strong></em><br />
+  The shapefile format (promulgated by <a href="http://esri.com" target="_parent">ESRI</a>) stores non-topological geometry and attribute information for the spatial features in a data set.  Shapefiles are used extensively in Geographic Information Systems (GIS) and they typically contain data related to coastlines, political boundaries, state or county boundaries, climate zones, roads, rivers, topography, etc. The geometry of each spatial feature or 'shape' is stored as a set of vector  [...]
+The projection file contains specifics about the spherical geometry; it is an optional but useful component of a shapefile.
+<P>Some resources for freely available shapefiles are:
+
+<ul>
+  <li><a href="http://www.weather.gov/geodata/" target="_blank">National Weather Service Shapefile Database</a></li>
+  <li><a href="http://www.nationalatlas.gov/atlasftp.html" target="_blank">National Atlas</a></li>
+  <li><a href="http://www.diva-gis.org/Data" target="_blank">DIVA-GIS</a></li>
+  <li><a href="http://www.naturalearthdata.com/downloads/">Natural Earth</a></li>
+</ul>
+<P><a name="draw" id="draw"></a><em><strong>Drawing Shapefiles</strong></em><br />
+GrADS will draw the contents of a shapefile as an overlay on top of an existing plot with the command <code><a href="gradcomddrawshp.html">draw shp</a></code>. It is necessary to draw a plot first in order to establish the dimensions and scaling of the display. Shapefiles contain 2-dimensional spatial features, so your plot must be varying in the X-Y (lon/lat) domain. 
+<P>A shapefile may contain one of three kinds of graphical elements: points, lines, or polygons. 
+<ul>
+  <li> For shapefiles that contain points, GrADS will draw a mark at each point location. The mark type and size are controlled by the <code><a href="gradcomdsetshpopts.html">set shpopts</a></code> command, and the color is controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. </li>
+  <li>For shapefiles that contain lines, GrADS will draw the line elements using the color, style, and thickness settings that are controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command. </li>
+  <li>For shapefiles that contain polygons, the default behavior of GrADS is draw only the perimeter of each polygon element.The color, style, and thickness of the polygon perimeters are controlled by the <code><a href="gradcomdsetline.html">set line</a></code> command.  Use  the <code><a href="gradcomdsetshpopts.html">set shpopts</a></code> command to draw filled polygons and set the fill color. </li>
+</ul>
+<p>The <code><a href="gradcomddrawshp.html">draw shp</a></code> command draws all the shapes in the shapefile by default, but it is possible to specify a single shape or a range of shapes to draw. Using these extra arguments to the  <code><a href="gradcomddrawshp.html">draw shp</a></code> command, you can control the line and color characteristics of individual shapes. The <code><a href="gradcomdqshpopts.html">q shpopts</a></code> command lists the current settings for drawing shapefiles. </p>
+<p><a name="query" id="query"></a><em><strong>Querying Shapefiles</strong></em><br />
+The GrADS shapefile interface also allows the user to discover the contents of a shapefile. The  <code><a href="gradcomdqshp.html">q shp</a></code> command returns information about the shapes in the file (number of vertices and lon/lat bounds), and the  <code><a href="gradcomdqdbf.html">q dbf</a></code> command returns all the attribute information for each shape in the file. </p>
+<p>The first line of the <code><a href="gradcomdqshp.html">q shp</a></code> output contains the shapefile type, the number of shapes in the file, and the X and Y bounds of actual extent of the shapes in the file. Subsequent lines list information about each shape element in the file: the identification number, the shape type, the number of parts, the number of vertices, and the bounds of the shape in the X, Y, Z, and M (measure) dimesions. The  GrADS interface ignores the Z or M values o [...]
+<p>The first line of the <code><a href="gradcomdqdbf.html">q dbf</a></code> output contains a comma-delimited list of the names of all the attributes for each record in the database. Subsequent lines contain the comma-delimited list of all the attribute values for each record. </p>
+<p>Please refer to the reference pages for <code><a href="gradcomdqshp.html">q shp</a></code> and <code><a href="gradcomdqdbf.html">q dbf</a></code> for additional information and examples of the output. </p>
+<p><em><strong><a name="envv" id="writing2"></a>Relevant Environment Variables</strong></em><br />
+When drawing and  querying shapefiles, if you put the  set of component files  (*.shp, *.shx, *.dbf) in the GrADS data directory (specified by the environment variable <a href="gradcomdgrads.html#env"><code>GADDIR</code></a>), then it is not necessary to include the full path when referring to the shapefile. Starting with <span class="style1">GrADS version 2.0.0</span>, a new  environment variable was introduced, <a href="gradcomdgrads.html#env"><code>GASHP</code></a>, for specifiying a  [...]
+<p><em><strong><a name="writing" id="writing"></a>Writing Shapefiles</strong></em><br /> 
+GrADS version 2.0.a9 adds the capability of writing out shapefiles based on gridded or station data sets. The shape types currently supported are points and lines. Point shapes may be created from  station data or from individual grid point values. The GrADS station data format is a natural fit for point shapefiles, but grid point values are also useful in the shapefile format -- they can be used to create a stippled overlay on top of shaded contour plot (see <a href="#examples">Examples [...]
+<p>To write out a shapefile, there is a new graphics output option, <code><a href="gradcomdsetgxout.html">set gxout shp</a></code>. This graphics  option is used in conjunction with   the <code><a href="gradcomdsetshp.html">set shp</a></code> command which allows the user to set  the filename root  for shapefile output, control the type of shapefile to be created, and set formatting options for numeric values. The <code><a href="gradcomddisplay.html">display</a></code> command  will then [...]
+<p>The dBase file created with the shapefile contains metadata fields or attributes for each shape. There are three data types for attributes: string, integer, or double. Attributes may be static (the attribute value is the same for each shape) or dynamic (the attribute value varies with shape). A set of attributes (both static and dynamic)  are automatically generated by GrADS for all shapes. Attributes for point shapes from station data are: GrADS version, longitude, latitude, station  [...]
+<p>The <code><a href="gradcomdqshpopts.html">q shpopts</a></code> command lists the current settings for shapefile output, including the output file name root, the type of shapefile to be created, the formatting of any numeric output, and any user-provided attributes.</p>
+<p> The <code><a href="gradcomdclear.html">clear shp</a></code> command releases all user-defined shapefile attributes from memory, and resets the  output filename root and shapefile type to their default values. The <code><a href="gradcomdreset.html">reset</a></code> and <code><a href="gradcomdreinit.html">reinit</a></code> commands will do the same thing -- use  <code><a href="gradcomdclear.html">clear shp</a></code> if you do not want to reset all the other user settings. </p>
+<p><a name="examples" id="examples"></a><em><strong>Examples </strong></em><br />
+  <em><strong><br />
+  </strong></em>Here are two examples showing a series of commands to create  shapefiles: </p>
+<pre>set gxout shp
+set shp -pt -fmt 8 4 gridptm
+set shpattr AUTHOR string JMA
+set shpattr TYPE string grid points
+set shpattr DESC string land surface temperature
+d maskout(tsfc,landmask-1)
+  
+set gxout shp
+clear shp
+set shp -ln -fmt 8 4 linem
+set shpattr AUTHOR string JMA
+set shpattr TYPE string grid contours
+set shpattr DESC string surface temperature
+d tsfc
+</pre>
+<p>Here is a slightly more complicated <a href="ftp://cola.gmu.edu/grads/scripts/shp_demo2.gs">example script</a> that shows how to create a shapefile from a GrADS gridded data set (a GFS precipitation forecast), and then draws the contents of that shapefile as a stippled overlay (with three gray shades) on top of a contour plot of another variable, sea level pressure. The script generates a plot that looks like this:</p>
+<p><img src="shp_demo2.png" alt="shp demo 2" /></p>
+<p>Here is  another <a href="ftp://cola.gmu.edu/grads/scripts/shp_demo1.gs">example script</a> that shows how to use the shapefile interface to draw U.S. climate divisions colorized according to the values of the Palmer Drought Severity Index (PDSI), and then overlays the 500mb height anomaly (from a GDS data set) for that same month and year. The script generates a plot that looks like this: </p>
+<p><img src="shp_demo1.png" alt="pdsi" /></p>
+<p>The final <a href="ftp://cola.gmu.edu/grads/scripts/shp_demo3.gs">example script</a> uses shapefiles to draw state and county boundaries as well as roads on a radar image instead of drawing the GrADS map. Here is the result:</p>
+<p><img src="shp_demo3.png" alt="shp demo 3" width="887" height="604" /></p>
+<p> </p>
+<p><em><strong><a name="caveat" id="caveat"></a>Caveat</strong><br />
+</em>The <a href="http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf">ESRI Shapefile Techncial Description</a> states that <em>"A polygon consists of one or more rings. A ring is a connected sequence of four or more points that form a closed, non-self-intersecting loop."</em>  A polygon with two rings would look something like a flat donut -- the area between the two rings forms the interior of the polygon, and the area enclosed by the inner ring is actually  in the ext [...]
+<p>The rings of a polygon are referred to as its parts, and the number of parts in each polygon is included in the ouput of the <code><a href="gradcomdqshp.html">q shp</a></code> command. So it is possible to discover whether this limitation is affecting your plot. </p>
diff --git a/doc/shp_demo1.png b/doc/shp_demo1.png
new file mode 100644
index 0000000..c2ce2e3
Binary files /dev/null and b/doc/shp_demo1.png differ
diff --git a/doc/shp_demo2.png b/doc/shp_demo2.png
new file mode 100644
index 0000000..18658e5
Binary files /dev/null and b/doc/shp_demo2.png differ
diff --git a/doc/shp_demo3.png b/doc/shp_demo3.png
new file mode 100644
index 0000000..51e4810
Binary files /dev/null and b/doc/shp_demo3.png differ
diff --git a/doc/start.html b/doc/start.html
new file mode 100644
index 0000000..4f44b7b
--- /dev/null
+++ b/doc/start.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
-->
</style><title>Starting and Quitting GrADS</title>

<table width="700" border="0">
  <tr>
    <td><h1>Starting and Quitting GrADS</h1>
      <p>GrADS is started by entering the name of one of the <a href="gradcomdgrads.html">GrADS executables</a> at the command line prompt. For example:</p>
      <p><code> # <a href="gradcomdgrads.html">grads</a></code> </p>
      <p> Before initialising the graphics output environment, GrADS will
        prompt for landscape or portrait mode.  Landscape is 11 x 8.5
        inches, portrait is 8.5 x 11 inches. 
        The actual size of the window will not, of course,  be 11 x 8.5
        inches (or 8.5 x 11 inches), but instead will be scaled to fit comfortably withing your workstation's display size.  </p>
      <h2><u>Startup options</u></h2>
      <p>You may specify the following options as arguments to the <a href="gradcomdgrads.html"><code>grads</code></a> command when GrADS is started:</p>
      <p> 
 <code>-help</code>    Prints out a list of all command line options. <br />
 <code>-l</code>    Run grads in landscape mode. The Portrait vs. Landscape question is not asked. <br />
 <code>-p</code>    Run grads in portrait mode. The Portrait vs. Landscape question is not asked. <br />
 <code>-b</code>    Run grads in batch mode.  No graphics output window is opened. <br />
 <code>-g <i>geom</i></code>    Explicitly set the dimensions of the display window at startup. <br>
 <code>-c <i>cmd</i></code>    Execute the supplied <code><i>cmd</i></code> as the first  GrADS
        command to execute after GrADS is started. <br>
      
      <p>Additional command line options are documented <a href="gradcomdgrads.html">here</a>. GrADS
        will always treat the display window as if it were  11 x 8.5
        or 8.5 x 11 so if you use the -g option at startup, it is best to size the window with  the proper aspect
        ratio.  Once GrADS is started up, you can resize the window at any time using the command:</p>
      <code>ga-> set xsize x y</code>
            <p> which resizes the window to <code>x,y</code> pixels.</p>
          <p>You will enter GrADS commands in the text window from where you
            started GrADS.  Graphics output will appear in the graphics
            display window in response to the commands you enter.  You will thus need
            to make the text window the "active" window; the window that
          receives keyboard input.<br />
      </p>
          <h2><u>Help</u></h2>
          <p>Typing <code>help</code> at the GrADS command prompt gives a summary list of
          operations essential to do anything in GrADS.</p>
         <p> <code>ga-> help</code></p>
          <p> This is intended
            to jog memory rather than provide an exhaustive help facility. If
            the GrADS manual is not available, you can obtain info on most
            command parameters by typing the command on its own. 
            Alternatively, we are setting up comprehensive documentation
            intended to be used as a local Web facility. </p>
          <h2><u>Diagnostics at startup</u></h2>
          When you start GrADS you get some information about the version and configured options, then you get the GrADS prompt to begin working with data. For
          example:
          <code>
          <p> # grads -l</p>
          <p>Grid Analysis and Display System (GrADS) Version 2.0.a3<br />
            Copyright (c) 1988-2008 by Brian Doty and the <br />
            Institute for Global Environment and Society (IGES)<br />
            GrADS comes with ABSOLUTELY NO WARRANTY<br />
            See file COPYRIGHT for more information</p>
          <p>Config: v2.0.a3 little-endian readline printim grib2 netcdf hdf4-sds<br />
            Issue 'q config' command for more information.<br />
            GX Package Initialization: Size = 11 8.5 <br />
            ga-></p>
          </code>
                    <p>
          </p>

          
            <h2><u>Quitting GrADS</u></h2>
            <p>To leave GrADS, enter the command:
      <p><code>ga-> quit</code> 
              
            </td>
  </tr>
</table>
<h1> </h1>

\ No newline at end of file
diff --git a/doc/stnmap.html b/doc/stnmap.html
new file mode 100644
index 0000000..fb2e781
--- /dev/null
+++ b/doc/stnmap.html
@@ -0,0 +1,72 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<h2>stnmap</h2>
+<code>stnmap [ -<i>i fname</i> ]</code><p>
+<h3>Usage Notes</h3>
+<code>stnmap</code> is a GrADS utility  that  writes  out  a  hash
+table
+     and/or  link  list  information for station data that allows
+     GrADS to access the report data more efficiently.
+     <p>
+If you change the data file - perhaps by  appending  another
+     time  group  -  you  will also have to change the descriptor
+     file to reflect the changes - the new number  of  times  for
+     example - and then rerun the <code>stnmap</code> utility.
+     <p>
+Note the difference between station descriptor  file  and  a
+     grid descriptor file:<p>
+<ul>
+
+<code>DTYPE</code>                   specify a data
+type of: station<p>
+<code>STNMAP</code>                  gives the file
+name of the station mapping file.     <p>
+<code>XDEF, YDEF, ZDEF</code>        not
+specified.<p>
+<code>TDEF</code>                    describes the
+time grouping interval and
+                         the  number  of  the  time groups in the
+                         file.<p>
+
+<code>VAR</code>                     surface
+variables must come first, and
+                         are     given    a    zero    for    the
+                         number-of-levels field. Level  dependent
+                         variables  are  listed after the surface
+                         variables,  and are given a one  in  the
+                         number-of-levels field.</ul><p>
+<h3>Examples</h3>
+When a data set, for example <code>ua.reps</code>  is  written,  and
+the
+     descriptor  file <code>stat.ctl</code>, including the information
+records
+     for the station data file <code>ua.reps</code>  is  created,  you
+should
+     then create the station map file <code>ua.map</code> (named in the
+<code>STNMAP</code>
+     record of the descriptor file; see  below)  by  running  the
+     <code>stnmap</code> utility.<p>
+Example descriptor file: <code>stat.ctl</code>
+<ul>
+<code>
+ DSET   ^ua.reps<br>
+                    DTYPE   station<br>
+                    STNMAP ^ua.map<br>
+                    UNDEF   -999.0<br>
+                    TITLE   Real Time Upper air obs<br>
+                    TDEF    10 linear 12z18jan1992 12hr<br>
+                    VARS    12<br>
+                        slp   0  99  SLP<br>
+                        ts    0  99 Temps<br>
+                        us    0  99  U Winds<br>
+                        vs    0  99  V Winds<br>
+                        z     1  99  Heightsa<br>
+                        t     1  99  Temps<br>
+                        u     1  99  U Winds<br>
+                        v     1  99  V WInds<br>
+                    ENDVARS</code></ul><p>
+Running the <code>stnmap</code> utility:<p>
+<dd>                    <code>stnmap -i stat.ctl</code><p>
+     The station map file <code>ua.map</code> is a binary file, which
+includes
+     the hash table and/or link list information.
diff --git a/doc/supplibs.html b/doc/supplibs.html
new file mode 100644
index 0000000..11c75f3
--- /dev/null
+++ b/doc/supplibs.html
@@ -0,0 +1,628 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Supplibs</title>
+<link href="GrADS.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+body {
+	background-color: #e0f0ff;
+}
+-->
+</style>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body text="#000000">
+
+<center>
+  <h3>Supplemental Libraries for GrADS version 2</h3>
+</center>
+<p>There are many supplemental libraries that are required to enable various features in the GrADS executable. Building all these libraries from source is not necessarily easy; this page provides some guidance and suggestions that have led to success on COLA's unix systems (64-bit linux running CentOS, and Mac OSX). COLA's objective in building GrADS is to make  our binary releases portable, so we strive to build all the libraries from scratch, disabling features GrADS doesn't need, and  [...]
+<p>To begin, make a directory top level directory for the supplibs under your $HOME:<br>
+  <span class="code">mkdir $HOME/supplibs</span></p>
+<p>Make a subdirectory where you will store the tar files containing the library source code:<br>
+  <span class="code">mkdir -p $HOME/supplibs/src/tarfiles</span></p>
+<p>Get the src from COLA's FTP server: <br>
+  <span class="code">cd $HOME/supplibs/src/tarfiles<br>
+  ftp iges.org<br>
+<login as anonymous><br>
+  cd grads/Supplibs/2.1/src<br>
+  mget *<br> 
+quit </span></p>
+<p>These are the directories where you will install the compiled libaries, pkgconfig files, the necessary include files, and any executable utilities from the libraries that GrADS will need:<br>
+  <span class="code">mkdir $HOME/supplibs/lib<br>
+  mkdir $HOME/supplibs/lib/pkgconfig</span><br>
+<span class="code">mkdir $HOME/supplibs/include<br>
+mkdir $HOME/supplibs/bin</span></p>
+<p>Move through the list of libraries in the table below, building them in order listed. Instructions for configuring and installing in the <span class="code">$HOME/supplibs</span> directory are given for each library. <span class="style1">If you are building on Mac OSX 10.6, set the environment variable CFLAGS to "-arch i386".</span> </p>
+<p>When you are done, unpack the GrADS source code tarball under $HOME. Change into the new GrADS directory you just created, and type<span class="code"> ./configure. </span>When the configuration is done, it will show a summary of which features have been enabled. Then type '<span class="code">make install</span>' and look for your executables in the ./bin directory. </p>
+<p>Good Luck!! </p>
+<table width="100%" border="0" cellpadding="4" cellspacing="4" class="plaintext">
+  <tr>
+    <td valign="top" bgcolor="#CCCCCC">Library</td>
+    <td valign="top" bgcolor="#CCCCCC">Version</td>
+    <td valign="top" bgcolor="#CCCCCC" class="plaintext">Why GrADS needs it </td>
+    <td bgcolor="#CCCCCC" class="plaintext">How to configure and install it for GrADS</td>
+  </tr>
+  <tr>
+    <td width="7%" valign="top" bgcolor="ccdceb">readline</td>
+    <td width="5%" valign="top" bgcolor="ccdceb">5.0</td>
+    <td width="19%" valign="top" bgcolor="ccdceb" class="plaintext"><p>Enables command line editing.<br>
+        Links: <a href="http://tiswww.case.edu/php/chet/readline/rltop.html" target="_parent"><br>
+        home page</a><br> 
+        <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/readline-5.0.tar.gz">local copy of source code</a></p>    </td>
+    <td width="69%" bgcolor="ccdceb" class="plaintext"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz ./tarfiles/readline-5.0.tar.gz <br>
+      mkdir readline<br>
+      cd readline-5.0<br>
+      ./configure --disable-shared 
+      --prefix=$HOME/supplibs/src/readline<br>
+      make ; 
+      make install<br>
+      cp $HOME/supplibs/src/readline/lib/libreadline.a $HOME/supplibs/lib<br>
+      mkdir -p $HOME/supplibs/include/readline<br>
+    cp $HOME/supplibs/src/readline/include/readline/*.h $HOME/supplibs/include/readline</p></td>
+  </tr>
+  <tr>
+    <td valign="top" bgcolor="b8c8d7">ncurses</td>
+    <td valign="top" bgcolor="b8c8d7">5.7</td>
+    <td valign="top" bgcolor="b8c8d7" class="plaintext"><p>Required by readline.<br>
+      Links:<br>
+      <a href="http://www.gnu.org/software/ncurses/">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/ncurses-5.7.tar.gz">local copy of source code</a></p></td>
+    <td bgcolor="b8c8d7" class="plaintext"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz ./tarfiles/ncurses-5.7.tar.gz<br>
+      mkdir ncurses<br>
+      cd ncurses-5.7<br>
+      ./configure --disable-shared 
+      --prefix=$HOME/supplibs/src/ncurses<br>
+      make ;
+      make install<br>
+      cp $HOME/supplibs/src/ncurses/lib/libncurses.a $HOME/supplibs/lib</p></td>
+  </tr>
+  <tr>
+    <td valign="top" bgcolor="ccdceb">zlib</td>
+    <td valign="top" bgcolor="ccdceb">1.2.5</td>
+    <td valign="top" bgcolor="ccdceb" class="plaintext"><p>General compression library.<br>
+      Required by NetCDF et al.<br>
+        Links:<br>    
+        <a href="http://www.zlib.net/" target="_parent">home page</a><br>    
+        <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/zlib-1.2.5.tar.gz">local copy of source code</a><br>
+      </p>
+    </td>
+    <td bgcolor="ccdceb" class="code"><p>cd $HOME/supplibs/src/<br>
+      tar xvfz ./tarfiles/zlib-1.2.5.tar.gz<br>
+      mkdir zlib<br>
+      cd zlib-1.2.5<br>
+      ./configure --prefix=$HOME/supplibs/src/zlib<br>
+      make ;
+      make install<br>
+      cp $HOME/supplibs/src/zlib/lib/libz.a $HOME/supplibs/lib<br>
+      mkdir $HOME/supplibs/include/zlib<br>
+    cp $HOME/supplibs/src/zlib/include/zlib.h $HOME/supplibs/include/zlib</p>
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" bgcolor="b8c8d7">libpng</td>
+    <td valign="top" bgcolor="b8c8d7">1.2.18</td>
+    <td valign="top" bgcolor="b8c8d7">PNG reference library. <br>
+      Links:<br>      
+      <a href="http://www.libpng.org/pub/png/libpng.html" target="_parent">home page</a><br>      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/libpng-1.2.18.tar.gz">local copy of source code</a><br></td>
+    <td bgcolor="b8c8d7" class="code"><p>cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/libpng-1.2.18.tar.gz<br>
+      mkdir libpng<br>
+      cd libpng-1.2.18<br>
+      ./configure --disable-shared 
+      --prefix=$HOME/supplibs/src/libpng<br>
+      make ; 
+      make install<br>
+      cp $HOME/supplibs/src/libpng/lib/libpng12.a $HOME/supplibs/lib<br>
+      mkdir $HOME/supplibs/include/libpng12<br>
+    cp $HOME/supplibs/src/libpng/include/libpng12/*.h $HOME/supplibs/include/libpng12<br>
+    cp $HOME/supplibs/src/libpng/lib/pkgconfig/libpng12.pc $HOME/supplibs/lib/pkgconfig</p>
+    <p><span class="style1">Note: The pkgconfig file is required for building cairo</span></p></td>
+  </tr>
+  <tr bgcolor="ccdceb">
+    <td valign="top" bgcolor="ccdceb">jpeg</td>
+    <td valign="top" bgcolor="ccdceb">6b</td>
+    <td valign="top" class="plaintext">Image compression library. <br>
+      Links:<br>      
+      <a href="http://www.ijg.org/" target="_parent">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/jpegsrc.v6b.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb" class="plaintext"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/jpegsrc.v6b.tar.gz <br>
+      mkdir -p jpeg/bin/cjpeg<br>
+      mkdir -p jpeg/man/man1<br>
+      mkdir jpeg/include<br>
+      mkdir jpeg/lib<br>
+      cd jpeg-6b<br>
+        ./configure  
+        --prefix=$HOME/supplibs/src/jpeg<br>
+        make ;       make install<br>
+        cp *.h $HOME/supplibs/src/jpeg/include/<br>
+        cp libjpeg.a $HOME/supplibs/src/jpeg/lib<br>
+    cp libjpeg.a $HOME/supplibs/lib</p>
+    </td>
+  </tr>
+  <tr>
+    <td valign="top" bgcolor="b8c8d7">gd</td>
+    <td valign="top" bgcolor="b8c8d7">2.0.34</td>
+    <td valign="top" bgcolor="b8c8d7" class="plaintext">GD Graphics Library. <br>
+      Requires: zlib, libpng, jpeg<br>
+      Links: <br>
+      <a href="http://www.libgd.org/Main_Page" target="_parent">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/gd-2.0.34.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7" class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/gd-2.0.34.tar.gz<br>
+      mkdir gd<br>
+      cd gd-2.0.34<br>
+      ./configure --disable-shared \<br>
+      --with-png=$HOME/supplibs/src/libpng \<br>
+      --with-jpeg=$HOME/supplibs/src/jpeg \<br>
+      --prefix=$HOME/supplibs/src/gd<br>
+      make ; 
+      make install<br>
+      cp $HOME/supplibs/src/gd/lib/libgd.a $HOME/supplibs/lib<br>
+      mkdir $HOME/supplibs/include/gd<br>
+    cp $HOME/supplibs/src/gd/include/* $HOME/supplibs/include/gd</td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">jasper</td>
+    <td valign="top" bgcolor="ccdceb">1.900.1</td>
+    <td valign="top" bgcolor="ccdceb">For image coding and manipulation <br>
+    Links:<br>    
+    <a href="http://www.ece.uvic.ca/~mdadams/jasper/" target="_parent">home page</a><br>
+    <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/jasper-1.900.1.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/jasper-1.900.1.tar.gz<br>
+      mkdir jasper<br>
+      cd jasper-1.900.1<br>
+      ./configure --disable-shared 
+      \<br>
+      --prefix=$HOME/supplibs/src/jasper \<br>
+      --with-jpeg=$HOME/supplibs/src/jpeg<br>
+        make ; 
+        make install<br>
+    cp $HOME/supplibs/src/jasper/lib/libjasper.a $HOME/supplibs/lib</p>
+    </td>
+  </tr>
+  <tr bgcolor="ccdceb">
+    <td valign="top" bgcolor="b8c8d7">g2clib</td>
+    <td valign="top" bgcolor="b8c8d7">1.4.0</td>
+    <td valign="top" bgcolor="b8c8d7"><p>Decodes data in GRIB2 format. <br>
+      Requires: zlib, png, jasper<br>
+      Links:<br>    
+    <a href="http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2/" target="_parent">home page</a><br>
+    <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/g2clib-1.4.0.tar.gz">local copy of source code</a></p>    </td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src/<br>
+tar xvfz tarfiles/g2clib-1.4.0.tar.gz<br>
+
+cd g2clib-1.4.0</p>
+      <p class="code style1">Note: There is no configure script in this library, so you must edit the makefile to change two lines identified below (INC, CC). Write out $HOME explicitly in the makefile.<br>
+        INC=-I/usr/include -I$HOME/supplibs/src/jasper/include \<br>
+ -I$HOME/supplibs/src/libpng -I$HOME/supplibs/src/zlib/include<br>
+        CC=gcc</p>
+      <p class="code">make<br>
+        cp libgrib2c.a $HOME/supplibs/lib/<br>
+        mkdir $HOME/supplibs/include/grib2c<br>
+    cp grib2.h $HOME/supplibs/include/grib2c</p></td>
+  </tr>
+  <tr bgcolor="ccdceb">
+    <td valign="top" bgcolor="ccdceb">szip</td>
+    <td valign="top" bgcolor="ccdceb">2.1</td>
+    <td valign="top"><p>General purpose lossless compression library.<br>
+      Required by HDF5<br>
+        Links:<br>      
+        <a href="http://www.compressconsult.com/szip/" target="_parent">home page</a><br>
+        <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/szip-2.1.tar.gz">local copy of source code</a></p>
+      </td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/szip-2.1.tar.gz<br>
+      mkdir szip<br>
+      cd szip-2.1<br>
+      ./configure --disable-shared --prefix=$HOME/supplibs/src/szip<br>
+      make ; 
+      make install<br>
+    cp $HOME/supplibs/src/szip/lib/libsz.a $HOME/supplibs/lib</p></td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">udunits</td>
+    <td valign="top" bgcolor="b8c8d7">1.11.7</td>
+    <td valign="top"><p>Supports units of physical quantities. <br>
+    Links:<br> 
+    <a href="http://www.unidata.ucar.edu/software/udunits/" target="_parent">home page</a><br>
+    <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/udunits-1.11.7.tar.gz">local copy of source code</a></p>    </td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz ./tarfiles/udunits-1.11.7.tar.gz<br>
+      ln -sf udunits-1.11.7 udunits<br>
+      cd udunits/src/<br>
+        ./configure --disable-shared --prefix=$HOME/supplibs/src/udunits<br>
+        make ;
+        make install<br>
+        cd ../<br>
+        cp ./lib/libudunits.a $HOME/supplibs/lib/<br>
+        mkdir $HOME/supplibs/include/udunits<br>
+    cp ./include/udunits.h $HOME/supplibs/include/udunits</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">hdf</td>
+    <td valign="top" bgcolor="ccdceb">4.2r3</td>
+    <td valign="top" bgcolor="ccdceb"> Hierarchical Data Format library, version 4. Requires: zlib, udunits, jpeg, szip<br>
+      Links:<br>      <a href="http://hdfgroup.org/products/hdf4/index.html" target="_parent">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/HDF4.2r3.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb" class="code"><p>cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/HDF4.2r3.tar.gz<br>
+      mkdir hdf<br>
+      cd HDF4.2r3<br>
+        ./configure --disable-netcdf --disable-shared --disable-fortran \<br>
+        --with-zlib=$HOME/supplibs/src/zlib \<br>
+        --with-jpeg=$HOME/supplibs/src/jpeg \<br>
+        --with-szip=$HOME/supplibs/src/szip \<br>
+        --prefix=$HOME/supplibs/src/hdf<br>
+        make ;
+        make install<br>
+        cp $HOME/supplibs/src/hdf/lib/libdf.a $HOME/supplibs/lib<br>
+        cp $HOME/supplibs/src/hdf/lib/libmfhdf.a $HOME/supplibs/lib<br>
+        mkdir $HOME/supplibs/include/hdf<br>
+    cp $HOME/supplibs/src/hdf/include/*.h $HOME/supplibs/include/hdf</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">hdf5</td>
+    <td valign="top" bgcolor="b8c8d7">1.8.7</td>
+    <td valign="top">(<span class="style1">GrADS 2.0.a7+</span>) <br>
+      Hierarchical Data Format library, version 5. Requires: zlib, szip<br>
+Links:<br><a href="http://www.hdfgroup.org/HDF5/" target="_parent">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/hdf5-1.8.7.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/hdf5-1.8.7.tar.gz<br>
+      mkdir hdf5<br>
+      cd hdf5-1.8.7<br>
+      ./configure --disable-shared --disable-fortran \<br>
+      --with-zlib=$HOME/supplibs/src/zlib \<br>
+      --with-szlib=$HOME/supplibs/src/szip \<br>
+      --prefix=$HOME/supplibs/src/hdf5<br>
+        make ;
+        make install<br>
+        cp $HOME/supplibs/src/hdf5/lib/libhdf5.a $HOME/supplibs/lib<br>
+        cp $HOME/supplibs/src/hdf5/lib/libhdf5_hl.a $HOME/supplibs/lib<br>
+        mkdir $HOME/supplibs/include/hdf5<br>
+    cp $HOME/supplibs/src/hdf5/include/*.h $HOME/supplibs/include/hdf5/</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">curl</td>
+    <td valign="top" bgcolor="ccdceb">7.19.6</td>
+    <td valign="top" bgcolor="ccdceb">      For enabling OPeNDAP access. <br>
+      Links:<br>      
+      <a href="http://curl.haxx.se/" target="_parent">home page</a><br>      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/curl-7.19.6.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb" class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/curl-7.19.6.tar.gz<br>
+      mkdir curl<br>
+      cd curl-7.19.6<br>
+      
+      ./configure --without-ssl --without-libidn 
+      --enable-static \<br>
+      --disable-shared --disable-ldap --prefix=$HOME/supplibs/src/curl<br>
+      make ; 
+      make install<br>
+    cp $HOME/supplibs/src/curl/lib/libcurl.a $HOME/supplibs/lib<br>
+cp $HOME/supplibs/src/curl/lib/pkgconfig/libcurl.pc $HOME/supplibs/lib/pkgconfig</td>
+  </tr>
+  <tr bgcolor="ccdceb">
+    <td valign="top" bgcolor="b8c8d7">netcdf</td>
+    <td valign="top" bgcolor="b8c8d7">4.1.3</td>
+    <td valign="top" bgcolor="b8c8d7">(<span class="style1">GrADS 2.0.a8+</span>) <br>
+      Network Common Data Form library. <br>
+      Requires hdf5, zlib, szip, curl. <br>
+      Links:<br>      <a href="http://www.unidata.ucar.edu/software/netcdf/" target="_parent">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/netcdf-4.1.3.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/netcdf-4.1.3.tar.gz<br>
+      mkdir 
+      netcdf<br>
+        cd netcdf-4.1.3</p>
+      <p class="code"><span class="style1">Note: before running configure, set the following environment variables:<br>
+        setenv LIBS "-lsz -lm -lrt -lz"<br>
+      setenv LDFLAGS -L$HOME/supplibs/lib<br>
+      setenv CPPFLAGS -I$HOME/supplibs/include/hdf5</span><br>
+        <br>
+        ./configure --disable-f77 --enable-netcdf-4 --enable-dap --disable-shared \<br>
+        --with-hdf5=$HOME/supplibs/src/hdf5 \<br>
+        --with-zlib=$HOME/supplibs/src/zlib \<br>
+        --with-szlib=$HOME/supplibs/src/szip \<br>
+        --with-curl=$HOME/supplibs/src/curl \<br>
+        --prefix=$HOME/supplibs/src/netcdf <br>
+        make ;
+        make install<br>
+        cp $HOME/supplibs/src/netcdf/lib/libnetcdf.a $HOME/supplibs/lib<br>
+        mkdir $HOME/supplibs/include/netcdf<br>
+        cp $HOME/supplibs/src/netcdf/include/netcdf.h $HOME/supplibs/include/netcdf<br>
+    cp $HOME/supplibs/src/netcdf/bin/nc-config $HOME/supplibs/bin</p>
+      <p class="code"><span class="style1">Note: After the library is built, you can unset the environment variables:<br>
+        unsetenv LIBS <br>
+unsetenv LDFLAGS<br>
+      unsetenv CPPFLAGS</span></p></td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">tiff</td>
+    <td valign="top" bgcolor="ccdceb">3.8.2</td>
+    <td valign="top" bgcolor="ccdceb">(<span class="style1">GrADS 2.0.a5+</span>) <br>
+      Library for storing image data in the Tag Image File Format.<br>
+      Links:<br>
+      <a href="http://www.libtiff.org/">home page</a><br>
+      <a href=
+      "ftp://cola.gmu.edu/grads/Supplibs/2.1/src/tiff-3.8.2.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb" class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/tiff-3.8.2.tar.gz<br>
+      mkdir tiff<br>
+      cd tiff-3.8.2<br>
+      ./configure --disable-shared 
+      --prefix=$HOME/supplibs/src/tiff<br>
+      make ; 
+      make install<br>
+      cp lib/libtiff.a $HOME/supplibs/lib/<br>
+      mkdir $HOME/supplibs/include/tiff<br>
+      cp ./include/*.h $HOME/supplibs/include/tiff</td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">geotiff</td>
+    <td valign="top" bgcolor="b8c8d7">1.2.5</td>
+    <td valign="top" bgcolor="b8c8d7">(<span class="style1">GrADS 2.0.a5+</span>) <br>
+      Library for reading, and writing georeferenced raster imagery. <br>
+      Requires: tiff.<br>
+      Links:<br>
+      <a href="http://geotiff.osgeo.org/">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/libgeotiff-1.2.5.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7" class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/libgeotiff-1.2.5.tar.gz <br>
+      mkdir geotiff<br>
+      cd libgeotiff-1.2.5<br>
+      ./configure --enable-incode-epsg 
+      --enable-static --disable-shared \<br>
+      --with-libtiff=$HOME/supplibs/src/tiff \<br>
+      --prefix=$HOME/supplibs/src/geotiff <br>
+      make ; 
+      make install<br>
+      cp $HOME/supplibs/src/geotiff/lib/libgeotiff.a $HOME/supplibs/lib<br>
+      mkdir $HOME/supplibs/include/geotiff<br>
+      cp $HOME/supplibs/src/geotiff/include/* $HOME/supplibs/include/geotiff</td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">shapelib</td>
+    <td valign="top" bgcolor="ccdceb">1.2.10</td>
+    <td valign="top" bgcolor="ccdceb">(<span class="style1">GrADS 2.0.a8+</span>) <br>
+      Enables handling of shapefiles<br>
+      Links:<br>
+      <a href="http://shapelib.maptools.org/">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/shapelib-1.2.10.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src/<br>
+      tar xvfz tarfiles/shapelib-1.2.10.tar.gz<br>
+      cd shapelib-1.2.10<br>
+      make lib<br>
+      cp ./.libs/libshp.a $HOME/supplibs/lib/<br>
+      mkdir $HOME/supplibs/include/shapelib<br>
+      cp shapefil.h  $HOME/supplibs/include/shapelib</p></td>
+  </tr>
+  
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">pkgconfig</td>
+    <td valign="top" bgcolor="b8c8d7">0.23</td>
+    <td valign="top" bgcolor="b8c8d7" bgcolo ="ccdceb">(<span class="style1">GrADS 2.1.a0+</span>)<br>
+      A helper tool used when compiling applications and libraries. 
+      Required for Cairo.<br>
+      Links:<br>
+      <a href="http://pkg-config.freedesktop.org/wiki/">home page</a><br>
+      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/pkgconfig-0.23.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/pkgconfig-0.23.tar.gz<br>
+      mkdir pkg-config<br>
+      cd pkg-config-0.23<br>
+      ./configure --disable-shared --prefix=$HOME/supplibs/src/pkg-config<br>
+      make  ; 
+      make install<br>
+      cp $HOME/supplibs/src/pkg-config/bin/pkg-config $HOME/supplibs/bin/<br>
+      <br>
+      <span class="style1">N.B. These environment variables are set AFTER pkg-config is built:<br>
+      setenv PKG_CONFIG $HOME/supplibs/bin/pkg-config<br>
+      setenv PKG_CONFIG_PATH $HOME/supplibs/lib/pkgconfig</span></p></td>
+  </tr>
+  <tr bgcolor="ccdceb">
+    <td valign="top" bgcolor="ccdceb">xml2</td>
+    <td valign="top" bgcolor="ccdceb">2.6.16</td>
+    <td valign="top" bgcolor="ccdceb"><p>An XML parser and toolkit. <br>
+      Enables OPeNDAP station data access,
+      also used by Cairo library.<br>
+        Links:<br>    
+        <a href="http://xmlsoft.org/" target="_parent">home page</a><br>
+        <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/libxml2-2.6.16.tar.gz">local copy of source code</a></p>    </td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/libxml2-2.6.16.tar.gz<br>
+      mkdir libxml2<br>
+      cd libxml2-2.6.16<br>
+      ./configure --disable-shared  --prefix=$HOME/supplibs/src/libxml2 \<br>
+      --with-zlib=$HOME/supplibs/src/zlib \<br>
+      --without-threads --without-iconv --without-iso8859x <br>
+      make ; 
+      make install<br>
+    cp $HOME/supplibs/src/libxml2/lib/libxml2.a $HOME/supplibs/lib <br>
+    cp $HOME/supplibs/src/libxml2/lib/pkgconfig/libxml-2.0.pc $HOME/supplibs/lib/pkgconfig</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">dap</td>
+    <td valign="top" bgcolor="b8c8d7">3.7.8</td>
+    <td valign="top" bgcolor="b8c8d7">Open-source Project for a Network Data Access Protocol (OPeNDAP). <br>
+      Requires: xml2, curl.<br>
+Links:<br>
+<a href="http://opendap.org/index.html" target="_parent">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/libdap-3.7.8.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/libdap-3.7.8.tar.gz<br>
+      mkdir libdap<br>
+    cd libdap-3.7.8</p>
+      <p class="code style1">N.B. You may need edit configure.ac so it won't use pkg-config to find curl or xml2 (libdap_pkgconfig_libcurl=no and libdap_pkgconfig_libxml2=no) then run 
+      autoreconf. This is only necessary if curl is installed someplace else on your system without the special configure options outlined above for building curl. Alternatively, you can set the following environment vars:<br>
+      setenv PKG_CONFIG $HOME/supplibs/bin/pkg-config<br>
+setenv PKG_CONFIG_PATH $HOME/supplibs/lib/pkgconfig</p>
+      <p class="code">./configure --disable-shared \<br>
+        --with-xml2=$HOME/supplibs/src/libxml2 \<br>
+        --with-zlib=$HOME/supplibs/src/zlib \<br>
+        --with-curl=$HOME/supplibs/src/curl \<br>
+        --prefix=$HOME/supplibs/src/libdap<br>
+        make ; 
+        make install<br>
+        cp $HOME/supplibs/src/libdap/lib/libdap.a $HOME/supplibs/lib<br>
+    cp $HOME/supplibs/src/libdap/lib/libdapclient.a $HOME/supplibs/lib</p></td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">gadap</td>
+    <td valign="top" bgcolor="ccdceb">2.0</td>
+    <td valign="top" bgcolor="ccdceb">Enables OPeNDAP access of <br>
+      in situ data. <br>
+      Requires dap, curl, and xml2. <br>
+      Links:<br>      <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/gadap-2.0.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/gadap-2.0.tar.gz<br>
+      mkdir gadap<br>
+      cd gadap-2.0<br>
+      setenv PATH {$PATH}:{$HOME}/supplibs/src/libdap/bin<br>
+      ./configure --prefix=$HOME/supplibs/src/gadap<br>
+      make ; 
+      make install<br>
+      cp $HOME/supplibs/src/gadap/lib/libgadap.a $HOME/supplibs/lib/<br>
+      mkdir $HOME/supplibs/include/gadap<br>
+    cp $HOME/supplibs/src/gadap/include/*.h $HOME/supplibs/include/gadap</p></td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">Xrender</td>
+    <td valign="top" bgcolor="b8c8d7">0.9.6</td>
+    <td valign="top" bgcolor="b8c8d7" bgcolo ="ccdceb">(<span class="style1">GrADS 2.1.a0+</span>)<br>
+A helper tool used when compiling applications and libraries. 
+Required for Cairo.<br>
+Links:<br>
+<a href="http://cgit.freedesktop.org/xorg/lib/libXrender/">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/libXrender-0.9.6.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/libXrender-0.9.6.tar.gz <br>
+      mkdir libXrender<br>
+      cd libXrender-0.9.6</p>
+      <p class="code style1">N.B. It may be necessary to unset the environment vars PGK_CONFIG and PKG_CONFIG_PATH before configuring libXrender. If so, be sure to reset them before continuing to build the remainder of the libraries.</p>
+      <p class="code">./configure --disable-shared --prefix=$HOME/supplibs/src/libXrender<br>
+        make ;
+        make install<br>
+        cp $HOME/supplibs/src/libXrender/lib/libXrender.a $HOME/supplibs/lib<br>
+    cp $HOME/supplibs/src/libXrender/lib/pkgconfig/xrender.pc $HOME/supplibs/lib/pkgconfig</p></td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">pixman</td>
+    <td valign="top" bgcolor="ccdceb">0.21.2</td>
+    <td valign="top" bgcolor="ccdceb"><p>(<span class="style1">GrADS 2.1.a0+</span>)<br>
+    A pixel manipulation library for <br>
+    X and Cairo.<br>
+    Links:<br>
+    <a href="http://cgit.freedesktop.org/pixman/">home page</a><br>
+    <a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/pixman-0.21.2.tar.gz">local copy of source code</a></p>    </td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/pixman-0.21.2.tar.gz <br>
+      mkdir pixman<br>
+      cd pixman-0.21.2<br>
+      ./configure --disable-shared --prefix=$HOME/supplibs/src/pixman<br> 
+      make ; 
+        make install<br>
+        cp $HOME/supplibs/src/pixman/lib/libpixman-1.a $HOME/supplibs/lib<br>
+    cp $HOME/supplibs/src/pixman/lib/pkgconfig/pixman-1.pc $HOME/supplibs/lib/pkgconfig</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">freetype</td>
+    <td valign="top" bgcolor="b8c8d7">2.4.4</td>
+    <td valign="top" bgcolor="b8c8d7">(<span class="style1">GrADS 2.1.a0+</span>)<br>
+A software font engine.
+Required by Cairo. <br>
+Links:<br>
+<a href="http://www.freetype.org/">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/freetype-2.4.4.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/freetype-2.4.3.tar.gz<br>
+      mkdir freetype<br>
+      cd freetype-2.4.3<br>
+        ./configure 
+        --disable-shared 
+        \<br>
+        --without-fsspec 
+        --without-fsref 
+        --without-ats \<br>
+        --without-quickdraw-toolbox 
+        --without-quickdraw-carbon \<br>
+        --with-zlib=$HOME/supplibs/src/zlib \<br>
+        --prefix=$HOME/supplibs/src/freetype<br>
+        make ; 
+        make install<br>
+        cp $HOME/supplibs/src/freetype/lib/libfreetype.a $HOME/supplibs/lib<br>
+    cp $HOME/supplibs/src/freetype/lib/pkgconfig/freetype2.pc $HOME/supplibs/lib/pkgconfig</p>    </td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="ccdceb">fontconfig</td>
+    <td valign="top" bgcolor="ccdceb">2.8.0</td>
+    <td valign="top" bgcolor="ccdceb">(<span class="style1">GrADS 2.1.a0+</span>)<br>
+      A library for configuring and customizing font access. 
+Required by Cairo. <br>
+Links:<br>
+<a href="http://www.freedesktop.org/wiki/Software/fontconfig">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/fontconfig-2.8.0.tar.gz">local copy of source code</a></td>
+    <td bgcolor="ccdceb"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvfz tarfiles/fontconfig-2.8.0.tar.gz<br>
+      mkdir fontconfig<br>
+      cd fontconfig-2.8.0<br>
+      ./configure --disable-shared --enable-libxml2 \<br>
+      --prefix=$HOME/supplibs/src/fontconfig \<br>
+    --with-freetype-config=$HOME/supplibs/src/freetype/bin/freetype-config \<br>
+    --with-add-fonts=/Library/Fonts,/System/Library/Fonts <span class="style1">(for mac)</span>   
+      <br>
+    --with-add-fonts=/usr/share/X11/fonts,/usr/share/fonts <span class="style1">(for unix)
+    </span>
+    <p class="code style1">N.B. After configuration,  edit config.h to set USE_ICONV = 0<br>
+      I don't know of another way to tell it not to use libiconv.       
+      <p class="code">make ; make install<br> 
+        cp $HOME/supplibs/src/fontconfig/lib/libfontconfig.a $HOME/supplibs/lib/<br>
+    cp $HOME/supplibs/src/fontconfig/lib/pkgconfig/fontconfig.pc $HOME/supplibs/lib/pkgconfig</td>
+  </tr>
+  <tr bgcolor="b8c8d7">
+    <td valign="top" bgcolor="b8c8d7">cairo</td>
+    <td valign="top" bgcolor="b8c8d7">1.10.2</td>
+    <td valign="top" bgcolor="b8c8d7">(<span class="style1">GrADS 2.1.a0+</span>)<br>
+A 2D graphics library with support for multiple output devices. Requires pkgconfig, zlib, xml2, libpng, pixman, fontconfig, freetype, and Xrender.<br>
+Links:<br>
+<a href="http://www.cairographics.org/">home page</a><br>
+<a href="ftp://cola.gmu.edu/grads/Supplibs/2.1/src/cairo-1.10.2.tar.gz">local copy of source code</a></td>
+    <td bgcolor="b8c8d7"><p class="code">cd $HOME/supplibs/src<br>
+      tar xvf tarfiles/cairo-1.10.2.tar.gz<br>
+      mkdir cairo<br>
+      cd cairo-1.10.2<br>
+      ./configure --prefix=$HOME/supplibs/src/cairo \<br>
+      --enable-xlib=yes \<br>
+      --enable-xml=yes \<br>
+      --enable-fc=yes \<br>
+      --enable-ft=yes \<br>
+      --enable-xlib-xrender=yes \<br>
+      --enable-pthread=yes \<br>
+      --enable-xcb=no \<br>
+      --enable-qt=no \<br>
+      --enable-quartz=no \<br>
+      --enable-win32=no \<br>
+      --enable-skia=no \<br>
+      --enable-os2=no \<br>
+      --enable-beos=no \<br>
+      --enable-drm=no \<br>
+    --enable-gl=no<br>
+    make ; 
+      make install<br>
+      cp $HOME/supplibs/src/cairo/lib/libcairo.a $HOME/supplibs/lib/<br>
+      cp $HOME/supplibs/src/cairo/lib/pkgconfig/* $HOME/supplibs/lib/pkgconfig/<br>
+      mkdir $HOME/supplibs/include/cairo/<br>
+    cp $HOME/supplibs/src/cairo/include/* $HOME/supplibs/include/cairo/</p>    </td>
+  </tr>
+</table>
+<p class="plaintext"><br>
+</p>
+</body>
+</html>
diff --git a/doc/templates.html b/doc/templates.html
new file mode 100644
index 0000000..33bdbaa
--- /dev/null
+++ b/doc/templates.html
@@ -0,0 +1,187 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Templates</title>
+<style type="text/css">
+<!--
+.style1 {color: #990000}
+-->
+</style>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2>Using Templates</h2>
+<p> GrADS allows you use a single data descriptor file to aggregate multiple data 
+  files and handle them as if they were one individual file. The individual data 
+  files must be identical in the X, Y, and Z dimensions and have the same list of variables. The time range of each individual file must be indicated it its filename. 
+Beginning with version 2.0, data files may also be aggregated in the ensemble dimension. 
+<p> First, the DSET entry has a substitution template instead of 
+  a filename. See below for a description of all the possible components of the 
+  template. Second, the OPTIONS entry contains the <code>template</code> 
+  keyword. Third, the TDEF entry describes the time range for the 
+  entire set of data files. 
+<p> Templating works on any GrADS data type for which you can write a descriptor 
+  file. If you specify any additional OPTIONS keywords in the data 
+  descriptor file, make sure the options apply equally to each file included in 
+  the template. 
+<h3>Templating over TIME</h3>
+<p>
+Valid components of the substitution template for the TIME axis are as follows:
+
+
+<ul>
+  <p><code>%x1   </code>1 digit decade <br>
+    <code>%x3   </code>3 digit decade <br>
+    <code>%y2   </code>2 digit year <br>
+    <code>%y4   </code>4 digit year <br>
+    <code>%m1   </code>1 or 2 digit month <br>
+    <code>%m2   </code>2 digit month (leading zero if needed) <br>
+    <code>%mc   </code>3 character month abbreviation <br>
+    <code>%d1   </code>1 or 2 digit day <br>
+    <code>%d2   </code>2 digit day (leading zero if needed) <br>
+    <code>%h1   </code>1 or 2 digit hour <br>
+    <code>%h2   </code>2 digit hour <br>
+    <code>%h3   </code>3 digit hour (e.g., 120 or 012) <br>
+    <code>%n2   </code>2 digit minute; leading zero if needed<br>
+    <code>%f2   </code>2 digit forecast hour;  leading zero if needed; more digits added for hours >99; hour values increase indefinitely<br>
+  <code>%f3   </code>3 digit forecast hour; leading zeros if needed; more digits added for hours >999; hour values increase indefinitely<br>
+    <code>%fn2  </code>2 digit forecast minute; leading zero if needed; more digits added for minutes > 99; minute values increase indefinitely  <span class="style1">(2.0.a9+)</span><br>
+    <code>%fhn  </code>forecast time expressed in  hours and minutes (<code>hhnn</code>) where minute value (<code>nn)</code> is always <=59<br>
+    <code>      </code>and hour value (<code>hh</code>) increases indefinitely. If<code> hh</code> or <code>nn</code> are <=9, they are padded with a 0 <br>
+    <code>      </code>so they are always at least 2 digits; more digits added for hours >99. <span class="style1">(2.0.a9+)<br>
+    </span><code>%fdhn </code>forecast time expressed in days, hours, and minutes (<code>ddhhnn</code>) where minute value (<code>nn)</code> is always <=59, <br>
+    <code>      </code>hour value (<code>hh</code>) is always <=23 and day value (<code>dd</code>) increases indefinitely. If <code>dd</code>, <code>hh,</code> or <code>nn</code> are <=9, <br>
+    <code>      </code>they are padded with a 0 so they are always at least 2 digits; more digits added for days >99.  <span class="style1">(2.0.a9+)</span><br>
+    <code>%j3   </code>3 digit julian day (day of year) <span class="style1">(2.0.a7+)</span><br>
+    <code>%t1   </code>1 or 2 digit time index (file names contain number sequences that begin with 1 or 01) <span class="style1">(2.0.a7+)</span><br>
+    <code>%t2   </code>2 digit time index (file names contain number sequences that  begin with 01)  <span class="style1">(2.0.a7+)</span><br>
+    <code>%t3   </code>3 digit time index  (file names contain number sequences that  begin with 001) <span class="style1">(2.0.a7+)</span><br>
+    <code>%t4   </code>4 digit time index  (file names contain number sequences that  begin with 0001)  <span class="style1">(2.0.a8+)</span><br>
+    <code>%t5   </code>5 digit time index  (file names contain number sequences that  begin with 00001)  <span class="style1">(2.0.a8+)</span><br>
+    <code>%t6   </code>6 digit time index  (file names contain number sequences that  begin with 000001)  <span class="style1">(2.0.a8+)</span><br>
+    <code>%tm1  </code>1 or 2 digit time index (file names contain number sequences that  begin with 0 or 00)  <span class="style1">(2.0.a7+)</span><br>
+    <code>%tm2  </code>2 digit time index (file names contain number sequences that  begin with 00)  <span class="style1">(2.0.a7+)</span><br>
+    <code>%tm3  </code>3 digit time index  (file names contain number sequences that  begin with 000)  <span class="style1">(2.0.a7+)</span><br>
+    <code>%tm4  </code>4 digit time index  (file names contain number sequences that  begin with 0000) <span class="style1">(2.0.a8+)</span><br>
+    <code>%tm5  </code>5 digit time index  (file names contain number sequences that  begin with 00000) <span class="style1">(2.0.a8+)</span><br>
+    <code>%tm6  </code>6 digit time index  (file names contain number sequences that  begin with 000000) <span class="style1">(2.0.a8+)</span><br>
+  </p>
+</ul>
+<p>
+When specifying the initial time (e.g., NWP model output), use these substitutions: 
+<ul>
+  <code>%ix1   </code>initial 1 digit decade <br>
+    <code>%ix3   </code>initial 3 digit decade <br>
+    <code>%iy2   </code>initial 2 digit year <br>
+    <code>%iy4   </code>initial 4 digit year <br>
+    <code>%im1   </code>initial 1 or 2 digit month <br>
+    <code>%im2   </code>initial 2 digit month (leading zero if 
+    needed) <br>
+    <code>%imc   </code>initial 3 character month abbreviation 
+    <br>
+    <code>%id1   </code>initial 1 or 2 digit day (leading zero 
+    if needed) <br>
+    <code>%id2   </code>initial 2 digit day <br>
+    <code>%ih1   </code>initial 1 or 2 digit hour <br>
+    <code>%ih2   </code>initial 2 digit hour <br>
+    <code>%ih3   </code>initial 3 digit hour <br>
+    <code>%in2   </code>initial 2 digit minute (leading zero if needed)<br>
+</ul>
+
+<a name="chsub"></a>Starting with version 1.9b4, a new template option has been added that allows 
+for any user-specified string substitution, instead of only date string substitution. 
+This is useful when none of the above template options match the time ranges in 
+the files you wish to aggregate, or if the files are located on different disk pathnames. 
+The syntax is as follows:
+<ul>
+  <code>%ch   </code>substitute string 
+</ul>
+If you put the <code>%ch</code> template in your DSET entry, then you also need 
+to put additional <a href="/grads/gadoc/descriptorfile.html#CHSUB">CHSUB</a> entries 
+in the descriptor file that contain two integers (t1 and t2) followed by a string 
+which will be substituted for <code>%ch</code> in the data file names for the 
+time steps beginning with<br>
+t1 and ending with t2. The CHSUB descriptor file entries have the following syntax: 
+<ul>
+  <p><code>chsub  <em>t1</em>  <em>t2</em>  <em>string</em></code></p>
+  <p>   </p>
+</ul>
+<h3>Templating over ENSEMBLE</h3>
+<p>In version 2.0, with the introduction of the extra grid dimension for ensembles, support was also added for file templating over E. The sole substitution template is <code>%e</code> and the substitution string is the ensemble name, which is provided in the EDEF entry in the descriptor file. Note that the ensemble names are limited to 15 characters -- keep this limit in mind when designing your data directory structure and file naming conventions (or use symbolic links to create short  [...]
+If your data set has an ensemble dimension, and you are using templating over T but not E (i.e., there is no %e in the DSET entry), then  all ensemble members are presumed to have identical time axes, and  all members must be contained in the data file for a given time. Templating over T but not E is not supported for  data sets in flat binary or GRIB1 formats. 
+<p>
+
+<h3>Examples</h3>
+<ol>
+  <li>Here's a set of binary files spanning a single month, where each day's worth 
+    of hourly data is contained in individual files: <br>
+    <code>    1may92.dat<br>
+       2may92.dat<br>
+       ...<br>
+       31may92.dat </code> <br>
+    Three records must be modified in the data descriptor file. Note that the 
+    TDEF entry reflects the entire month's worth of data: <br>
+    <code>    DSET ^%d1may92.dat<br>
+       OPTIONS template<br>
+       TDEF 744 linear 0z1may1992 1hr   </code>
+    <br>
+    <br>
+  </li>
+  <li>If your data set expanded, and there were more files containing hourly data 
+    for other months and years: <br>
+    <code>    1jun92.dat<br>
+       2jun92.dat<br>
+       ...<br>
+       1jan93.dat </code> <br>
+    Then you would add a template for month and year in your DSET entry and extend 
+    the length of your TDEF: <br>
+    <code>    DSET ^%d1%mc%y2.dat<br>
+       OPTIONS template<br>
+       TDEF 6624 linear 0z1may1992 1hr<br>
+    </code><br><br></li>
+  <li>Suppose you have a set of seven netcdf files, each containing monthly data 
+    spanning a decade:<br>
+       <code>pr.1880_1889.nc</code><br>
+       <code>pr.1890_1899.nc</code><br>
+       <code>pr.1900_1909.nc</code><br>
+       <code>pr.1910_1919.nc</code><br>
+       <code>pr.1920_1929.nc</code><br>
+       <code>pr.1930_1939.nc</code><br>
+       <code>pr.1940_1949.nc</code><br>
+	Then your descriptor file would include the following entries:<br>
+       <code>DSET ^pr.%x30_%x39.nc </code><br>
+       <code>OPTIONS template </code><br>
+       <code>DTYPE netcdf </code><br>
+       <code>TDEF 840 linear jan1880 1mo</code>
+    <br><br>
+  </li>
+  <li> Here are two netcdf files, one containing 50 years of monthly data (600 
+    time steps), the other 100 years (1200 time steps): <br>
+       <code>pr.1851-1900.nc</code><br>
+       <code>pr.1901-2000.nc</code> <br>
+    Your descriptor file should include the following entries:<br>
+       <code>DSET ^pr.%ch.nc</code><br>
+       <code>CHSUB   1  600 1851-1900</code><br>
+       <code>CHSUB 601 1800 1901-2000</code><br>
+       <code>OPTIONS template</code><br>
+       <code>DTYPE netcdf</code><br>
+       <code>TDEF 1800 linear jan1851 1mo</code><br>
+    If these two data files were located on different disks, you could write out the relevant descriptor file entries this way instead:<br>
+       <code>DSET %ch</code><br>
+       <code>CHSUB   1  600 /disk1/pr.1851-1900.nc</code><br>
+       <code>CHSUB 601 1800 /disk2/pr.1901-2000.nc</code><br>
+    <br><vr>
+  </li>
+  <li>Your forecast model output looks like this:<br>
+   <code>   MMOUT_DOMAIN1_00<br>
+      MMOUT_DOMAIN1_01<br>
+      MMOUT_DOMAIN1_02<br>
+   </code>
+  so your DSET enry will look like this: <br>
+  <code>   DSET ^MMOUT_DOMAIN1_%tm2</code><br>
+  <br></li>
+</ol>
+</body>
+</html>
+
diff --git a/doc/tutorial.html b/doc/tutorial.html
new file mode 100644
index 0000000..41508e1
--- /dev/null
+++ b/doc/tutorial.html
@@ -0,0 +1,374 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS Tutorial</title>
+<link href="GrADS.css" rel="stylesheet" type="text/css">
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h1>Tutorial (<a href="Tutorial_Espanol.doc">En Español</a>)</h1>
+<p>
+<h3>What is it?</h3>
+This document presents a brief tutorial for Brian Doty's <a
+href="http://grads.iges.org/grads">Grid
+Analysis and Display System (GrADS)</a>. The following sample
+session
+will give you a feeling for how to use the basic capabilities of
+GrADS. This sample session takes about 30 minutes to run through. Here is a copy of
+<p>
+
+<h3>Before you start:download the sample data</h3>
+You will need the following sample data files in order to go through
+this tutorial: 
+<p>
+<ul>
+<a href="ftp://cola.gmu.edu/grads/sprite/tutorial/model.ctl">
+<code>model.ctl   </code></a>GrADS descriptor file (0.7 kb) <br>
+<a href="ftp://cola.gmu.edu/grads/sprite/tutorial/model.grb">
+<code>model.grb   </code></a>GrADS (GRIB) data file (579 kb) <br>
+<a href="ftp://cola.gmu.edu/grads/sprite/tutorial/model.gmp">
+<code>model.gmp   </code></a>GrADS gribmap index file (4 kb) <br>
+</ul>
+
+<p>
+This data file is described by the data descriptor file
+<a href="ftp://cola.gmu.edu/grads/sprite/tutorial/model.ctl">
+<code>model.ctl</code></a>. You may want to look at this file before
+continuing.  The data descriptor file describes the actual data file,
+which in the case contains 5 days of global grids that are 72 x 46
+elements in size.<p> Please download these 3 files to a local
+directory before proceeding. 
+<p> 
+<h3>Sample Session</h3>
+<p>
+To start up GrADS, enter:
+<p>
+<dd><a href="gradcomdgrads.html"><code>grads</code></a> 
+  <p> If the <span class="code">grads</span> executable is not in your current 
+    directory, or if it is not in your PATH somewhere, you may need to enter the 
+    full pathname, ie: 
+  <p>
+<dd><code>/usr/homes/smith/grads/grads</code> 
+  <p>
+GrADS will prompt you with a landscape vs. portrait question;
+just press enter.  At this point a graphics output window should
+open on your console.  You may wish to move or resize this
+window. Keep in mind that you will be entering GrADS commands
+from the window where you first started GrADS -- this window will
+need to be made the 'active' window and you will not want to
+entirely cover that window with the graphics output window.
+<p>
+In the text window (where you started grads from), you should now
+see a prompt:  <code>ga-></code>    You will enter GrADS commands at this
+prompt and see the results displayed in the graphics output
+window.<p>
+
+The first command you will enter is:<p>
+
+<dd><code><a href="gradcomdopen.html">open</a> model.ctl</code><p>
+
+You may want to see what is in this file, so enter:<p>
+
+<dd><code><a href="gradcomdquery.html">query</a> file</code><p>
+
+One of the available variable is called <code>ps</code>, for surface pressure. 
+We can display this variable by entering:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> ps</code><p>
+
+<code>d</code> is short for <a href="gradcomddisplay.html"><code>display</code></a>.   You
+will note that by default, GrADS
+will display an X, Y plot at the first time and at the lowest
+level in the data set.<p>
+<center><img src="tutorial_fig1.gif"></center><p><br>
+
+Now you will enter commands to alter the <a
+href="dimenv.html"><code>dimension environment</code></a>. 
+The <a href="gradcomddisplay.html"><code>display</code></a> command (and
+implicitly, the access,
+operation, and
+output of the data) will do things with respect to the current
+dimension environment.  You control the dimension environment 
+with the <code>set</code> command:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdclear.html">clear</a>
+          </code>clears the display<br> 
+<code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a> -90
+    </code>sets longitude to 90 degrees West<br> 
+<code><a href="gradcomdsetlatlonlevtimeens.html">set lat</a> 40
+     </code>sets latitude to 40 degrees North<br> 
+<code><a href="gradcomdsetlatlonlevtimeens.html">set lev</a> 500
+    </code>sets level to 500 mb<br>
+<code><a href="gradcomdsetlatlonlevtimeens.html">set t</a> 1
+        </code>sets time to first time step<br> 
+<code><a href="gradcomddisplay.html">d</a> z
+            </code>displays the variable 'z'<br>
+</ul>
+
+<p>
+In the above sequence of commands, we have set all four GrADS
+dimensions to a single value.  When we set a dimension to a
+single value, we say that dimension is "fixed".  Since all the
+dimensions are fixed, when we display a variable we get a single
+value, in this case the value at the location 90W, 40N, 500mb,
+and the 1st time in the data set.<p>
+
+If we now enter:<p>
+<ul>
+<code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a> -180 0</code>             X is now a varying
+dimension<br>
+<code><a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+We have set the X dimension, or longitude, to vary.  We have done
+this by entering two values on the set command.  We now have one
+varying dimension (the other dimensions are still fixed), and
+when we display a variable we get a line graph, in this case a
+graph of 500mb Heights at 40N.<p>
+<center><img src="tutorial_fig2.gif"></center><p><br>
+Now enter:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lat</a> 0 90<br> 
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+We now have two varying dimensions, so by default we get a
+contour plot.  If we have 3 varying dimensions:<p>
+<ul>
+<code><a href="gradcomdclear.html">c</a><br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set t</a> 1 5<br>
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+we get an animation sequence, in this case through time.<p>
+
+Now enter:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lon</a> -90<br>
+<a href="gradcomdsetlatlonlevtimeens.html">set lat</a> -90 90<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lev</a> 1000 100<br>
+<a href="gradcomdsetlatlonlevtimeens.html">set t</a> 1<br>
+<a href="gradcomddisplay.html"> d</a> t<br>
+<a href="gradcomddisplay.html"> d</a> u</code></ul><p>
+
+In this case we have set the Y (latitude) and Z (level)
+dimensions to vary, so we get a vertical cross section.  We have
+also displayed two variables, which simply overlay each other. 
+You may display as many items as you desire overlaid before you
+enter the <code><a href="gradcomdclear.html">clear</a></code> command.<p>
+<center><img src="tutorial_fig3.gif"></center><p><br>
+Another example, in this case with X and T varying (Hovmoller
+plot):<p>
+<ul>
+<code><a href="gradcomdclear.html">c</a><br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lon</a> -180 0<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lat</a> 40<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lev</a> 500<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set t 1 5<br>
+<a href="gradcomddisplay.html"> d z</a></code></ul><p>
+<center><img src="tutorial_fig4.gif"></center><p><br>
+Now that you know how to select the portion of the data set to
+view, we will move on to the topic of operations on the data. 
+First, set the dimension environment to an Z, Y varying one:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lon</a> -180 0<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lat</a> 0 90<br>
+<a href="gradcomdsetlatlonlevtimeens.html"> set lev</a> 500 <br>
+<a href="gradcomdsetlatlonlevtimeens.html">set t</a> 1</code></ul><p>
+
+Now lets say that we want to see the temperature in Fahrenheit
+instead of Kelvin.  We can do the conversion by entering:<p>
+
+<dd><code><a href="gradcomddisplay.html">display</a> (t-273.16)*9/5+32</code><p>
+
+Any expression may be entered that involves the standard
+operators of +, -, *, and /, and which involves operands which
+may be constants, variables, or functions.  An example involving
+functions:<p>
+
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> <a
+href="gradfuncsqrt.html">sqrt</a>(u*u+v*v)</code></ul><p>
+
+
+to calculate the magnitude of the wind.  A function is provided
+to do this calculation directly:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> <a
+href="gradfuncmag.html">mag</a>(u,v)</code><p>
+<center><img src="tutorial_fig5.gif"></center><p><br>
+Another built in function is the averaging function:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> <a
+href="gradfuncave.html">ave</a>(z,t=1,t=5)</code></ul><p>
+
+In this case we calculate the 5 day mean.  We can also remove the
+mean from the current field:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> z - <a
+href="gradfuncave.html">ave</a>(z,t=1,t=5)</code><p>
+
+We can also take means over longitude to remove the zonal mean:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a> d z-<a href="gradfuncave.html">ave</a>(z,x=1,x=72)<br>
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+We can also perform time differencing:<p>
+<ul>
+<a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> z(t=2)-z(t=1)</code></ul><p>
+
+This computes the change between the two fields over 1 day.  We
+could have also done this calculation using an offset from the
+current time:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> z(t+1) - z</code><p>
+
+The complete specification of a variable name is:<p>
+
+<dd><code>name.file(dim +|-|= value, ...)</code><p>
+
+If we had two files open, perhaps one with model output, the
+other with analyses, we could take the difference between the two
+fields by entering:<p>
+
+
+<dd><code><a href="gradcomddisplay.html">display</a> z.2 - z.1</code><p>
+
+Another built in function calculates horizontal relative
+vorticity via finite differencing:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> <a
+href="gradfunchcurl.html">hcurl</a>(u,v)</code></ul><p>
+
+Yet another function takes a mass weighted vertical integral:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> <a href="gradfuncvint.html">
+vint</a>(ps,q,275)</code></ul><p>
+
+Here we have calculated precipitable water in mm.<p>
+
+Now we will move on to the topic of controlling the graphics
+output.  So far, we have allowed GrADS to chose a default contour
+interval.  We can override this by:<p>
+
+<ul><code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetcint.html">set cint</a> 30<br>
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+We can also control the contour color by:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</br>
+<a href="gradcomdsetccolor.html">set ccolor</a> 3<br>
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+We can select alternate ways of displaying the data:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetgxout.html">set gxout</a> shaded<br>
+<a href="gradcomddisplay.html">d</a> <a href="gradfunchcurl.html">
+hcurl</a>(u,v)</code></ul><p>
+
+This is not very smooth; we can apply a cubic smoother by
+entering:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetcsmooth.html">set csmooth</a> on<br>
+<a href="gradcomddisplay.html">d</a> <a href="gradfunchcurl.html">
+hcurl</a>(u,v)</code></ul><p>
+<center><img src="tutorial_fig6.gif"></center><p><br>
+We can overlay different graphics types:<p>
+<ul>
+<code><a href="gradcomdsetgxout.html">set gxout</a> contour<br>
+<a href="gradcomdsetccolor.html">set ccolor</a> 0<br>
+<a href="gradcomdsetcint.html">set cint</a> 30<br>
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+and we can annotate:<p>
+
+<dd><code><a href="gradcomddrawtitle.html">draw title</a> 500mb Heights and
+Vorticity</code><p>
+
+We can view wind vectors:<p>
+
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetgxout.html">set gxout</a> vector<br>
+<a href="gradcomddisplay.html">d</a> u;v</code></ul><p>
+<center><img src="tutorial_fig7.gif"></center><p><br>
+Here we are displaying two expressions, the first for the U
+component of the vector; the 2nd the V component of the vector. 
+We can also colorize the vectors by specifying a 3rd field:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> u;v;q</code><p>
+
+or maybe:<p>
+
+<dd><code><a href="gradcomddisplay.html">d</a> u;v;<a
+href="gradfunchcurl.html">hcurl</a>(u,v)</code><p>
+
+You may display pseudo vectors by displaying any field you want:<p>
+
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomddisplay.html">d</a> <a href="gradfuncmag.html">mag</a>(u,v) ;
+q*10000</code></ul><p>
+
+Here the U component is the wind speed; the V component is
+moisture.<p>
+
+We can also view streamlines (and colorize them):<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetgxout.html">set gxout</a> stream<br>
+<a href="gradcomddisplay.html">d</a> u;v;<a
+href="gradfunchcurl.html">hcurl</a>(u,v)</code></ul><p>
+
+Or we can display actual grid point values:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br>
+<a href="gradcomdsetgxout.html">set gxout</a> grid<br>
+<a href="gradcomddisplay.html">d</a> u</code></ul><p>
+<center><img src="tutorial_fig8.gif"></center><p><br>
+We may wish to alter the map background:<p>
+<ul>
+<code><a href="gradcomdclear.html">clear</a><br> 
+<a href="gradcomdsetlatlonlevtimeens.html">set lon</a> -110 -70<br>
+<a href="gradcomdsetlatlonlevtimeens.html">set lat</a> 30 45<br>
+<a href="gradcomdsetmpdset.html">set mpdset</a> nam<br>
+<a href="gradcomdsetdigsize.html">set digsize</a> 0.2<br>
+<a href="gradcomdsetdignum.html">set dignum</a> 2<br> 
+<a href="gradcomddisplay.html">d</a> u</code></ul><p>
+
+To alter the projection:<p>
+<ul>
+<code><a href="gradcomdsetlatlonlevtimeens.html">set lon</a> -140 -40<br>
+<a href="gradcomdsetlatlonlevtimeens.html">set lat</a> 15 80 <br>
+<a href="gradcomdsetmpvals.html">set mpvals</a> -120 -75 25 65<br>
+<a href="gradcomdsetmproj.html">set mproj</a> nps<br>
+<a href="gradcomdsetgxout.html">set gxout</a> contour<br>
+<a href="gradcomdsetcint.html">set cint</a> 30<br> 
+<a href="gradcomddisplay.html">d</a> z</code></ul><p>
+
+In this case, we have told grads to access and operate on data
+from longitude 140W to 40W, and latitude 15N to 80N.  But we have
+told it to display a polar stereographic plot that contains the
+region bounded by 120W to 75W and 25N to 65N.  The extra plotting
+area is clipped by the map projection routine.<p>
+<center><img src="tutorial_fig9.gif"></center><p><br>
+This concludes the sample session.  At this point, you may wish
+to examine the data set further, or you may want to go through
+the GrADS documentation and try out the other options described
+there.
+
+</body>
+</html>
+
diff --git a/doc/tutorial_fig1.gif b/doc/tutorial_fig1.gif
new file mode 100644
index 0000000..8d5eb2b
Binary files /dev/null and b/doc/tutorial_fig1.gif differ
diff --git a/doc/tutorial_fig2.gif b/doc/tutorial_fig2.gif
new file mode 100644
index 0000000..bb84362
Binary files /dev/null and b/doc/tutorial_fig2.gif differ
diff --git a/doc/tutorial_fig3.gif b/doc/tutorial_fig3.gif
new file mode 100644
index 0000000..50627f2
Binary files /dev/null and b/doc/tutorial_fig3.gif differ
diff --git a/doc/tutorial_fig4.gif b/doc/tutorial_fig4.gif
new file mode 100644
index 0000000..1fd80b7
Binary files /dev/null and b/doc/tutorial_fig4.gif differ
diff --git a/doc/tutorial_fig5.gif b/doc/tutorial_fig5.gif
new file mode 100644
index 0000000..a8f18a8
Binary files /dev/null and b/doc/tutorial_fig5.gif differ
diff --git a/doc/tutorial_fig6.gif b/doc/tutorial_fig6.gif
new file mode 100644
index 0000000..bcf712c
Binary files /dev/null and b/doc/tutorial_fig6.gif differ
diff --git a/doc/tutorial_fig7.gif b/doc/tutorial_fig7.gif
new file mode 100644
index 0000000..a0fc9f4
Binary files /dev/null and b/doc/tutorial_fig7.gif differ
diff --git a/doc/tutorial_fig8.gif b/doc/tutorial_fig8.gif
new file mode 100644
index 0000000..a35cb32
Binary files /dev/null and b/doc/tutorial_fig8.gif differ
diff --git a/doc/tutorial_fig9.gif b/doc/tutorial_fig9.gif
new file mode 100644
index 0000000..bb4ce87
Binary files /dev/null and b/doc/tutorial_fig9.gif differ
diff --git a/doc/udf.html b/doc/udf.html
new file mode 100644
index 0000000..7df3b40
--- /dev/null
+++ b/doc/udf.html
@@ -0,0 +1,433 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>GrADS User Defined Functions</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h2>User Defined Functions (UDFs)</h2><p>
+
+<a href="#overview">Overview of User Defined Functions</a><br>
+<a href="#table">The user defined function table</a><br>
+<a href="#dtf">Format of the function data transfer file</a><br>
+<a href="#frf">Format of the function result file</a><br>
+<a href="#example">Example: Linear Regression Function</a><br><br>
+<hr>
+<br>
+
+Users may write their own GrADS functions in the computer
+language of their choice, and have them available from the GrADS
+expression facility (via the <a
+href="gradcomddisplay.html"><code>display</code></a> command). Some
+possible user defined functions might be:<p>
+<ul>
+<li>filtering functions
+<li>grid interpolation functions
+<li>thermodynamic functions
+</ul>
+<p>
+You may write a function that can be invoked via the GrADs
+expression facility.  This function may be written in any
+computer language, and may perform any desired I/O, calculations,
+etc. Please read the following documentation carefully to
+understand the restrictions to this capability.<p>
+
+<a name="overview">
+<h3>Overview of User Defined Functions</h3></a>
+<p>
+The steps that GrADS uses to invoke a user defined function are:<p>
+
+<ol>
+<li> When GrADS is first started, it reads a file that describes
+the user defined functions.  This file is called the 'user
+defined function table'.<p>
+
+<li>When a user function is invoked via the display command
+expression, GrADS parses the arguments to the functions, obtains
+the results of any expressions, and writes the resultant data to
+a 'function data transfer file'.<p>
+
+Please note that in a user-defined function adding the double
+quote ("") around a <code>char</code> argument passes the string directly
+<i>without</i> the usual conversion to lower case and removal of blanks,
+e.g.,<p>
+
+<dd><code>d grhilo(slp,F8.2,"This is the Label",0.25)</code><p>
+
+Here <code>F8.2</code> is passed as <code>f8.2</code>, but the second
+character string
+would not be converted to <code>thisisthelabel</code>.<p>
+
+<li>A user written program is then invoked.  This program may read
+the function data transfer file, do any desired processing, then
+write the result into a function result file.<p>
+
+<li>GrADS will read the function result file and generate the
+internal objects necessary for this result to participate in the
+remainder of the expression evaluation.</ol>
+<p>
+
+<a name="table">
+<h3>The user defined function table</h3></a>
+<p>
+The user defined function table (UDFT) is a simple text file that
+contains information about each user defined function. There are five
+records for each defined function, and the file may contains
+descriptions for any number of functions. The 5 records are:
+<p>
+<ul>
+Record 1: This record contains several blank delimited fields:
+<p>
+<ul>
+Field 1: The name of the function, 1-8 characters, beginning with
+a letter.  The name should be in lower case.  Note that function
+names are not case dependent, and that GrADS converts all
+expression to lower case before evaluation. 
+<p>
+Field 2: An integer value, specifying the minimum number of arguments
+that the function may have.
+<p>
+Field 3: An integer value, specifying the maximum number of
+arguments that the function may have.  This may not be more than 8. 
+<p>
+Field 4 to N: A keyword describing the data type of each
+argument: <br>
+<dd><code>expr: </code> The argument is an expression.
+<dd><code>value:</code> The argument is a data value.
+<dd><code>char: </code> The argument is a character string.
+</ul>
+<p>
+Record 2:  This record contains blank delimited option keywords.  
+Current keywords are: 
+<ul>
+<p>
+<code>sequential</code> - GrADS will write data to the function data
+transfer file in FORTRAN sequential unformatted records. This is
+typically appropriate if the function is written in FORTRAN.
+<p>
+<code>direct</code> - GrADS will write data to the function data
+transfer file without any record descriptor words. This is 
+typically appropriate if the function is written in C.
+</ul>
+<p>
+Record 3: This record contains the file name of the function
+executable routine.  This routine will be invoked as its own separate
+process via the <code>system</code> call. Do a <code>man system</code>
+if you would like more information on the rules governing this system
+feature.
+<p>
+Record 4:   This record contains the file name of the function
+data transfer file.  This is the file that GrADS will write data
+to before invoking the user function executable, and is typically
+the file the function will read to obtain the data to be operated
+upon.<p>
+
+Record 5:   This record contains the file name of the function
+result file.  The function writes the result of its operations
+into this file in a specified format, and GrADS reads this file
+to obtain the result of the function calculation.
+</ul>
+<p>
+The user function definition table itself is pointed to by the
+environment variable GAUDFT.  If this variable is not set, the
+function table will not be read.  An example of setting this
+variable is:<p>
+
+<dd><code>setenv GAUDFT /usr/local/grads/udft</code><p>
+
+User defined functions have precedence over GrADS intrinsic
+functions, thus a user defined function can be set up to replace
+a GrADS function.  Be sure you do not do this inadvertently by
+choosing a function name already in use by GrADS.
+<p>
+
+<a name="dtf">
+<h3>Format of the function data transfer file</h3></a>
+<p>
+The function data transfer file contains a header record plus
+one or more records representing each argument to
+the function. The user function routine will know what data
+types to expect (since they will be specified in the UDFT), and
+can read the file in a predictable way. 
+<p>
+
+<b>Header record</b>: The header record always contains 20
+floating point numbers.  The record will always be the same size.
+Values defined in this record are:<p>
+
+<ul>
+1st value: Number of arguments used when invoking the function.
+<p>
+2nd value: Set to zero, to indicate this particular transfer
+file format.  The function should test this value, and return an
+error if non-zero, in order to be compatible with future
+enhancements to this file format. 
+<p>
+Values 3 to 20:   Reserved for future use.
+</ul>
+
+<p>
+<b>Argument records</b>: The argument records are written out in the
+order that the arguments are presented. The contents of the argument
+records depends on the data type of the argument: value, character
+string, or expression. Each of these data types will result in a
+different argument record being written out:
+<p>
+<ul>
+<li><code>value</code>: If the argument data type is a value, then the argument
+record will contain a single floating point value.
+<p>
+<li><code>char</code>: If the argument data type is a character
+string, then the argument record will an 80-byte character array that
+contains the argument string. If the argument string is longer than 80
+bytes, the trailing bytes will be lost. If the argument is shorter, it
+will be padded with blanks.  Note that the argument will already be
+processed by the GrADS expression parser, which will convert all
+characters to lower case and remove any blanks.
+<p>
+<li><code>expr</code>: If the argument data type is a gridded
+expression, then GrADS will evaluate the expression and write a series
+of records to the transfer file. Listed below are the records that
+will be written to the transfer file for each argument that is a 
+gridded expression:
+<p>
+
+<ul>
+1st record: This record contains 20 values, all floating
+point, that make up the header for the gridded expression.  Note that
+some of the values are essentially integer, but for convenience they
+are written as a floating point array.  Appropriate care should be
+taken in the function program when converting these values back to
+integer.
+<p>
+<ul>
+1 -- Undefined value for the grid 
+<p>
+2 -- An index to identify the i dimension (idim). Options for the index are: 
+<ul>
+<code>-1 &nbsp&nbsp&nbsp</code>None <br>
+<code> 0 &nbsp&nbsp&nbsp</code>X dimension (lon) <br>
+<code> 1 &nbsp&nbsp&nbsp</code>Y dimension (lat) <br>
+<code> 2 &nbsp&nbsp&nbsp</code>Z dimension (lev) <br>
+<code> 3 &nbsp&nbsp&nbsp</code>T dimension (time)<br>
+</ul>
+<p>
+3 -- An index to identify the j dimension (jdim). Options are the same
+as for idim. If both idim and jdim are -1, the grid is a single value.
+<p>
+4 -- number of elements in the i direction (isiz). 
+<p>
+5 -- number of elements in the j direction (jsiz). 
+<p>
+6 -- i dimension linear flag. If 0, the dimension has non-linear scaling.
+<p> 
+7 -- j dimension linear flag. If 0, the dimension has non-linear scaling.
+<p>
+8 -- istrt. This is the world coordinate value of the first idim element,
+ONLY if idim has linear scaling and idim is not time.
+<p>
+9 -- iincr. This is the increment of the world coordinate values for idim,
+ONLY if idim has linear scaling. 
+<p>
+10 -- jstrt. This is the world coordinate value of the first jdim element,
+ONLY if jdim has linear scaling and jdim is not time.  
+<p>
+11 -- jincr. This is the increment of the world coordinate values for jdim,
+ONLY if jdim has linear scaling. 
+<p>
+12 -- If one of the dimensions is time, values 12 to 16 define the start
+time:
+<ul>
+12: start year <br>
+13: start month <br>
+14: start day <br>
+15: start hour <br>
+16: start minute <br>
+</ul>
+<p>
+17 -- If one of the dimensions is time, values 17 and 18 define the time 
+increment:
+<ul>
+17: time increment in minutes <br>
+18: time increment in months <br>
+</ul>
+(GrADS handles all increments in terms of minutes and months.)
+<p>
+19,20 -- reserved for future use
+</ul>
+
+<p>
+2nd record: This record contains the actual grid of data. It contains
+isiz*jsiz floating point elements.
+<p>
+3rd record: This record contains the world coordinate values for each
+grid element in the i dimension. Thus, the record will contain isiz
+floating point elements.
+<p>
+4th record: This record contains the world coordinate values for each
+grid element in the j dimension. Thus, the record will contain jsiz
+floating point elements.
+</ul>
+</ul>
+<p>
+<a name="frf"><h3>Format of the function result file</h3></a>
+<p>
+The function result file returns the result of the user defined
+function to GrADS.  It is the responsibility of the function program
+to write this file in the proper format. A file written out in an
+improper format may cause GrADS to crash, or to produce incorrect
+results.
+<p>
+The result of a function is always a grid.  Thus, the format of
+the function result file is as follows:<p>
+
+<b>Header record</b>: The header record should always contain 20
+floating point numbers.  The record will always be the same size.
+Values defined in this record are:<p>
+
+<ul>
+1st value: This value
+contains the return code. Any non-zero return code causes GrADS to
+assume the function detected an error, and GrADS does not read
+any further output. 
+<p>
+2nd value: Set to zero, to indicate this particular transfer
+file format.  The function should test this value, and return an
+error if non-zero, in order to be compatible with future
+enhancements to this file format. 
+<p>
+Values 3 to 20: Reserved for future use.
+</ul>
+<p>
+<b>Grid records</b>: The grid records should be written in the same
+order and format as the <code>expr</code> argument record in
+the data transfer file, with one important exception: the 3rd and 4th
+records containing the world coordinate values for each grid element
+in the i and j dimensions are written out to the function result file
+only if the scaling is non-linear. Thus the transfer file and the result
+file are not symmetric: GrADS writes a transfer file with record #3
+and #4 always included, but it does NOT like to see record #3 and #4
+in the result file if the dimensions are linear.
+<p>
+The linear/non-linear scaling of the grid dimensions is determined by
+examining the grid header contents -- values 6 and 7 contain the idim
+and jdim linear flags.  Note that the time dimension is always linear.
+<p>
+
+
+<a name="example">
+<h3><i>Example</i>: Linear Regression Function</h3></a>
+<p>
+This is a simple example of what a user defined function might
+look like in FORTRAN.  This is a simple linear regression
+function, which only handles a 1-D grid and takes one argument,
+and expression.<p>
+
+First, the user defined function table (UDFT):
+<p>
+<ul>
+<pre>
+linreg 1 1 expr 
+sequential 
+/mnt/grads/linreg
+/mnt/grads/linreg.out 
+/mnt/grads/linreg.in
+</pre>
+</ul>
+<p>
+
+The source code for the FORTRAN program linreg is:
+<p>
+<pre>
+      real vals(20),ovals(20) 
+      real x(10000),y(10000) 
+c 
+      open (8,file='/mnt/grads/linreg.out',form='unformatted') 
+      open (10,file='/mnt/grads/linreg.in',form='unformatted') 
+c 
+      read (8)
+      read (8) vals 
+      idim = vals(2) 
+      jdim = vals(3) 
+c 
+c  If this is not a 1-D grid, write error message and exit 
+      if (idim.eq.-1 .or. jdim.ne.-1) then 
+        write (6,*) 'Error: Invalid dimension environment'
+        vals(1) = 1 
+        write (10) vals 
+        stop
+      endif 
+c 
+c  If the grid is too big, write error message and exit 
+      isiz = vals(4) 
+      if (isiz.gt.10000) then 
+        write (6,*) 'Error from linreg: Grid too big' 
+        vals(1) = 1 
+        write (10) vals 
+        stop
+      endif 
+c 
+c  Read the data 
+      read (8) (y(i),i=1,isiz) 
+c 
+c  Read non-linear scaling if necessary 
+      ilin = vals(6) 
+      if (ilin.eq.0) then 
+        read (8) (x(i),i=1,isiz) 
+      else 
+        do 100 i=1,isiz
+          x(i) = i  
+100     continue
+      endif 
+c 
+c  Do linear regression 
+      call fit (x,y,isiz,a,b) 
+c 
+c  Fill in data values 
+      do 110 i=1,isiz 
+        y(i) = a+x(i)*b  
+110   continue 
+c 
+c  Write out return info.  
+c  The header and the non-linear scaling 
+c  info will be the same as what GrADs gave us. 
+      ovals(1) = 0.0 
+      write (10) ovals 
+      write (10) vals 
+      write (10) (y(i),i=1,isiz) 
+      if (ilin.eq.0) write(10) (x(i),i=1,isiz) 
+c 
+      stop
+      end 
+c
+c---------------------------------------------------
+      SUBROUTINE FIT(X,Y,NDATA,A,B) 
+c 
+c A is the intercept 
+c B is the slope 
+c 
+      REAL X(NDATA), Y(NDATA) 
+c 
+      SX = 0. 
+      SY = 0. 
+      ST2 = 0.
+      B = 0. 
+      DO 12 I = 1, NDATA 
+        SX = SX + X(I) 
+        SY = SY + Y(I)  
+12    CONTINUE 
+      SS = FLOAT(NDATA) 
+      SXOSS = SX/SS
+      DO 14 I = 1, NDATA 
+        T = X(I) - SXOSS 
+        ST2 = ST2 + T * T 
+        B = B + T * Y(I)  
+14    CONTINUE 
+      B = B/ST2 
+      A = (SY - SX * B)/SS 
+      RETURN 
+      END
+</pre>
+</body>
+</html>
diff --git a/doc/users.html b/doc/users.html
new file mode 100644
index 0000000..731600b
--- /dev/null
+++ b/doc/users.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS User's Guide</title>
</head>
<body bgcolor="e0f0ff" text="#000000">

<center>
<font size=+2><a href="users.html">GrADS User's Guide<br>Table of Contents</a></font>
</center>
<ul>
<font size=+1>General Topics</font><br>
<ul>
<li><a href="start.html">Starting and Quiting GrADS</a>
<li><a href="basic.html">Basic Concept of Operation</a>
<li><a href="aboutgriddeddata.html">Gridded Data Sets</a>
  <ul>
  <li><a href="aboutgriddeddata.html#descriptor">Gridded Data Descriptor File</a>
  <li><a href="aboutgriddeddata.html#structure">Structure of a Gridded Binary Data File</a>
  <li><a href="aboutgriddeddata.html#formats">Binary Data Formats</a>
  <li><a href="aboutgriddeddata.html#create">Creating Data Files</a>
  <li><a href="ensembles.html">The Ensemble Dimension in GrADS version 2.0</a>
  <li><a href="descriptorfile.html">Elements of a GrADS Data Descriptor File</a>
  <li><a href="grib.html">Creating a Data Descriptor File for GRIB Data</a>
  <li><a href="SDFdescriptorfile.html">Reading NetCDF and HDF-SDS Files with GrADS</a>
  <li><a href="compression.html">Reading and Writing Compressed Data Sets</a>  
  </ul>
<li><a href="reinitialization.html">Reinitialization of GrADS</a>
<li><a href="commandline.html">Command Line Editing and History</a>
<li><a href="utilities.html">External Utilities</a>
</ul>

<p>
<font size=+1>Analysis Topics</font><br>
<ul>
<li><a href="dimenv.html">Dimension Environment</a>
<li><a href="variable.html">GrADS Variables</a>
  <ul>
  <li><a href="variable.html#names">Variable Names</a>
  <li><a href="variable.html#new">Defining New Variables</a>
  <li><a href="variable.html#undefine">Undefining Variables</a>
  </ul>
<li><a href="expressions.html">GrADS Expressions</a>
<li><a href="templates.html">Using Templates to Aggregate Data Files</a>
<li><a href="aboutstationdata.html">About GrADS Station Data</a>
  <ul>
      <li><a href="aboutstationdata.html#station">Structure of a GrADS Station 
        Data File</a> 
      <li><a href="aboutstationdata.html#create">Creating a GrADS Station Data 
        File</a> 
      <li><a href="aboutstationdata.html#descriptor">GrADS Station Data Descriptor 
        File</a> 
      <li><a href="aboutstationdata.html#stnmap">The STNMAP Utility</a>
  </ul>
<li><a href="bufrformat.html">The BUFR Format for Station Data</a></li>
<li><a href="usingstationdata.html">Using Station Data</a>
  <ul>
  <li><a href="usingstationdata.html#operating">Operating on Station Data</a>
  <li><a href="usingstationdata.html#model">Plotting Station Models</a>
  <li><a href="usingstationdata.html#xsection">Drawing Arbitrary Cross Sections</a>
  </ul>
<li><a href="udf.html">User Defined Functions</a>
  <ul>
  <li><a href="udf.html#overview">Overview of User Defined Functions</a>
  <li><a href="udf.html#table">The user defined function table</a>
  <li><a href="udf.html#dtf">Format of the function data transfer file</a>
  <li><a href="udf.html#frf">Format of the function result file</a>
  <li><a href="udf.html#example">Example: Linear Regression Function</a>
  </ul>
<li><a href="map.html">Using Pre-Projected Data in GrADS</a>
  <ul>
  <li><a href="map.html#polar">Polar Stereo Preprojected Data</a>
  <li><a href="map.html#lambert">Lambert Conformal Preprojected Data</a>
  <li><a href="map.html#eta">NCEP ETA Model</a>
  <li><a href="map.html#nmc">NCEP polar stereographic grid for SSMI data</a>
  <li><a href="map.html#csu">CSU RAMS oblique polar stereographic grid</a>
  <li><a href="map.html#pit">Pitfalls when using preprojected data</a>
  <li><a href="map.html#proj">GrADS Display Projections</a>
  <li><a href="map.html#summary">Summary and Plans</a>
  </ul>
<li><a href="variableformats.html">Non-Standard Variable Formats and Data File Structures</a>
</ul>

<p>
<font size=+1>Display Topics</font><br>
<ul>
<li><a href="display.html">Displaying Data</a>
  <ul>
  <li><a href="display.html#DDP">Drawing Plots</a>
  <li><a href="display.html#CTD">Clearing the Display</a>
  <li><a href="display.html#GOT">Graphics Output Types</a>
  <li><a href="advdisplay.html">Graphics Options</a>
  <li><a href="graphelem.html">Drawing Basic Graphics Elements</a>
  <li><a href="shapefiles.html">Drawing the Contents of a Shapefile</a>
  </ul>
<li><a href="animation.html">Animation</a>
<li><a href="pagecontrol.html">Page Control</a>
  <ul>
  <li><a href="pagecontrol.html#real">Real and Virtual Pages</a>
  <li><a href="pagecontrol.html#plotarea">Controlling the Plot Area</a>
  <li><a href="pagecontrol.html#multipanel">Drawing Multi-Panel Plots</a>
  </ul>
<li><a href="colorcontrol.html">Color Control</a>
<li><a href="fontcontrol.html">Font Control</a><br>
<li><a href="imageoutput.html">Producing Hardcopy and Image Output from GrADS</a>
</ul>

<p>
<font size=+1>GrADS Scripting Language</font><br>
<ul>
<li><a href="script.html#intro">Introduction to GrADS scripts</a>
<li><a href="script.html#elements">Elements of the Language:</a>
  <ul>
  <li><a href="script.html#comment">comment</a>
  <li><a href="script.html#statement">statement</a>
  <li><a href="script.html#assignment">assignment</a>
  <li><a href="script.html#standardio">say / prompt / pull</a>
  <li><a href="script.html#ifendif">if / else / endif</a>
  <li><a href="script.html#while">while / endwhile</a>
  <li><a href="script.html#variables">variables</a>
  <li><a href="script.html#operators">operators</a>
  <li><a href="script.html#expressions">expressions</a>
  <li><a href="script.html#functions">Functions</a>
  <li><a href="script.html#intrinsic">Intrinsic Functions</a>
  </ul>
<li><a href="script.html#commands">Commands that complement the scripting language</a>
<li><a href="script.html#widgets">Widgets</a>
<li><a href="gsf.html">Dynamic Loading of Script Functions</a>
<li><a href="library.html">Script Library</a>
</ul>

</body>
</html>









\ No newline at end of file
diff --git a/doc/usingstationdata.html b/doc/usingstationdata.html
new file mode 100644
index 0000000..ef160ee
--- /dev/null
+++ b/doc/usingstationdata.html
@@ -0,0 +1,285 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Using GrADS Station Data</title>
+</head>
+<body bgcolor="e0f0ff" text="#000000">
+
+<h1>Using GrADS Station Data</h1>
+<p>
+This section describes some of the GrADS commands and functions that are
+available for analyzing and displaying station data.  Please refer to
+the companion section <a href="aboutstationdata.html">About Station
+Data</a> for information on the structure of station data files, how
+to create them, and how to instruct GrADS to interpret them properly.
+<p>
+Here are some quick links for skipping through this section:
+<ul>
+<li><a href="usingstationdata.html#operating">Operating on Station Data</a>
+<li><a href="usingstationdata.html#model">Plotting Station Models</a>
+<li><a href="usingstationdata.html#xsection">Drawing Arbitrary Cross Sections</a>
+</ul>
+
+<hr>
+<p>
+<h2><a name="operating">Operating on Station Data</a></h2>
+
+<p>
+Currently, station data operations and display are supported for
+three distinct dimension environments:
+<p>
+<ul>
+<li>X, Y varying (horizontal X, Y plot)
+<li>Z varying  (vertical profile)
+<li>T varying  (time series)
+</ul>
+
+<p>
+Operations may be done on station data as with gridded data. 
+Operations between grids and station data are not supported.
+
+<p>
+Operations between station data are defined as being the
+operation performed on data points that have exactly the same
+varying dimension values.<p>
+
+For example, if T is the only varying dimension, the expression:<p>
+
+<dd><code>display ts-ds</code><p>
+
+would result in a time series of station data reports being
+retrieved for two separate variables.  Then, for station reports
+having exactly the same time, the operation is performed.  Note
+that duplicates are ignored, with the operation being performed
+between the first occurrences encountered.<p>
+
+When both X and Y are both fixed dimensions, the variable
+specification may include a station identifier, which specifies a
+local override for both lat and lon.<p>
+
+The syntax for this would be:<p>
+
+<dd><code>varname(stid=ident)</code><p>
+
+The station identifiers are case insensitive.<p>
+
+Some functions do not support station data types.  These are:<p>
+
+<dd><code><a href="gradfunchdivg.html">hdivg</a>  <a href="gradfunchcurl.html"> 
+hcurl</a> <a href="gradfuncvint.html">vint</a> <a
+href="gradfuncmaskout.html">maskout</a> <a href="gradfuncave.html">ave</a> <a 
+href="gradfuncaave.html">aave</a> <a
+href="gradfunctloop.html">tloop</a></code><p>
+
+When X and Y are varying, station data values are displayed as
+numbers centred at their locations.  If two expressions are
+supplied on the <a href="gradcomddisplay.html"><code>display</code></a> command
+(ie,
+<code>display</code> ts;ds) then two
+values are displayed, above and below the station location. The
+display is controlled by the following <a
+href="commands.html#set"><code>set</code></a> commands:<p>
+
+<ul>
+<code>
+<a href="gradcomdsetccolor.html">set ccolor</a> <i>color</i><br>
+<a href="gradcomdsetdignum.html">set dignum</a> <i>digits</i><br>
+<a href="gradcomdsetdigsiz.html">set digsiz</a> <i>size</i><br>
+<a href="gradcomdsetstid.html">set stid</a> <i>on|off</i><br>
+</code>
+</ul>
+
+<p>
+The <a href="gradcomdsetstid.html"><code>set stid</code></a> command
+controls whether the station identifier is displayed with each value.
+
+<p>
+<h2><a name="model">Plotting Station Models</a></h2>
+<p>
+GrADs will plot station models from station data. This is enabled
+by:<p>
+
+<dd><a href="gradcomdsetgxout.html"><code>set gxout</a> model</code><p>
+
+The appropriate display command is:<p>
+
+<dd><code>display u;v;t;d;slp;delta;cld;wx;vis</code><p>
+
+where:<p>
+
+<ul><code>u</code> and <code>v</code> are the wind components.  A wind barb will
+be drawn using
+these values.  If either is missing, the station model will not
+be plotted at all. <p>
+<code>t, d, slp</code>, and <code>delta</code> are plotted numerically
+around the station model<p>
+
+<code>cld</code> is the value of the symbol desired at the center of the
+station model.  Values <code>1</code> to <code>9</code> are assumed to be the
+marker types
+(ie, circle, square, crosshair, etc). Values <code>20</code> to <code>25</code> 
+are assumed
+to be cloudiness values:<br>
+<ul><br>
+<code>20</code>  -clear <br>
+<code>21</code>  -scattered 
+<code>22</code>  -broken <br>
+<code>23</code>  -overcast <br>
+<code>24</code>  -obscured <br>
+<code>25</code>  -missing (M plotted)</ul><p>
+<code>wx</code> is the
+value
+of the <code>wx</code> symbol (see <a
+href="gradcomddrawwxsym.html"><code>draw wxsym</code></a>) to be plotted
+in the <code>wx</code> location. <p>
+<code>vis</code> is the visibility as a real number.  It will be
+plotted as a whole number and a fraction.</ul><p>
+
+When any of these items are missing (other than <code>u</code> and
+<code>v</code>), the
+model is plotted without that element. To represent a globally
+missing value, enter a constant in the <code>display</code> command.  For
+example, if the <code>delta</code> were always missing, use:<p>
+
+<dd><code>display u;v;t;d;slp;0.0;cld</code><p>
+
+The station models respond to the usual set commands such as 
+<a href="gradcomdsetdigsize.html"><code>set digsiz</code></a>, <a
+href="gradcomdsetdignum.html"><code>set dignum</code></a>, <a
+href="gradcomdsetcthick.html"><code>set cthick</code></a>, <a
+href="gradcomdsetccolor.html"><code>set ccolor</code></a>.<p>
+
+In addition, there is:<p>
+
+<dd><code>set stnopts <dig3> <nodig3></code><p>
+
+which will cause the model to plot the number in the slp location
+as a three digit number, with only the <i>last</i> three digits of the
+whole number plotted.  This allows the  standard 3 digit sea
+level pressure to be plotted by enabling <code>dig3</code> and plotting
+slp*10.
+
+<p>
+<h2><a name="xsection">Drawing Arbitrary Cross Sections</a></h2>
+<p>
+Drawing arbitrary vertical cross sections based on a collection of
+station data profiles involves transforming station data (scattered
+observations) into gridded data so as to take advantage of the GrADS
+grid display and analysis features.
+
+<p>
+The first step is to form a collection of 1-D data (Z or T
+varying). The <a href="gradcomdcollect.html"><code>collect</code></a>
+command saves station data profiles or time series in memory as a
+set. The 1-D data may be either real station data or
+gridded data converted to station data using 
+<a href="gradfuncgr2stn.html"><code>gr2stn</code></a>. 
+
+<p> 
+The second stop is to convert the collection of station data into
+a grid for display or analysis purposes. This is accomplished by
+the new function <a href="gradfunccoll2gr.html"><code>coll2gr</code></a>. 
+ 
+
+<p>
+<a href="gradfunccoll2gr.html"><code>coll2gr</code></a> does not yet
+support time slices; currently, it will only work when the collection
+of stations is a collection of vertical profiles.
+
+<p>
+<a href="gradfunccoll2gr.html"><code>coll2gr</code></a> produces an
+output grid that varies in X and Z; the dimension environment used
+when <a href="gradfunccoll2gr.html"><code>coll2gr</code></a> is
+invoked must also be X and Z varying. The X axis of the output grid
+will contain the equally spaced station profiles and will span the
+range of the current X dimension environment. The Z axis of the output
+grid will span the range of the current Z dimension environment and
+will have either the specified number of levels or a union of the
+levels. Data points outside of the range of levels will be used for
+interpolating to within the range if appropriate.
+
+<p>
+The X axis of the output grid from <a
+href="gradfunccoll2gr.html"><code>coll2gr</code></a> is artificial in
+terms of the world coordinates -- it doesn't really represent
+longitudes. A way to completely control the labelling of the display
+output is provided:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetxlabs.html">set xlabs</a> lab1 | lab2 | lab3 ...<br>
+<a href="gradcomdsetylabs.html">set ylabs</a> lab1 | lab2 | lab3 ...<br>
+</code>
+</ul>
+
+<p>
+Each label string may include blanks. The labels will be plotted
+equally spaced along the indicated axis. Spacing can be
+modified by adding blank strings:
+<p>
+<ul>
+<code><a href="gradcomdsetxlabs.html">set xlabs</a> | | | | lab1 | ...<br>
+</code>
+</ul>
+
+<p>
+Here is a sample script written by M. Fiorino that uses these features:
+<p>
+<code>
+*********************************************************************<br>
+* The following lines will display an arbitrary X section<br>
+* from one specified point to another.  <br>
+*<br>
+* lon1 is the westernmost longitude point<br>
+* lon2 is the easternmost longitude point<br>
+* lat1 is the latitude that corresponds to lon1<br>
+* lat2 is the latitude that corresponds to lon2<br>
+*<br>
+* The loop is used to interpolate between points in<br>
+* the arbitrary cross section.  This code will plot<br>
+* any cross section as long as you specify the points. <br> 
+* My code plots cross sections of PV after I calculated<br>
+* PV on 11 pressure surfaces.  I have another script<br>
+* that plots cross sections of potential temperature, and<br>
+* the code is very similar to this, except theta is substituted<br>
+* for PV.<br>
+*<br>
+* Many thanks to Brian Doty at COLA for his help with this code.<br>
+*<br>
+********************************************************************<br>
+<br>
+'open pv.ctl'<br>
+'set grads off'<br>
+'set zlog on'<br>
+'set x 1'<br>
+'set y 1'<br>
+'set lev 1000 100'<br>
+lon1 = -95.0<br>
+lon2 = -90.0<br>
+lat1 =  55.0<br>
+lat2 =  15.0<br>
+lon = lon1<br>
+'collect 1 free'<br>
+while (lon <= lon2)<br>
+  lat = lat1 + (lat2-lat1)*(lon-lon1) / (lon2-lon1)<br>
+  'collect 1 gr2stn(pv,'lon','lat')'<br>
+  lon = lon + 1<br>
+endwhile<br>
+<br>
+'set x 14 16'<br>
+'set xaxis 'lon1' 'lon2<br>
+'set clab on'<br>
+'set gxout shaded'<br>
+'set clevs 0 .5 15'<br>
+'set ccols 0 0 7 0'<br>
+'d coll2gr(1,-u)'<br>
+'set gxout contour' <br>
+'set cint .5'<br>
+'d coll2gr(1,-u)'<br>
+</code>
+
+</body>
+</html>
+
diff --git a/doc/utilities.html b/doc/utilities.html
new file mode 100644
index 0000000..f112236
--- /dev/null
+++ b/doc/utilities.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<body>

<h1>External Utilities</h1>
<ul>
  <p><a href="gradutilbufrscan.html">bufrscan</a><br>
      <a href="gradutilgribmap.html">gribmap</a><br>
      <a href="gradutilgribscan.html">gribscan</a><br>
      <a href="gradutilgrib2scan.html">grib2scan</a><br>
      <a href="gradutilgxeps.html">gxeps</a><br>
      <a href="gradutilgxps.html">gxps</a><br>
      <a href="gradutilgxtran.html">gxtran</a><br>
      <a href="gradutilstnmap.html">stnmap</a><br>
  </p>
</ul>
 
</body>
</html>

\ No newline at end of file
diff --git a/doc/variable.html b/doc/variable.html
new file mode 100644
index 0000000..d01b715
--- /dev/null
+++ b/doc/variable.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.--><style type="text/css">
<!--
body {
	background-color: #e0f0ff;
}
.style2 {color: #990000}
-->
</style>

<h1>Grads Variables</h1>
<ul>
<a href=variable.html#names>Variable Names</a><br>
<a href=variable.html#new>Defining New Variables</a><br>
<a href=variable.html#undefine>Undefining Variables</a><br>
</ul>
<p>
<h2><a name="names">Variable names</a></h2>
The complete specification for a variable name is:

<ul>
  <p><code>abbrev.file#(dimexpr,dimexpr,...)</code>    where: </p>

  <ul>
    <code>abbrev   </code>is the abbreviation for the variable as
    specified in the
    data descriptor file
    <br />
    <code>file#    </code>is the file number that contains
      this variable.  If <code>file#</code> is absent, GrADS assumes the default file number. <br />
      <code>dimexpr  </code>is a dimension expression that locally
      modifies the current dimension environment.
</ul>
</ul>
<p>

The <code>dimexpr</code> is used to override or modify the current dimension environment only for the <code>abbrev</code> variable. Only fixed dimensions can be
modified with a <code>dimexpr</code>. The <code>dimexpr</code> can be given in grid or world coordinates. <b>An important note:</b> When you specify a dimension in grid units,
GrADS always converts it to world coordinates.  In general, this conversion
is done using the scaling of the <i>default file</i>. The only exception to this rule is in this case, when  a
grid coordinate (x, y, z, t, or e) is supplied within a <code>dimexpr</code> as part of a variable specification. In the case of this special exception, the conversion is done using the scaling for
 the file that variable is to be taken from (i.e., file number <code>file#</code>).
<p>An absolute <code>dimexpr</code> uses the "=" operator to override the currently set dimension value:

<br />
<code>  x|y|z|t|e|lon|lat|lev|time|ens = value</code>
<br />
Examples of absolute dimension expressions are:<code> x=1, lat=-10, lev=500, t=1, time=02feb1982, e=1, ens=spr</code>
<p>A relative <code>dimexpr</code> uses the "+" or "-" operators to modify the currently set dimension value with an offset: <br />
<code>   x|y|z|t|e|lon|lat|lev|time|ens +/- offset<br />
</code>

Examples of relative dimension expressions are:<code> x+1, lat+30, y-3, t+0, time+12hr</code>
<p>Starting with <span class="style2">GrADS version 2.0.a7</span>, a third option is available, a  <code>dimexpr</code> that specifies an offset
  from the variable's initial time: <br />
  <code>   offt =/+/- offset<br />
  </code> Examples of absolute offset dimension expressions are:<code> offt=0, offt+4, offt-1</code> <br />
  Please consult the section on <a href="offt.html">evaluating expressions that contain the <code>offt</code> dimension override</a> for additional information. <br />
<p>The following sets of commands will yeild the same result, which is to display the 2nd time step of a variable "ps": <br />
  <code>
  'set t 2'; 'd ps'<br />
  'set t 1'; 'd ps(t+1)'<br />
  'set t 1'; 'd ps(t=2)'<br />
  'set t 1'; 'd ps(offt=1)'<br />
  'set t 1'; 'd ps(offt+0)'<br />
    </code>Note that an offset of 0 returns the 1st time step, an offset of 1 returns the 2nd time step, etc. 
<p>Using a <code>dimexpr</code> that contains <code>offt</code> is especially handy when your data set has multiple <a href="ensembles.html">ensemble members</a>, and the start time for individual members is not the same. In that case, an expression like:<br /> 
  <code>  'set t 1'; 'set e 1 last'; 'd ps(offt=0)'</code> <br />
  will give you the first time step of all ensemble members, which may occur at different time steps in the file. 
  
  
<p>Examples of complete variable specifications are:
<ul>
<code>z.3(lev=500)</code>         
File 3, absolute dimension 
expression<br>
<code>tv.1(time-12hr)</code>    Relative dimension expression<br>
<code>rh</code>                             
Default file number is used <br>
<code>q.2(t-1,lev=850)</code>  Two dimension expressions <br>
<code>z(t+0)</code>                     
This does have uses....</ul>
<p>

GrADS has a few "<b>predefined</b>" variable names.  You can think of
these as being variables implicitly contained within any opened
gridded file.  The variable names are:


<ul>
<code>lat <br>
lon <br>
lev</code></ul><p>

When used, they will contain the <code>lat</code>, <code>lon</code>, and
<code>lev</code> at the
respective grid points, using the scaling of the appropriate
file.  You can specify:  <code>lat.2</code>  for example, to get latitudes on
the grid of the 2nd opened data set.


<p>
<h2><a name="new">Defining new variables</a></h2>

<p>
The <a href="gradcomddefine.html"><code>define</code></a> command
allows you to interactively create a new variable. The syntax is:<p>

<ul><code>define varname = <i>expression</i></code></ul>

<p>
The new variable can then be used in subsequent <a
href="gradcomddefine.html"><code>define</code></a> and/or <a
href="gradcomddisplay.html"><code>display</code></a> commands. The new
variable is stored in memory, not on disk, so avoid defining variables
over large dimension ranges.

<p>
Defined variables cover the dimension ranges in effect
at the time the command is issued. You may define a variable that
has from 0 to 4 varying dimensions.  The <a
href="gradcomddefine.html"><code>define</code></a> command is the
only case within GrADS where four varying dimensions is valid.

<p>
When <code>Z</code> and/or <code>T</code> are varying dimensions, the
<a href="gradcomddefine.html"><code>define</code></a> command
evaluates the expression by stepping through <code>Z</code> and <code>T</code>.
In other words, the expression is evaluated within a dimension environment
that has fixed <code>Z</code> and <code>T</code>.  This will affect how you
compose the expression.

<p>
When you use a defined variable, data is taken from the variable in a
way similar to data taken from a GrADS data file.  For example, say
you define a four dimensional variable:<p>

<ul>
<code>
set lon -180 0 <br>
set lat 0 90 <br>
set lev 1000 100 <br>
set t 1 10 <br>
define temp = rh<br>
</code>
</ul>

<p>
After issuing the <a href="gradcomddefine.html"><code>define</code></a> 
command, remember to change the dimension environment so less than 4
dimensions are varying!<p>

<ul>
<code>
set t 5 <br>
set lev 500 <br>
d temp
</code>
</ul>

<p>
The display of the defined variable will display a 2-D slice
taken at time 5 and level 500.

<p>
If you define a variable that has fixed dimensions, and then
later access this variable, the fixed dimensions are treated as
"wild cards".  The best way to show this is with an example:

<ul>
<code>
set lon -180 0 <br>
set lat 0 90 <br>
set lev 500 <br>
set t 10 <br>
define zave = ave(z,t=1,t=30)<br>
</code>
</ul>

<p>
The defined variable has two varying dimensions.  If we now
display this variable (or use it in an expression), the fixed
dimensions of the defined variable, namely <code>Z</code> and <code>T</code>,
will match
ANY <code>Z</code> and <code>T</code> dimension setting:<p>

<ul>
<code>
set t 1 <br>
set lev 200 <br>
d zave<br>
</code>
</ul>

<p>
In the above display, the variable <code>zave</code> would be displayed as it
was defined, ie you would get a time average of 500mb heights,
even though the level is set to 850.

<p>
When the defined variable has varying dimensions, and you have a
dimension environment where that dimension is fixed, the proper
dimension will be retrieved from the variable:

<ul>
<code>
set lon -180 0 <br>
set lat 0 90 <br>
set lev 500 <br>
set t 10 <br>
define temp = z<br>
set lat 40 <br>
d temp<br>
</code>
</ul>

<p>
In the above example, the defined variable has a varying Y
dimension. We then fix the Y dimension to be 40N, and display a
1-D slice.  The data from 40N in the defined grid will be
accessed.  If you then did:

<ul>
<code>
set lat -40 <br>
d temp<br>
</code>
</ul>

<p>
The data from 40S would be accessed from the defined variable. 
Since this is beyond the dimensions originally used when the
variable was defined, the data would be set to missing.

<p>
You can also locally override the dimension environment:

<ul><code>d temp(lat=50)</code></ul>

<p>
If that dimension is a varying dimension within the defined
variable.  If the dimension is a fixed dimension for that
variable, the local override will be ignored:

<ul><code>d temp(t=15)</code></ul>

<p>
In the above command, the defined variable temp has fixed T, so
the t=15 would be ignored.

<p>
N.B.: The <code>define</code> command currently supports only grids.

<p>
Once you have defined a grid variables, you may tell GrADS that
the new variable is climatological, ie that you wish to treat the
time dimension of the new variable in a wild card sense.

<p>
The command is:<p>

<ul>
<code>
<a href="gradcomdmodify.html">modify</a> varname  <<i>seasonal/diurnal</i>><br>
</code>
</ul>

<p>
where <code>varname</code> is the name of a defined variable.  If the
grid is described as <code>seasonal</code>, then it is assumed that
the defined variable contains monthly (or multi month) means. Daily or
multi-day means are not yet supported.  If <code>diurnal</code> is
specified, it is assumed the defined variable contains means over some
time period less than a day.

<p>
After describing the defined variable as climatological, then the
date/times are treated appropriately when data is accessed from
the defined variable.

<p>
In the following example, the data set contains 10 years of monthly means:<p>

<ul>
<code>
set lon -180 180 <br>
set lat -90 90 <br>
set lev 500 <br>
set t 1 12 <br>
define zave = ave(z,t+0,t=120,1yr)</code></ul>

<p>
This define will set up a variable called <code>zave</code> which
contains 12 times, each time being the 10 year mean for that month. We
are making use here of the fact that the define command loops through
a varying time dimension when evaluating the expression, and within
the <a href="gradfuncave.html"><code>ave</code></a> function we are
making use of the variable time offset of t+0, which uses a start time
that is whatever time the <a
href="gradcomddefine.html"><code>define</code></a> command is using as
it loops.

<ul>
<code>
modify zave seasonal <br>
set t 120 <br>
d z - zave</code></ul>

<p>
The final display will remove the 10 year monthly mean for
December from the last December in the data set.

<p>
<h2><a name="undefine">Undefining variables</a></h2>

<p>
Each variable defined using the <a
href="gradcomddefine.html"><code>define</code></a> command reserves
some system resources.  If you no longer need a defined variable it is
sensible to free these resources for other use.  This is accomplished
with the <a href="gradcomdundefine.html"><code>undefine</code></a>
command. For example:

<ul><code>undefine p</code></ul>

<p>
would free the resources used by the defined variable <code>p</code>.  Of
course, the variable <code>p</code> would no longer be available for GrADS
processing.

</body>
</html>


\ No newline at end of file
diff --git a/doc/variableformats.html b/doc/variableformats.html
new file mode 100644
index 0000000..b313ceb
--- /dev/null
+++ b/doc/variableformats.html
@@ -0,0 +1 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->

<html>
<head>
<title>GrADS Variable Formats</title>
<style type="text/css">
<!--
.style1 {
	color: #990000;
	font-style: italic;
}
-->
</style>
</head>
<body bgcolor="e0f0ff" text="#000000">

<h2>Variable Formats and Binary Data File Structure</h2>
<p>
This section describes how to refine the variable declarations in the
data descriptor file to accurately reflect the structure and format of
each variable in a binary file. Before continuing, it is recommended 
that you review the material in these other sections:
<ul>
<li><a href="aboutgriddeddata.html">About GrADS Gridded Data Sets</a>
<li><a href="descriptorfile.html">Elements of a GrADS Data Descriptor File</a>
</ul>

<p>
In a GrADS data descriptor file each variable declaration record
has the following syntax:
<p>
<ul><code><i>varname levs units description</i></code></ul>

<p>
The <a href="descriptorfile.html#VARS">VARS</a> section of <a
href="descriptorfile.html">Elements of a GrADS Data Descriptor
File</a> explains the general syntax of the variable declaration
record. This section goes into further detail on the use of the
<code><i>units</i></code> keyword to invoke some special features that
allow GrADS to read binary files that do not conform to the default
structure.

<p>
The structure of a 3-D or 4-D data set is determined by the order in
which the horizonal grids are written to file. The default sequence
goes in the following order starting from the fastest varying
dimension to the slowest varying dimension: longitude (X), latitude
(Y), vertical level (Z), variable (VAR), time (T). 

<p>
If your binary data set was created or "packed" according to a
different dimension sequence, then you can use the
<code><i>units</i></code> keyword to tell GrADS exactly how to unpack
the data. The <code><i>units</i></code> keyword is actually a series
of one or more comma-delimited numbers. If <code><i>units</i></code>
is set to <code>99</code> then all the features for unpacking special
data formats are ignored. If <code><i>units</i></code> is set to
<code>-1</code>, then the features are invoked via additional
parameters that follow the <code>-1</code> and are separated by
commas:
<p>
<ul><code><i>units</i> = -1, <i>structure</i> <,arg></i></code></ul>

<p>
There are four options for <code><i>structure</i></code>, outlined
below.  Some of these options have additional attributes which are
specified with <code><i>arg</i></code>.

<p>
<ol>
<li><code><i>units</i> = -1,10,1</code>
<p>
<span class="style1">This option was removed in GrADS version 2.0. </span>This option indicates that "VAR" and "Z" have been transposed in the
dimension sequence. The order is: longitude (X), latitude (Y),
variable (VAR), vertical level (Z), time(T). Thus, all variables are
written out one level at a time. 
<p>
This feature was designed to be used with NASA GCM data in the
"phoenix" format. The upper air <i>prognostic</i> variables were
transposed, but the <i>diagnostic</i> variables were not. Thus an
<code><i>arg</i></code> of <code>1</code> means the variable has been
var-z transposed, and an <code><i>arg</i></code> of <code>2</code>
means the variable has not.
<p class="style1">
<li><code><i>units</i> = -1,20</code>
<p>
This option indicates that "VAR" and "T" have been transposed in the
dimension sequence. The order is: longitude (X), latitude (Y),
vertical level (Z), time(T), variable (VAR). Thus, all times for one
variable are written out in order followed by all times for the next
variable, etc.
<p>
Suppose your data set is actually a collection of separate files that
are aggregated by using a <a href="templates.html">template</a>. Then
you must use an additional argument to tell GrADS how many time steps
are contained in each individual file. Use <code><i>arg</i></code> to
tell GrADS the size of the time dimension in each individual file. For
example, here are the relevant records from a descriptor file for 10
years of monthly wind component and temperature data packaged with
"VAR" and "T" dimensions transposed:
<p>
<ul>
<pre>
DSET ^monthlydata_%y4.dat
OPTIONS template
...
TDEF 120 linear jan79 1mo 
VARS 3 <br>
  u 18 -1,20,12 u component
  v 18 -1,20,12 v component 
  t 18 -1,20,12 temperature 
ENDVARS
</pre>
</ul>

<p>
<li><code><i>units</i> = -1,30</code>
<p>
<span class="style1">This option was removed in GrADS version 2.0. </span>This option handles the cruel and unusual case where X and Y
dimensions are transposed and the horizontal grids are (lat,lon) as
opposed to (lon,lat) data. This option causes GrADS to work very
inefficiently because it wasn't worth it to make a big change to GrADS
internal I/O to handle this type of pathological data.  However, it is
useful for initial inspection and debugging and that's basically what
it is designed for.
<p>
<li><code><i>units</i> = -1,40</code>
<p>
This option handles non-float data. Data are converted to floats
internally after they are read from the binary file. The dimension
sequence is assumed to be the default. The secondary <code><i>arg</i></code>
tells GrADS what type of data values are in the binary file:
<p>
<ul>
<code><i>units</i> = -1,40,1    </code>
= 1-byte unsigned chars (0-255) <br>
<code><i>units</i> = -1,40,2    </code>
= 2-byte unsigned integers<br>
<code><i>units</i> = -1,40,-2   </code>
= 2-byte signed integers<br>
<code><i>units</i> = -1,40,4    </code>
= 4-byte integers<br>
</ul>
</ol>

</body>
</html>
\ No newline at end of file
diff --git a/doc/wrf.ncdump b/doc/wrf.ncdump
new file mode 100644
index 0000000..c4ab9f7
--- /dev/null
+++ b/doc/wrf.ncdump
@@ -0,0 +1,90 @@
+netcdf wrf_sample.nc {
+dimensions:
+	Time = UNLIMITED ; // (2 currently)
+	south_north = 249 ;
+	west_east = 249 ;
+	bottom_top = 25 ;
+variables:
+	float T(Time, bottom_top, south_north, west_east) ;
+		T:FieldType = 104 ;
+		T:MemoryOrder = "XYZ" ;
+		T:description = "perturbation potential temperature (theta-t0)" ;
+		T:units = "K" ;
+		T:stagger = "" ;
+	float P(Time, bottom_top, south_north, west_east) ;
+		P:FieldType = 104 ;
+		P:MemoryOrder = "XYZ" ;
+		P:description = "pressure" ;
+		P:units = "pascals" ;
+		P:stagger = "" ;
+	float T2(Time, south_north, west_east) ;
+		T2:FieldType = 104 ;
+		T2:MemoryOrder = "XY " ;
+		T2:description = "TEMP at 2 M" ;
+		T2:units = "K" ;
+		T2:stagger = "" ;
+	float HGT(Time, south_north, west_east) ;
+		HGT:FieldType = 104 ;
+		HGT:MemoryOrder = "XY " ;
+		HGT:description = "Terrain Height" ;
+		HGT:units = "m" ;
+		HGT:stagger = "" ;
+	float XLAT(Time, south_north, west_east) ;
+		XLAT:FieldType = 104 ;
+		XLAT:MemoryOrder = "XY " ;
+		XLAT:description = "LATITUDE, SOUTH IS NEGATIVE" ;
+		XLAT:units = "degree" ;
+		XLAT:stagger = "" ;
+	float XLONG(Time, south_north, west_east) ;
+		XLONG:FieldType = 104 ;
+		XLONG:MemoryOrder = "XY " ;
+		XLONG:description = "LONGITUDE, WEST IS NEGATIVE" ;
+		XLONG:units = "degree" ;
+		XLONG:stagger = "" ;
+
+// global attributes:
+		:TITLE = " OUTPUT FROM WRF V1.3 MODEL" ;
+		:START_DATE = "2002-06-11_00:00:00" ;
+		:WEST-EAST_GRID_DIMENSION = 250 ;
+		:SOUTH-NORTH_GRID_DIMENSION = 250 ;
+		:BOTTOM-TOP_GRID_DIMENSION = 25 ;
+		:DYN_OPT = 2 ;
+		:DIFF_OPT = 0 ;
+		:KM_OPT = 1 ;
+		:DAMP_OPT = 0 ;
+		:KHDIF = 0.f ;
+		:KVDIF = 0.f ;
+		:MP_PHYSICS = 3 ;
+		:RA_LW_PHYSICS = 1 ;
+		:RA_SW_PHYSICS = 1 ;
+		:BL_SFCLAY_PHYSICS = 1 ;
+		:BL_SURFACE_PHYSICS = 1 ;
+		:BL_PBL_PHYSICS = 1 ;
+		:CU_PHYSICS = 1 ;
+		:WEST-EAST_PATCH_START_UNSTAG = 1 ;
+		:WEST-EAST_PATCH_END_UNSTAG = 249 ;
+		:WEST-EAST_PATCH_START_STAG = 1 ;
+		:WEST-EAST_PATCH_END_STAG = 250 ;
+		:SOUTH-NORTH_PATCH_START_UNSTAG = 1 ;
+		:SOUTH-NORTH_PATCH_END_UNSTAG = 249 ;
+		:SOUTH-NORTH_PATCH_START_STAG = 1 ;
+		:SOUTH-NORTH_PATCH_END_STAG = 250 ;
+		:BOTTOM-TOP_PATCH_START_UNSTAG = 1 ;
+		:BOTTOM-TOP_PATCH_END_UNSTAG = 25 ;
+		:BOTTOM-TOP_PATCH_START_STAG = 1 ;
+		:BOTTOM-TOP_PATCH_END_STAG = 26 ;
+		:DX = 8000.f ;
+		:DY = 8000.f ;
+		:DT = 48.f ;
+		:CEN_LAT = 36.299995f ;
+		:CEN_LON = -116.f ;
+		:TRUELAT1 = 36.299999f ;
+		:TRUELAT2 = 36.299999f ;
+		:GMT = 0.f ;
+		:JULYR = 2002 ;
+		:JULDAY = 162 ;
+		:ISWATER = 16 ;
+		:MAP_PROJ = 1 ;
+		:MMINLU = "USGS" ;
+
+}
diff --git a/doc/wrfgrid.ctl b/doc/wrfgrid.ctl
new file mode 100644
index 0000000..a04e6d1
--- /dev/null
+++ b/doc/wrfgrid.ctl
@@ -0,0 +1,12 @@
+dset ^wrf_sample.nc
+dtype netcdf
+undef -888
+TITLE WRF Output Grid Coordinates: south_north, west_east
+xdef 249 linear 1 1
+ydef 249 linear 1 1
+zdef 1 linear 1 1
+tdef 2 linear 11jun2002 3hr
+vars 2
+XLONG=>glon  0  t,y,x    grid longitude 
+XLAT=>glat   0  t,y,x    grid latitude
+endvars
diff --git a/doc/wrfvars.ctl b/doc/wrfvars.ctl
new file mode 100644
index 0000000..318457b
--- /dev/null
+++ b/doc/wrfvars.ctl
@@ -0,0 +1,15 @@
+dset ^wrf_sample.nc
+dtype netcdf
+undef -888
+TITLE WRF Output Grid: Time, bottom_top, south_north, west_east
+pdef 249 249 lcc 26.9628 -125.898 1 1 36.2999 36.2999 -116.0 8000 8000
+xdef 270 linear -129 0.1
+ydef 200 linear   26 0.1
+zdef  25 linear 1 1
+tdef   2 linear 11jun2002 3hr
+vars 4
+P=>p      25  t,z,y,x  Pressure
+T=>t      25  t,z,y,x  perturbation potential temperature (theta-t0)
+HGT=>hgt   0  t,y,x    terrain height
+T2=>t2     0  t,y,x    temperature at 2m
+endvars
diff --git a/doc/xdfsample1.txt b/doc/xdfsample1.txt
new file mode 100644
index 0000000..68906ee
--- /dev/null
+++ b/doc/xdfsample1.txt
@@ -0,0 +1,36 @@
+netcdf moisture {
+
+dimensions:
+    dimension1 = 144 ;
+    dimension2 = 73 ; 
+    dimension3 = UNLIMITED ; // Currently 365
+
+variables:
+    float Moisture(dimension3, dimension2, dimension1) ; 
+
+data:
+  
+ dimension1 = 0, 2.5, 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 
+    35, 37.5, 40, 42.5, 45, 47.5, 50, 52.5, 55, 57.5, 60, 62.5, 65, 67.5, 70, 
+    72.5, 75, 77.5, 80, 82.5, 85, 87.5, 90, 92.5, 95, 97.5, 100, 102.5, 105, 
+    107.5, 110, 112.5, 115, 117.5, 120, 122.5, 125, 127.5, 130, 132.5, 135, 
+    137.5, 140, 142.5, 145, 147.5, 150, 152.5, 155, 157.5, 160, 162.5, 165, 
+    167.5, 170, 172.5, 175, 177.5, 180, 182.5, 185, 187.5, 190, 192.5, 195, 
+    197.5, 200, 202.5, 205, 207.5, 210, 212.5, 215, 217.5, 220, 222.5, 225, 
+    227.5, 230, 232.5, 235, 237.5, 240, 242.5, 245, 247.5, 250, 252.5, 255, 
+    257.5, 260, 262.5, 265, 267.5, 270, 272.5, 275, 277.5, 280, 282.5, 285, 
+    287.5, 290, 292.5, 295, 297.5, 300, 302.5, 305, 307.5, 310, 312.5, 315, 
+    317.5, 320, 322.5, 325, 327.5, 330, 332.5, 335, 337.5, 340, 342.5, 345, 
+    347.5, 350, 352.5, 355, 357.5 ;
+
+ dimension2  = 90, 87.5, 85, 82.5, 80, 77.5, 75, 72.5, 70, 67.5, 65, 62.5, 60, 
+    57.5, 55, 52.5, 50, 47.5, 45, 42.5, 40, 37.5, 35, 32.5, 30, 27.5, 25, 22.5, 
+    20, 17.5, 15, 12.5, 10, 7.5, 5, 2.5, 0, -2.5, -5, -7.5, -10, -12.5, -15, 
+    -17.5, -20, -22.5, -25, -27.5, -30, -32.5, -35, -37.5, -40, -42.5, -45, 
+    -47.5, -50, -52.5, -55, -57.5, -60, -62.5, -65, -67.5, -70, -72.5, -75, 
+    -77.5, -80, -82.5, -85, -87.5, -90 ;
+
+ dimension3 = 1, 2, 3, ... , 364, 365 ;  // some number  omitted for brevity
+
+}
+ 
\ No newline at end of file
diff --git a/doc/xdfsample2.txt b/doc/xdfsample2.txt
new file mode 100644
index 0000000..3eab58e
--- /dev/null
+++ b/doc/xdfsample2.txt
@@ -0,0 +1,80 @@
+netcdf DAOE054A.hdf {
+dimensions:
+        TIME4DIMS:DAOgrid = 4 ; // TDEF_dimension_name = TDEF_count
+        HGHT1DIMS:DAOgrid = 1 ;
+        YDim:DAOgrid = 91 ; // YDEF_dimension_name = YDEF_count
+        XDim:DAOgrid = 144 ; // XDEF_dimension_name = XDEF_count
+        TIME8DIMS:DAOgrid = 8 ;
+        HGHT18DIMS:DAOgrid = 18 ; // ZDEF_dimension_name = ZDEF_count
+
+variables:
+// float internal_variable_name(dimlist) ;  VARS_count is 3
+        float GEOPOTENTIAL_HEIGHT(TIME4DIMS:DAOgrid, HGHT18DIMS:DAOgrid,
+                                  YDim:DAOgrid, XDim:DAOgrid) ;
+        float SPECIFICHUMIDITY(TIME4DIMS:DAOgrid, HGHT18DIMS:DAOgrid,
+                               YDim:DAOgrid, XDim:DAOgrid) ;
+        float TEMPERATURE(TIME4DIMS:DAOgrid, HGHT18DIMS:DAOgrid, YDim:DAOgrid,
+                          XDim:DAOgrid) ;
+
+// global attributes:
+                :coremetadata.0 = "\n",
+    "    /*  This attribute contains a duplicate of the Collection- */\n",
+    "    /*  level EastBoundingCoordinate value. */\n",
+    "    OBJECT                 = EASTBOUNDINGCOORDINATE\n",
+    "      NUM_VAL              = 1\n",
+// XDEF_step value = (Final_XDEF_value - First_XDEF_value)/(XDEF_count - 1)
+// (assumes equal spacing)  (177.5 - (-180))/143) => 2.5
+    "      VALUE                = 177.500000\n",      // Final_XDEF_value
+    "    END_OBJECT             = EASTBOUNDINGCOORDINATE\n",
+    "    /*  This attribute contains a duplicate of the Collection- */\n",
+    "    /*  level WestBoundingCoordinate value. */\n",
+    "    OBJECT                 = WESTBOUNDINGCOORDINATE\n",
+    "      NUM_VAL              = 1\n",
+    "      VALUE                = -180.000000\n",       // First_XDEF_value
+    "    END_OBJECT             = WESTBOUNDINGCOORDINATE\n",
+    "    /*  This attribute contains a duplicate of the Collection- */\n",
+    "    /*  level NorthBoundingCoordinate value. */\n",
+    "    OBJECT                 = NORTHBOUNDINGCOORDINATE\n",
+    "      NUM_VAL              = 1\n",
+// YDEF_step = range/(YDEF_count-1) (equal spacing assumed) (90 - (-90))/90=>2
+// (one of the 91 is 0, the equator)
+    "      VALUE                = 90.000000\n",          // Final_YDEF_value
+    "    END_OBJECT             = NORTHBOUNDINGCOORDINATE\n",
+    "    /*  This attribute contains a duplicate of the Collection- */\n",
+    "    /*  level SouthBoundingCoordinate value. */\n",
+    "    OBJECT                 = SOUTHBOUNDINGCOORDINATE\n",
+    "      NUM_VAL              = 1\n",
+    "      VALUE                = -90.000000\n",         // First_YDEF_value
+    "    END_OBJECT             = SOUTHBOUNDINGCOORDINATE\n",
+    "  END_GROUP              = BOUNDINGRECTANGLE\n",
+    "  /*  The RangeDateTime attribute values will be set at DME */\n",
+    "  /*  runtime by retrieval the granule time from the data set. */\n",
+    "  /*  The starting date of the DAO granule */\n",
+    "  GROUP                  = RANGEDATETIME\n",
+    "    /* Format of RangeBeginningDate is YYYY-MM-DD or YYYY-DDD */\n",
+    "    OBJECT                 = RANGEBEGINNINGDATE\n",
+    "      NUM_VAL              = 1\n",
+// First_TDEF_value(YYYY-DDD)
+    "      VALUE                = \"1993-181\"\n",
+    "    END_OBJECT             = RANGEBEGINNINGDATE\n",
+    "    /* Format of RangeBeginningTime is HH:MM:SS.SSSS... */\n",
+    "    OBJECT                 = RANGEBEGINNINGTIME\n",
+    "      NUM_VAL              = 1\n",
+// First_TDEF_value (HMS)
+    "      VALUE                = \"00:00:00.000000\"\n",
+    "    END_OBJECT             = RANGEBEGINNINGTIME\n",
+    "    /* Format of RangeEndingDate is YYYY-MM-DD or YYYY-DDD */\n",
+    "    OBJECT                 = RANGEENDINGDATE\n",
+    "      NUM_VAL              = 1\n",
+// TDEF_step = range/TDEF_count (equal spacing assumed) (1 day/4 => 6hr step)
+// Final_TDEF_value (YYYY-DDD)
+    "      VALUE                = \"1993-181\"\n",
+    "    END_OBJECT             = RANGEENDINGDATE\n",
+    "    /* Format of RangeEndingTime is HH:MM:SS.SSSS... */\n",
+    "    OBJECT                 = RANGEENDINGTIME\n",
+    "      NUM_VAL              = 1\n",
+// Final_TDEF_value (HMS) (round up)
+    "      VALUE                = \"23:59:59.999999\"\n",
+    "    END_OBJECT             = RANGEENDINGTIME\n",
+    "  END_GROUP              = RANGEDATETIME\n",
+}
\ No newline at end of file
diff --git a/doc/xsections.html b/doc/xsections.html
new file mode 100644
index 0000000..da0d030
--- /dev/null
+++ b/doc/xsections.html
@@ -0,0 +1,130 @@
+<!--Copyright (C) 1988-2005 by the Institute of Global Environment and Society (IGES). See file COPYRIGHT for more information.-->
+
+<html>
+<head>
+<title>Cross Sections</title>
+</head>
+<body text="#000000" bgcolor="e0f0ff">
+
+<h2>Drawing Arbitrary Cross Sections</h2>
+<p>
+Drawing arbitrary vertical cross sections based on a collection of
+station data profiles involves transforming station data (scattered
+observations) into gridded data so as to take advantage of the GrADS
+grid display and analysis features.
+
+<p>
+The first step is to form a collection of 1-D data (Z or T
+varying). The <a href="gradcomdcollect.html"><code>collect</code></a>
+command saves station data profiles or time series in memory as a
+set. The 1-D data may be either real station data or
+gridded data converted to station data using 
+<a href="gradfuncgr2stn.html"><code>gr2stn</code></a>. 
+
+<p> 
+The second stop is to convert the collection of station data into
+a grid for display or analysis purposes. This is accomplished by
+the new function <a href="gradfunccoll2gr.html"><code>coll2gr</code></a>. 
+ 
+
+<p>
+<a href="gradfunccoll2gr.html"><code>coll2gr</code></a> does not yet
+support time slices; currently, it will only work when the collection
+of stations is a collection of vertical profiles.
+
+<p>
+<a href="gradfunccoll2gr.html"><code>coll2gr</code></a> produces an
+output grid that varies in X and Z; the dimension environment used
+when <a href="gradfunccoll2gr.html"><code>coll2gr</code></a> is
+invoked must also be X and Z varying. The X axis of the output grid
+will contain the equally spaced station profiles and will span the
+range of the current X dimension environment. The Z axis of the output
+grid will span the range of the current Z dimension environment and
+will have either the specified number of levels or a union of the
+levels. Data points outside of the range of levels will be used for
+interpolating to within the range if appropriate.
+
+<p>
+The X axis of the output grid from <a
+href="gradfunccoll2gr.html"><code>coll2gr</code></a> is artificial in
+terms of the world coordinates -- it doesn't really represent
+longitudes. A way to completely control the labelling of the display
+output is provided:
+
+<p>
+<ul>
+<code>
+<a href="gradcomdsetxlabs.html">set xlabs</a> lab1 | lab2 | lab3 ...<br>
+<a href="gradcomdsetylabs.html">set ylabs</a> lab1 | lab2 | lab3 ...<br>
+</code>
+</ul>
+
+<p>
+Each label string may include blanks. The labels will be plotted
+equally spaced along the indicated axis. Spacing can be
+modified by adding blank strings:
+<p>
+<ul>
+<code><a href="gradcomdsetxlabs.html">set xlabs</a> | | | | lab1 | ...<br>
+</code>
+</ul>
+
+<p>
+Here is a sample script written by M. Fiorino that uses these features:
+<p>
+<code>
+*********************************************************************<br>
+* The following lines will display an arbitrary X section<br>
+* from one specified point to another.  <br>
+*<br>
+* lon1 is the westernmost longitude point<br>
+* lon2 is the easternmost longitude point<br>
+* lat1 is the latitude that corresponds to lon1<br>
+* lat2 is the latitude that corresponds to lon2<br>
+*<br>
+* The loop is used to interpolate between points in<br>
+* the arbitrary cross section.  This code will plot<br>
+* any cross section as long as you specify the points. <br> 
+* My code plots cross sections of PV after I calculated<br>
+* PV on 11 pressure surfaces.  I have another script<br>
+* that plots cross sections of potential temperature, and<br>
+* the code is very similar to this, except theta is substituted<br>
+* for PV.<br>
+*<br>
+* Many thanks to Brian Doty at COLA for his help with this code.<br>
+*<br>
+********************************************************************<br>
+<br>
+'open pv.ctl'<br>
+'set grads off'<br>
+'set zlog on'<br>
+'set x 1'<br>
+'set y 1'<br>
+'set lev 1000 100'<br>
+lon1 = -95.0<br>
+lon2 = -90.0<br>
+lat1 =  55.0<br>
+lat2 =  15.0<br>
+lon = lon1<br>
+'collect 1 free'<br>
+while (lon <= lon2)<br>
+  lat = lat1 + (lat2-lat1)*(lon-lon1) / (lon2-lon1)<br>
+  'collect 1 gr2stn(pv,'lon','lat')'<br>
+  lon = lon + 1<br>
+endwhile<br>
+<br>
+'set x 14 16'<br>
+'set xaxis 'lon1' 'lon2<br>
+'set clab on'<br>
+'set gxout shaded'<br>
+'set clevs 0 .5 15'<br>
+'set ccols 0 0 7 0'<br>
+'d coll2gr(1,-u)'<br>
+'set gxout contour' <br>
+'set cint .5'<br>
+'d coll2gr(1,-u)'<br>
+</code>
+
+</body>
+</html>
+
diff --git a/etc/compile b/etc/compile
new file mode 100755
index 0000000..9bb997a
--- /dev/null
+++ b/etc/compile
@@ -0,0 +1,99 @@
+#! /bin/sh
+
+# Wrapper for compilers which do not understand `-c -o'.
+
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# compile PROGRAM [ARGS]...
+# `-o FOO.o' is removed from the args passed to the actual compile.
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+   case "$1" in
+    -o)
+       # configure might choose to run compile as `compile cc -o foo foo.c'.
+       # So we do something ugly here.
+       ofile=$2
+       shift
+       case "$ofile" in
+	*.o | *.obj)
+	   ;;
+	*)
+	   args="$args -o $ofile"
+	   ofile=
+	   ;;
+       esac
+       ;;
+    *.c)
+       cfile=$1
+       args="$args $1"
+       ;;
+    *)
+       args="$args $1"
+       ;;
+   esac
+   shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+   # If no `-o' option was seen then we might have been invoked from a
+   # pattern rule where we don't need one.  That is ok -- this is a
+   # normal compilation that the losing compiler can handle.  If no
+   # `.c' file was seen then we are probably linking.  That is also
+   # ok.
+   exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+   if mkdir $lockdir > /dev/null 2>&1; then
+      break
+   fi
+   sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+   mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status
diff --git a/etc/config.guess b/etc/config.guess
new file mode 100755
index 0000000..ed2e03b
--- /dev/null
+++ b/etc/config.guess
@@ -0,0 +1,1321 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+	  if test $? = 0 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	rm -f $dummy.c $dummy.o $dummy.rel ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >$dummy.s
+	.data
+\$Lformat:
+	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
+
+	.text
+	.globl main
+	.align 4
+	.ent main
+main:
+	.frame \$30,16,\$26,0
+	ldgp \$29,0(\$27)
+	.prologue 1
+	.long 0x47e03d80 # implver \$0
+	lda \$2,-1
+	.long 0x47e20c21 # amask \$2,\$1
+	lda \$16,\$Lformat
+	mov \$0,\$17
+	not \$1,\$18
+	jsr \$26,printf
+	ldgp \$29,0(\$26)
+	mov 0,\$16
+	jsr \$26,exit
+	.end main
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		case `./$dummy` in
+			0-0)
+				UNAME_MACHINE="alpha"
+				;;
+			1-0)
+				UNAME_MACHINE="alphaev5"
+				;;
+			1-1)
+				UNAME_MACHINE="alphaev56"
+				;;
+			1-101)
+				UNAME_MACHINE="alphapca56"
+				;;
+			2-303)
+				UNAME_MACHINE="alphaev6"
+				;;
+			2-307)
+				UNAME_MACHINE="alphaev67"
+				;;
+			2-1307)
+				UNAME_MACHINE="alphaev68"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+		rm -f $dummy.c $dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+		    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+		    rm -f $dummy.c $dummy
+		fi ;;
+	esac
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3D:*:*:*)
+	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:3*)
+	echo i386-pc-interix3
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	rm -f $dummy.c
+	test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;		
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	rm -f $dummy.c
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/etc/config.sub b/etc/config.sub
new file mode 100755
index 0000000..f365797
--- /dev/null
+++ b/etc/config.sub
@@ -0,0 +1,1443 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dsp16xx \
+	| fr30 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el | mips64vr4300 \
+	| mips64vr4300el | mips64vr5000 | mips64vr5000el \
+	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+	| mipsisa32 | mipsisa64 \
+	| mn10200 | mn10300 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c54x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+	        ;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+	        ;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+        sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3d)
+		basic_machine=alpha-cray
+		os=-unicos
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	windows32)
+		basic_machine=i386-pc
+		os=-windows32-msvcrt
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh3eb | sh4eb)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	c4x*)
+		basic_machine=c4x-none
+		os=-coff
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto*)
+		os=-nto-qnx
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+	        os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/etc/install-sh b/etc/install-sh
new file mode 100755
index 0000000..398a88e
--- /dev/null
+++ b/etc/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	:
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=$mkdirprog
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		:
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		:
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		:
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+	'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		:
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		:
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/etc/missing b/etc/missing
new file mode 100755
index 0000000..dd58370
--- /dev/null
+++ b/etc/missing
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar ${1+"$@"} && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar ${1+"$@"} && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" ${1+"$@"} && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" ${1+"$@"} && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/etc/mkinstalldirs b/etc/mkinstalldirs
new file mode 100755
index 0000000..eb28f8c
--- /dev/null
+++ b/etc/mkinstalldirs
@@ -0,0 +1,101 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1 2003/06/25 18:30:22 joew Exp $
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+   case "${1}" in
+     -h | --help | --h* )			# -h for help
+	echo "${usage}" 1>&2; exit 0 ;;
+     -m )					# -m PERM arg
+	shift
+	test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
+	dirmode="${1}"
+	shift ;;
+     -- ) shift; break ;;			# stop option processing
+     -* ) echo "${usage}" 1>&2; exit 1 ;;	# unknown option
+     * )  break ;;				# first non-opt arg
+   esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+0) exit 0 ;;
+esac
+
+case $dirmode in
+'')
+  if mkdir -p -- . 2>/dev/null; then
+    echo "mkdir -p -- $*"
+    exec mkdir -p -- "$@"
+  fi ;;
+*)
+  if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+    echo "mkdir -m $dirmode -p -- $*"
+    exec mkdir -m "$dirmode" -p -- "$@"
+  fi ;;
+esac
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+	echo "mkdir $pathcomp"
+
+	mkdir "$pathcomp" || lasterr=$?
+
+	if test ! -d "$pathcomp"; then
+	  errstatus=$lasterr
+	else
+	  if test ! -z "$dirmode"; then
+	     echo "chmod $dirmode $pathcomp"
+
+	     lasterr=""
+	     chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	     if test ! -z "$lasterr"; then
+	       errstatus=$lasterr
+	     fi
+	  fi
+	fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 3
+# End:
+# mkinstalldirs ends here
diff --git a/lib/emacs/README-emacs.txt b/lib/emacs/README-emacs.txt
new file mode 100644
index 0000000..5b64e52
--- /dev/null
+++ b/lib/emacs/README-emacs.txt
@@ -0,0 +1,7 @@
+Emacs modes for GrADS:
+
+To enable, add the following lines to the .emacs file in your home directory:
+
+(require 'gs-mode "<your_grads_home>/lib/emacs/gs-mode.el")
+(require 'ctl-mode "<your_grads_home>/lib/emacs/ctl-mode.el")
+
diff --git a/lib/emacs/ctl-mode.el b/lib/emacs/ctl-mode.el
new file mode 100644
index 0000000..a4915a8
--- /dev/null
+++ b/lib/emacs/ctl-mode.el
@@ -0,0 +1,111 @@
+;;; ctl-mode-el -- Major mode for editing GrADS script files
+
+;; Author: Joe Wielgosz <joew at cola.iges.org>
+;; Created: 2 Oct 2003
+;; Keywords: GrADS script major-mode
+
+;; Copyright (C) Joe Wielgosz <joew at cola.iges.org>
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be
+;; useful, but WITHOUT ANY WARRANTY; without even the implied
+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+;; PURPOSE.  See the GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public
+;; License along with this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+
+;;; Commentary:
+;; 
+;; Based on wpdl-mode-el, a major mode for editing WPDL files
+;; by Scott Andrew Borton <scott at pp.htv.fi>,
+;; which is an example used in a tutorial about Emacs
+;; mode creation. The tutorial can be found here:
+;; http://two-wugs.net/emacs/mode-tutorial.html
+
+;; $$revision$$
+
+;;; Code:
+(defvar ctl-mode-hook nil)
+(defvar ctl-mode-map nil
+  "Keymap for ctl-mode.")
+
+(if ctl-mode-map nil
+  (setq ctl-mode-map (make-keymap)))
+
+(setq auto-mode-alist
+	  (append
+	   '(("\\.ctl\\'" . ctl-mode))
+	   auto-mode-alist))
+
+(defconst ctl-font-lock-keywords-1
+  (list
+
+   ; generated with (regexp-opt '("dset" "dtype" "index" "title"
+   ; "undef" "options" "xdef" "ydef" "zdef" "tdef" "vars" "endvars"
+   ; "fileheader" "theader" "xyheader" "unpack") t)
+
+   '("\\<\\(d\\(?:set\\|type\\)\\|endvars\\|fileheader\\|index\\|stnmap\\|options\\|t\\(?:def\\|header\\|itle\\)\\|un\\(?:def\\|pack\\)\\|vars\\|x\\(?:def\\|yheader\\)\\|[yz]def\\|D\\(?:SET\\|TYPE\\)\\|ENDVARS\\|FILEHEADER\\|INDEX\\|STNMAP\\|OPTIONS\\|T\\(?:DEF\\|HEADER\\|ITLE\\)\\|UN\\(?:DEF\\|PACK\\)\\|VARS\\|X\\(?:DEF\\|YHEADER\\)\\|[YZ]DEF\\)\\>" . font-lock-keyword-face)
+
+   ; builtins: 365_day_calendar big_endian byteswapped cray_32bit_ieee
+   ; gribhdfsds levels linear little_endian netcdf sequential station
+   ; template yrev zrev
+   '("\\<\\(365_day_calendar\\|b\\(?:ig_endian\\|yteswapped\\)\\|cray_32bit_ieee\\|grib\\|hdfsds\\|l\\(?:evels\\|i\\(?:near\\|ttle_endian\\)\\)\\|netcdf\\|s\\(?:equential\\|tation\\)\\|template\\|[yz]rev\\|365_DAY_CALENDAR\\|B\\(?:IG_ENDIAN\\|YTESWAPPED\\)\\|CRAY_32BIT_IEEE\\|GRIB\\|HDFSDS\\|L\\(?:EVELS\\|I\\(?:NEAR\\|TTLE_ENDIAN\\)\\)\\|NETCDF\\|S\\(?:EQUENTIAL\\|TATION\\)\\|TEMPLATE\\|[YZ]REV\\)\\>" . font-lock-builtin-face)
+
+; unused faces:
+;   '("\\('\\d*'\\)" . font-lock-variable-name-face)
+  '("\\<\\([-+eE.0-9]+\\)\\>" . font-lock-constant-face)
+  "Highlighting expressions for ctl-mode."))
+
+(defvar ctl-font-lock-keywords ctl-font-lock-keywords-1
+  "Default highlighting expressions for ctl-mode.")
+
+(defvar ctl-mode-syntax-table nil
+  "Syntax table for ctl-mode.")
+
+(defun ctl-create-syntax-table ()
+  (if ctl-mode-syntax-table
+	  ()
+	(setq ctl-mode-syntax-table (make-syntax-table))
+	
+    ; This is added so entity names with underscores and periods can be more easily parsed
+	(modify-syntax-entry ?_ "w" ctl-mode-syntax-table)
+	(modify-syntax-entry ?- "w" ctl-mode-syntax-table)
+  
+	; Comment syntax
+	(modify-syntax-entry ?* "<" ctl-mode-syntax-table)
+	(modify-syntax-entry ?\n ">" ctl-mode-syntax-table)) 
+
+  (set-syntax-table ctl-mode-syntax-table))
+
+(defun ctl-mode ()
+  "Major mode for editing GrADS descriptor files."
+  (interactive)
+  (kill-all-local-variables)
+  (ctl-create-syntax-table)
+  
+  ;; Set up font-lock
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults
+		'(ctl-font-lock-keywords))
+  
+  ;; Register our indentation function
+;  (make-local-variable 'indent-line-function)
+;  (setq indent-line-function 'ctl-indent-line)
+  
+  (setq major-mode 'ctl-mode)
+  (setq mode-name "GrADS descriptor file")
+  (run-hooks 'ctl-mode-hook))
+
+(provide 'ctl-mode)
+
+;;; ctl-mode.el ends here
+
+
+
diff --git a/lib/emacs/gs-mode.el b/lib/emacs/gs-mode.el
new file mode 100644
index 0000000..3a32763
--- /dev/null
+++ b/lib/emacs/gs-mode.el
@@ -0,0 +1,151 @@
+;;; gs-mode-el -- Major mode for editing GrADS script files
+
+;; Author: Joe Wielgosz <joew at cola.iges.org>
+;; Created: 2 Oct 2003
+;; Keywords: GrADS script major-mode
+
+;; Copyright (C) Joe Wielgosz <joew at cola.iges.org>
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2 of
+;; the License, or (at your option) any later version.
+
+;; This program is distributed in the hope that it will be
+;; useful, but WITHOUT ANY WARRANTY; without even the implied
+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+;; PURPOSE.  See the GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public
+;; License along with this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+
+;;; Commentary:
+;; 
+;; Based on wpdl-mode-el, a major mode for editing WPDL files
+;; by Scott Andrew Borton <scott at pp.htv.fi>,
+;; which is an example used in a tutorial about Emacs
+;; mode creation. The tutorial can be found here:
+;; http://two-wugs.net/emacs/mode-tutorial.html
+
+;; $$revision$$
+
+;;; Code:
+(defvar gs-mode-hook nil)
+(defvar gs-mode-map nil
+  "Keymap for GrADS script major mode.")
+
+(if gs-mode-map nil
+  (setq gs-mode-map (make-keymap)))
+
+(setq auto-mode-alist
+	  (append
+	   '(("\\.gs\\'" . gs-mode))
+	   auto-mode-alist))
+
+(defconst gs-font-lock-keywords-1
+  (list
+   '("\\(e\\(?:lse\\|nd\\(?:if\\|while\\)\\)\\|function\\|if\\|while\\)" . font-lock-keyword-face)
+;   '("\\('\\w*'\\)" . font-lock-variable-name-face)
+   '("\\(close\\|p\\(?:rompt\\|ull\\)\\|read\\|s\\(?:ay\\|ub\\(?:lin\\|str\\|wrd\\)\\)\\|write\\)" . font-lock-builtin-face)
+;   '("\\<\\(TRUE\\|FALSE\\)\\>" . font-lock-constant-face)))
+  "Highlighting expressions for GrADS script mode."))
+
+(defvar gs-font-lock-keywords gs-font-lock-keywords-1
+  "Default highlighting expressions for GrADS script mode.")
+
+(defun gs-indent-line ()
+  "Indent current line as GrADS script code."
+  (interactive)
+  (beginning-of-line)
+  (if (or (bobp) (looking-at "\\s-*\\*") (looking-at "\\s-*function"))
+					; First line is always non-indented
+					; so are comments and functions
+	(indent-line-to 0)
+      
+      (let ((not-indented t) cur-indent)
+	(if (looking-at "\\s-*\\(endif\\|endwhile\\|else\\)") 
+					; If the line we are looking at 
+					; is the end of a block, 
+					; then decrease the indentation
+	    (progn
+	      (save-excursion
+		(forward-line -1)
+		(setq cur-indent (- (current-indentation) 2)))
+	      (if (< cur-indent 0)        ; We can't indent past the left margin
+		  (setq cur-indent 0)))
+	  
+	  (save-excursion
+	    (while not-indented           ; Iterate backwards until 
+					; we find an indentation hint
+	      (forward-line -1)
+	      (unless (looking-at "\\s-*\\*")
+		(if (looking-at ".*\\b\\(endif\\|endwhile\\)") 
+					; This hint indicates that we need to 
+					; indent at the level of the endwhile/endif
+		    (progn
+		      (setq cur-indent (current-indentation))
+		      (setq not-indented nil))
+		  (if (looking-at ".*\\b\\(if\\|while\\|else\\)") 
+					; This hint indicates that we need to 
+					; indent an extra level
+		    (progn
+		      (setq cur-indent 
+			    (+ (current-indentation) 2)) 
+					; Do the actual indenting
+		      (setq not-indented nil)))))
+	      (if (bobp)
+		  (setq not-indented nil)))))
+	(if cur-indent
+	    (indent-line-to cur-indent)
+	  (indent-line-to 0)))))          ; If we didn't see an indentation hint, 
+					; then allow no indentation
+
+(defvar gs-mode-syntax-table nil
+  "Syntax table for gs-mode.")
+
+(defun gs-create-syntax-table ()
+  (if gs-mode-syntax-table
+	  ()
+	(setq gs-mode-syntax-table (make-syntax-table))
+	
+    ; This is added so entity names with underscores and periods can be more easily parsed
+	(modify-syntax-entry ?_ "w" gs-mode-syntax-table)
+  
+	; Comment syntax
+	(modify-syntax-entry ?* "<" gs-mode-syntax-table)
+	(modify-syntax-entry ?\n ">" gs-mode-syntax-table)
+
+        ; Quote syntax
+	(modify-syntax-entry ?\' "\"" gs-mode-syntax-table)
+	(modify-syntax-entry ?\" "\"" gs-mode-syntax-table))
+      
+
+  (set-syntax-table gs-mode-syntax-table))
+
+(defun gs-mode ()
+  "Major mode for editing GrADS script files."
+  (interactive)
+  (kill-all-local-variables)
+  (gs-create-syntax-table)
+  
+  ;; Set up font-lock
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults
+		'(gs-font-lock-keywords))
+  
+  ;; Register our indentation function
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'gs-indent-line)
+  
+  (setq major-mode 'gs-mode)
+  (setq mode-name "GS")
+  (run-hooks 'gs-mode-hook))
+
+(provide 'gs-mode)
+
+;;; gs-mode.el ends here
+
+
+
diff --git a/m4/Xaw.m4 b/m4/Xaw.m4
new file mode 100644
index 0000000..cf9b9f9
--- /dev/null
+++ b/m4/Xaw.m4
@@ -0,0 +1,81 @@
+dnl GA_CHECK_XAW : Check for Xaw 
+dnl args :             action-if-yes, action-if-no
+dnl sets XAW_CFLAGS, XAW_LIBS, and XAW_XLIBS. XAW_XLIBS is set to the 
+dnl necessary X library flags determined by AC_PATH_XTRA, or is empty
+dnl if all the dependencies are already in XAW_XLIBS, which is the case
+dnl when pkgconfig is used
+AC_DEFUN([GA_CHECK_XAW],
+[
+  AC_REQUIRE([AC_PATH_XTRA])
+
+  XAW_LIBS=
+  XAW_XLIBS=
+  XAW_CFLAGS=
+  ac_pkgconfig_xaw=no
+
+  ac_pkgconfig_xaw7=yes
+  PKG_CHECK_MODULES([XAW7],[xaw7],,[ac_pkgconfig_xaw7=no])
+  ac_save_LDFLAGS=$LDFLAGS
+  ac_save_LIBS=$LIBS
+  ac_save_CFLAGS=$CFLAGS
+  LDFLAGS="$LDFLAGS $X_LIBS"
+  LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+  CFLAGS="$CFLAGS $X_CFLAGS"
+  ga_xaw_flag=''
+  ga_xaw_libs='-lXmu -lXt'
+  AC_CHECK_LIB([Xt],[main],
+  [ 
+    AC_CHECK_LIB([Xmu],[main],
+    [
+      # we add Xext if found. Not sure which platform needs it
+      AC_CHECK_LIB([Xext],[main],
+      [
+         ga_xaw_libs="$ga_xaw_libs -lXext"
+      ])
+      # we add Xpm if found, and we don't check for neXtaw if no Xpm
+      AC_CHECK_LIB([Xpm],[main],
+      [ 
+        ga_xaw_libs="$ga_xaw_libs -lXpm"
+        AC_CHECK_LIB([neXtaw],[main],
+        [ ga_xaw_flag='-lneXtaw'],,
+        [])
+      ])
+      if test z"$ga_xaw_flag" = 'z'; then
+        AC_CHECK_LIB([Xaw3d],[main],
+        [  ga_xaw_flag='-lXaw3d' ],,
+        [])
+      fi
+      if test z"$ga_xaw_flag" = 'z'; then
+        if test $ac_pkgconfig_xaw7 = 'yes'; then
+          ac_pkgconfig_xaw=xaw7
+          ga_use_xaw=yes
+          XAW_LIBS=$XAW7_LIBS
+          XAW_CFLAGS=$XAW7_CFLAGS
+          XAW_XLIBS=
+        else
+          AC_CHECK_LIB([Xaw],[main],
+          [  ga_xaw_flag='-lXaw' ],,
+          [$ga_xaw_libs])
+        fi
+      fi
+      if test z"$ga_xaw_flag" != 'z'; then
+        XAW_LIBS="$ga_xaw_flag $ga_xaw_libs"
+        XAW_XLIBS="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+        ga_use_xaw=yes
+      fi
+       
+    ])
+  ])
+
+  CFLAGS=$ac_save_CFLAGS
+  LIBS=$ac_save_LIBS
+  LDFLAGS=$ac_save_LDFLAGS
+  if test "z$ga_use_xaw" = "zyes"; then
+     m4_if([$1], [], [:], [$1])
+  else
+     m4_if([$2], [], [:], [$2])
+  fi
+  AC_SUBST([XAW_LIBS])
+  AC_SUBST([XAW_XLIBS])
+  AC_SUBST([XAW_CFLAGS])
+])
diff --git a/m4/ga_lib_readline.m4 b/m4/ga_lib_readline.m4
new file mode 100644
index 0000000..51d4118
--- /dev/null
+++ b/m4/ga_lib_readline.m4
@@ -0,0 +1,98 @@
+dnl @synopsis GA_LIB_READLINE
+dnl  args :             action-if-found, action-if-not-found
+dnl                     it is found if readline is found and has 
+dnl                     history
+dnl
+dnl Searches for a readline compatible library.  If found, defines
+dnl `HAVE_LIBREADLINE'.  If the found library has the `add_history'
+dnl function, sets also `HAVE_READLINE_HISTORY'.  Also checks for the
+dnl locations of the necessary include files and sets `HAVE_READLINE_H'
+dnl or `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or
+dnl 'HAVE_HISTORY_H' if the corresponding include files exists.
+dnl
+dnl The libraries that may be readline compatible are `libedit',
+dnl `libeditline' and `libreadline'.  Sometimes we need to link a termcap
+dnl library for readline to work, this macro tests these cases too by
+dnl trying to link with `libtermcap', `libcurses' or `libncurses' before
+dnl giving up.
+dnl
+dnl Here is an example of how to use the information provided by this
+dnl macro to perform the necessary includes or declarations in a C file:
+dnl
+dnl   #ifdef HAVE_LIBREADLINE
+dnl   #  if defined(HAVE_READLINE_READLINE_H)
+dnl   #    include <readline/readline.h>
+dnl   #  elif defined(HAVE_READLINE_H)
+dnl   #    include <readline.h>
+dnl   #  else /* !defined(HAVE_READLINE_H) */
+dnl   extern char *readline ();
+dnl   #  endif /* !defined(HAVE_READLINE_H) */
+dnl   char *cmdline = NULL;
+dnl   #else /* !defined(HAVE_READLINE_READLINE_H) */
+dnl     /* no readline */
+dnl   #endif /* HAVE_LIBREADLINE */
+dnl
+dnl   #ifdef HAVE_READLINE_HISTORY
+dnl   #  if defined(HAVE_READLINE_HISTORY_H)
+dnl   #    include <readline/history.h>
+dnl   #  elif defined(HAVE_HISTORY_H)
+dnl   #    include <history.h>
+dnl   #  else /* !defined(HAVE_HISTORY_H) */
+dnl   extern void add_history ();
+dnl   extern int write_history ();
+dnl   extern int read_history ();
+dnl   #  endif /* defined(HAVE_READLINE_HISTORY_H) */
+dnl     /* no history */
+dnl   #endif /* HAVE_READLINE_HISTORY */
+dnl
+dnl
+dnl @version 1.1
+dnl @author Ville Laurikari <vl at iki.fi>
+dnl
+dnl Pat: add args, rename to GA_LIB_READLINE
+AC_DEFUN([GA_LIB_READLINE], [
+  AC_CACHE_CHECK([for a readline compatible library],
+                 vl_cv_lib_readline, [
+    ORIG_LIBS="$LIBS"
+    for readline_lib in readline edit editline; do
+      for termcap_lib in "" termcap curses ncurses; do
+        if test -z "$termcap_lib"; then
+          TRY_LIB="-l$readline_lib"
+        else
+          TRY_LIB="-l$readline_lib -l$termcap_lib"
+        fi
+        LIBS="$ORIG_LIBS $TRY_LIB"
+        AC_TRY_LINK_FUNC(readline, vl_cv_lib_readline="$TRY_LIB")
+        if test -n "$vl_cv_lib_readline"; then
+          break
+        fi
+      done
+      if test -n "$vl_cv_lib_readline"; then
+        break
+      fi
+    done
+    if test -z "$vl_cv_lib_readline"; then
+      vl_cv_lib_readline="no"
+      LIBS="$ORIG_LIBS"
+    fi
+  ])
+
+  if test "$vl_cv_lib_readline" != "no"; then
+    AC_DEFINE(HAVE_LIBREADLINE, 1,
+              [Define if you have a readline compatible library])
+    AC_CHECK_HEADERS(readline.h readline/readline.h)
+    AC_CACHE_CHECK([whether readline supports history],
+                   vl_cv_lib_readline_history, [
+      vl_cv_lib_readline_history="no"
+      AC_TRY_LINK_FUNC(add_history, vl_cv_lib_readline_history="yes")
+    ])
+    if test "$vl_cv_lib_readline_history" = "yes"; then
+      AC_DEFINE(HAVE_READLINE_HISTORY, 1,
+                [Define if your readline library has \`add_history'])
+      AC_CHECK_HEADERS(history.h readline/history.h)
+      m4_if([$1], [], [:], [$1])
+    else
+      m4_if([$2], [], [:], [$2])
+    fi
+  fi
+])dnl
diff --git a/m4/gd.m4 b/m4/gd.m4
new file mode 100644
index 0000000..cb2673a
--- /dev/null
+++ b/m4/gd.m4
@@ -0,0 +1,76 @@
+dnl GA_CHECK_LIB_GD : check for gd library
+dnl args :             action-if-yes, action-if-no
+
+AC_DEFUN([GA_CHECK_LIB_GD],
+[
+  ga_check_gd="no"
+  GD_LIBS=
+  GD_CFLAGS=
+  GD_LDFLAGS=
+
+  ga_pkgconfig_gd=yes
+  PKG_CHECK_MODULES([GD],[gdlib],,[ga_pkgconfig_gd=no])
+  ac_save_LIBS="$LIBS"
+  ac_save_CPPFLAGS="$CPPFLAGS"
+  ac_save_LDFLAGS="$LDFLAGS"
+
+  ga_config_gd=no
+  if test $ga_pkgconfig_gd != 'yes'; then
+    AC_PATH_PROG([GD_CONFIG],[gdlib-config],[no])
+    if test "$GD_CONFIG" != "no"; then
+      GD_LIBS=`$GD_CONFIG --libs`
+      GD_CFLAGS=`$GD_CONFIG --cflags`
+      GD_LDFLAGS=`$GD_CONFIG --ldflags`
+      ga_config_gd=yes
+    fi
+  fi
+  
+  if test $ga_pkgconfig_gd = 'yes' -o $ga_config_gd = 'yes'; then
+     LDFLAGS="$LDFLAGS $GD_LDFLAGS"
+     LIBS="$LIBS $GD_LIBS"
+     AC_CHECK_HEADER([gd.h],
+     [  AC_CHECK_LIB([gd], [gdImageCreate],
+        [  ga_check_gd=yes
+           GD_LIBS="-lgd $GD_LIBS"
+           AC_CHECK_FUNCS([gdCompareInt])
+        ],
+        [
+           GD_LDFLAGS=
+           GD_LIBS=
+           LIBS="$ac_save_LIBS"
+           LDFLAGS="$ac_save_LDFLAGS"
+        ])
+     ],
+     [
+       GD_CFLAGS=
+       CPPFLAGS="$ac_save_CPPFLAGS"
+     ])
+  fi
+  if test $ga_check_gd = 'no'; then
+     AC_CHECK_HEADER([gd.h],
+      [ AC_CHECK_LIB([z], [compress],
+        [ AC_CHECK_LIB([png], [main],
+          [ AC_CHECK_LIB([gd], [gdImageCreate],
+            [ ga_check_gd=yes
+              AC_CHECK_FUNCS([gdCompareInt])
+              GD_LIBS='-lgd -lpng -lz'
+            ])
+          ])
+        ])
+     ])
+  fi
+
+  LIBS="$ac_save_LIBS"
+  CPPFLAGS="$ac_save_CPPFLAGS"
+  LDFLAGS="$ac_save_LDFLAGS"
+
+  if test $ga_check_gd = 'yes'; then
+     m4_if([$1], [], [:], [$1])
+  else
+     m4_if([$2], [], [:], [$2])
+  fi
+
+  AC_SUBST([GD_LIBS])
+  AC_SUBST([GD_LDFLAGS])
+  AC_SUBST([GD_CFLAGS])
+])
diff --git a/m4/geotiff.m4 b/m4/geotiff.m4
new file mode 100644
index 0000000..20e12b9
--- /dev/null
+++ b/m4/geotiff.m4
@@ -0,0 +1,169 @@
+dnl AC_CHECK_GEOTIFF : Check for geotiff
+dnl args :             action-if-yes, action-if-no
+AC_DEFUN([AC_CHECK_GEOTIFF],
+[
+  AC_ARG_WITH([geotiff],
+            [AS_HELP_STRING([--with-geotiff=ARG],[geotiff directory])],
+            [GEOTIFF_PATH=$withval], 
+            [GEOTIFF_PATH=""])
+
+  AC_ARG_WITH([geotiff_include],
+            [AS_HELP_STRING([--with-geotiff-include=ARG],[geotiff include directory])],
+            [GEOTIFF_PATH_INC=$withval],
+            [GEOTIFF_PATH_INC=""])
+
+  AC_ARG_WITH([geotiff_libdir],
+            [AS_HELP_STRING([--with-geotiff-libdir=ARG],[geotiff library directory])],
+            [GEOTIFF_PATH_LIBDIR=$withval], 
+            [GEOTIFF_PATH_LIBDIR=""])
+
+  dnl This is a very common location for the geotiff code. jhrg 10/11/05
+dnl  AS_IF([test -d /usr/local/libgeotiff], [GEOTIFF_PATH="/usr/local/libgeotiff"])
+      
+  AS_IF([test "z$GEOTIFF_PATH" != "z"],
+  [
+    AS_IF([test "z$GEOTIFF_PATH_LIBDIR" = "z"],
+      [GEOTIFF_PATH_LIBDIR="$GEOTIFF_PATH/lib"])  
+    AS_IF([test "z$GEOTIFF_PATH_INC" = "z"],
+      [GEOTIFF_PATH_INC="$GEOTIFF_PATH/include"])  
+  ])
+  
+  
+  ac_geotiff_lib_ok='no'
+  ac_geotiff_save_LDFLAGS=$LDFLAGS
+  GEOTIFF_LIBS=
+  AS_IF([test -d "$GEOTIFF_PATH_LIBDIR"],
+    [
+      GEOTIFF_LDFLAGS="-L$GEOTIFF_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS"
+      AC_CHECK_GEOTIFF_LIB([ac_geotiff_lib_ok='yes'])
+    ],
+    [
+      for ac_geotiff_libdir in "" /usr/geotiff/lib64 /usr/local/lib64/geotiff \
+       /usr/libgeotiff/lib64 /usr/local/lib64/libgeotiff \
+       /opt/lib64/geotiff /opt/lib64/libgeotiff \
+       /opt/geotiff/lib64 /usr/lib64/geotiff /usr/local/geotiff/lib64 \
+       /opt/libgeotiff/lib64 /usr/lib64/libgeotiff /usr/local/libgeotiff/lib64 \
+       /usr/local/geotiff/lib /opt/geotiff/lib \ 
+       /usr/local/libgeotiff/lib /opt/libgeotiff/lib \ 
+       /usr/geotiff/lib /usr/local/lib/geotiff /opt/lib/geotiff \
+       /usr/libgeotiff/lib /usr/local/lib/libgeotiff /opt/lib/libgeotiff \
+       /usr/lib/geotiff /usr/lib/libgeotiff ; do
+        AS_IF([test ! -d "$ac_geotiff_libdir"],
+           [GEOTIFF_LDFLAGS=],
+           [
+             AC_MSG_NOTICE([searching geotiff libraries in $ac_geotiff_libdir])
+             GEOTIFF_LDFLAGS="-L$ac_geotiff_libdir"
+           ])
+        LDFLAGS="$LDFLAGS $GEOTIFF_LDFLAGS" 
+        AC_CHECK_GEOTIFF_LIB([ac_geotiff_lib_ok='yes'])
+        AS_IF([test $ac_geotiff_lib_ok = 'yes'],[break])
+        LDFLAGS=$ac_geotiff_save_LDFLAGS
+      done
+    ])
+  LDFLAGS=$ac_geotiff_save_LDFLAGS
+  
+  ac_geotiff_h='no'
+  GEOTIFF_CFLAGS=
+  ac_geotiff_save_CPPFLAGS=$CPPFLAGS
+  AS_IF([test -d "$GEOTIFF_PATH_INC"],
+    [
+       GEOTIFF_CFLAGS="-I$GEOTIFF_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $GEOTIFF_CFLAGS"
+       AC_CHECK_HEADER_NOCACHE_GEOTIFF([geotiffio.h],[ac_geotiff_h='yes'])
+    ],
+    [
+      for ac_geotiff_incdir in /usr/include \
+       /usr/local/geotiff/include /opt/geotiff/include \ 
+       /usr/geotiff/include /usr/local/include/geotiff \
+       /opt/include/geotiff /usr/include/geotiff /usr/local/libgeotiff/include \
+       /opt/libgeotiff/include /usr/libgeotiff/include /usr/local/include/libgeotiff \
+       /opt/include/libgeotiff /usr/include/libgeotiff ; do
+        AS_IF([test ! -d "$ac_geotiff_incdir"],
+           [GEOTIFF_CFLAGS=],
+           [
+             AC_MSG_NOTICE([searching geotiff includes in $ac_geotiff_incdir])
+             GEOTIFF_CFLAGS="-I$ac_geotiff_incdir"
+             CPPFLAGS="$CPPFLAGS $GEOTIFF_CFLAGS"
+             AC_CHECK_HEADER_NOCACHE_GEOTIFF([geotiffio.h],[ac_geotiff_h='yes'])
+             AS_IF([test $ac_geotiff_h = 'yes'],[break])
+             CPPFLAGS=$ac_geotiff_save_CPPFLAGS
+           ])
+      done
+    ])
+  CPPFLAGS=$ac_geotiff_save_CPPFLAGS
+  
+  AS_IF([test "$ac_geotiff_h" = 'yes' -a "$ac_geotiff_lib_ok" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+
+  AC_SUBST([GEOTIFF_LIBS])
+  AC_SUBST([GEOTIFF_CFLAGS])
+  AC_SUBST([GEOTIFF_LDFLAGS])
+])
+
+AC_DEFUN([AC_CHECK_GEOTIFF_LIB],
+[
+  GEOTIFF_LIBS=
+  ac_geotiff_lib='no'
+  ac_geotiff_save_LIBS=$LIBS
+  AC_CHECK_LIB_NOCACHE_GEOTIFF([tiff], [main],
+  [ AC_CHECK_LIB_NOCACHE_GEOTIFF([geotiff],[main],
+    [ ac_geotiff_lib="yes"
+      GEOTIFF_LIBS="-lgeotiff -ltiff $GEOTIFF_LIBS"
+    ],[],[-ltiff])
+  ])
+  LIBS=$ac_geotiff_save_LIBS
+  
+  AS_IF([test "$ac_geotiff_lib" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+])
+
+AC_DEFUN([AC_CHECK_LIB_NOCACHE_GEOTIFF],
+[
+  AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='no'
+  AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])=$LIBS
+  LIBS="-l$1 $5 $LIBS"
+  AC_MSG_CHECKING([for $2 in -l$1])
+  AC_LINK_IFELSE([AC_LANG_CALL([], [$2])],
+  [ 
+    AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='yes' 
+    AC_MSG_RESULT([yes])
+  ],[ 
+    AC_MSG_RESULT([no])
+  ])
+  LIBS=$AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])
+  AS_IF([test $AS_TR_SH([ac_check_lib_nocache_ok_$1_$2]) = 'yes'],
+  [m4_if([$3], [], [:], [$3])],
+  [m4_if([$4], [], [:], [$4])])
+])
+ 
+AC_DEFUN([AC_CHECK_HEADER_NOCACHE_GEOTIFF],
+[
+  AS_TR_SH([ac_check_header_nocache_compile_$1])='no'
+  AS_TR_SH([ac_check_header_nocache_preproc_$1])='no'
+  AC_MSG_CHECKING([for $1 with compiler])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
+    [
+      AC_MSG_RESULT([yes])
+      AS_TR_SH([ac_check_header_nocache_compile_$1])='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+    ])
+  AC_MSG_CHECKING([for $1 with preprocessor])
+  AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
+    [
+      AC_MSG_RESULT([yes])
+      AS_TR_SH([ac_check_header_nocache_preproc_$1])='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
+        [AC_MSG_WARN([trusting compiler result, ignoring preprocessor error])])
+    ])
+  AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
+  [m4_if([$2], [], [:], [$2])],
+  [m4_if([$3], [], [:], [$3])])
+])
diff --git a/m4/grib2.m4 b/m4/grib2.m4
new file mode 100644
index 0000000..8de5146
--- /dev/null
+++ b/m4/grib2.m4
@@ -0,0 +1,26 @@
+dnl GA_CHECK_LIB_GRIB2 : Checks whether GrADS can be built with grib2 interface
+dnl  args : 		action-if-yes, action-if-no
+AC_DEFUN([GA_CHECK_LIB_GRIB2],
+[
+  ga_check_grib2="no"
+  AC_CHECK_HEADER(grib2.h,
+  [ AC_CHECK_LIB(grib2c, main, 
+    [ AC_CHECK_LIB(png12, main,
+      [ AC_CHECK_LIB(z, main,
+        [ AC_CHECK_LIB(jasper, main,
+          [ ga_check_grib2="yes"
+            G2_LIBS='-lgrib2c -ljasper -lpng -lz'
+	  ])
+        ])
+      ])
+    ])
+  ])
+
+  if test $ga_check_grib2 = "yes" ; then
+     m4_if([$1], [], [:], [$1])
+  else
+     m4_if([$2], [], [:], [$2])
+  fi
+
+  AC_SUBST([G2_LIBS])
+])
diff --git a/m4/gui.m4 b/m4/gui.m4
new file mode 100644
index 0000000..f2ccc99
--- /dev/null
+++ b/m4/gui.m4
@@ -0,0 +1,30 @@
+dnl GA_CHECK_GUI : Checks whether GrADS can be built with GUI features 
+dnl  		      	enabled.
+dnl  args : 		action-if-yes, action-if-no
+AC_DEFUN([GA_CHECK_GUI],
+[
+  # Check libs and headers for GUI widgets
+  ga_check_gui="no"
+  GA_SET_FLAGS([X11/neXtaw libsx],[$X_CFLAGS], [$X_LIBS],[$X_PRE_LIBS -lX11 $X_EXTRA_LIBS])
+dnl  GA_SET_FLAGS([X11/neXtaw libsx])
+  AC_CHECK_LIB(Xext, main, [gui_libs_Xext="-lXext"])  
+  AC_CHECK_LIB(Xt, main,
+    [ AC_CHECK_LIB(Xmu,main,
+      [ AC_CHECK_LIB(Xpm, main,
+        [ AC_CHECK_LIB(Xaw, main,
+          [ AC_CHECK_LIB(sx, main,
+            [ ga_check_gui="yes" ])
+          ])
+        ])
+      ])
+    ])
+  GA_UNSET_FLAGS
+  if test $ga_check_gui = "yes" ; then
+    $1 
+    true #dummy command
+  else
+    $2
+    true #dummy command
+  fi
+
+])
diff --git a/m4/hdf4.m4 b/m4/hdf4.m4
new file mode 100644
index 0000000..4b80b41
--- /dev/null
+++ b/m4/hdf4.m4
@@ -0,0 +1,251 @@
+dnl AC_CHECK_HDF : Check for hdf4
+dnl args :             action-if-yes, action-if-no
+AC_DEFUN([AC_CHECK_HDF4],
+[
+  AC_ARG_WITH([hdf4],
+            [AS_HELP_STRING([--with-hdf4=ARG],[hdf4 directory])],
+            [HDF4_PATH=$withval], 
+            [HDF4_PATH=""])
+
+  AC_ARG_WITH([hdf4_include],
+            [AS_HELP_STRING([--with-hdf4-include=ARG],[hdf 4 include directory])],
+            [HDF4_PATH_INC=$withval],
+            [HDF4_PATH_INC=""])
+
+  AC_ARG_WITH([hdf4_libdir],
+            [AS_HELP_STRING([--with-hdf4-libdir=ARG],[hdf 4 library directory])],
+            [HDF4_PATH_LIBDIR=$withval], 
+            [HDF4_PATH_LIBDIR=""])
+
+  dnl This is a very common location for the hdf4 code. jhrg 10/11/05
+dnl  AS_IF([test -d /usr/local/hdf], [HDF4_PATH="/usr/local/hdf"])
+      
+  AS_IF([test "z$HDF4_PATH" != "z"],
+  [
+    AS_IF([test "z$HDF4_PATH_LIBDIR" = "z"],
+      [HDF4_PATH_LIBDIR="$HDF4_PATH/lib"])  
+    AS_IF([test "z$HDF4_PATH_INC" = "z"],
+      [HDF4_PATH_INC="$HDF4_PATH/include"])  
+  ])
+  
+  
+  ac_hdf4_lib_ok='no'
+  ac_hdf4_save_LDFLAGS=$LDFLAGS
+  HDF4_LIBS=
+  AS_IF([test "z$HDF4_PATH_LIBDIR" != "z"],
+    [
+      HDF4_LDFLAGS="-L$HDF4_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+      AC_CHECK_HDF4_LIB([ac_hdf4_lib_ok='yes'])
+    ],
+    [
+      for ac_hdf4_libdir in "" /usr/local/hdf4.2r1/lib64 /opt/hdf4.2r1/lib64 \ 
+       /usr/hdf4.2r1/lib64 /usr/local/lib64/hdf4.2r1 /opt/lib64/hdf4.2r1 \
+       /usr/lib64/hdf4.2r1 /usr/local/hdf/lib64/ /opt/hdf/lib64 /usr/hdf/lib64 \
+       /usr/local/lib64/hdf /opt/lib64/hdf /usr/lib64/hdf \
+       /usr/local/hdf4.2r1/lib /opt/hdf4.2r1/lib \ 
+       /usr/hdf4.2r1/lib /usr/local/lib/hdf4.2r1 /opt/lib/hdf4.2r1 \
+       /usr/lib/hdf4.2r1 /usr/local/hdf/lib/ /opt/hdf/lib /usr/hdf/lib \
+       /usr/local/lib/hdf /opt/lib/hdf /usr/lib/hdf ; do
+        AS_IF([test "z$ac_hdf4_libdir" = 'z'],
+           [HDF4_LDFLAGS=],
+           [
+             AC_MSG_NOTICE([searching hdf libraries in $ac_hdf4_libdir])
+             HDF4_LDFLAGS="-L$ac_hdf4_libdir"
+           ])
+        LDFLAGS="$LDFLAGS $HDF4_LDFLAGS" 
+        AC_CHECK_HDF4_LIB([ac_hdf4_lib_ok='yes'])
+        AS_IF([test $ac_hdf4_lib_ok = 'yes'],[break])
+        LDFLAGS=$ac_hdf4_save_LDFLAGS
+      done
+    ])
+  LDFLAGS=$ac_hdf4_save_LDFLAGS
+  
+  ac_hdf4_h='no'
+  HDF4_CFLAGS=
+  ac_hdf4_save_CPPFLAGS=$CPPFLAGS
+  AS_IF([test "z$HDF4_PATH_INC" != "z"],
+    [
+       HDF4_CFLAGS="-I$HDF4_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS"
+       AC_CHECK_HEADER_NOCACHE_HDF4([mfhdf.h],[ac_hdf4_h='yes'])
+    ],
+    [
+      for ac_hdf4_incdir in "" /usr/local/hdf4.2r1/include /opt/hdf4.2r1/include \ 
+       /usr/hdf4.2r1/include /usr/local/include/hdf4.2r1 \
+       /opt/include/hdf4.2r1 /usr/include/hdf4.2r1 /usr/local/hdf/include \
+       /opt/hdf/include /usr/hdf/include /usr/local/include/hdf \
+       /opt/include/hdf /usr/include/hdf ; do
+        AS_IF([test "z$ac_hdf4_incdir" = 'z'],
+           [HDF4_CFLAGS=],
+           [
+             AC_MSG_NOTICE([searching hdf includes in $ac_hdf4_incdir])
+             HDF4_CFLAGS="-I$ac_hdf4_incdir"
+           ])
+        CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS" 
+        AC_CHECK_HEADER_NOCACHE_HDF4([mfhdf.h],[ac_hdf4_h='yes'])
+        AS_IF([test $ac_hdf4_h = 'yes'],[break])
+        CPPFLAGS=$ac_hdf4_save_CPPFLAGS
+      done
+    ])
+  CPPFLAGS=$ac_hdf4_save_CPPFLAGS
+  
+  AS_IF([test "$ac_hdf4_h" = 'yes' -a "$ac_hdf4_lib_ok" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+
+  AC_SUBST([HDF4_LIBS])
+  AC_SUBST([HDF4_CFLAGS])
+  AC_SUBST([HDF4_LDFLAGS])
+])
+
+dnl check for the netcdf 2 interface provided by hdf
+dnl it defines the C preprocessor macro HDF_NETCDF_NAME(name) which
+dnl prepends sd_ to name if needed and otherwise keep the name
+dnl as is.
+dnl
+dnl args            action-if-found,
+dnl                 action-if-found with sd_ appended to netcdf symbols,
+dnl                 action-if-no-found
+dnl
+dnl in case it is detected that sd_ should be appended, the C preprocessor
+dnl symbol HDF_HAVE_NETCDF is defined.
+
+AC_DEFUN([AC_CHECK_HDF4_NETCDF],
+[
+  ac_hdf4_netcdf_lib='no'
+  ac_hdf4_sd_netcdf_lib='no'
+  ac_hdf4_netcdf_h='no'
+  AC_CHECK_HDF4([
+    ac_hdf4_netcdf_save_LDFLAGS=$LDFLAGS
+    ac_hdf4_netcdf_save_LIBS=$LIBS
+    LIBS="$LIBS $HDF4_LIBS"
+    LDFLAGS="$LDFLAGS $HDF4_LDFLAGS"
+    AC_MSG_CHECKING([for sd_ncopen])
+    AC_LINK_IFELSE([AC_LANG_CALL([],[sd_ncopen])],
+      [
+        AC_MSG_RESULT([yes])
+        ac_hdf4_sd_netcdf_lib='yes'
+      ],
+      [
+        AC_MSG_RESULT([no])
+        ac_hdf4_sd_netcdf_lib='no'
+      ])
+    AS_IF([test "$ac_hdf4_sd_netcdf_lib" = 'no'],
+    [
+      AC_MSG_CHECKING([for ncopen with hdf link flags])
+      AC_LINK_IFELSE([AC_LANG_CALL([],[ncopen])],
+      [
+        AC_MSG_RESULT([yes])
+        ac_hdf4_netcdf_lib='yes'
+      ],
+      [
+        AC_MSG_RESULT([no])
+        ac_hdf4_netcdf_lib='no'
+      ])
+    ])
+    LDFLAGS=$ac_hdf4_netcdf_save_LDFLAGS
+    LIBS=$ac_hdf4_netcdf_save_LIBS
+
+    ac_hdf4_netcdf_save_CPPFLAGS=$CPPFLAGS
+dnl not needed anymore
+dnl    ac_hdf4_netcdf_save_NC_CFLAGS=$NC_CFLAGS
+    CPPFLAGS="$CPPFLAGS $HDF4_CFLAGS"
+    AC_CHECK_HEADERS([hdf4_netcdf.h],[ac_hdf4_netcdf_h='yes'])
+    AC_CHECK_NETCDF_HEADER([],[ac_hdf4_netcdf_h='yes'])
+    CPPFLAGS=$ac_hdf4_netcdf_save_CPPFLAGS
+dnl    NC_CFLAGS=$ac_hdf4_netcdf_save_NC_CFLAG
+  ])
+
+  AH_TEMPLATE([HDF_NETCDF_NAME],[A macro that append sd_ to netcdf symbols if needed])
+  AS_IF([test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_sd_netcdf_lib = 'yes'],
+  [
+     AC_DEFINE([HDF_HAVE_NETCDF],[],[Define if hdf prefixes netcdf symbols by sd])
+     AC_DEFINE([HDF_NETCDF_NAME(name)], [sd_ ## name])
+     m4_if([$2], [], [:], [$2])
+  ],
+  [
+    AC_DEFINE([HDF_NETCDF_NAME(name)], [name])
+    AS_IF([test $ac_hdf4_netcdf_h = 'yes' -a $ac_hdf4_netcdf_lib = 'yes'],
+    [m4_if([$1], [], [:], [$1])],
+    [m4_if([$3], [], [:], [$3])])
+  ])
+])
+
+AC_DEFUN([AC_CHECK_HDF4_LIB],
+[
+  HDF4_LIBS=
+  ac_hdf4_save_LIBS=$LIBS
+  AC_CHECK_LIB_NOCACHE_HDF4([sz], [SZ_BufftoBuffCompress],
+  [
+      LIBS="$LIBS -lsz"
+      HDF4_LIBS='-lsz'
+  ])
+
+dnl -lsz is not required because due to licencing it may not be present
+dnl nor required everywhere
+  ac_hdf4_lib='no'
+  AC_CHECK_LIB_NOCACHE_HDF4([z],[deflate],
+  [ AC_CHECK_LIB_NOCACHE_HDF4([jpeg],[jpeg_start_compress],
+    [ AC_CHECK_LIB_NOCACHE_HDF4([df],[Hopen],
+      [ AC_CHECK_LIB_NOCACHE_HDF4([mfhdf],[SDstart],
+        [ ac_hdf4_lib="yes"
+          HDF4_LIBS="-lmfhdf -ldf -ljpeg -lz $HDF4_LIBS"
+        ],[],[-ldf -ljpeg -lz])
+      ],[],[-ljpeg -lz])
+    ])
+  ])
+  LIBS=$ac_hdf4_save_LIBS
+  
+  AS_IF([test "$ac_hdf4_lib" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+])
+
+AC_DEFUN([AC_CHECK_LIB_NOCACHE_HDF4],
+[
+  AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='no'
+  AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])=$LIBS
+  LIBS="-l$1 $5 $LIBS"
+  AC_MSG_CHECKING([for $2 in -l$1])
+  AC_LINK_IFELSE([AC_LANG_CALL([], [$2])],
+  [ 
+    AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='yes' 
+    AC_MSG_RESULT([yes])
+  ],[ 
+    AC_MSG_RESULT([no])
+  ])
+  LIBS=$AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])
+  AS_IF([test $AS_TR_SH([ac_check_lib_nocache_ok_$1_$2]) = 'yes'],
+  [m4_if([$3], [], [:], [$3])],
+  [m4_if([$4], [], [:], [$4])])
+])
+ 
+AC_DEFUN([AC_CHECK_HEADER_NOCACHE_HDF4],
+[
+  AS_TR_SH([ac_check_header_nocache_compile_$1])='no'
+  AS_TR_SH([ac_check_header_nocache_preproc_$1])='no'
+  AC_MSG_CHECKING([for $1 with compiler])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
+    [
+      AC_MSG_RESULT([yes])
+      AS_TR_SH([ac_check_header_nocache_compile_$1])='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+    ])
+  AC_MSG_CHECKING([for $1 with preprocessor])
+  AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
+    [
+      AC_MSG_RESULT([yes])
+      AS_TR_SH([ac_check_header_nocache_preproc_$1])='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
+        [AC_MSG_WARN([trusting compiler result, ignoring preprocessor error])])
+    ])
+  AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
+  [m4_if([$2], [], [:], [$2])],
+  [m4_if([$3], [], [:], [$3])])
+])
diff --git a/m4/hdf5.m4 b/m4/hdf5.m4
new file mode 100644
index 0000000..5b3d994
--- /dev/null
+++ b/m4/hdf5.m4
@@ -0,0 +1,155 @@
+dnl AC_CHECK_HDF5 : Check for hdf5
+dnl args :             action-if-yes, action-if-no
+AC_DEFUN([AC_CHECK_HDF5],
+[
+  AC_ARG_WITH([hdf5],
+            [AS_HELP_STRING([--with-hdf5=ARG],[hdf5 directory])],
+            [HDF5_PATH=$withval], 
+            [HDF5_PATH=""])
+
+  AC_ARG_WITH([hdf5_include],
+            [AS_HELP_STRING([--with-hdf5-include=ARG],[hdf5 include directory])],
+            [HDF5_PATH_INC=$withval],
+            [HDF5_PATH_INC=""])
+
+  AC_ARG_WITH([hdf5_libdir],
+            [AS_HELP_STRING([--with-hdf5-libdir=ARG],[hdf5 library directory])],
+            [HDF5_PATH_LIBDIR=$withval], 
+            [HDF5_PATH_LIBDIR=""])
+
+  AS_IF([test "z$HDF5_PATH" != "z"],
+  [
+    AS_IF([test "z$HDF5_PATH_LIBDIR" = "z"],
+      [HDF5_PATH_LIBDIR="$HDF5_PATH/lib"])  
+    AS_IF([test "z$HDF5_PATH_INC" = "z"],
+      [HDF5_PATH_INC="$HDF5_PATH/include"])  
+  ])
+  
+  
+  ac_hdf5_lib_ok='no'
+  ac_hdf5_save_LDFLAGS=$LDFLAGS
+  HDF5_LIBS=
+  AS_IF([test "z$HDF5_PATH_LIBDIR" != "z"],
+    [
+      HDF5_LDFLAGS="-L$HDF5_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $HDF5_LDFLAGS"
+      AC_CHECK_HDF5_LIB([ac_hdf5_lib_ok='yes'])
+    ],
+    [
+      for ac_hdf5_libdir in "" /usr/local/hdf5/lib64/ /opt/hdf5/lib64 /usr/hdf5/lib64 \
+       /usr/local/lib64/hdf5 /opt/lib64/hdf5 /usr/lib64/hdf5 /usr/lib64 \
+       /usr/local/hdf5/lib/ /opt/hdf5/lib /usr/hdf5/lib \
+       /usr/local/lib/hdf5 /opt/lib/hdf5 /usr/lib/hdf5 /usr/lib ; do
+        AS_IF([test "z$ac_hdf5_libdir" = 'z'],
+           [HDF5_LDFLAGS=],
+           [
+             AC_MSG_NOTICE([searching hdf5 libraries in $ac_hdf5_libdir])
+             HDF5_LDFLAGS="-L$ac_hdf5_libdir"
+           ])
+        LDFLAGS="$LDFLAGS $HDF5_LDFLAGS" 
+        AC_CHECK_HDF5_LIB([ac_hdf5_lib_ok='yes'])
+        AS_IF([test $ac_hdf5_lib_ok = 'yes'],[break])
+        LDFLAGS=$ac_hdf5_save_LDFLAGS
+      done
+    ])
+  LDFLAGS=$ac_hdf5_save_LDFLAGS
+  
+  ac_hdf5_h='no'
+  HDF5_CFLAGS=
+  ac_hdf5_save_CPPFLAGS=$CPPFLAGS
+  AS_IF([test "z$HDF5_PATH_INC" != "z"],
+    [
+       HDF5_CFLAGS="-I$HDF5_PATH_INC"
+       CPPFLAGS="$CPPFLAGS $HDF5_CFLAGS"
+       AC_CHECK_HEADER_NOCACHE_HDF5([hdf5.h],[ac_hdf5_h='yes'])
+    ],
+    [
+      for ac_hdf5_incdir in "" /usr/include /usr/local/hdf5/include \
+       /opt/hdf5/include /usr/hdf5/include /usr/local/include/hdf5 \
+       /opt/include/hdf5 /usr/include/hdf5 ; do
+        AS_IF([test "z$ac_hdf5_incdir" = 'z'],
+           [HDF5_CFLAGS=],
+           [
+             AC_MSG_NOTICE([searching hdf5 includes in $ac_hdf5_incdir])
+             HDF5_CFLAGS="-I$ac_hdf5_incdir"
+           ])
+        CPPFLAGS="$CPPFLAGS $HDF5_CFLAGS" 
+        AC_CHECK_HEADER_NOCACHE_HDF5([hdf5.h],[ac_hdf5_h='yes'])
+        AS_IF([test $ac_hdf5_h = 'yes'],[break])
+        CPPFLAGS=$ac_hdf5_save_CPPFLAGS
+      done
+    ])
+  CPPFLAGS=$ac_hdf5_save_CPPFLAGS
+  
+  AS_IF([test "$ac_hdf5_h" = 'yes' -a "$ac_hdf5_lib_ok" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+
+  AC_SUBST([HDF5_LIBS])
+  AC_SUBST([HDF5_CFLAGS])
+  AC_SUBST([HDF5_LDFLAGS])
+])
+
+AC_DEFUN([AC_CHECK_HDF5_LIB],
+[
+  HDF5_LIBS=
+  ac_hdf5_save_LIBS=$LIBS
+  AC_CHECK_LIB_NOCACHE_HDF5([sz], [main],
+  [
+      LIBS="$LIBS -lsz"
+      HDF5_LIBS='-lsz'
+  ])
+
+dnl -lsz is not required because due to licencing it may not be present
+dnl nor required everywhere
+  ac_hdf5_lib='no'
+  AC_CHECK_LIB_NOCACHE_HDF5([z],[compress],
+  [ AC_CHECK_LIB_NOCACHE_HDF5([jpeg],[main],
+    [ AC_CHECK_LIB_NOCACHE_HDF5([hdf5],[H5Fopen],
+      [ ac_hdf5_lib="yes"
+          HDF5_LIBS="-lhdf5 -ljpeg -lz $HDF5_LIBS"
+      ],[],[-lhdf5 -ljpeg -lz])
+    ])
+  ])
+  LIBS=$ac_hdf5_save_LIBS
+  
+  AS_IF([test "$ac_hdf5_lib" = 'yes'],
+  [m4_if([$1], [], [:], [$1])],
+  [m4_if([$2], [], [:], [$2])])
+])
+
+AC_DEFUN([AC_CHECK_LIB_NOCACHE_HDF5],
+[
+  AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='no'
+  AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])=$LIBS
+  LIBS="-l$1 $5 $LIBS"
+  AC_MSG_CHECKING([for $2 in -l$1])
+  AC_LINK_IFELSE([AC_LANG_CALL([], [$2])],
+  [ 
+    AS_TR_SH([ac_check_lib_nocache_ok_$1_$2])='yes' 
+    AC_MSG_RESULT([yes])
+  ],[ 
+    AC_MSG_RESULT([no])
+  ])
+  LIBS=$AS_TR_SH([ac_check_lib_nocache_$1_$2_LIBS])
+  AS_IF([test $AS_TR_SH([ac_check_lib_nocache_ok_$1_$2]) = 'yes'],
+  [m4_if([$3], [], [:], [$3])],
+  [m4_if([$4], [], [:], [$4])])
+])
+ 
+AC_DEFUN([AC_CHECK_HEADER_NOCACHE_HDF5],
+[
+  AS_TR_SH([ac_check_header_nocache_compile_$1])='no'
+  AC_MSG_CHECKING([for $1 with compiler])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <$1>]])],
+    [
+      AC_MSG_RESULT([yes])
+      AS_TR_SH([ac_check_header_nocache_compile_$1])='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+    ])
+  AS_IF([test "$AS_TR_SH([ac_check_header_nocache_compile_$1])" = 'yes'],
+  [m4_if([$2], [], [:], [$2])],
+  [m4_if([$3], [], [:], [$3])])
+])
diff --git a/m4/libdap.m4 b/m4/libdap.m4
new file mode 100644
index 0000000..88ff737
--- /dev/null
+++ b/m4/libdap.m4
@@ -0,0 +1,314 @@
+# -*- mode: autoconf -*-
+# Configure macros for Libdap
+#
+# Code for version detection and comparison comes from freetype2.m4
+# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+#
+# Copyright 2001, 2003 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+#
+# As a special exception to the FreeType project license, this file may be
+# distributed as part of a program that contains a configuration script
+# generated by Autoconf, under the same distribution terms as the rest of
+# that program.
+#
+# modified by Patrice Dumas 2005 for libdap
+#
+# AC_CHECK_DODS is based on code from gdal configure.in
+
+# AC_CHECK_LIBDAP([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libdap and define DAP_CFLAGS and DAP_LIBS.
+# Check that the version is above MINIMUM-VERSION 
+# use when linking with a c++ aware linker, with a c linker you may also
+# need -lstdc++
+
+AC_DEFUN([AC_CHECK_LIBDAP],
+[
+  dap_min_version=m4_if([$1], [], [3.5.0], [$1])
+  dap_no=
+  dap_pkgconfig_libdap=yes 
+  PKG_CHECK_MODULES([DAP],[libdap >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  PKG_CHECK_MODULES([DAP_CLIENT],[libdapclient >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  PKG_CHECK_MODULES([DAP_SERVER],[libdapserver >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  
+  if test $dap_pkgconfig_libdap = no; then
+    AC_PATH_PROG([DAP_CONFIG], [dap-config], [no])
+    if test "$DAP_CONFIG" = "no" ; then
+      dap_no=yes
+    else
+      dap_config_major_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\1/'`
+      dap_config_minor_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\2/'`
+      dap_config_micro_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\2/'`
+      dap_min_major_version=`echo $dap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+      dap_min_minor_version=`echo $dap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+      dap_min_micro_version=`echo $dap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+      dap_config_is_lt=""
+      if test $dap_config_major_version -lt $dap_min_major_version ; then
+        dap_config_is_lt=yes
+      else
+        if test $dap_config_major_version -eq $dap_min_major_version ; then
+          if test $dap_config_minor_version -lt $dap_min_minor_version ; then
+            dap_config_is_lt=yes
+          else
+            if test $dap_config_minor_version -eq $dap_min_minor_version ; then
+              if test $dap_config_micro_version -lt $dap_min_micro_version ; then
+                dap_config_is_lt=yes
+              fi
+            fi
+          fi
+        fi
+      fi
+      if test x$dap_config_is_lt = xyes ; then
+        dap_no=yes
+      else
+        DAP_LIBS="`$DAP_CONFIG --libs`"
+        if ($DAP_CONFIG --client-libs 2>&1 | grep unknown) >/dev/null 2>&1; then
+          DAP_CLIENT_LIBS=$DAP_LIBS
+          DAP_SERVER_LIBS=$DAP_LIBS
+        else
+          DAP_CLIENT_LIBS="`$DAP_CONFIG --client-libs`"
+          DAP_SERVER_LIBS="`$DAP_CONFIG --server-libs`"
+        fi
+        DAP_CFLAGS="`$DAP_CONFIG --cflags`"
+      fi
+    fi
+  else
+     DAP_STATIC_LIBS="`$PKG_CONFIG --static --libs libdap`"
+     DAP_CLIENT_STATIC_LIBS="`$PKG_CONFIG --static --libs libdapclient`"
+     DAP_SERVER_STATIC_LIBS="`$PKG_CONFIG --static --libs libdapserver`"
+  fi
+  AC_MSG_CHECKING([for libdap version >= $dap_min_version])
+  if test x$dap_no = x ; then
+    AC_MSG_RESULT([yes])
+    m4_if([$2], [], [:], [$2])
+  else
+    AC_MSG_RESULT([no])
+    if test "$DAP_CONFIG" = "no" ; then
+    AC_MSG_NOTICE([The dap-config script could not be found.])
+    else
+      if test x$dap_config_is_lt = xyes ; then
+        AC_MSG_NOTICE([the installed libdap library is too old.])
+      fi
+    fi
+    DAP_LIBS=""
+    DAP_CFLAGS=""
+    m4_if([$3], [], [:], [$3])
+  fi
+  if test x"$DAP_CFLAGS" != x -a x"$DAP_CLIENT_CFLAGS" = x ; then
+    DAP_CLIENT_CFLAGS=$DAP_CFLAGS
+  fi
+  if test x"$DAP_CFLAGS" != x -a x"$DAP_SERVER_CFLAGS" = x ; then
+    DAP_SERVER_CFLAGS=$DAP_CFLAGS
+  fi
+  if test x"$DAP_STATIC_LIBS" = x ; then
+    DAP_STATIC_LIBS=$DAP_LIBS
+    DAP_CLIENT_STATIC_LIBS=$DAP_CLIENT_LIBS
+    DAP_SERVER_STATIC_LIBS=$DAP_SERVER_LIBS
+  fi
+  AC_SUBST([DAP_CFLAGS])
+  AC_SUBST([DAP_CLIENT_CFLAGS])
+  AC_SUBST([DAP_SERVER_CFLAGS])
+  AC_SUBST([DAP_LIBS])
+  AC_SUBST([DAP_CLIENT_LIBS])
+  AC_SUBST([DAP_SERVER_LIBS])
+  AC_SUBST([DAP_STATIC_LIBS])
+  AC_SUBST([DAP_CLIENT_STATIC_LIBS])
+  AC_SUBST([DAP_SERVER_STATIC_LIBS])
+]) 
+
+# AC_CHECK_DODS([ ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libdap or older versions. Define DAP_CFLAGS and DAP_LIBS and
+# optionnaly DAP_ROOT
+
+AC_DEFUN([AC_CHECK_DODS],
+[
+  AC_ARG_WITH([dods_root],
+    [AS_HELP_STRING([--with-dods-root=ARG],[DODS root fallback])],
+    ,,)
+
+  ac_dods_ok='no'
+  DAP_ROOT=
+  AC_MSG_CHECKING([DODS specific root])
+  if test -z "$with_dods_root" -o "$with_dods_root" = "no"; then
+    AC_MSG_RESULT([disabled])
+  else
+    AC_MSG_RESULT([$with_dods_root])
+    DODS_ROOT=$with_dods_root
+    DODS_LIB=$with_dods_root/lib
+    DODS_INC=$with_dods_root/include
+    DODS_BIN=$with_dods_root/bin
+
+    dnl Add the DODS libraries to LIBS
+    if test -x "$DODS_BIN/opendap-config" ; then 
+      dnl OPeNDAP 3.4 and earlier lack opendap-config, but use it if avail.
+      DAP_LIBS="`$DODS_BIN/opendap-config --libs`"
+      DAP_CFLAGS="`$DODS_BIN/opendap-config --cflags`"
+      ac_dods_ok='yes'
+    elif test -x "$DODS_BIN/dap-config" ; then
+      dnl for OPeNDAP 3.5
+      DAP_LIBS="`$DODS_BIN/dap-config --libs`"
+      DAP_CFLAGS="`$DODS_BIN/dap-config --cflags`"
+      ac_dods_ok='yes'
+    else
+      dnl Otherwise try to put things together in a more primitive way.
+      DAP_LIBS="-L$DODS_LIB -ldap++ -lpthread"
+      DAP_CFLAGS="-I$DODS_INC"
+    
+      ac_dods_curl='yes'
+      dnl Add curl to LIBS; it might be local to DODS or generally installed
+      AC_MSG_CHECKING([For curl])
+      if test -x "$DODS_BIN/curl-config"; then
+         DAP_LIBS="$DAP_LIBS  `$DODS_BIN/curl-config --libs`"
+      elif which curl-config > /dev/null 2>&1; then
+         DAP_LIBS="$DAP_LIBS  `curl-config --libs`"
+      else
+         ac_dods_curl='no'
+      fi
+      if test $ac_dods_curl = 'no' ; then
+         AC_MSG_RESULT([no]) 
+         dnl AC_MSG_WARN([You gave a dods root, but I can't find curl!])
+      else
+         AC_MSG_RESULT([yes])
+      fi 
+         
+      
+      AC_MSG_CHECKING([For libxml2])
+      ac_dods_xml2='yes'
+      if test -x "$DODS_BIN/xml2-config"; then
+         DAP_LIBS="$DAP_LIBS `$DODS_BIN/xml2-config --libs`"
+      elif which xml2-config > /dev/null 2>&1; then
+         DAP_LIBS="$DAP_LIBS  `xml2-config --libs`"
+      else
+         ac_dods_xml2='no'
+      fi
+      if test $ac_dods_xml2 = 'no' ; then
+         AC_MSG_RESULT([no]) 
+         dnl AC_MSG_WARN([You gave a dods root, but I can't find xml2!])
+      else
+         AC_MSG_RESULT([yes])
+      fi 
+         
+      AC_LANG_PUSH([C++])
+      if test $ac_dods_xml2 = 'yes' -a $ac_dods_curl = 'yes'; then
+         dnl We check that linking is succesfull
+         ac_save_LIBS=$LIBS
+         ac_save_CFLAGS=$CFLAGS
+         LIBS="$LIBS $DAP_LIBS"
+         CFLAGS="$CFLAGS $DAP_CFLAGS"
+         dnl AC_CHECK_LIB is not used because it caches results
+         dnl AC_CHECK_LIB([dap++],[main],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+         AC_MSG_CHECKING([for DODS with curl and libxml2])
+         AC_LINK_IFELSE([AC_LANG_CALL([],[main])],[
+           ac_dods_ok='yes'
+           AC_MSG_RESULT([yes])
+         ],[
+           ac_dods_ok='no'
+           AC_MSG_RESULT([no])
+         ])
+         LIBS=$ac_save_LIBS
+         CFLAGS=$ac_save_CFLAGS
+         if test "z$ac_dods_ok" = "zno"; then
+           ac_save_LIBS=$LIBS
+           ac_save_CFLAGS=$CFLAGS
+           LIBS="$LIBS $DAP_LIBS -lrx"
+           CFLAGS="$CFLAGS $DAP_CFLAGS"
+           AC_MSG_CHECKING([for DODS with curl, libxml2 and librx])
+           AC_LINK_IFELSE([AC_LANG_CALL([],[main])],[
+               AC_MSG_RESULT([yes])
+               ac_dods_ok='yes'
+               DAP_LIBS="$DAP_LIBS -lrx"
+           ],[
+               ac_dods_ok='no'
+               AC_MSG_RESULT([no])
+           ])
+           LIBS=$ac_save_LIBS
+           CFLAGS=$ac_save_CFLAGS
+         fi
+      fi
+      if test $ac_dods_ok = 'no'; then
+         dnl assume it is an old version of DODS
+         AC_MSG_NOTICE([Checking for DODS with libwww and librx])
+         DAP_LIBS="-L$DODS_LIB -ldap++ -lwww -lpthread -lrx"
+         DAP_CFLAGS="-I$DODS_INC"
+         ac_save_LIBS=$LIBS
+         ac_save_CFLAGS=$CFLAGS
+         LIBS="$LIBS $DAP_LIBS"
+         CFLAGS="$CFLAGS $DAP_CFLAGS"
+         AC_CHECK_LIB([dap++],[main],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+         LIBS=$ac_save_LIBS
+         CFLAGS=$ac_save_CFLAGS
+      fi
+      AC_LANG_POP
+    fi
+      
+    AC_MSG_CHECKING([for DODS in a specific root])
+    if test "z$ac_dods_ok" = "zyes"; then
+       AC_MSG_RESULT([yes])
+       AC_MSG_NOTICE([setting DAP_ROOT directory to $DODS_ROOT])
+       DAP_ROOT=$DODS_ROOT
+    else
+       AC_MSG_RESULT([no])
+    fi
+  fi
+  if test "z$ac_dods_ok" = "zno" ; then
+     AC_CHECK_LIBDAP([],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+     if test "z$ac_dods_ok" = "zno" ; then
+       AC_PATH_PROG([OPENDAP_CONFIG], [opendap-config], [no])
+       AC_MSG_CHECKING([for libdap with opendap-config])
+       if test "$OPENDAP_CONFIG" = "no" ; then
+         ac_dods_ok='no'
+         AC_MSG_RESULT([no])
+       else
+         DAP_LIBS="`$OPENDAP_CONFIG --libs`"
+         DAP_CFLAGS="`$OPENDAP_CONFIG --cflags`"
+         ac_dods_ok='yes'
+         AC_MSG_RESULT([yes])
+       fi
+     fi
+  fi 
+  if test "x$ac_dods_ok" = "xyes" ; then
+     if test "z$DAP_CLIENT_LIBS" = 'z' ; then
+       DAP_CLIENT_LIBS=$DAP_LIBS
+       DAP_SERVER_LIBS=$DAP_LIBS
+     fi
+     if test x"$DAP_CFLAGS" != x -a x"$DAP_CLIENT_CFLAGS" = x ; then
+        DAP_CLIENT_CFLAGS=$DAP_CFLAGS
+     fi
+     if test x"$DAP_CFLAGS" != x -a x"$DAP_SERVER_CFLAGS" = x ; then
+       DAP_SERVER_CFLAGS=$DAP_CFLAGS
+     fi
+     if test x"$DAP_STATIC_LIBS" = x ; then
+       DAP_STATIC_LIBS=$DAP_LIBS
+       DAP_CLIENT_STATIC_LIBS=$DAP_CLIENT_LIBS
+       DAP_SERVER_STATIC_LIBS=$DAP_SERVER_LIBS
+     fi
+     m4_if([$1], [], [:], [$1])
+  else
+     DAP_LIBS=""
+     DAP_CFLAGS=""
+     DAP_CLIENT_LIBS=""
+     DAP_SERVER_LIBS=""
+     m4_if([$2], [], [:], [$2])
+  fi
+dnl done above
+dnl  AC_SUBST([DAP_CFLAGS])
+dnl  AC_SUBST([DAP_CLIENT_CFLAGS])
+dnl  AC_SUBST([DAP_SERVER_CFLAGS])
+dnl  AC_SUBST([DAP_LIBS])
+dnl  AC_SUBST([DAP_CLIENT_LIBS])
+dnl  AC_SUBST([DAP_SERVER_LIBS])
+dnl  AC_SUBST([DAP_STATIC_LIBS])
+dnl  AC_SUBST([DAP_CLIENT_STATIC_LIBS])
+dnl  AC_SUBST([DAP_SERVER_STATIC_LIBS])
+dnl  AC_SUBST([DAP_ROOT])
+])
diff --git a/m4/libnc-dap.m4 b/m4/libnc-dap.m4
new file mode 100644
index 0000000..1d18b05
--- /dev/null
+++ b/m4/libnc-dap.m4
@@ -0,0 +1,265 @@
+# -*- mode: autoconf -*-
+# Configure macro for Libnc-dap
+#
+# Code for version detection and comparison comes from freetype2.m4
+# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+#
+# Copyright 2001, 2003 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+#
+# As a special exception to the FreeType project license, this file may be
+# distributed as part of a program that contains a configuration script
+# generated by Autoconf, under the same distribution terms as the rest of
+# that program.
+#
+# Patrice Dumas 2005 Libnc-dap specific code
+
+# AC_CHECK_LIBNC_DAP([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libnc-dap and define NC_DAP_CFLAGS and NC_DAP_LIBS.
+# Check that the version is above MINIMUM-VERSION 
+# Check for the inclusion of a netcdf.h header file with netcdf 3 interface
+AC_DEFUN([AC_CHECK_LIBNC_DAP],
+[
+  ncdap_header_ok='no'
+  ncdap_lib_ok='no'
+
+  ncdap_pkgconfig_libncdap=yes
+  ncdap_min_version=m4_if([$1], [], [3.5.0], [$1])
+  PKG_CHECK_MODULES([NC_DAP],[libnc-dap >= $ncdap_min_version],,
+    [ncdap_pkgconfig_libncdap=no])
+
+  if test $ncdap_pkgconfig_libncdap = yes ; then
+    ncdap_lib_ok=yes
+    ncdap_header_ok=yes
+  else
+    AC_CHECK_LIBNC_DAP_LIB([$1],[ncdap_lib_ok='yes'],
+      [ncdap_lib_ok='no'])
+    ncdap_save_CPPFLAGS=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS $NC_DAP_CFLAGS"
+    AC_CHECK_NETCDF_DAP_HEADER([],[ncdap_header_ok='yes'],
+      [ncdap_header_ok='no'],[3])
+    CPPFLAGS=$ncdap_save_CPPFLAGS
+  fi
+
+  if test "$ncdap_lib_ok" = 'yes' -a "$ncdap_header_ok" = 'yes' ; then
+    m4_if([$2], [], [:], [$2])
+  else
+    m4_if([$3], [], [:], [$3])
+  fi
+])
+
+# AC_CHECK_LIBNC_DAP_LIB([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libnc-dap and define NC_DAP_CFLAGS and NC_DAP_LIBS.
+# Check that the version is above MINIMUM-VERSION
+AC_DEFUN([AC_CHECK_LIBNC_DAP_LIB],
+[
+  AC_PATH_PROG([NC_DAP_CONFIG], [ncdap-config], [no])
+  ncdap_min_version=m4_if([$1], [], [3.5.0], [$1])
+  AC_MSG_CHECKING([for libnc-dap version >= $ncdap_min_version])
+  ncdap_ok='no'
+  if test "$NC_DAP_CONFIG" = "no" ; then
+     ncdap_ok='no'
+  else
+     ncdap_config_major_version=`$NC_DAP_CONFIG --version | sed 's/^libnc-dap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\1/'`
+     ncdap_config_minor_version=`$NC_DAP_CONFIG --version | sed 's/^libnc-dap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\2/'`
+     ncdap_config_micro_version=`$NC_DAP_CONFIG --version | sed 's/^libnc-dap \([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$/\2/'`
+     ncdap_min_major_version=`echo $ncdap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+     ncdap_min_minor_version=`echo $ncdap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+     ncdap_min_micro_version=`echo $ncdap_min_version | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+     ncdap_config_is_lt='no'
+     if test $ncdap_config_major_version -lt $ncdap_min_major_version ; then
+       ncdap_config_is_lt='yes'
+     else
+       if test $ncdap_config_major_version -eq $ncdap_min_major_version ; then
+         if test $ncdap_config_minor_version -lt $ncdap_min_minor_version ; then
+           ncdap_config_is_lt='yes'
+         else
+           if test $ncdap_config_minor_version -eq $ncdap_min_minor_version ; then
+             if test $ncdap_config_micro_version -lt $ncdap_min_micro_version ; then
+               ncdap_config_is_lt='yes'
+             fi
+           fi
+         fi
+       fi
+     fi
+     if test "x$ncdap_config_is_lt" = "xyes" ; then
+       ncdap_ok='no'
+     else
+       NC_DAP_LIBS="`$NC_DAP_CONFIG --libs`"
+       NC_DAP_CFLAGS="`$NC_DAP_CONFIG --cflags`"
+     fi
+   fi
+   if test "x$ncdap_ok" = 'xyes' ; then
+     AC_MSG_RESULT([yes])
+     m4_if([$2], [], [:], [$2])
+   else
+     AC_MSG_RESULT([no])
+     if test "$NC_DAP_CONFIG" = "no" ; then
+     AC_MSG_NOTICE([The ncdap-config script could not be found.])
+     else
+       if test x$ncdap_config_is_lt = xyes ; then
+         AC_MSG_NOTICE([The installed libnc-dap library is too old.])
+       fi
+     fi
+     NC_DAP_LIBS=""
+     NC_DAP_CFLAGS=""
+     m4_if([$3], [], [:], [$3])
+     
+   fi
+   AC_SUBST([NC_DAP_CFLAGS])
+   AC_SUBST([NC_DAP_LIBS])
+]) 
+
+
+# AC_FC_CHECK_LIBNC_DAP([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libnc-dap and define NC_DAP_FFLAGS and NC_DAP_FLIBS with flags
+# for fortran.
+# Check that the version is above MINIMUM-VERSION 
+
+AC_DEFUN([AC_FC_CHECK_LIBNC_DAP],
+[
+  libnc_fc_dap_ok="no"
+  AC_CHECK_LIBNC_DAP_LIB([$1],[libnc_fc_dap_ok="yes"],[libnc_fc_dap_ok="no"])
+  if test $libnc_fc_dap_ok = "yes"; then
+     NC_DAP_FLIBS="`$NC_DAP_CONFIG --flibs`"
+     NC_DAP_FFLAGS="$NC_DAP_CFLAGS"
+     m4_if([$2], [], [:], [$2])
+  else
+     m4_if([$3], [], [:], [$3])
+     NC_DAP_FLIBS=""
+     NC_DAP_FFLAGS=""
+  fi
+  AC_SUBST([NC_DAP_FFLAGS])
+  AC_SUBST([NC_DAP_FLIBS])
+])
+
+# AC_CHECK_NC_DODS([ ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libnc-dap or older versions. Define NC_DAP_CFLAGS and NC_DAP_LIBS.
+# check for the netcdf.h file inclusion
+# the old way of finding libs is used first to allow the user to 
+# specify a root with the 'old style' nc-dods all-in-a-root.
+AC_DEFUN([AC_CHECK_NC_DODS],
+[
+  ncdods_header_ok='no'
+  ncdods_lib_ok='no'
+  
+# we find lib using pkg-config now, before we set NC_DAP_* to something else, 
+# and we keep the result. 
+  ncdods_pkgconfig_ncdods=yes
+  PKG_CHECK_MODULES([NC_DAP],[libnc-dap],,
+    [ncdods_pkgconfig_ncdods=no])
+  if test $ncdods_pkgconfig_ncdods = yes ; then
+    ncdods_pkgconfig_NC_DAP_LIBS=$NC_DAP_LIBS
+    ncdods_pkgconfig_NC_DAP_CFLAGS=$NC_DAP_CFLAGS
+    NC_DAP_LIBS=
+    NC_DAP_CFLAGS=
+  fi
+
+  AC_CHECK_NC_DODS_LIB([ncdods_lib_ok='yes'],
+     [ncdods_lib_ok='no'])
+  ncdods_save_CPPFLAGS=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS $NC_DAP_CFLAGS"
+  AC_CHECK_NETCDF_DAP_HEADER([],[ncdods_header_ok='yes'],
+    [ncdods_header_ok='no'])
+  CPPFLAGS=$ncdods_save_CPPFLAGS
+
+# if the 'old style' failed or DAP_ROOT is unset and pkg-config succeded, 
+# use pkg-config
+  if test "$ncdods_lib_ok" = 'no' -o "$ncdods_header_ok" = 'no' -o "z$DAP_ROOT" = 'z' ; then
+    if test $ncdods_pkgconfig_ncdods = 'yes' ; then
+      NC_DAP_LIBS=$ncdods_pkgconfig_NC_DAP_LIBS
+      NC_DAP_CFLAGS=$ncdods_pkgconfig_NC_DAP_CFLAGS
+      ncdods_lib_ok=yes
+      ncdods_header_ok=yes
+    fi
+  fi
+
+  if test "$ncdods_lib_ok" = 'yes' -a "$ncdods_header_ok" = 'yes' ; then
+    m4_if([$1], [], [:], [$1])
+  else
+    m4_if([$2], [], [:], [$2])
+  fi
+])
+
+# AC_CHECK_NC_DODS_LIB([ ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libnc-dap or older versions. Define NC_DAP_CFLAGS and NC_DAP_LIBS.
+# use AC_CHECK_DODS first
+AC_DEFUN([AC_CHECK_NC_DODS_LIB],
+[
+  ac_ncdods_ok='no'
+  ac_ncdods_dap_ok='no'
+  NC_DAP_LIBS=
+  NC_DAP_CFLAGS=
+  dnl it may happen that the cflags are not the ones associated 
+  dnl with -L and -l flags, however even in that case the most recent 
+  dnl netcdf.h should be picked up and things should go smoothly
+  AC_PATH_PROG([OPENNC_DAP_CONFIG], [opendap-config], [no])
+  if test "$OPENNC_DAP_CONFIG" != "no" ; then
+     NC_DAP_CFLAGS="`$OPENNC_DAP_CONFIG --cflags`"
+  fi
+  AC_PATH_PROG([NC_DAP_CONFIG], [ncdap-config], [no])
+  if test "$NC_DAP_CONFIG" != "no" ; then
+     NC_DAP_CFLAGS="`$NC_DAP_CONFIG --cflags`"
+  fi
+  AC_CHECK_DODS([ac_ncdods_dap_ok='yes'],[ac_ncdods_dap_ok='no'])
+  if test "z$ac_ncdods_dap_ok" = 'zyes'; then
+     if test "z$DAP_ROOT" != "z" ; then
+        NC_DAP_CFLAGS=$DAP_ROOT/include
+     fi
+     dnl We check that linking is succesfull
+     dnl instead of using a C++ compiler we add -lstdc++
+     dnl AC_LANG_PUSH([C++])
+     NC_DAP_LIBS="-lnc-dap $DAP_LIBS -ldap"
+     ac_save_LIBS=$LIBS
+     LIBS="$LIBS $NC_DAP_LIBS -lstdc++"
+     AC_MSG_CHECKING([for nc_open with -lnc-dap -ldap])
+     AC_LINK_IFELSE([AC_LANG_CALL([],[nc_open])],
+       [ ac_ncdods_ok='yes'
+         AC_MSG_RESULT([yes])
+       ],[ ac_ncdods_ok='no'
+         AC_MSG_RESULT([no])
+       ])
+     LIBS=$ac_save_LIBS
+     if test $ac_ncdods_ok = 'no' ; then
+       NC_DAP_LIBS="-lnc-dods $DAP_LIBS -ldap++"
+       LIBS="$LIBS $NC_DAP_LIBS -lstdc++"
+       AC_MSG_CHECKING([for nc_open with -lnc-dods -ldap++])
+       AC_LINK_IFELSE([AC_LANG_CALL([],[nc_open])],
+         [ ac_ncdods_ok='yes'
+           AC_MSG_RESULT([yes])
+         ],[ ac_ncdods_ok='no'
+           AC_MSG_RESULT([no])
+         ])
+       LIBS=$ac_save_LIBS
+     fi
+     dnl AC_LANG_POP
+  fi
+  if test $ac_ncdods_ok = no ; then
+    AC_CHECK_LIBNC_DAP_LIB([],[ac_ncdods_ok='yes'],[ac_ncdods_ok='no'])
+    if test "z$ac_ncdods_ok" = "zno" ; then
+      AC_MSG_CHECKING([for libnc-dap with opendap-config])
+      if test "$OPENNC_DAP_CONFIG" = "no" ; then
+        ac_ncdods_ok='no'
+        AC_MSG_RESULT([no])
+      else
+        NC_DAP_LIBS="`$OPENNC_DAP_CONFIG --libs-nc`"
+        ac_ncdods_ok='yes'
+        AC_MSG_RESULT([yes])
+      fi
+    fi
+  fi 
+  if test "x$ac_ncdods_ok" = "xyes" ; then
+     m4_if([$1], [], [:], [$1])
+  else
+     m4_if([$2], [], [:], [$2])
+  fi
+  AC_SUBST([NC_DAP_CFLAGS])
+  AC_SUBST([NC_DAP_LIBS])
+])
diff --git a/m4/libnc-dap_header.m4 b/m4/libnc-dap_header.m4
new file mode 100644
index 0000000..e0123bf
--- /dev/null
+++ b/m4/libnc-dap_header.m4
@@ -0,0 +1,97 @@
+# Check for the netcdf header.
+# AC_CHECK_NETCDF_DAP_HEADER([INCLUDE-DIR],[ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND],[INTERFACE-NR])
+# if interface number is given, check for a specific interface
+# sets NC_CPPFLAGS and maybe NC_NETCDF_3_CPPFLAG
+AC_DEFUN([AC_CHECK_NETCDF_DAP_HEADER],
+[
+  NC_CPPFLAGS=
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+  
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  m4_if([$1],[],[:],[
+    ac_nc_include_dir="$1"
+    AS_IF([test "z$ac_nc_include_dir" != "z"],
+       [CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"])
+  ])
+  m4_if([$4],[],[:],[ac_nc_header_interface=$4])
+dnl dont use AC_CHECK_HEADERS to avoid autoconf internal caching
+  AC_MSG_CHECKING([for netcdf.h with compiler])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
+    [
+      AC_MSG_RESULT([yes])
+      ac_netcdf_h_compile='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      ac_netcdf_h_compile='no'
+    ])
+    AC_MSG_CHECKING([for netcdf.h with preprocessor])
+    AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
+    [
+      AC_MSG_RESULT([yes])
+      ac_netcdf_h_preproc='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      ac_netcdf_h_preproc='no'
+    ])
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  AS_IF([test $ac_netcdf_h_compile = 'yes'],
+    [ac_netcdf_h='yes'
+    AS_IF([test "z$ac_nc_header_interface" = 'z3'],
+      [AC_CHECK_NETCDF_3_DAP_HEADER([$1],
+         [ac_netcdf_h='yes'],[ac_netcdf_h='no'])])
+    ])
+
+  AS_IF([test "$ac_netcdf_h" = 'yes'],
+    [
+      AS_IF([test "z$ac_nc_include_dir" != "z"],
+        [NC_CPPFLAGS="-I$ac_nc_include_dir"])
+      m4_if([$2], [], [:], [$2])
+    ],
+    [m4_if([$3], [], [:], [$3])])
+
+  AC_SUBST([NC_CPPFLAGS])
+])
+
+AC_DEFUN([AC_CHECK_NETCDF_3_DAP_HEADER],
+[
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  AC_MSG_CHECKING([for netcdf 3 interface])
+  m4_if([$1],[],[:],[
+    ac_check_netcdf_3_include="$1"
+  ])
+  AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
+    [CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netcdf.h>]],
+    [[int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();]])],
+    [
+      AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
+        [NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"])
+      ac_check_netcdf_3_header='yes'
+    ],[ac_check_netcdf_3_header='no'])
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  AS_IF([test "$ac_check_netcdf_3_header" = 'yes'],
+    [
+      AC_MSG_RESULT([yes])
+      m4_if([$2], [], [:], [$2])
+    ],
+    [
+      AC_MSG_RESULT([no])
+      m4_if([$3], [], [:], [$3])
+    ])
+  
+  AC_SUBST([NC_NETCDF_3_CPPFLAG])
+])
diff --git a/m4/libsx.m4 b/m4/libsx.m4
new file mode 100644
index 0000000..e407756
--- /dev/null
+++ b/m4/libsx.m4
@@ -0,0 +1,84 @@
+dnl GA_CHECK_LIBSX : Checks whether GrADS can be built with libsx
+dnl  		      	enabled.
+dnl  args : 		action-if-yes, action-if-no
+AC_DEFUN([GA_CHECK_LIBSX],
+[
+# Check libs and headers for GUI widgets
+  GA_LIBSX_LIBS=
+  ac_save_LDFLAGS=$LDFLAGS
+  ac_save_LIBS=$LIBS
+  ac_save_CFLAGS=$CFLAGS
+
+  GA_CHECK_XAW([ga_xaw_found='yes'],[ga_xaw_found='no'])
+
+  LDFLAGS="$LDFLAGS -L$ga_supplib_dir/lib $X_LIBS"
+  CFLAGS="$CFLAGS -I$ga_supplib_dir/include/libsx"
+  ga_use_libsx='no'
+  ga_libsx_header='no'
+  ga_libsx_freq_header='no'
+
+  if test "z$ga_xaw_found" = "zyes"; then
+    LIBS="$LIBS $XAW_LIBS $XAW_XLIBS"
+    CFLAGS="$CFLAGS $X_CFLAGS $XAW_CFLAGS"
+  
+    AC_CHECK_HEADER([libsx.h],
+    [ AC_CHECK_HEADER([freq.h],
+      [
+         ga_libsx_freq_header='yes'
+      ])
+      ga_libsx_header='yes'
+    ])
+  
+    if test "z$ga_libsx_header" = "zyes"; then
+      if test "z$ga_libsx_freq_header" = "zyes"; then 
+        AC_CHECK_LIB([freq],[main],
+        [ AC_CHECK_LIB([sx],[GetFile],
+          [ ga_use_libsx='freq'
+            GA_LIBSX_LIBS="-lsx -lfreq $XAW_LIBS"
+          ])
+        ])
+      fi
+      if test "z$ga_use_libsx" = "zno"; then
+         AC_CHECK_LIB([sx],[GetFile],
+         [  ga_use_libsx='yes'
+            GA_LIBSX_LIBS="-lsx $XAW_LIBS"
+         ])
+      fi
+      if test "z$ga_use_libsx" != "zno"; then
+         AC_CHECK_FUNCS([SimpleGetFile])
+         ga_getfile_short_prototype=no
+         AC_MSG_CHECKING([if GetFile has a short prototype])
+         AC_LANG_PUSH(C)
+         if test "z$ga_use_libsx" = "zfreq"; then
+            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libsx.h>
+#include <freq.h>]],
+[[GetFile("/path/to/file")]])],[ga_getfile_short_prototype=yes])
+         else
+            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libsx.h>]],
+[[GetFile("/path/to/file")]])],[ga_getfile_short_prototype=yes])
+         fi
+         if test $ga_getfile_short_prototype = 'yes'; then
+           AC_DEFINE([GETFILE_SHORT_PROTOTYPE],[],[Define if GetFile has a short prototype])
+           AC_MSG_RESULT([yes])
+         else
+           AC_MSG_RESULT([no])
+         fi
+         AC_LANG_POP
+      fi
+    fi
+  fi
+
+  if test "z$ga_use_libsx" = "zfreq" ; then
+      m4_if([$1], [], [:], [$1])
+  else
+      if test "z$ga_use_libsx" = "zyes" ; then
+         m4_if([$2], [], [:], [$2])
+      else
+         m4_if([$3], [], [:], [$3])
+      fi
+  fi
+  AC_SUBST([GA_LIBSX_LIBS])
+  CFLAGS=$ac_save_CFLAGS
+  LIBS=$ac_save_LIBS
+  LDFLAGS=$ac_save_LDFLAGS
+])
diff --git a/m4/netcdf.m4 b/m4/netcdf.m4
new file mode 100644
index 0000000..70b18d7
--- /dev/null
+++ b/m4/netcdf.m4
@@ -0,0 +1,154 @@
+dnl example of use
+dnl AC_CHECK_NETCDF(
+dnl   [
+dnl       LIBS="$LIBS $NC_LIBS"
+dnl       LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+dnl       CPPFLAGS="$CPPFLAGS $NC_CFLAGS"
+dnl   ],
+dnl   [
+dnl       echo "*** Use --with-netcdf for the root netcdf directory."
+dnl       echo "*** Otherwise use --with-netcdf-include switch for includes directory"
+dnl       echo "*** and --with-netcdf-libdir switch for libraries directory."
+dnl       AC_MSG_ERROR([netcdf library and netcdf headers are required.])
+dnl   ]
+dnl )
+
+# Check for the netcdf library.
+# AC_CHECK_NETCDF([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],[INTERFACE-NR])
+# if interface number is given, check for a specific interface
+# sets NC_LDFLAGS, NC_LIBS, and, by calling other macros
+# NC_CFLAGS and maybe NC_NETCDF_3_CFLAGS
+AC_DEFUN([AC_CHECK_NETCDF],
+[
+  AC_ARG_WITH([netcdf],
+            [AS_HELP_STRING([--with-netcdf=ARG],[netcdf directory])],
+            [NC_PATH=$withval], 
+            [NC_PATH=""])
+
+  AC_ARG_WITH([netcdf_include],
+            [AS_HELP_STRING([--with-netcdf-include=ARG],[netcdf include directory])],
+            [NC_PATH_INC=$withval], 
+            [NC_PATH_INC=""])
+
+  AC_ARG_WITH([netcdf_libdir],
+            [AS_HELP_STRING([--with-netcdf-libdir=ARG],[netcdf library directory])],
+            [NC_PATH_LIBDIR=$withval], 
+            [NC_PATH_LIBDIR=""])
+
+  AS_IF([test "z$NC_PATH" != "z"],
+  [
+    AS_IF([test "z$NC_PATH_LIBDIR" = "z"],[NC_PATH_LIBDIR="$NC_PATH/lib"])
+    AS_IF([test "z$NC_PATH_INC" = "z"],[NC_PATH_INC="$NC_PATH/include"])
+  ])
+
+  ac_netcdf_ok='no'
+  NC_LIBS=
+  NC_LDFLAGS=
+  ac_nc_save_LDFLAGS=$LDFLAGS
+  ac_nc_save_LIBS=$LIBS
+  ac_check_nc_func_checked='ncopen'
+  ac_check_nc_interface=
+dnl the interface number isn't quoted with "" otherwise a newline 
+dnl following the number isn't stripped.
+  m4_if([$3],[],[ac_check_nc_interface=2],[ac_check_nc_interface=$3])
+  AS_IF([test "z$ac_check_nc_interface" = 'z3'],
+    [ac_check_nc_func_checked='nc_open'])
+  AS_IF([test "z$NC_PATH_LIBDIR" != "z"],
+    [
+      NC_LDFLAGS="-L$NC_PATH_LIBDIR"
+      LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+dnl the autoconf internal cache isn't avoided because we really check for
+dnl libnetcdf, other libraries that implement the same api have other names
+dnl  AC_LINK_IFELSE([AC_LANG_CALL([],[$ac_check_func_checked])],
+      AC_CHECK_LIB([netcdf],[$ac_check_nc_func_checked],
+        [
+          NC_LIBS='-lnetcdf'
+          ac_netcdf_ok='yes'
+        ])
+    ],
+    [
+      for ac_netcdf_libdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib64 \
+       /opt/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/netcdf-${ac_check_nc_interface}/lib64 \
+       /usr/local/lib64/netcdf-${ac_check_nc_interface} \
+       /opt/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/lib64/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib64 /opt/netcdf/lib64 \
+       /usr/netcdf/lib64 /usr/local/lib64/netcdf /opt/lib64/netcdf \
+       /usr/lib64/netcdf \
+       /usr/local/netcdf-${ac_check_nc_interface}/lib \
+       /opt/netcdf-${ac_check_nc_interface}/lib \
+       /usr/netcdf-${ac_check_nc_interface}/lib \
+       /usr/local/lib/netcdf-${ac_check_nc_interface} \
+       /opt/lib/netcdf-${ac_check_nc_interface} \
+       /usr/lib/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/lib /opt/netcdf/lib \
+       /usr/netcdf/lib /usr/local/lib/netcdf /opt/lib/netcdf \
+       /usr/lib/netcdf ; do
+        AS_IF([test "z$ac_netcdf_libdir" = 'z'],
+          [NC_LDFLAGS=],
+          [
+            AC_MSG_CHECKING([for netcdf libraries in $ac_netcdf_libdir])
+            NC_LDFLAGS="-L$ac_netcdf_libdir"
+          ])
+        LDFLAGS="$LDFLAGS $NC_LDFLAGS"
+        LIBS="$LIBS -lnetcdf"
+dnl we have to avoid the autoconf internal cache in that case
+        AC_LINK_IFELSE([AC_LANG_CALL([],[$ac_check_nc_func_checked])],
+          [
+            NC_LIBS='-lnetcdf'
+            ac_netcdf_ok='yes'
+            AS_IF([test "z$ac_netcdf_libdir" != 'z'],[AC_MSG_RESULT([yes])])
+          ],
+          [
+            AS_IF([test "z$ac_netcdf_libdir" != 'z'],[AC_MSG_RESULT([no])])
+          ])
+        AS_IF([test $ac_netcdf_ok = 'yes'],[break])
+        LDFLAGS=$ac_nc_save_LDFLAGS
+        LIBS=$ac_nc_save_LIBS
+      done
+    ])
+  LDFLAGS=$ac_nc_save_LDFLAGS
+  LIBS=$ac_nc_save_LIBS
+
+  AC_SUBST([NC_LDFLAGS])
+  AC_SUBST([NC_LIBS])
+  ac_netcdf_header='no'
+
+  NC_CFLAGS=
+  AS_IF([test "z$NC_PATH_INC" != "z"],
+    [
+      AC_CHECK_NETCDF_HEADER([$NC_PATH_INC],
+        [ac_netcdf_header='yes'],
+        [ac_netcdf_header='no'],
+        [$ac_check_nc_interface])
+    ],
+    [
+      for ac_netcdf_incdir in "" \
+       /usr/local/netcdf-${ac_check_nc_interface}/include \
+       /opt/netcdf-${ac_check_nc_interface}/include \ 
+       /usr/netcdf-${ac_check_nc_interface}/include \
+       /usr/local/include/netcdf-${ac_check_nc_interface} \
+       /opt/include/netcdf-${ac_check_nc_interface} \
+       /usr/include/netcdf-${ac_check_nc_interface} \
+       /usr/local/netcdf/include \
+       /opt/netcdf/include /usr/netcdf/include /usr/local/include/netcdf \
+       /opt/include/netcdf /usr/include/netcdf ; do
+        AC_MSG_NOTICE([searching netcdf includes in $ac_netcdf_incdir])
+        AC_CHECK_NETCDF_HEADER([$ac_netcdf_incdir],[ac_netcdf_header='yes'],
+          [ac_netcdf_header='no'],[$ac_check_nc_interface])
+        AS_IF([test $ac_netcdf_header = 'yes'],
+        [
+           AS_IF([test "z$ac_netcdf_incdir" != "z"],
+             [NC_CFLAGS="-I$ac_nc_include_dir"])
+           break
+        ])
+      done
+    ])
+  AC_SUBST([NC_CFLAGS])
+
+  AS_IF([test "$ac_netcdf_ok" = 'no' -o "$ac_netcdf_header" = 'no'],
+    [m4_if([$2], [], [:], [$2])],
+    [m4_if([$1], [], [:], [$1])])
+])
diff --git a/m4/netcdf_header.m4 b/m4/netcdf_header.m4
new file mode 100644
index 0000000..e765693
--- /dev/null
+++ b/m4/netcdf_header.m4
@@ -0,0 +1,92 @@
+# Check for the netcdf header.
+# AC_CHECK_NETCDF_HEADER([INCLUDE-DIR],[ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND],[INTERFACE-NR])
+# if interface number is given, check for a specific interface
+# sets maybe NC_NETCDF_3_CPPFLAG
+AC_DEFUN([AC_CHECK_NETCDF_HEADER],
+[
+  ac_netcdf_h='no'
+  ac_netcdf_h_compile='no'
+  ac_netcdf_h_preproc='no'
+  ac_nc_include_dir=
+  ac_nc_header_interface=
+  
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  m4_if([$1],[],[:],[
+    ac_nc_include_dir="$1"
+    AS_IF([test "z$ac_nc_include_dir" != "z"],
+       [CPPFLAGS="$CPPFLAGS -I$ac_nc_include_dir"])
+  ])
+  m4_if([$4],[],[:],[ac_nc_header_interface=$4])
+dnl dont use AC_CHECK_HEADERS to avoid autoconf internal caching
+  AC_MSG_CHECKING([for netcdf.h with compiler])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
+    [
+      AC_MSG_RESULT([yes])
+      ac_netcdf_h_compile='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      ac_netcdf_h_compile='no'
+    ])
+    AC_MSG_CHECKING([for netcdf.h with preprocessor])
+    AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <netcdf.h>]])],
+    [
+      AC_MSG_RESULT([yes])
+      ac_netcdf_h_preproc='yes'
+    ],
+    [
+      AC_MSG_RESULT([no])
+      ac_netcdf_h_preproc='no'
+    ])
+  CPPFLAGS="$ac_nc_save_CPPFLAGS"
+  AS_IF([test $ac_netcdf_h_compile = 'yes'],
+    [ac_netcdf_h='yes'
+    AS_IF([test "z$ac_nc_header_interface" = 'z3'],
+      [AC_CHECK_NETCDF_3_HEADER([$1],
+         [ac_netcdf_h='yes'],[ac_netcdf_h='no'])])
+    ])
+
+  AS_IF([test "$ac_netcdf_h" = 'yes'],
+    [
+      m4_if([$2], [], [:], [$2])
+    ],
+    [m4_if([$3], [], [:], [$3])])
+])
+
+AC_DEFUN([AC_CHECK_NETCDF_3_HEADER],
+[
+  NC_NETCDF_3_CPPFLAG=
+  ac_check_netcdf_3_include=
+  ac_check_netcdf_3_header='no'
+  ac_nc_save_CPPFLAGS=$CPPFLAGS
+  AC_MSG_CHECKING([for netcdf 3 interface])
+  m4_if([$1],[],[:],[
+    ac_check_netcdf_3_include="$1"
+  ])
+  AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
+    [CPPFLAGS="$CPPFLAGS -I$ac_check_netcdf_3_include"])
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netcdf.h>]],
+    [[int status;
+int ncid;
+char vernum;
+status = nc_open("foo.nc", 0, &ncid);
+vernum = *nc_inq_libvers();]])],
+    [
+      AS_IF([test "z$ac_check_netcdf_3_include" != "z"],
+        [NC_NETCDF_3_CPPFLAG="-I$ac_check_netcdf_3_include"])
+      ac_check_netcdf_3_header='yes'
+    ],[ac_check_netcdf_3_header='no'])
+  CPPFLAGS=$ac_nc_save_CPPFLAGS
+  AS_IF([test "$ac_check_netcdf_3_header" = 'yes'],
+    [
+      AC_MSG_RESULT([yes])
+      m4_if([$2], [], [:], [$2])
+    ],
+    [
+      AC_MSG_RESULT([no])
+      m4_if([$3], [], [:], [$3])
+    ])
+  
+  AC_SUBST([NC_NETCDF_3_CPPFLAG])
+])
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644
index 0000000..0048a3f
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,157 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# 
+# Copyright © 2004 Scott James Remnant <scott at netsplit.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+		
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+    if test -n "$$1"; then
+        pkg_cv_[]$1="$$1"
+    else
+        PKG_CHECK_EXISTS([$3],
+                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+			 [pkg_failed=yes])
+    fi
+else
+	pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+        else 
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+	ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+		[AC_MSG_RESULT([no])
+                $4])
+elif test $pkg_failed = untried; then
+	ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
+		[$4])
+else
+	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+	ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
diff --git a/m4/udunits.m4 b/m4/udunits.m4
new file mode 100644
index 0000000..91129a8
--- /dev/null
+++ b/m4/udunits.m4
@@ -0,0 +1,20 @@
+dnl GA_CHECK_UDUNITS : Check for udunits
+dnl args :             action-if-yes, action-if-no
+
+AC_DEFUN([GA_CHECK_UDUNITS],
+[
+  ga_use_udunits='no'
+  AC_CHECK_HEADER([udunits.h],
+  [  AC_CHECK_LIB([udunits],[utInit],
+     [  ga_use_udunits='yes'
+        UDUNITS_LIBS='-ludunits'
+     ])
+  ])
+  
+  if test "z$ga_use_udunits" = "zyes" ; then
+      m4_if([$1], [], [:], [$1])
+  else
+      m4_if([$2], [], [:], [$2])
+  fi
+  AC_SUBST([UDUNITS_LIBS])
+])
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..d14fa5b
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,191 @@
+##
+##          Makefile.am  for GrADS
+##
+######################################################################
+
+######################################################################
+#
+# Targets
+#
+
+# Targets that will built by "make all"
+bin_PROGRAMS	       = grads \
+		         gribmap gxeps gxps stnmap wgrib gribscan bufrscan \
+			 $(extra_utils)
+
+# Targets that will not always be built
+EXTRA_PROGRAMS	       = gxtran grib2scan
+
+# Convenience target
+utils: bufrscan gribscan gribmap gxeps gxps stnmap wgrib $(extra_utils)
+
+######################################################################
+#
+# Compiler and linker settings
+#
+
+# Paths to external headers and libraries
+supp_include_dir	= $(SUPPLIBS)/include
+supp_lib_dir		= $(SUPPLIBS)/lib
+
+# Settings used for all binaries
+LDADD			= -L$(supp_lib_dir) 
+INCLUDES		= $(readline_inc) $(printim_inc) $(grib2_inc) $(gui_inc) $(nc_inc) \
+			  $(hdf_inc) $(hdf5_inc) $(geotiff_inc) $(shp_inc) $(gadap_inc) \
+                          $(X_CFLAGS) $(XAW_CFLAGS) $(GD_CFLAGS) $(HDF4_CFLAGS)
+
+# Settings used for all GrADS binaries
+common_ldadd            = $(LDADD) $(X_LIBS) $(host_ldadd) -lX11
+
+######################################################################
+#
+# Headers and data
+#
+
+# Headers must be listed here to be included in the distribution.  The
+# "noinst_" prefix prevents "make install" from trying to do anything
+# with them
+hdr_core            = gagmap.h grads.h gs.h gatypes.h \
+		      gvt.h gx.h gxmap.h wx.h
+hdr_bufr	    = gabufr.h
+hdr_x11		    = gx.h bitmaps.h
+hdr_sdf             = gasdf.h gasdf_std_time.h 
+hdr_gui		    = gagui.h
+hdr_png             = mtables.c
+noinst_HEADERS	    = $(hdr_core) $(hdr_x11) $(hdr_sdf) $(hdr_png) $(hdr_gui) $(hdr_bufr)
+
+# Get rid of buildinfo.h on "make distclean"
+DISTCLEANFILES	       = buildinfo.h
+
+
+######################################################################
+#
+# Configuration-dependent sources & headers
+#
+
+if USEGADAP
+src_gadap 	    = dodstn.c
+obj_gadap           = dodstn.o
+endif
+
+if USEGUI
+src_gui             = gagui.c gsgui.c
+endif
+
+
+##############################################################
+#
+# Sources for GrADS binary
+
+# Source files to be compiled
+grads_SOURCES          = grads.c gxsubs.c gxmeta.c gxchpl.c gxcntr.c gxstrm.c \
+			 gxwmap.c gxshad.c gxshad2.c gaexpr.c gafunc.c gautil.c gagx.c \
+			 gscrpt.c gamach.c bufrstn.c gabufr.c gabufrtbl.c \
+			 gxX.c gxdxwd.c galloc.c $(src_gui) $(src_gadap) \
+                         gaddes.c gaio.c gacfg.c gauser.c gasdf.c gatxt.c
+
+# Sources that will not always be compiled
+# Since gradsc is the only GrADS binary that is not conditionally compiled,
+# any source file that we want to go in the distribution must be listed.
+#EXTRA_grads_SOURCES    = gagmap.c gagui.c gsgui.c gxhpng.c dodstn.c
+EXTRA_grads_SOURCES    = gagmap.c gagui.c gsgui.c dodstn.c
+
+
+# libraries needed 
+grads_LDADD	       = $(common_ldadd) $(readline_libs) $(printim_libs) \
+			 $(grib2_libs) $(hdf_libs) $(hdf5_libs) $(nc_libs) \
+			 $(gui_libs) $(geotiff_libs) $(shp_libs) $(dap_libs)
+
+# Custom compilation for object files specific to this GrADS binary
+COMPILE_C = $(COMPILE) 
+
+
+##############################################################
+#
+# gradsdap
+#
+
+# If gadap is enabled, use C++ linker instead of C linker
+if USEGADAP
+grads_LINK          = $(CXX) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+else
+grads_LINK          = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+endif
+
+# Object files that should not be reused by the other GrADS binaries,
+# plus libraries needed by this GrADS binary
+
+
+# Custom compilation for object files specific to this GrADS binary
+COMPILE_DAP = $(COMPILE) 
+
+
+##############################################################
+#
+# Utilities
+#
+
+# Object files that need to be recompiled for standalone utilities
+gaddes.sa.o: $(srcdir)/gaddes.c
+	$(COMPILE) -DSTNDALN -o gaddes.sa.o -c $(srcdir)/gaddes.c
+
+gautil.sa.o: $(srcdir)/gautil.c
+	$(COMPILE) -DSTNDALN -o gautil.sa.o -c $(srcdir)/gautil.c
+
+gxmeta.sa.o: $(srcdir)/gxmeta.c
+	$(COMPILE) -DSTNDALN -o gxmeta.sa.o -c $(srcdir)/gxmeta.c
+
+##############################################################
+#
+# stnmap
+#
+stnmap_SOURCES	       = stnmap.c gamach.c galloc.c
+stnmap_LDADD	       = gaddes.sa.o gautil.sa.o gatxt.o $(LDADD) $(readline_libs)
+
+##############################################################
+#
+# gribmap
+#
+gribmap_SOURCES	       = gribmap.c gagmap.c gamach.c galloc.c
+gribmap_LDADD	       = gaddes.sa.o gautil.sa.o gatxt.o $(LDADD) $(readline_libs) $(grib2_libs)
+
+##############################################################
+#
+# wgrib
+#
+wgrib_SOURCES	       = wgrib.c
+
+##############################################################
+#
+# gxps
+#
+gxps_SOURCES	       = gxps.c
+gxeps_SOURCES	       = gxeps.c
+
+##############################################################
+#
+# gxtran
+#
+gxtran_SOURCES	       = gxtran.c gxsubs.c gxchpl.c gxX.c gxdxwd.c galloc.c 
+gxtran_LDADD	       = gxmeta.sa.o $(LDADD) $(X_LIBS) $(printim_libs) -lX11
+
+##############################################################
+#
+# gribscan
+#
+gribscan_SOURCES       = gribscan.c gamach.c galloc.c
+gribscan_LDADD	       = gautil.sa.o gatxt.o $(LDADD) $(readline_libs)
+
+##############################################################
+#
+# grib2scan
+#
+grib2scan_SOURCES      = grib2scan.c gamach.c galloc.c
+grib2scan_LDADD	       = gautil.sa.o gatxt.o $(LDADD) $(grib2_libs) $(readline_libs)
+
+##############################################################
+#
+# bufrscan
+#
+bufrscan_SOURCES       = bufrscan.c gabufr.c gabufrtbl.c gamach.c
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..97b0fff
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,757 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+######################################################################
+
+######################################################################
+#
+# Targets
+#
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = grads$(EXEEXT) gribmap$(EXEEXT) gxeps$(EXEEXT) \
+	gxps$(EXEEXT) stnmap$(EXEEXT) wgrib$(EXEEXT) gribscan$(EXEEXT) \
+	bufrscan$(EXEEXT) $(am__EXEEXT_1)
+EXTRA_PROGRAMS = gxtran$(EXEEXT) grib2scan$(EXEEXT)
+subdir = src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/Xaw.m4 \
+	$(top_srcdir)/m4/ga_lib_readline.m4 $(top_srcdir)/m4/gd.m4 \
+	$(top_srcdir)/m4/geotiff.m4 $(top_srcdir)/m4/grib2.m4 \
+	$(top_srcdir)/m4/gui.m4 $(top_srcdir)/m4/hdf4.m4 \
+	$(top_srcdir)/m4/hdf5.m4 $(top_srcdir)/m4/libsx.m4 \
+	$(top_srcdir)/m4/netcdf.m4 $(top_srcdir)/m4/netcdf_header.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/udunits.m4 \
+	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/etc/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+am__EXEEXT_1 = @extra_utils@
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_bufrscan_OBJECTS = bufrscan.$(OBJEXT) gabufr.$(OBJEXT) \
+	gabufrtbl.$(OBJEXT) gamach.$(OBJEXT)
+bufrscan_OBJECTS = $(am_bufrscan_OBJECTS)
+bufrscan_LDADD = $(LDADD)
+bufrscan_DEPENDENCIES =
+am__grads_SOURCES_DIST = grads.c gxsubs.c gxmeta.c gxchpl.c gxcntr.c \
+	gxstrm.c gxwmap.c gxshad.c gxshad2.c gaexpr.c gafunc.c \
+	gautil.c gagx.c gscrpt.c gamach.c bufrstn.c gabufr.c \
+	gabufrtbl.c gxX.c gxdxwd.c galloc.c gagui.c gsgui.c dodstn.c \
+	gaddes.c gaio.c gacfg.c gauser.c gasdf.c gatxt.c
+ at USEGUI_TRUE@am__objects_1 = gagui.$(OBJEXT) gsgui.$(OBJEXT)
+ at USEGADAP_TRUE@am__objects_2 = dodstn.$(OBJEXT)
+am_grads_OBJECTS = grads.$(OBJEXT) gxsubs.$(OBJEXT) gxmeta.$(OBJEXT) \
+	gxchpl.$(OBJEXT) gxcntr.$(OBJEXT) gxstrm.$(OBJEXT) \
+	gxwmap.$(OBJEXT) gxshad.$(OBJEXT) gxshad2.$(OBJEXT) \
+	gaexpr.$(OBJEXT) gafunc.$(OBJEXT) gautil.$(OBJEXT) \
+	gagx.$(OBJEXT) gscrpt.$(OBJEXT) gamach.$(OBJEXT) \
+	bufrstn.$(OBJEXT) gabufr.$(OBJEXT) gabufrtbl.$(OBJEXT) \
+	gxX.$(OBJEXT) gxdxwd.$(OBJEXT) galloc.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2) gaddes.$(OBJEXT) \
+	gaio.$(OBJEXT) gacfg.$(OBJEXT) gauser.$(OBJEXT) \
+	gasdf.$(OBJEXT) gatxt.$(OBJEXT)
+grads_OBJECTS = $(am_grads_OBJECTS)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+grads_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am_grib2scan_OBJECTS = grib2scan.$(OBJEXT) gamach.$(OBJEXT) \
+	galloc.$(OBJEXT)
+grib2scan_OBJECTS = $(am_grib2scan_OBJECTS)
+grib2scan_DEPENDENCIES = gautil.sa.o gatxt.o $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_gribmap_OBJECTS = gribmap.$(OBJEXT) gagmap.$(OBJEXT) \
+	gamach.$(OBJEXT) galloc.$(OBJEXT)
+gribmap_OBJECTS = $(am_gribmap_OBJECTS)
+gribmap_DEPENDENCIES = gaddes.sa.o gautil.sa.o gatxt.o \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am_gribscan_OBJECTS = gribscan.$(OBJEXT) gamach.$(OBJEXT) \
+	galloc.$(OBJEXT)
+gribscan_OBJECTS = $(am_gribscan_OBJECTS)
+gribscan_DEPENDENCIES = gautil.sa.o gatxt.o $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am_gxeps_OBJECTS = gxeps.$(OBJEXT)
+gxeps_OBJECTS = $(am_gxeps_OBJECTS)
+gxeps_LDADD = $(LDADD)
+gxeps_DEPENDENCIES =
+am_gxps_OBJECTS = gxps.$(OBJEXT)
+gxps_OBJECTS = $(am_gxps_OBJECTS)
+gxps_LDADD = $(LDADD)
+gxps_DEPENDENCIES =
+am_gxtran_OBJECTS = gxtran.$(OBJEXT) gxsubs.$(OBJEXT) gxchpl.$(OBJEXT) \
+	gxX.$(OBJEXT) gxdxwd.$(OBJEXT) galloc.$(OBJEXT)
+gxtran_OBJECTS = $(am_gxtran_OBJECTS)
+gxtran_DEPENDENCIES = gxmeta.sa.o $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_stnmap_OBJECTS = stnmap.$(OBJEXT) gamach.$(OBJEXT) galloc.$(OBJEXT)
+stnmap_OBJECTS = $(am_stnmap_OBJECTS)
+stnmap_DEPENDENCIES = gaddes.sa.o gautil.sa.o gatxt.o \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_wgrib_OBJECTS = wgrib.$(OBJEXT)
+wgrib_OBJECTS = $(am_wgrib_OBJECTS)
+wgrib_LDADD = $(LDADD)
+wgrib_DEPENDENCIES =
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(bufrscan_SOURCES) $(grads_SOURCES) $(EXTRA_grads_SOURCES) \
+	$(grib2scan_SOURCES) $(gribmap_SOURCES) $(gribscan_SOURCES) \
+	$(gxeps_SOURCES) $(gxps_SOURCES) $(gxtran_SOURCES) \
+	$(stnmap_SOURCES) $(wgrib_SOURCES)
+DIST_SOURCES = $(bufrscan_SOURCES) $(am__grads_SOURCES_DIST) \
+	$(EXTRA_grads_SOURCES) $(grib2scan_SOURCES) $(gribmap_SOURCES) \
+	$(gribscan_SOURCES) $(gxeps_SOURCES) $(gxps_SOURCES) \
+	$(gxtran_SOURCES) $(stnmap_SOURCES) $(wgrib_SOURCES)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+G2_LIBS = @G2_LIBS@
+GA_LIBSX_LIBS = @GA_LIBSX_LIBS@
+GD_CFLAGS = @GD_CFLAGS@
+GD_CONFIG = @GD_CONFIG@
+GD_LDFLAGS = @GD_LDFLAGS@
+GD_LIBS = @GD_LIBS@
+GEOTIFF_CFLAGS = @GEOTIFF_CFLAGS@
+GEOTIFF_FALSE = @GEOTIFF_FALSE@
+GEOTIFF_LDFLAGS = @GEOTIFF_LDFLAGS@
+GEOTIFF_LIBS = @GEOTIFF_LIBS@
+GEOTIFF_TRUE = @GEOTIFF_TRUE@
+GXPNG_FALSE = @GXPNG_FALSE@
+GXPNG_TRUE = @GXPNG_TRUE@
+HDF4_CFLAGS = @HDF4_CFLAGS@
+HDF4_LDFLAGS = @HDF4_LDFLAGS@
+HDF4_LIBS = @HDF4_LIBS@
+HDF5_CFLAGS = @HDF5_CFLAGS@
+HDF5_LDFLAGS = @HDF5_LDFLAGS@
+HDF5_LIBS = @HDF5_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NC_CFLAGS = @NC_CFLAGS@
+NC_LDFLAGS = @NC_LDFLAGS@
+NC_LIBS = @NC_LIBS@
+NC_NETCDF_3_CPPFLAG = @NC_NETCDF_3_CPPFLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+READLINE_FALSE = @READLINE_FALSE@
+READLINE_TRUE = @READLINE_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SUPPLIBS = @SUPPLIBS@
+UDUNITS_LIBS = @UDUNITS_LIBS@
+USEDAP_FALSE = @USEDAP_FALSE@
+USEDAP_TRUE = @USEDAP_TRUE@
+USEGADAP_FALSE = @USEGADAP_FALSE@
+USEGADAP_TRUE = @USEGADAP_TRUE@
+USEGUI_FALSE = @USEGUI_FALSE@
+USEGUI_TRUE = @USEGUI_TRUE@
+USEHDF_FALSE = @USEHDF_FALSE@
+USEHDF_TRUE = @USEHDF_TRUE@
+USESHP_FALSE = @USESHP_FALSE@
+USESHP_TRUE = @USESHP_TRUE@
+VERSION = @VERSION@
+XAW7_CFLAGS = @XAW7_CFLAGS@
+XAW7_LIBS = @XAW7_LIBS@
+XAW_CFLAGS = @XAW_CFLAGS@
+XAW_LIBS = @XAW_LIBS@
+XAW_XLIBS = @XAW_XLIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+dap_libs = @dap_libs@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+extra_utils = @extra_utils@
+gadap_inc = @gadap_inc@
+geotiff_inc = @geotiff_inc@
+geotiff_libs = @geotiff_libs@
+grads_xlibs = @grads_xlibs@
+grib2_inc = @grib2_inc@
+grib2_libs = @grib2_libs@
+gui_inc = @gui_inc@
+gui_libs = @gui_libs@
+hdf5_inc = @hdf5_inc@
+hdf5_libs = @hdf5_libs@
+hdf_inc = @hdf_inc@
+hdf_libs = @hdf_libs@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_ldadd = @host_ldadd@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nc_inc = @nc_inc@
+nc_libs = @nc_libs@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+printim_inc = @printim_inc@
+printim_libs = @printim_libs@
+program_transform_name = @program_transform_name@
+readline_inc = @readline_inc@
+readline_libs = @readline_libs@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+shp_inc = @shp_inc@
+shp_libs = @shp_libs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+######################################################################
+#
+# Compiler and linker settings
+#
+
+# Paths to external headers and libraries
+supp_include_dir = $(SUPPLIBS)/include
+supp_lib_dir = $(SUPPLIBS)/lib
+
+# Settings used for all binaries
+LDADD = -L$(supp_lib_dir) 
+INCLUDES = $(readline_inc) $(printim_inc) $(grib2_inc) $(gui_inc) $(nc_inc) \
+			  $(hdf_inc) $(hdf5_inc) $(geotiff_inc) $(shp_inc) $(gadap_inc) \
+                          $(X_CFLAGS) $(XAW_CFLAGS) $(GD_CFLAGS) $(HDF4_CFLAGS)
+
+
+# Settings used for all GrADS binaries
+common_ldadd = $(LDADD) $(X_LIBS) $(host_ldadd) -lX11
+
+######################################################################
+#
+# Headers and data
+#
+
+# Headers must be listed here to be included in the distribution.  The
+# "noinst_" prefix prevents "make install" from trying to do anything
+# with them
+hdr_core = gagmap.h grads.h gs.h gatypes.h \
+		      gvt.h gx.h gxmap.h wx.h
+
+hdr_bufr = gabufr.h
+hdr_x11 = gx.h bitmaps.h
+hdr_sdf = gasdf.h gasdf_std_time.h 
+hdr_gui = gagui.h
+hdr_png = mtables.c
+noinst_HEADERS = $(hdr_core) $(hdr_x11) $(hdr_sdf) $(hdr_png) $(hdr_gui) $(hdr_bufr)
+
+# Get rid of buildinfo.h on "make distclean"
+DISTCLEANFILES = buildinfo.h
+
+######################################################################
+#
+# Configuration-dependent sources & headers
+#
+ at USEGADAP_TRUE@src_gadap = dodstn.c
+ at USEGADAP_TRUE@obj_gadap = dodstn.o
+ at USEGUI_TRUE@src_gui = gagui.c gsgui.c
+
+##############################################################
+#
+# Sources for GrADS binary
+
+# Source files to be compiled
+grads_SOURCES = grads.c gxsubs.c gxmeta.c gxchpl.c gxcntr.c gxstrm.c \
+			 gxwmap.c gxshad.c gxshad2.c gaexpr.c gafunc.c gautil.c gagx.c \
+			 gscrpt.c gamach.c bufrstn.c gabufr.c gabufrtbl.c \
+			 gxX.c gxdxwd.c galloc.c $(src_gui) $(src_gadap) \
+                         gaddes.c gaio.c gacfg.c gauser.c gasdf.c gatxt.c
+
+
+# Sources that will not always be compiled
+# Since gradsc is the only GrADS binary that is not conditionally compiled,
+# any source file that we want to go in the distribution must be listed.
+#EXTRA_grads_SOURCES    = gagmap.c gagui.c gsgui.c gxhpng.c dodstn.c
+EXTRA_grads_SOURCES = gagmap.c gagui.c gsgui.c dodstn.c
+
+# libraries needed 
+grads_LDADD = $(common_ldadd) $(readline_libs) $(printim_libs) \
+			 $(grib2_libs) $(hdf_libs) $(hdf5_libs) $(nc_libs) \
+			 $(gui_libs) $(geotiff_libs) $(shp_libs) $(dap_libs)
+
+
+# Custom compilation for object files specific to this GrADS binary
+COMPILE_C = $(COMPILE) 
+ at USEGADAP_FALSE@grads_LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+
+##############################################################
+#
+# gradsdap
+#
+
+# If gadap is enabled, use C++ linker instead of C linker
+ at USEGADAP_TRUE@grads_LINK = $(CXX) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+
+# Object files that should not be reused by the other GrADS binaries,
+# plus libraries needed by this GrADS binary
+
+# Custom compilation for object files specific to this GrADS binary
+COMPILE_DAP = $(COMPILE) 
+
+##############################################################
+#
+# stnmap
+#
+stnmap_SOURCES = stnmap.c gamach.c galloc.c
+stnmap_LDADD = gaddes.sa.o gautil.sa.o gatxt.o $(LDADD) $(readline_libs)
+
+##############################################################
+#
+# gribmap
+#
+gribmap_SOURCES = gribmap.c gagmap.c gamach.c galloc.c
+gribmap_LDADD = gaddes.sa.o gautil.sa.o gatxt.o $(LDADD) $(readline_libs) $(grib2_libs)
+
+##############################################################
+#
+# wgrib
+#
+wgrib_SOURCES = wgrib.c
+
+##############################################################
+#
+# gxps
+#
+gxps_SOURCES = gxps.c
+gxeps_SOURCES = gxeps.c
+
+##############################################################
+#
+# gxtran
+#
+gxtran_SOURCES = gxtran.c gxsubs.c gxchpl.c gxX.c gxdxwd.c galloc.c 
+gxtran_LDADD = gxmeta.sa.o $(LDADD) $(X_LIBS) $(printim_libs) -lX11
+
+##############################################################
+#
+# gribscan
+#
+gribscan_SOURCES = gribscan.c gamach.c galloc.c
+gribscan_LDADD = gautil.sa.o gatxt.o $(LDADD) $(readline_libs)
+
+##############################################################
+#
+# grib2scan
+#
+grib2scan_SOURCES = grib2scan.c gamach.c galloc.c
+grib2scan_LDADD = gautil.sa.o gatxt.o $(LDADD) $(grib2_libs) $(readline_libs)
+
+##############################################################
+#
+# bufrscan
+#
+bufrscan_SOURCES = bufrscan.c gabufr.c gabufrtbl.c gamach.c
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  --ignore-deps src/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  --ignore-deps src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	cd $(top_srcdir) && $(AUTOHEADER)
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
+	done
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+bufrscan$(EXEEXT): $(bufrscan_OBJECTS) $(bufrscan_DEPENDENCIES) 
+	@rm -f bufrscan$(EXEEXT)
+	$(LINK) $(bufrscan_LDFLAGS) $(bufrscan_OBJECTS) $(bufrscan_LDADD) $(LIBS)
+grads$(EXEEXT): $(grads_OBJECTS) $(grads_DEPENDENCIES) 
+	@rm -f grads$(EXEEXT)
+	$(grads_LINK) $(grads_LDFLAGS) $(grads_OBJECTS) $(grads_LDADD) $(LIBS)
+grib2scan$(EXEEXT): $(grib2scan_OBJECTS) $(grib2scan_DEPENDENCIES) 
+	@rm -f grib2scan$(EXEEXT)
+	$(LINK) $(grib2scan_LDFLAGS) $(grib2scan_OBJECTS) $(grib2scan_LDADD) $(LIBS)
+gribmap$(EXEEXT): $(gribmap_OBJECTS) $(gribmap_DEPENDENCIES) 
+	@rm -f gribmap$(EXEEXT)
+	$(LINK) $(gribmap_LDFLAGS) $(gribmap_OBJECTS) $(gribmap_LDADD) $(LIBS)
+gribscan$(EXEEXT): $(gribscan_OBJECTS) $(gribscan_DEPENDENCIES) 
+	@rm -f gribscan$(EXEEXT)
+	$(LINK) $(gribscan_LDFLAGS) $(gribscan_OBJECTS) $(gribscan_LDADD) $(LIBS)
+gxeps$(EXEEXT): $(gxeps_OBJECTS) $(gxeps_DEPENDENCIES) 
+	@rm -f gxeps$(EXEEXT)
+	$(LINK) $(gxeps_LDFLAGS) $(gxeps_OBJECTS) $(gxeps_LDADD) $(LIBS)
+gxps$(EXEEXT): $(gxps_OBJECTS) $(gxps_DEPENDENCIES) 
+	@rm -f gxps$(EXEEXT)
+	$(LINK) $(gxps_LDFLAGS) $(gxps_OBJECTS) $(gxps_LDADD) $(LIBS)
+gxtran$(EXEEXT): $(gxtran_OBJECTS) $(gxtran_DEPENDENCIES) 
+	@rm -f gxtran$(EXEEXT)
+	$(LINK) $(gxtran_LDFLAGS) $(gxtran_OBJECTS) $(gxtran_LDADD) $(LIBS)
+stnmap$(EXEEXT): $(stnmap_OBJECTS) $(stnmap_DEPENDENCIES) 
+	@rm -f stnmap$(EXEEXT)
+	$(LINK) $(stnmap_LDFLAGS) $(stnmap_OBJECTS) $(stnmap_LDADD) $(LIBS)
+wgrib$(EXEEXT): $(wgrib_OBJECTS) $(wgrib_DEPENDENCIES) 
+	@rm -f wgrib$(EXEEXT)
+	$(LINK) $(wgrib_LDFLAGS) $(wgrib_OBJECTS) $(wgrib_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+.c.o:
+	$(COMPILE) -c $<
+
+.c.obj:
+	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS) config.h
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic ctags distclean distclean-compile \
+	distclean-generic distclean-hdr distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am install-man \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-info-am
+
+
+# Convenience target
+utils: bufrscan gribscan gribmap gxeps gxps stnmap wgrib $(extra_utils)
+
+##############################################################
+#
+# Utilities
+#
+
+# Object files that need to be recompiled for standalone utilities
+gaddes.sa.o: $(srcdir)/gaddes.c
+	$(COMPILE) -DSTNDALN -o gaddes.sa.o -c $(srcdir)/gaddes.c
+
+gautil.sa.o: $(srcdir)/gautil.c
+	$(COMPILE) -DSTNDALN -o gautil.sa.o -c $(srcdir)/gautil.c
+
+gxmeta.sa.o: $(srcdir)/gxmeta.c
+	$(COMPILE) -DSTNDALN -o gxmeta.sa.o -c $(srcdir)/gxmeta.c
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/VERSION b/src/VERSION
new file mode 100644
index 0000000..e9307ca
--- /dev/null
+++ b/src/VERSION
@@ -0,0 +1 @@
+2.0.2
diff --git a/src/bitmaps.h b/src/bitmaps.h
new file mode 100644
index 0000000..84607ff
--- /dev/null
+++ b/src/bitmaps.h
@@ -0,0 +1,237 @@
+#define icon_bitmap_width 41
+#define icon_bitmap_height 41
+static  char icon_bitmap_bits[] = {
+   0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+   0xff, 0xff, 0xff, 0xff, 0xff, 0x01};
+#define line_0_1_bitmap_width 12
+#define line_0_1_bitmap_height 12
+static unsigned char line_0_1_bitmap_bits[] = {
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+   0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0};
+#define line_0_2_bitmap_width 12
+#define line_0_2_bitmap_height 12
+static unsigned char line_0_2_bitmap_bits[] = {
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0};
+#define line_0_3_bitmap_width 12
+#define line_0_3_bitmap_height 12
+static unsigned char line_0_3_bitmap_bits[] = {
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0,
+   0x00, 0xf0, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0};
+#define line_0_4_bitmap_width 12
+#define line_0_4_bitmap_height 12
+static unsigned char line_0_4_bitmap_bits[] = {
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0,
+   0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0x00, 0xf0};
+#define line_0_5_bitmap_width 12
+#define line_0_5_bitmap_height 12
+static unsigned char line_0_5_bitmap_bits[] = {
+   0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0,
+   0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x00, 0xf0};
+#define line_120_1_bitmap_width 14
+#define line_120_1_bitmap_height 14
+static unsigned char line_120_1_bitmap_bits[] = {
+   0x81, 0x00, 0x81, 0x00, 0x02, 0x01, 0x02, 0x01, 0x04, 0x02, 0x04, 0x02,
+   0x08, 0x04, 0x08, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x10, 0x20, 0x10,
+   0x40, 0x20, 0x40, 0x20};
+#define line_120_2_bitmap_width 10
+#define line_120_2_bitmap_height 10
+static unsigned char line_120_2_bitmap_bits[] = {
+   0x21, 0x00, 0x21, 0x00, 0x42, 0x00, 0x42, 0x00, 0x84, 0x00, 0x84, 0x00,
+   0x08, 0x01, 0x08, 0x01, 0x10, 0x02, 0x10, 0x02};
+#define line_120_3_bitmap_width 8
+#define line_120_3_bitmap_height 8
+static unsigned char line_120_3_bitmap_bits[] = {
+   0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88};
+#define line_120_4_bitmap_width 6
+#define line_120_4_bitmap_height 6
+static unsigned char line_120_4_bitmap_bits[] = {
+   0x09, 0x09, 0x12, 0x12, 0x24, 0x24};
+#define line_120_5_bitmap_width 5
+#define line_120_5_bitmap_height 5
+static unsigned char line_120_5_bitmap_bits[] = {
+   0x05, 0x09, 0x0a, 0x12, 0x14};
+#define line_135_1_bitmap_width 12
+#define line_135_1_bitmap_height 12
+static unsigned char line_135_1_bitmap_bits[] = {
+   0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00,
+   0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08};
+#define line_135_2_bitmap_width 8
+#define line_135_2_bitmap_height 8
+static unsigned char line_135_2_bitmap_bits[] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+#define line_135_3_bitmap_width 6
+#define line_135_3_bitmap_height 6
+static unsigned char line_135_3_bitmap_bits[] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20};
+#define line_135_4_bitmap_width 4
+#define line_135_4_bitmap_height 4
+static unsigned char line_135_4_bitmap_bits[] = {
+   0x01, 0x02, 0x04, 0x08};
+#define line_135_5_bitmap_width 3
+#define line_135_5_bitmap_height 3
+static unsigned char line_135_5_bitmap_bits[] = {
+   0x01, 0x02, 0x04};
+#define line_150_1_bitmap_width 14
+#define line_150_1_bitmap_height 14
+static unsigned char line_150_1_bitmap_bits[] = {
+   0x03, 0x00, 0x0c, 0x00, 0x30, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x0c,
+   0x00, 0x30, 0x03, 0x00, 0x0c, 0x00, 0x30, 0x00, 0xc0, 0x00, 0x00, 0x03,
+   0x00, 0x0c, 0x00, 0x30};
+#define line_150_2_bitmap_width 10
+#define line_150_2_bitmap_height 10
+static unsigned char line_150_2_bitmap_bits[] = {
+   0x03, 0x00, 0x0c, 0x00, 0x30, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x03, 0x00,
+   0x0c, 0x00, 0x30, 0x00, 0xc0, 0x00, 0x00, 0x03};
+#define line_150_3_bitmap_width 8
+#define line_150_3_bitmap_height 8
+static unsigned char line_150_3_bitmap_bits[] = {
+   0x03, 0x0c, 0x30, 0xc0, 0x03, 0x0c, 0x30, 0xc0};
+#define line_150_4_bitmap_width 6
+#define line_150_4_bitmap_height 6
+static unsigned char line_150_4_bitmap_bits[] = {
+   0x03, 0x0c, 0x30, 0x03, 0x0c, 0x30};
+#define line_150_5_bitmap_width 5
+#define line_150_5_bitmap_height 5
+static unsigned char line_150_5_bitmap_bits[] = {
+   0x03, 0x0c, 0x11, 0x06, 0x18};
+#define line_30_1_bitmap_width 14
+#define line_30_1_bitmap_height 14
+static unsigned char line_30_1_bitmap_bits[] = {
+   0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00,
+   0x03, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0xc0, 0x00, 0x30, 0x00,
+   0x0c, 0x00, 0x03, 0x00};
+#define line_30_2_bitmap_width 10
+#define line_30_2_bitmap_height 10
+static unsigned char line_30_2_bitmap_bits[] = {
+   0x00, 0x03, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x03,
+   0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00};
+#define line_30_3_bitmap_width 8
+#define line_30_3_bitmap_height 8
+static unsigned char line_30_3_bitmap_bits[] = {
+   0xc0, 0x30, 0x0c, 0x03, 0xc0, 0x30, 0x0c, 0x03};
+#define line_30_4_bitmap_width 6
+#define line_30_4_bitmap_height 6
+static unsigned char line_30_4_bitmap_bits[] = {
+   0x30, 0x0c, 0x03, 0x30, 0x0c, 0x03};
+#define line_30_5_bitmap_width 5
+#define line_30_5_bitmap_height 5
+static unsigned char line_30_5_bitmap_bits[] = {
+   0x18, 0x06, 0x11, 0x0c, 0x03};
+#define line_45_1_bitmap_width 12
+#define line_45_1_bitmap_height 12
+static unsigned char line_45_1_bitmap_bits[] = {
+   0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00,
+   0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00};
+#define line_45_2_bitmap_width 8
+#define line_45_2_bitmap_height 8
+static unsigned char line_45_2_bitmap_bits[] = {
+   0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+#define line_45_3_bitmap_width 6
+#define line_45_3_bitmap_height 6
+static unsigned char line_45_3_bitmap_bits[] = {
+   0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+#define line_45_4_bitmap_width 4
+#define line_45_4_bitmap_height 4
+static unsigned char line_45_4_bitmap_bits[] = {
+   0x08, 0x04, 0x02, 0x01};
+#define line_45_5_bitmap_width 3
+#define line_45_5_bitmap_height 3
+static unsigned char line_45_5_bitmap_bits[] = {
+   0x04, 0x02, 0x01};
+#define line_60_1_bitmap_width 14
+#define line_60_1_bitmap_height 14
+static unsigned char line_60_1_bitmap_bits[] = {
+   0x40, 0x20, 0x40, 0x20, 0x20, 0x10, 0x20, 0x10, 0x10, 0x08, 0x10, 0x08,
+   0x08, 0x04, 0x08, 0x04, 0x04, 0x02, 0x04, 0x02, 0x02, 0x01, 0x02, 0x01,
+   0x81, 0x00, 0x81, 0x00};
+#define line_60_2_bitmap_width 10
+#define line_60_2_bitmap_height 10
+static unsigned char line_60_2_bitmap_bits[] = {
+   0x10, 0x02, 0x10, 0x02, 0x08, 0x01, 0x08, 0x01, 0x84, 0x00, 0x84, 0x00,
+   0x42, 0x00, 0x42, 0x00, 0x21, 0x00, 0x21, 0x00};
+#define line_60_3_bitmap_width 8
+#define line_60_3_bitmap_height 8
+static unsigned char line_60_3_bitmap_bits[] = {
+   0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x11, 0x11};
+#define line_60_4_bitmap_width 6
+#define line_60_4_bitmap_height 6
+static unsigned char line_60_4_bitmap_bits[] = {
+   0x24, 0x24, 0x12, 0x12, 0x09, 0x09};
+#define line_60_5_bitmap_width 5
+#define line_60_5_bitmap_height 5
+static unsigned char line_60_5_bitmap_bits[] = {
+   0x14, 0x12, 0x0a, 0x09, 0x05};
+#define line_90_1_bitmap_width 12
+#define line_90_1_bitmap_height 12
+static unsigned char line_90_1_bitmap_bits[] = {
+   0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+   0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00};
+#define line_90_2_bitmap_width 12
+#define line_90_2_bitmap_height 12
+static unsigned char line_90_2_bitmap_bits[] = {
+   0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00,
+   0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00};
+#define line_90_3_bitmap_width 12
+#define line_90_3_bitmap_height 12
+static unsigned char line_90_3_bitmap_bits[] = {
+   0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01,
+   0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01};
+#define line_90_4_bitmap_width 12
+#define line_90_4_bitmap_height 12
+static unsigned char line_90_4_bitmap_bits[] = {
+   0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02,
+   0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02, 0x49, 0x02};
+#define line_90_5_bitmap_width 12
+#define line_90_5_bitmap_height 12
+static unsigned char line_90_5_bitmap_bits[] = {
+   0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05,
+   0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05};
+#define dot_1_bitmap_width 6
+#define dot_1_bitmap_height 6
+static unsigned char dot_1_bitmap_bits[] = {
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define dot_2_bitmap_width 5
+#define dot_2_bitmap_height 5
+static unsigned char dot_2_bitmap_bits[] = {
+   0x01, 0x00, 0x00, 0x00, 0x00};
+#define dot_3_bitmap_width 4
+#define dot_3_bitmap_height 4
+static unsigned char dot_3_bitmap_bits[] = {
+   0x01, 0x00, 0x00, 0x00};
+#define dot_4_bitmap_width 4
+#define dot_4_bitmap_height 4
+static unsigned char dot_4_bitmap_bits[] = {
+   0x01, 0x00, 0x04, 0x00};
+#define dot_5_bitmap_width 2
+#define dot_5_bitmap_height 2
+static unsigned char dot_5_bitmap_bits[] = {
+   0x01, 0x00};
+#define dot_6_bitmap_width 2
+#define dot_6_bitmap_height 2
+static unsigned char dot_6_bitmap_bits[] = {
+   0x01, 0x02};
+#define open_bitmap_width 12
+#define open_bitmap_height 12
+static unsigned char open_bitmap_bits[] = {
+   0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+   0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0};
diff --git a/src/bufrscan.c b/src/bufrscan.c
new file mode 100644
index 0000000..dc49f16
--- /dev/null
+++ b/src/bufrscan.c
@@ -0,0 +1,106 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/*  written by Joe Wielgosz */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "config.h"
+#include "gabufr.h"
+
+#ifndef HAVE_FSEEKO
+gaint fseeko(FILE *stream, off_t offset, gaint whence) {
+  fseek(stream, (long)offset, whence);
+}
+off_t ftello(FILE *stream) {
+  return (off_t)ftell(stream);
+}
+#endif
+
+enum bufrscan_modes {
+  HEADER_MODE = 0,
+  DATA_MODE
+};
+
+void gabufr_print_dset(gabufr_dset * dset) {
+  gabufr_msg * msg;
+  gabufr_val * val;
+  gabufr_varinf *varinf=NULL;
+  gaint i;
+
+  for (msg = dset->msgs; msg != NULL; msg = msg->next) {
+    printf("\n\nmsg %d:\n", msg->fileindex);
+    for (i = 0; i < msg->subcnt; i++) {
+      printf("\nsubset %d:\n", i);
+      for (val = msg->subs[i]; val != NULL; val = val->next) {
+	printf("%d (%d) [%.3d]    0-%.2d-%.3d     ", msg->fileindex, 
+	       i, val->z, val->x, val->y);
+	if (val->sval) {
+	  printf("[%s]", val->sval);
+	} else {
+	  if (val->undef) {
+	    printf("undef (%g)", val->val);
+	  } else {
+	    printf("%g", val->val);
+	  }	    
+	}
+	if ( gabufr_valid_varid(0, val->x, val->y)
+	     && varinf == gabufr_get_varinf(val->x, val->y)) {
+	  printf("\t\t(%s)", varinf->description);
+	}
+	printf("\n");
+      }
+    }
+  }
+}
+
+void help() {
+      printf("bufrscan [-h] [-d] tablepath filenames ...\n");
+      printf("tablepath: directory containing BUFR decoding tables\n");
+      printf("filenames: BUFR messages to be decoded\n");
+      printf("-h, --header: print BUFR message headers (default)\n");
+      printf("-d, --data: print BUFR message contents \n");
+      printf("-?, --help: print this help message\n");
+}
+
+gaint main (gaint argc, char *argv[]) {
+  gabufr_dset * dset;
+  gaint i;
+  const char * tablepath = NULL;
+  gaint mode = HEADER_MODE;
+  if (argc < 3) {
+    help();
+  }
+  for (i = 1; i < argc; i++) {
+    if (! strcmp(argv[i], "-d") || ! strcmp(argv[i], "--data")) {
+      mode = DATA_MODE;
+    } else if (! strcmp(argv[i], "-h") || ! strcmp(argv[i], "--header")) {
+      mode = HEADER_MODE;
+    } else if (! strcmp(argv[i], "-?") || ! strcmp(argv[i], "--help")) {
+      help();
+    } else if (!tablepath) {
+	tablepath = argv[i];
+	gabufr_set_tbl_base_path(tablepath);
+    } else {
+      if (mode == HEADER_MODE) {
+	dset = gabufr_scan(argv[i]);
+	if (! dset) {
+	  return GABUFR_ERR;
+	}
+	gabufr_close(dset);
+      } else {
+	dset = gabufr_open(argv[i]);
+	if (! dset) {
+	  return GABUFR_ERR;
+	}
+	gabufr_print_dset(dset);
+	
+	gabufr_close(dset);
+      }
+    }	   
+  }
+  return GABUFR_OK;
+}
diff --git a/src/bufrstn.c b/src/bufrstn.c
new file mode 100644
index 0000000..addb696
--- /dev/null
+++ b/src/bufrstn.c
@@ -0,0 +1,550 @@
+/*  Copyright (C) 1988-2011 by Brian doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by Jennifer Adams */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include "grads.h"
+#include "gx.h"
+
+/* This routine parses a BUFR file, then collects reports that match a data request */
+ 
+gaint getbufr (struct gastn *stn) {
+  char   ch1[16],ch2[16],pout[256];
+  gaint    i,k,rc,mintim,maxtim,tim,oflg,dummy,keepreport,msgcnt;
+  gaint    t,f,minf,maxf,minft,maxft,verb,toffneg;
+  gadouble  minlon,maxlon,minlat,maxlat,minlev,maxlev;
+  gadouble  hlon=0,hlat=0,hlev,htim;
+  double rfold;
+  struct garpt *rpt;
+  struct bufrhdr subsethdr,rfhdr;
+  gabufr_msg *msg;
+  gabufr_val *val, *bval, *rfblockbeg;
+
+  /* For informational messages, set verb=1. For debugging, set verb=2. */
+  verb=1;
+
+  /* Get dimension limits */
+  mintim = stn->tmin;    maxtim = stn->tmax;
+  minlon = stn->dmin[0]; maxlon = stn->dmax[0];
+  minlat = stn->dmin[1]; maxlat = stn->dmax[1];
+  minlev = stn->dmin[2]; maxlev = stn->dmax[2];
+  if (minlev > maxlev) {
+    minlev = stn->dmax[2];
+    maxlev = stn->dmin[2];
+  }
+  if (stn->rflag) {
+    minlon = minlon - stn->radius;
+    maxlon = maxlon + stn->radius;
+    minlat = minlat - stn->radius;
+    maxlat = maxlat + stn->radius;
+  }
+  stn->rnum = 0;
+
+  /* Loop through times -- How many data files are we going to have to open? */
+  maxf=maxft=0;
+  minf=minft=stn->pfi->dnum[3];
+  for (tim=mintim; tim<=maxtim; tim++) {
+    if (tim < 1) continue;
+    if (tim > stn->pfi->dnum[3]) break;
+    f = *(stn->pfi->fnums+tim-1);  /* f is filenumber for this time */
+    if (f < minf) {
+      minf = f;
+      minft = tim;
+    }
+    if (f > maxf) {
+      maxf = f;
+      maxft = tim;
+    }
+  }
+
+  /* Loop through files */
+  for (f=minf; f<=maxf; f++) {
+
+    /* Find a time axis index that will open file f */
+    for (t=minft; t<=maxft; t++) {
+      if (*(stn->pfi->fnums+t-1) == f) {
+	tim=t;
+	break;
+      }
+    }
+
+    /* Call gaopfn to set the file name */
+    rc = gaopfn(tim,1,&dummy,&oflg,stn->pfi);
+    if (rc==-99999) {
+      gaprnt(0,"getbufr error: gaopfn returned -99999\n");
+      goto err;
+    }
+    if (rc==-88888) continue;
+      
+    /* Parse the BUFR data if it hasn't already been done */
+    if (!stn->pfi->bufrdset) {
+      gabufr_set_tbl_base_path(gxgnam("tables"));
+      if (stn->pfi->tmplat) {
+	if (verb) {
+	  snprintf(pout,255,"Parsing BUFR file %s\n",stn->pfi->tempname);
+	  gaprnt(2,pout);
+	}
+	stn->pfi->bufrdset = gabufr_open(stn->pfi->tempname);
+      } 
+      else { 
+	if (verb) {
+	  snprintf(pout,255,"Parsing BUFR file %s\n",stn->pfi->name);
+	  gaprnt(2,pout);
+	}
+	stn->pfi->bufrdset = gabufr_open(stn->pfi->name);
+      }
+      if (!stn->pfi->bufrdset) {
+	gaprnt(0,"Error from getbufr: gabufr_open failed\n");
+	goto err; 
+
+      } else {
+	if (verb) gaprnt(2,"Finished parsing BUFR file\n");
+      }
+    }
+
+    msgcnt = -1;
+    /* Loop through bufr messages looking for valid reports */
+    for (msg = stn->pfi->bufrdset->msgs; msg != NULL; msg = msg->next) { 
+      msgcnt++;
+      if (msg->is_new_tbl) continue;
+
+      /* loop through msg subsets */
+      for (i = 0; i < msg->subcnt; i++) {                     
+  
+	/* Copy time vals from the msg header, intialize others */
+	subsethdr.tvals.yr = msg->year; 
+	subsethdr.tvals.mo = msg->month;
+	subsethdr.tvals.dy = msg->day;
+	subsethdr.tvals.hr = msg->hour;
+	subsethdr.tvals.mn = msg->min;
+	toffneg = 0;
+	subsethdr.sec = 0;
+	subsethdr.toffvals.yr = 0;     /* offset times are initially zero */
+	subsethdr.toffvals.mo = 0;
+	subsethdr.toffvals.dy = 0;
+	subsethdr.toffvals.hr = 0;
+	subsethdr.toffvals.mn = 0;
+	subsethdr.offsec = 0;
+	subsethdr.lon      = -999;
+	subsethdr.lat      = -999;
+	subsethdr.lev      = -999;
+	for (k=0;k<8;k++) *(subsethdr.stid+k)='?';
+
+	/* Look for coordinate values in subset (First loop through subset vals) */
+	getbufrhdr(msg->subs[i], NULL, stn->pfi->bufrinfo, &subsethdr, 0, &toffneg);
+
+	/* Sort gabufr_vals into blocks according to their repetition factors (rf) */
+	val = msg->subs[i];    /* first val in subset */
+	rfblockbeg = val;      /* first val in initial rfblock */
+	rfold = val->z;        /* initial rf */
+
+	while (1) {  
+
+	  /* (!val) occurs when all gabufr_vals in the subset have the same rf */
+	  /* (val->z != rfold) marks the end of a block of gabufr_vals that have the same rf */
+	  if ( (!val) || (val->z != rfold) ) {    
+
+	    /* rfblock is a set of gabufr_vals that have the same repetition factor */
+	    /* Copy bufrhdr values from the subset, look in the rfblock for more */
+	    rfhdr.tvals = subsethdr.tvals;
+	    rfhdr.toffvals = subsethdr.toffvals;
+	    rfhdr = subsethdr;	  
+	    getbufrhdr(rfblockbeg, val, stn->pfi->bufrinfo, &rfhdr, 1, &toffneg);
+
+	    /* Determine if we want this report */
+	    keepreport=1;
+	    /* Convert seconds to minutes and add fields */ 
+	    rfhdr.tvals.mn    += rfhdr.sec/60;   
+	    rfhdr.toffvals.mn += rfhdr.offsec/60;  
+
+	    /* Merge the time values and time offset values to get report time */
+	    if (toffneg) {
+ 	      timsub(&rfhdr.tvals,&rfhdr.toffvals);  
+	    } else {
+	      timadd(&rfhdr.tvals,&rfhdr.toffvals);  
+	    }
+
+	    /* Get the report time in grid coordinates */
+	    htim = t2gr(stn->tvals,&rfhdr.toffvals); 
+
+	    /* Check if time is within range*/
+	    if (stn->ftmin==stn->ftmax) {
+	      if (fabs(htim-stn->ftmin)>0.5) {
+		keepreport=0;
+		if (verb==2) {
+		  printf("report time (%4.1f) is outside range; dmin/dmax=%4.1f tim=%d\n",
+			 htim,stn->ftmin,mintim);
+		}
+	      } 		
+	    } else {
+	      if (htim<stn->ftmin || htim>stn->ftmax) {
+		keepreport=0;
+		if (verb==2) {
+		  printf("report time (%4.1f) is outside range; dmin=%4.1f dmax=%4.1f tmin=%d tmax=%d\n",
+			 htim,stn->ftmin,stn->ftmax,mintim,maxtim);
+		}
+	      }
+	    }
+
+	    if (keepreport) {
+	      if (stn->sflag) {
+		/* check if stids match */
+		for (k=0; k<8; k++) *(ch1+k) = tolower(*(rfhdr.stid+k));
+		for (k=0; k<8; k++) *(ch2+k) = *(stn->stid+k);
+		if (!cmpwrd(ch1,ch2)) {
+		  keepreport=0;
+		  if (verb==2) printf("report stid doesn't match\n");
+		}
+
+	      } else {
+		/* check if stid is still the initialized value */
+		for (k=0;k<8;k++) if (*(rfhdr.stid+k) == '?') {
+		  keepreport=0;
+		  if (verb==2) printf("report has no stid\n");
+		}
+		/* check if lat and lon are within range */
+		hlon = rfhdr.lon;
+		hlat = rfhdr.lat;
+		if (hlon<minlon) hlon+=360.0;
+		if (hlon>maxlon) hlon-=360.0;
+		if (hlon<minlon || hlon>maxlon || hlat<minlat || hlat>maxlat) {
+		  keepreport=0;
+		  if (verb==2) printf("report not in lat/lon domain\n");
+		}
+		if (keepreport && stn->rflag &&
+		    hypot(hlon-minlon,hlat-minlat)>stn->radius) {
+		  keepreport=0;
+		  if (verb==2) printf("report not within radius of lat/lon location\n");
+		}
+	      }
+	    }
+	    
+	    /* loop through rfblock to get a data value */
+	    if (keepreport) {
+	      for (bval=rfblockbeg; bval != val; bval=bval->next) {
+		if (bval->undef) continue;
+
+		/* Non-replicated surface report */
+		if ((stn->pvar->levels==0) && (bval->z == -1)) {           
+		    
+		  /* If variable x,y matches, chain report off stn block */
+		  if ((dequal(bval->x,stn->pvar->units[0],1e-08)==0) && 
+		      (dequal(bval->y,stn->pvar->units[1],1e-08)==0)) {
+		    rpt = gaarpt(stn);
+		    if (rpt==NULL) {
+		      gaprnt(0,"getbufr error: gaarpt returned NULL\n");
+		      goto err;
+		    }
+		    rpt->lat = hlat;
+		    rpt->lon = hlon;
+		    rpt->lev = stn->pfi->undef;
+		    rpt->tim = htim;   
+		    rpt->val = bval->val;
+		    for (k=0; k<8; k++) *(rpt->stid+k) = *(rfhdr.stid+k);
+		    stn->rnum++;
+		    break;   /* quit loop now that we've got non-replicated report */
+		  }
+
+		} 
+		/* Replicated surface report */
+		else if ((stn->pvar->levels==2) && (bval->z != -1)) {    
+		  
+		  /* If variable x,y matches, chain report off stn block */
+		  if ((dequal(bval->x,stn->pvar->units[0],1e-08)==0) && 
+		      (dequal(bval->y,stn->pvar->units[1],1e-08)==0)) {
+		    rpt = gaarpt(stn);
+		    if (rpt==NULL) {
+		      gaprnt(0,"getbufr error: gaarpt returned NULL\n");
+		      goto err;
+		    }
+		    rpt->lat = hlat;
+		    rpt->lon = hlon;
+		    rpt->lev = stn->pfi->undef;
+		    rpt->tim = htim;   
+		    rpt->val = bval->val;
+		    for (k=0; k<8; k++) *(rpt->stid+k) = *(rfhdr.stid+k);
+		    stn->rnum++;
+		  }
+		  
+		} 
+		/* Replicated upper air report */
+		else if ((stn->pvar->levels==1) && (bval->z != -1)) {
+
+		  /* check if level is within range */
+		  hlev = rfhdr.lev;
+		  if (minlev==maxlev) {
+		    if (fabs(hlev-minlev)>0.01) {
+		      keepreport=0;
+		      if (verb==2) printf("report level doesn't match\n");
+		    }
+		  } else {
+		    if (hlev<minlev || hlev>maxlev) {
+		      keepreport=0;
+		      if (verb==2) printf("report level is out of range\n");
+		    }
+		  }
+		  if (keepreport) {
+		    /* If variable x,y matches, chain report off stn block */
+		  if ((dequal(bval->x,stn->pvar->units[0],1e-08)==0) && 
+		      (dequal(bval->y,stn->pvar->units[1],1e-08)==0)) {
+		      rpt = gaarpt (stn);
+		      if (rpt==NULL) {
+			gaprnt(0,"getbufr error: gaarpt returned NULL\n");
+			goto err;
+		      }
+		      rpt->lat = hlat;
+		      rpt->lon = hlon;
+		      rpt->lev = hlev;
+		      rpt->tim = htim;
+		      rpt->val = bval->val;
+		      for (k=0; k<8; k++) *(rpt->stid+k) = *(rfhdr.stid+k);
+		      stn->rnum++;
+		    }
+		  }
+		}  /* Matches  if (stn->pvar->levels==0) { ... } else {   */
+	      }  /* Matches  for (bval=rfblockbeg; bval != val; bval=bval->next) {  */
+	    }  /* Matches  if (keepreport) {  */
+
+	    /* If we've gotten here then we've reached the end of the subset */
+	    if (!val) break; 
+
+	    /* reset markers */
+	    rfblockbeg = val;  
+	    rfold = val->z;
+	  }
+	  val = val->next;
+	} /* end of while loop */
+      }   /* end of loop through message subsets */
+    }     /* end of loop through messages */
+  }  /* Matches  for (f=minf; f<=maxf; f++) {  */
+  
+  stn->rpt = sortrpt(stn->rpt);
+  return(0);
+
+err:
+  for (i=0; i<BLKNUM; i++) {
+    if (stn->blks[i] != NULL) free (stn->blks[i]);
+  }
+  return (1);
+}
+
+void getbufrhdr (gabufr_val *first, gabufr_val *last, struct bufrinfo *info, 
+		 struct bufrhdr *hdr, gaint flag, gaint *toffneg) {
+  gaint k,toffhr;
+  char bigstr[256];
+  gadouble pval;
+  gadouble tofffrac;
+  
+  gabufr_val *val;
+
+  for (val = first; val != last; val = val->next) {    
+    if (!val) break;
+    if (val->undef) continue; 
+    /* flag should be 0 for subsets, 1 for rfblocks */
+    if ((!flag) && (val->z != -1)) continue; 
+    
+    /* YEAR */
+    if (val->x == info->base.yrxy[0] && val->y == info->base.yrxy[1]) {
+      if (val->sval == NULL) hdr->tvals.yr = (gaint)val->val;
+    }
+    if (val->x == info->offset.yrxy[0] && val->y == info->offset.yrxy[1]) {
+      if (val->sval == NULL) hdr->toffvals.yr = (gaint)val->val;
+    }
+    /* MONTH */
+    if (val->x == info->base.moxy[0] && val->y == info->base.moxy[1]) {
+      if (val->sval == NULL) hdr->tvals.mo = (gaint)val->val;
+    }
+    if (val->x == info->offset.moxy[0] && val->y == info->offset.moxy[1]) {
+      if (val->sval == NULL) hdr->toffvals.mo = (gaint)val->val;
+    }
+    /* DAY */
+    if (val->x == info->base.dyxy[0] && val->y == info->base.dyxy[1]) {
+      if (val->sval == NULL) hdr->tvals.dy = (gaint)val->val;
+    }
+    if (val->x == info->offset.dyxy[0] && val->y == info->offset.dyxy[1]) {
+      if (val->sval == NULL) hdr->toffvals.dy = (gaint)val->val;
+    }
+    /* HOUR */
+    if (val->x == info->base.hrxy[0] && val->y == info->base.hrxy[1]) {
+      if (val->sval == NULL) hdr->tvals.hr = (gaint)val->val;
+    }
+    if (val->x == info->offset.hrxy[0] && val->y == info->offset.hrxy[1]) {
+      if (val->sval == NULL) {
+	/* If offset is negative, trip flag and then use absolute value */
+	if (val->val < 0) *toffneg = 1; 
+	pval = fabs(val->val); 
+	/* If offset contains fractional hours, update minutes too */
+	toffhr   = (gaint)pval;
+	tofffrac = pval - toffhr;
+	hdr->toffvals.hr = toffhr;
+	hdr->toffvals.mn = (gaint)(0.5+(tofffrac*60.0));
+      }
+    }
+    /* MINUTE */
+    if (val->x == info->base.mnxy[0] && val->y == info->base.mnxy[1]) {
+      if (val->sval == NULL) hdr->tvals.mn = (gaint)val->val;
+    }
+    if (val->x == info->offset.mnxy[0] && val->y == info->offset.mnxy[1]) {
+      if (val->sval == NULL) hdr->toffvals.mn = (gaint)val->val;   
+    }
+    /* SECONDS */
+    if (val->x == info->base.scxy[0] && val->y == info->base.scxy[1]) {
+      if (val->sval == NULL) hdr->sec = (gaint)val->val;
+    }
+    if (val->x == info->offset.scxy[0] && val->y == info->offset.scxy[1]) {
+      if (val->sval == NULL) hdr->offsec = (gaint)val->val;
+    }
+    /* STATION ID */
+    if (val->x == info->stidxy[0] && val->y == info->stidxy[1]) {
+      if (val->sval != NULL) {  
+	/* copy string */
+	for (k=0; k<8; k++) {
+	  if (*(val->sval+k) == '\0') break;
+	  *(hdr->stid+k) = *(val->sval+k);
+	}
+	/* pad with spaces */
+	while (k<8) {
+	  *(hdr->stid+k) = ' ';
+	  k++;
+	}
+      } else {                  
+	snprintf(bigstr,255,"%-10d",(gaint)val->val);
+	for (k=0; k<8; k++) *(hdr->stid+k) = *(bigstr+k);
+      }
+    }
+    /* LATITUDE */
+    if (val->x == info->latxy[0] && val->y == info->latxy[1]) {
+      if (val->sval == NULL) hdr->lat = val->val;
+    }
+    /* LONGITUDE */
+    if (val->x == info->lonxy[0] && val->y == info->lonxy[1]) {
+      if (val->sval == NULL) hdr->lon = val->val;
+    }
+    /* LEVEL */
+    if (val->x == info->levxy[0] && val->y == info->levxy[1]) {
+      if (val->sval == NULL) hdr->lev = val->val;
+    }
+  }
+}
+
+/* 
+ * Code for sorting a linked list of station reports so they are 
+ * in increasing time order. The algorithm used is Mergesort.
+ * The sort function returns the new head of the list. 
+ * 
+ * This code is copyright 2001 Simon Tatham.
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+struct garpt * sortrpt(struct garpt *list) {
+  struct garpt *p, *q, *e, *tail;
+  gaint insize, nmerges, psize, qsize, i;
+
+  if (!list) return NULL;
+  insize = 1;
+  while (1) {
+    p = list;
+    list = NULL;
+    tail = NULL;
+    nmerges = 0;  /* count number of merges we do in this pass */
+    while (p) {
+      nmerges++;  /* there exists a merge to be done */
+      /* step `insize' places along from p */
+      q = p;
+      psize = 0;
+      for (i = 0; i < insize; i++) {
+	psize++;
+	q = q->rpt;
+	if (!q) break;
+      }
+
+      /* if q hasn't fallen off end, we have two lists to merge */
+      qsize = insize;
+
+      /* now we have two lists; merge them */
+      while (psize > 0 || (qsize > 0 && q)) {
+
+	/* decide whether next rpt of merge comes from p or q */
+	if (psize == 0) {   
+	  /* p is empty; e must come from q. */
+	  e = q; 
+	  q = q->rpt; 
+	  qsize--;
+	} else if (qsize == 0 || !q) {	
+	  /* q is empty; e must come from p. */
+	  e = p; 
+	  p = p->rpt; 
+	  psize--;
+	} else if ((p->tim - q->tim) <= 0) {
+	  /* First rpt of p is lower (or same); e must come from p. */
+	  e = p; 
+	  p = p->rpt; 
+	  psize--;
+	} else {
+	  /* First garpt of q is lower; e must come from q. */
+	  e = q; 
+	  q = q->rpt; 
+	  qsize--;
+	}
+
+	/* add the next rpt to the merged list */
+	if (tail) {
+	  tail->rpt = e;
+	} else {
+	  list = e;
+	}
+	tail = e;
+      }
+
+      /* now p has stepped `insize' places along, and q has too */
+      p = q;
+    }
+    tail->rpt = NULL;
+
+    /* If we have done only one merge, we're finished. */
+    if (nmerges <= 1)   /* allow for nmerges==0, the empty list case */
+      return list;
+
+    /* Otherwise repeat, merging lists twice the size */
+    insize *= 2;
+  }
+}
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..9ce8068
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,188 @@
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* little_endian machine */
+#undef BYTEORDER
+
+/* Enable geotiff */
+#undef GEOTIFF
+
+/* Define if GetFile has a short prototype */
+#undef GETFILE_SHORT_PROTOTYPE
+
+/* Machine is a Cray */
+#undef GRADS_CRAY
+
+/* Obsolete feature description string */
+#undef GRADS_DESC
+
+/* Machine is 64-bit HP */
+#undef GRADS_HP64
+
+/* GrADS version */
+#undef GRADS_VERSION
+
+/* Enable grib2 */
+#undef GRIB2
+
+/* Enable printim using zlib, libpng, and libgd */
+#undef GXPNG
+
+/* Enable netcdf4 */
+#undef HAVENETCDF4
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `gdCompareInt' function. */
+#undef HAVE_GDCOMPAREINT
+
+/* Define to 1 if you have the <hdf4_netcdf.h> header file. */
+#undef HAVE_HDF4_NETCDF_H
+
+/* Define to 1 if you have the <history.h> header file. */
+#undef HAVE_HISTORY_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define if you have a readline compatible library */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <readline.h> header file. */
+#undef HAVE_READLINE_H
+
+/* Define if your readline library has \`add_history' */
+#undef HAVE_READLINE_HISTORY
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#undef HAVE_READLINE_HISTORY_H
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
+/* Define to 1 if you have the <shapefil.h> header file. */
+#undef HAVE_SHAPEFIL_H
+
+/* Define to 1 if you have the `SimpleGetFile' function. */
+#undef HAVE_SIMPLEGETFILE
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtod' function. */
+#undef HAVE_STRTOD
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <tiffio.h> header file. */
+#undef HAVE_TIFFIO_H
+
+/* Define to 1 if you have the <tiff.h> header file. */
+#undef HAVE_TIFF_H
+
+/* Define to 1 if you have the <udunits.h> header file. */
+#undef HAVE_UDUNITS_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define if hdf prefixes netcdf symbols by sd */
+#undef HDF_HAVE_NETCDF
+
+/* A macro that append sd_ to netcdf symbols if needed */
+#undef HDF_NETCDF_NAME
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Enable command line editing */
+#undef READLINE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable OPeNDAP for grids */
+#undef USEDAP
+
+/* Use GetFile from freq */
+#undef USEFREQ
+
+/* Enable OPeNDAP for station data */
+#undef USEGADAP
+
+/* Enable GUI widgets */
+#undef USEGUI
+
+/* Enable hdf4 */
+#undef USEHDF
+
+/* Enable hdf5 */
+#undef USEHDF5
+
+/* Enable netcdf */
+#undef USENETCDF
+
+/* Enable shapefile */
+#undef USESHP
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
diff --git a/src/dodstn.c b/src/dodstn.c
new file mode 100644
index 0000000..ed09cd9
--- /dev/null
+++ b/src/dodstn.c
@@ -0,0 +1,603 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by Joe Wielgosz 
+ * 
+ * dodstn.c: interface to gadap library, for reading remote station data
+ *
+ * to do:
+ * 
+ *  - as in BUFR datafiles, any given coordinate may occur in
+ *  either header or profile of DODS data. for example, in an EPIC
+ *  time series, lat/lon/lev are in the header, time is in the
+ *  profile. the loop that builds garpt structures needs to handle
+ *  this.
+ *
+ *  - queries to the EPIC system do not send the time constraints;
+ *  a function needs to be written to convert floating point grid
+ *  time into epic integer-format absolute time, and print that
+ *  out into the constraint string.
+ *  
+ *  the following features will reduce unnecessary use of server resorces, 
+ *  by making it quicker and easier to figure out where the data is 
+ *  located in a station dataset:
+ * 
+ *  - ideally there should be a way to request just coordinate data,
+ *  without a data variable. 
+ *
+ * - dappfi should check for some kind of metadata fields that set
+ *   lat/lon/lev to reasonable values if present. 
+ *
+ * - one could even go further, and have attributes for average
+ *   number of stations, average profile length etc. in order to
+ *   get a sense of how many data points are in the dataset.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include "grads.h"
+#include "gadap.h"
+
+/* returns dimension index (0,1,2,3 or -1 for no match) associated
+   with the varid, by searching the dapinf structure */
+gaint doddim(gaint varid, struct gafile *pfi) {
+  gaint i;
+  for (i=0; i<5; i++) {
+    if (varid == pfi->dapinf[i]) return i;
+  }
+  return -1;
+}
+
+/* gets the index of variable named either name1 or if not found, name2 */
+gaint dodgvar(char *name1, char *name2, struct gafile *pfi) {
+  gaint var = gadap_d_varindex(pfi->dhandle, name1);
+  if (var < 0) var = gadap_d_varindex(pfi->dhandle, name2);
+  if (var < 0) var = -999;
+  return var;
+}
+
+/* True if this is an EPIC data set (has _id variable. Need better way)*/
+gaint isepic(GADAP_DATASET handle) {
+  return gadap_d_varindex(handle, "_id") >= 0;
+}
+
+/* Convert EPIC time format, which is a 64-bit double, into a dt structure */
+struct dt epict2dt(gadouble);
+struct dt epict2dt(gadouble val) {
+  gadouble tim;
+  long ltim;
+  struct dt dtbase,dtval;
+  
+  dtbase.yr = 1970;
+  dtbase.mo = 1;
+  dtbase.dy = 1;
+  dtbase.hr = 0;
+  dtbase.mn = 0;
+  
+  tim = val;                        /* millisecs since 01-01-1970 */
+  tim = (tim / 60 / 1000);          /* minutes since 01-01-1970 */
+  ltim = tim;
+  if (ltim < 0) ltim = (-1)*ltim;   /* absolute value of minutes since 01-01-1970 */
+
+  dtval.yr = 0;
+  dtval.mo = 0;
+  dtval.mn = (ltim % 60);
+  dtval.hr = (ltim / 60) % 24;
+  dtval.dy = (ltim / 60 / 24);
+  if (val >= 0.0) {
+    timadd(&dtbase, &dtval);
+  }
+  else {
+    timsub(&dtbase, &dtval);
+  }
+  return dtval;
+}
+
+/* handle EPIC time format, which is a 64-bit double */
+gadouble epict2gr(gadouble val, struct gafile *pfi) {
+  gadouble tim;
+  long ltim;
+  struct dt dtbase, dtval;
+  
+  dtbase.yr = 1970;
+  dtbase.mo = 1;
+  dtbase.dy = 1;
+  dtbase.hr = 0;
+  dtbase.mn = 0;
+  
+  tim = val; /* millisecs since 01-01-1970 */
+  tim = (tim / 60 / 1000); /* minutes since 01-01-1970 */
+  ltim = tim;
+  
+  dtval.yr = 0;
+  dtval.mo = 0;
+  dtval.mn = (ltim % 60);
+  dtval.hr = (ltim / 60) % 24;
+  dtval.dy = (ltim / 60 / 24);
+  timadd(&dtbase, &dtval);
+
+  return t2gr(pfi->abvals[3], &dtval);
+  /* change this function to return a dtval structure instead of a grads grid value 
+     so that this can be used when there is no grads grid structure defined */
+}
+
+
+/* builds URL for sending a query to epic, which uses generic DODS
+ * constraint clauses (i.e. '&varname>value') instead of GDS functions
+ * bounds() and stid()
+ */
+void epicqstr(char * buf, struct gastn * stn) {
+
+  GADAP_DATASET handle;
+  struct gafile *pfi;
+  const char *name;
+  gaint *dapinf;
+  gaint i;
+  char *next, *stid;
+
+  pfi = stn->pfi;
+  handle = pfi->dhandle;
+  dapinf = pfi->dapinf;
+  stid = stn->stid;
+  next = buf;
+  if (stn->sflag) {
+    name = gadap_d_varname(handle, dapinf[4]);
+    snprintf(next,8191,"&%s=",name);
+    next += strlen(next);
+    for (i=0; i<8; i++) {
+      if (stid[i] == ' ') break;
+      (*next) = stid[i];
+      next++;
+    }
+    (*next) = '\0';
+  } 
+  else {
+ 
+
+    /* could add code here to build time constraint on request */
+    /* create a gradstime2epic time routine have to give epic server
+       time constaints in its own units: msec since jan1970  */
+
+    name = gadap_d_varname(handle, dapinf[0]);
+    snprintf(next,8191,"&%s>=%f&%s<=%f", name, stn->dmin[0], name, stn->dmax[0]);
+    next += strlen(next);
+
+    name = gadap_d_varname(handle, dapinf[1]);
+    snprintf(next,8191,"&%s>=%f&%s<=%f", name, stn->dmin[1], name, stn->dmax[1]);
+    next += strlen(next);
+
+  }
+
+  if (stn->pvar->levels) {
+    name = gadap_d_varname(handle, dapinf[2]);
+    snprintf(next,8191,"&%s>=%f&%s<=%f", name, stn->dmax[2], name, stn->dmin[2]);
+    next += strlen(next);
+  }
+}
+
+/*  Open an OPeNDAP station data set and fill in the gafile
+    info from metadata from the server */
+
+gaint dappfi (char *url, struct gafile *pfi) {
+  struct gavar *pvar;
+  struct dt tdef,dt1,dt2;
+  gaint i,j,isvert,nvars,nivars,lcnt,len,gotfill,tvar,tminid,tsizeid,tstepid,trngid;
+  size_t sz;
+  const char *name, *longname;
+  const char *trngstr;
+  GADAP_DATASET handle;
+  GADAP_STATUS rc;
+  gadouble v1=0,v2=0,*vals;
+  gadouble fill,tmin,tmax;
+  char *pos;
+
+  rc = gadap_open(url, &handle);
+  if (rc!=0) {
+    gaprnt (0,"Open Error on OPeNDAP URL\n");
+    return (99);
+  }
+
+  nvars = gadap_d_numvars(handle);
+  if (nvars<1) {
+    gaprnt (0,"Open error: OPeNDAP URL is not a station dataset\n");
+    gadap_close(handle,1);
+    return(99);
+  }
+
+  /* save handle, url, and dataset title */
+  pfi->type = 2;
+  pfi->dhandle = (gaint)handle; 
+  len = 0;
+  while (*(url+len) && len<4095) {
+    pfi->name[len] = *(url+len);
+    pfi->dnam[len] = *(url+len);
+    len++;
+  }
+  pfi->name[len] = '\0';  
+  pfi->dnam[len] = '\0';
+  name = gadap_d_title(handle);
+  if (name) {
+    len = 0;
+    while (*(name+len) && len<510) {
+      pfi->title[len] = *(name+len);
+      len++;
+    }
+    pfi->title[len] = '\0';
+  } 
+  else {
+    /* empty string for title by default */
+    pfi->title[0] = '\0';
+  }
+  
+  /* search for coordinate variables */
+  pfi->dapinf[0] = dodgvar("lon", "longitude", pfi);
+  pfi->dapinf[1] = dodgvar("lat", "latitude", pfi);
+  pfi->dapinf[2] = dodgvar("lev", "depth", pfi);
+  pfi->dapinf[3] = dodgvar("time", "time", pfi);
+  pfi->dapinf[4] = dodgvar("stid", "_id", pfi);
+  tvar = pfi->dapinf[3];
+
+  /* search for data variables */
+  nivars = gadap_d_numlivars(handle);
+  sz = nvars * (sizeof(struct gavar) + 7 );
+  pvar = (struct gavar *)galloc(sz,"dapstnpvar");
+  if (pvar==NULL) {
+    gaprnt (0,"Memory allocation error in dappfi\n");
+    gadap_close(handle,1);
+    return(99);
+  }
+  pfi->pvar1 = pvar;
+  lcnt = 0;
+  gotfill = 0;
+  /* set default values for file-wide undef and ulow/uhi */
+  pfi->undef =  -9.99e8; 
+  pfi->ulow = fabs(pfi->undef/EPSILON);
+  pfi->uhi  = pfi->undef + pfi->ulow;
+  pfi->ulow = pfi->undef - pfi->ulow;
+  
+  for (i=0; i<nvars; i++) {
+    isvert = 0;
+    if (i>=nivars) isvert = 1;
+    name = longname = NULL;
+    name = gadap_d_varname(handle,i);
+    longname = gadap_d_attrstr(handle, i, gadap_d_attrindex(handle, i, "long_name"));
+    if (!longname) longname = name;
+    if (doddim(i, pfi) == -1) {
+      if (!gotfill) {
+	if (gadap_d_fill(handle,i,&fill) == GADAP_SUCCESS)  {
+	  gotfill = 1;
+	  /* Use the first missing value found in file (1st variable) as file-wide 
+	     undef, provided that it is not a NaN. If it is, keep the default value. */
+	  if (!isnan(fill)) {
+	    pfi->undef = fill;
+	    pfi->ulow = fabs(pfi->undef/EPSILON);
+	    pfi->uhi  = pfi->undef + pfi->ulow;
+	    pfi->ulow = pfi->undef - pfi->ulow;
+	  } 
+	}
+      }
+      pvar->offset = i;
+      for (j=0;j<16;j++) pvar->units[j] = -999;
+      pvar->units[0] = 99;
+      pvar->levels = isvert;
+      len = 0;
+      while (*(name+len) && len < 16) {
+        pvar->abbrv[len] = tolower(*(name+len));
+        len++;
+      }
+      pvar->abbrv[len] = '\0';
+      len = 0;
+      while (*(longname+len) && len < 128) {
+        pvar->varnm[len] = (*(longname+len));
+        len++;
+      }
+      pvar->varnm[len] = '\0'; 
+      pvar++;
+      lcnt++;
+    }
+  }
+  pfi->vnum = lcnt;
+  pfi->ivnum = nivars-4; 
+  pfi->lvnum = lcnt - pfi->ivnum;
+  if (pfi->lvnum>0 && pfi->dapinf[2]<0) goto leverr;
+
+  /* Parse tdef info provided by server */
+
+  tminid  = gadap_d_attrindex(handle,tvar,"grads_size");
+  tsizeid = gadap_d_attrindex(handle,tvar,"grads_min");
+  tstepid = gadap_d_attrindex(handle,tvar,"grads_step");
+
+  if ((tminid >= 0) && (tsizeid >= 0) && (tstepid >= 0)) {
+    name = gadap_d_attrstr(handle,tvar,tminid);
+    if ( (pos = intprs((char *)name,&(pfi->dnum[3])))==NULL) goto tdeferr;
+    
+    name = gadap_d_attrstr(handle,tvar,tsizeid);
+    tdef.yr = -1000;
+    tdef.mo = -1000;
+    tdef.dy = -1000;
+    if ( (pos = adtprs((char *)name,&tdef,&dt1))==NULL) goto tdeferr;
+    if (dt1.yr == -1000 || dt1.mo == -1000.0 || dt1.dy == -1000) goto tdeferr;
+    
+    name = gadap_d_attrstr(handle,tvar,tstepid);
+    if ((pos = rdtprs((char *)name,&dt2))==NULL) goto tdeferr;
+    v1 = (gadouble)((dt2.yr * 12) + dt2.mo);
+    v2 = (gadouble)((dt2.dy * 1440) + (dt2.hr * 60) + dt2.mn);
+    if (dequal(v1,0.0,1e-08)==0 && dequal(v2,0.0,1e-08)==0) goto tdeferr;
+
+  } 
+  /* could add an else-if statment here to get attributes from epic
+     server and populate time metadata */
+  else if (isepic(handle)) {
+    trngid = gadap_d_attrindex(handle,nvars,"time_range");
+    trngstr = gadap_d_attrstr(handle,nvars,trngid);
+    tmin = strtod(trngstr,&trngstr);
+    tmax = strtod(trngstr,NULL);
+    dt1 = epict2dt(tmax);
+    dt1 = epict2dt(tmin);
+  }
+  else {
+    /* If no tdef info, use default time grid - daily, starting at UNIX epoch */
+    dt1.yr = 1970;
+    dt1.mo = 1;
+    dt1.dy = 1;
+    dt1.hr = 0;
+    dt1.mn = 0;
+    v1 = 0;
+    v2 = 1440;
+  }
+    
+  /* The info we just collected gets hung off the pfi block
+     as the time conversion constants */
+
+  sz = sizeof(gadouble)*8;
+  vals = (gadouble *)galloc(sz,"dapstnvals");
+  if (vals==NULL) goto tdeferr;
+  *(vals) = dt1.yr;
+  *(vals+1) = dt1.mo;
+  *(vals+2) = dt1.dy;
+  *(vals+3) = dt1.hr;
+  *(vals+4) = dt1.mn;
+  *(vals+5) = v1;
+  *(vals+6) = v2;
+  *(vals+7) = -999.9;
+  pfi->grvals[3] = vals;
+  pfi->abvals[3] = vals;
+  pfi->linear[3] = 1;
+
+  return (0);
+
+tdeferr:
+  gaprnt (0,"Invalid tdef info from server; error in dappfi\n");
+  gadap_close(handle,1);
+  return(99);
+leverr:
+  gaprnt (0,"Invalid lev info from server; error in dappfi\n");
+  gadap_close(handle,1);
+  return(99);
+}
+
+
+
+/* Obtain data to satisfy the request described in the gastn block  */
+gaint dapget(struct gastn *stn) {
+  struct gafile *pfi;
+  struct gavar *pvar;
+  struct garpt *rpt;
+  struct dt dt;
+  gadouble ulow,uhi;
+  gaint *dapinf;
+  gaint rptinfo[5];
+  GADAP_DATASET handle;
+  GADAP_STATUS rc;
+  GADAP_STN_QUERY *query;
+  GADAP_RPTCOL r_handle;
+  gadouble lon,lat,lev,val,time;
+  gaint nreps,nlevs,i,j,k,num, rptdatavar, gotepic;
+  char tchmn[20],tchmx[20],stid[10];
+  const char *stid2=NULL, *varnm;
+  char extra[8192];
+
+  pfi = stn->pfi;
+  handle = pfi->dhandle;
+  dapinf = pfi->dapinf;
+  query = gadap_sq_new(handle);
+  if (query==NULL) { 
+    gaprnt (0,"Memory allocation error in dapget\n");
+    return (99);
+  }
+
+  /* select variables to request */
+
+  pvar = stn->pvar;
+  for (i=0; i<5; i++) {
+    if (i == 2 && pvar->levels == 0) continue;
+    query->varflags[dapinf[i]] = 1;
+  }
+  query->varflags[pvar->offset] = 1;
+
+  /* set query constraints */
+
+  if (isepic(handle)) {
+    gotepic = 1;
+    epicqstr(extra, stn);
+    query->extra = extra;
+    query->usebounds = 0;
+  } 
+  else {
+    gotepic = 0;
+    query->minlon = stn->dmin[0];
+    query->maxlon = stn->dmax[0];
+    query->minlat = stn->dmin[1];
+    query->maxlat = stn->dmax[1];
+    query->minlev = stn->dmin[2];
+    query->maxlev = stn->dmax[2];
+    gr2t (stn->tvals, stn->tmin, &dt);
+    gat2ch (&dt, 4, tchmn, 20);  
+    query->mintime = tchmn;
+    gr2t (stn->tvals, stn->tmax, &dt);
+    gat2ch (&dt, 4, tchmx, 20);
+    query->maxtime = tchmx;
+    if (stn->sflag) {
+      for (i=0; i<8; i++) stid[i] = stn->stid[i];
+      i = 0;
+      while (stid[i]!=' ' && i<8) i++;
+      stid[i] = '\0';
+      query->stid = stid;
+    } else {
+      query->stid = NULL;
+    }
+    query->usebounds = 1;
+  }
+
+  gaprnt(2, "gadap: requesting ");
+  gaprnt(2, (char*)gadap_sq_url(query));
+  gaprnt(2, "\n");
+
+  rc = gadap_sq_send(query, &r_handle);
+  if (rc) {
+    gaprnt (0,"OPeNDAP data retrieval error\n");
+    gadap_sq_free(query);
+    return(99);
+  }
+
+  /* indices of coordinate variables in report will differ from
+     indices in original dataset, since some vars are missing */
+  for (i=0; i<5; i++) {
+    if (i == 2 && pvar->levels == 0) continue;
+    varnm = gadap_d_varname(handle, dapinf[i]);
+    rptinfo[i] = gadap_r_varindex(r_handle, varnm);
+  }
+  varnm = gadap_d_varname(handle, pvar->offset);
+  rptdatavar = gadap_r_varindex(r_handle, varnm);
+  nreps = gadap_r_numrpts(r_handle);
+
+  /* set uhi and ulow for fuzzy undef test */
+  if (pfi->undef==0.0) {   
+    ulow = 1e-5; 
+  } 
+  else {
+    ulow = fabs(pfi->undef/EPSILON);   
+  }
+  uhi  = pfi->undef + ulow;
+  ulow = pfi->undef - ulow;
+
+  num = 0;
+  for (i = 0; i < nreps; i++) {
+
+    /* get "header" info (lat/lon/stid/time coordinates) */
+    gadap_r_valdbl(r_handle, i, 0, rptinfo[0], 0, &lon); 
+    if (isnan(lon)) continue;
+    gadap_r_valdbl(r_handle, i, 0, rptinfo[1], 0, &lat); 
+    if (isnan(lat)) continue;
+
+    if (gotepic) {
+      gadap_r_valdbl(r_handle, i, 0, rptinfo[4], 0, &val); 
+      if (isnan(val)) continue;
+      snprintf(stid,8,"%d", (gaint)val);
+      
+      gadap_r_valdbl(r_handle, i, 0, rptinfo[3], 0, &val); 
+      if (isnan(val)) continue;
+      time = epict2gr(val, pfi);
+
+    } else {
+      stid2 = gadap_r_valstr(r_handle, i, 0, rptinfo[4], 0);
+      for (j = 0; j < 8; j++) {
+	if (stid2[j] == '\0') break;
+	stid[j] = stid2[j];
+      }
+      if (stid2) free(stid2);
+      gadap_r_valdbl(r_handle, i, 0, rptinfo[3], 0, &time); 
+    }
+
+    /* pad station id with spaces */
+    for (j = 0; j < 8; j++) {
+      if (stid[j] == '\0') break;
+    }
+    while (j < 8) {
+      stid[j] = ' ';
+      j++;
+    }
+    stid[8] = '\0';
+
+    /* get surface value or vertical profile */
+    if (pvar->levels==0) {
+      gadap_r_valdbl(r_handle, i, 0, rptdatavar, 0, &val);
+      if (isnan(val) || isinf(val)) val=pfi->undef;
+      rpt = gaarpt(stn);
+      for (k=0; k<8; k++) rpt->stid[k] = *(stid+k);  
+      rpt->lon = lon;
+      rpt->lat = lat;
+      rpt->tim = time;
+      rpt->lev = -9.99e8;
+      /* Test if value is within EPSILON of the missing data value.
+	 If yes, set undef mask to 0. The undef mask is 1 for valid data */
+      if (val >= ulow && val <= uhi) {
+	rpt->umask = 0;
+	rpt->val = pfi->undef;   
+      }
+      else {
+	rpt->umask = 1;
+	rpt->val = val;
+      }
+      num++;
+    } else {
+      nlevs = gadap_r_numlev(r_handle, i);
+      for (j=0; j<nlevs; j++) {
+	/* get the level and the data value */
+	gadap_r_valdbl(r_handle, i, j, rptinfo[2], 0, &lev);
+	if (isnan(lev) || isinf(lev))  continue;
+        gadap_r_valdbl(r_handle, i, j, rptdatavar, 0, &val);
+	if (isnan(val) || isinf(val)) val=pfi->undef;
+        rpt = gaarpt(stn);
+        for (k=0; k<8; k++) rpt->stid[k] = *(stid+k);  
+        rpt->lon = lon;
+        rpt->lat = lat;
+        rpt->tim = time;
+        rpt->lev = lev;
+	/* Test if value is within EPSILON of the missing data value.
+	   If yes, set undef mask to 0. The undef mask is 1 for valid data */
+	if (val >= ulow && val <= uhi) {
+	  rpt->umask = 0;
+	  rpt->val = pfi->undef;   
+	}
+	else {
+	  rpt->umask = 1;
+	  rpt->val = val;
+	}
+        num++;
+      }
+    }
+  }
+  stn->rnum = num;
+  gadap_r_free(r_handle);
+  gadap_sq_free(query);
+  return (0);
+}
+
+/*  Close gadap data set */
+
+void dapclo (struct gafile *pfi) {
+GADAP_DATASET handle;
+
+  if (pfi->dhandle == -999) return;
+  handle = pfi->dhandle;
+  gadap_close(handle,1);
+  pfi->dhandle = -999;
+}
diff --git a/src/gabufr.c b/src/gabufr.c
new file mode 100644
index 0000000..eb97219
--- /dev/null
+++ b/src/gabufr.c
@@ -0,0 +1,948 @@
+/* Copyright (C) 1988-2011 by Brian Doty and the 
+   Institute of Global Environment and Society (IGES).  
+   See file COPYRIGHT for more information.   */
+
+/* Authored by Joe Wielgosz */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#include <float.h>
+
+#include "gabufr.h"
+#include "grads.h"
+
+#ifndef GABUFR_DEBUG
+#define GABUFR_DEBUG 0
+#endif
+
+#define GABUFR_NO_PARSE_DATA 0
+#define GABUFR_PARSE_DATA 1
+
+typedef struct {
+  gabufr_msg * msg; /* msg being parsed */
+  gabufr_varid * descpos; /* current descriptor */
+  gabufr_varid * parentpos; /* descriptor in next level out (needed
+			       for NCEP use of a sequence to indicate
+			       replication of next descriptor */
+  unsigned char * datapos; /* position in raw data */
+  gaint databits;   /* bit offset in raw data */
+  gaint z;  /* current replication count in outermost level */
+  gaint sub; /* current subset */
+  gaint delrep; /* flag set if previous descriptor was delayed
+		 replication (F=2,Y=0) */
+  gabufr_val * curval; /* end of list of parsed data values */
+} gabufr_parseinf;
+
+
+void gabufr_free_val(gabufr_val * val) {
+  if (val->sval) {
+    free(val->sval);
+  }
+  free(val);
+}
+  
+
+void gabufr_free_msg(gabufr_msg * msg) {
+  gabufr_val * val, * nextval;
+  gaint i;
+  if (msg->subs) {
+    for (i = 0; i < msg->subcnt; i++) {
+      if (msg->subs[i]) {
+	for (val = msg->subs[i]; val != NULL; val = nextval) {
+	  nextval = val->next;
+	  gabufr_free_val(val);
+	}
+      }
+    }
+    free(msg->subs);
+  }
+  free(msg);
+}  
+ 
+void gabufr_close(gabufr_dset * dset) {
+  gabufr_msg * msg, * nextmsg;
+
+  for (msg = dset->msgs; msg != NULL; msg = nextmsg) {
+    nextmsg = msg->next;
+    gabufr_free_msg(msg);
+ }
+
+  if (dset->buf) {
+    printf("should have been done already");
+    free(dset->buf);
+  }
+
+  free(dset);
+}
+
+/* loads file contents into a memory block */
+gaint gabufr_load2mem(const char * path, gabufr_dset * dset) {
+  off_t bytesread, bytesleft, filesize;
+  FILE * datafile;
+  unsigned char * filebuf;
+  unsigned char * pos;
+
+  if ((datafile = fopen(path, "r")) == NULL) {
+      printf("Can't open BUFR file %s: %s\n", path, strerror(errno));
+      return GABUFR_ERR;
+  }
+
+  fseeko(datafile, 0, SEEK_END);
+  bytesleft = filesize = ftello(datafile);
+  fseeko(datafile, 0, SEEK_SET);
+  if (GABUFR_DEBUG) printf("filesize is %ld\n", filesize);
+
+  pos = filebuf = malloc(filesize);
+  if (filebuf == NULL) {
+    printf("Couldn't allocate memory for file parsing\n");
+    return GABUFR_ERR;
+  }
+
+  while (bytesleft > 0) {
+    bytesread = fread(pos, 1, bytesleft, datafile);
+    if (GABUFR_DEBUG) printf("read %ld bytes\n", bytesleft);
+    if (ferror(datafile)) {
+      printf("Low level read error on BUFR file %s\n", path);
+      free(filebuf);
+      fclose(datafile);
+      return GABUFR_ERR;
+    }
+    
+    if (feof(datafile) && bytesleft) {
+      if (GABUFR_DEBUG) printf("Ran out of data in BUFR file %s!\n", path);
+      free(filebuf);
+      fclose(datafile);
+      return GABUFR_ERR;
+    }
+
+    bytesleft -= bytesread;
+    pos += bytesread;
+  }
+  fclose(datafile);
+  dset->buf = filebuf;
+  dset->len = filesize;
+  dset->msgs = NULL;
+  return GABUFR_OK;
+}  
+
+/* prints a full description of a varid, expanding sequence contents*/
+void gabufr_print_varid (gabufr_varid *varid, gaint indent) {
+  gabufr_varid * seq_varid;
+  gabufr_varinf * varinf;
+  gaint i;
+  static gaint delrep = 0;
+
+  for (i = 0; i < indent; i++) {
+    printf(" ");
+  }
+
+  printf("%d %.2d %.3d  ", 
+	 varid->f, varid->x, varid->y);
+  
+  if (delrep) {
+    printf("(replication count)\n");
+    delrep = 0;
+    return;
+  }
+  switch (varid->f) {
+
+  case 0:
+    varinf = gabufr_get_varinf(varid->x, varid->y);
+    printf("(%s) %s\n",
+	   (varinf->datatype == GABUFR_STR_TYPE) ? "text" : "numeric",
+	   varinf->description);
+    break;
+
+  case 1:
+    printf("(replicate next %d", varid->x);
+    if (varid->y == 0) {
+      printf(", not including replication count)\n");
+      delrep = 1;
+    } else {
+      printf(", %d times)\n", varid->y);
+    }
+      
+    break;
+
+  case 2:
+    printf("(operator)\n");
+    break;
+
+  case 3:
+    printf("(sequence)\n");
+    for (seq_varid = gabufr_get_seq(varid->x, varid->y); 
+	 seq_varid; 
+	 seq_varid = seq_varid->next) {
+      gabufr_print_varid(seq_varid, indent + 2);
+    }
+    break;
+  }
+
+
+}
+
+/* builds a list of varid's from the message header */
+gabufr_varid * gabufr_extract_msg_desc(gabufr_msg * msg, gaint parse_data) {
+  unsigned char * pos, * start, * end;
+  gabufr_varid * head, * current, * next;
+  gabufr_varinf * varinf;
+
+  if (msg == NULL) {
+    return NULL;
+  }
+
+  if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA)  {
+    printf("\n\n\n>>> start of message\n");
+  }
+
+  head = current = NULL;
+  start = msg->section3 + 7;
+  end = msg->section4;
+  for (pos = start; pos < end; pos += 2) {
+    next = (gabufr_varid *) malloc(sizeof(gabufr_varid));
+    if (next == NULL) {
+      printf("Memory allocation failed during parsing\n");
+      gabufr_free_varids(head);
+      return NULL;
+    }
+      
+    next->f = gagbb(pos, 0, 2);
+    next->x = gagbb(pos, 2, 6);
+    next->y = gagbb(pos, 8, 8);
+    
+    if (next->f == 0 && next->x == 0 && next->y == 0) {
+      free(next);
+      continue;
+    }
+
+    next->next = NULL;
+
+    if (!gabufr_valid_varid(next->f, next->x, next->y)) {
+      printf("error: corrupt message (contains invalid FXY %d-%.2d-%.3d)\n", 
+	     next->f, next->x, next->y);
+      free(next);
+      gabufr_free_varids(head);
+      return NULL;
+    }
+
+    if (next->f == 0) {
+      varinf = gabufr_get_varinf(next->x, next->y);
+      if (varinf->width == 0) {
+	printf("error: no table information for FXY %d-%.2d-%.3d\n", 
+	       next->f, next->x, next->y); 
+	free(next);
+	gabufr_free_varids(head);
+	return NULL;
+      }
+    }
+
+    if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA) gabufr_print_varid(next, 0);
+
+    if (head) {
+      current->next = next;
+    } else {
+      head = next;
+    }
+    current = next;
+  }
+
+  if (GABUFR_DEBUG || parse_data == GABUFR_NO_PARSE_DATA)  {
+    printf("\n<<< end of message");
+  }
+
+  return head;
+}
+
+void gabufr_seekbits(gabufr_parseinf *inf, gaint bits) {
+  inf->databits += bits;
+  inf->datapos += (inf->databits / 8);
+  inf->databits %= 8;
+  /* if (GABUFR_DEBUG) printf("set position to %p (offset %d)\n", 
+     inf->datapos, inf->databits); */
+}  
+
+gaint gabufr_all_ones(gaint bitcnt) {
+  return (1 << bitcnt) - 1;
+}
+
+long gabufr_readbits2num(unsigned char * pos, gaint offset, gaint bitcnt) {
+  long retval;
+  if (bitcnt <= 0 || bitcnt > sizeof(long) * 8) {
+    printf("warning: can't read %d-bit data value; max is %d\n",
+	   bitcnt, (gaint) (sizeof(long) * 8));
+    return gabufr_all_ones(bitcnt);
+  } else {
+    retval = gagbb(pos, offset, bitcnt);
+    if (GABUFR_DEBUG) printf("read %2d bits at (%p + %d):  %ld\n", 
+			     bitcnt, pos, offset, retval);
+    return retval;
+  }
+}
+
+char * gabufr_readbits2str(unsigned char * pos, gaint offset, gaint bitcnt) {
+  gaint i, bytecnt;
+  char * retval;
+  if (bitcnt < 0 || bitcnt % 8) {
+    printf("error: invalid bit count for string: %d\n", 
+	   bitcnt);
+    return NULL;
+  }
+  bytecnt = bitcnt / 8;
+
+  if (GABUFR_DEBUG) printf("read %2d chars at (%p + %d): [", 
+	 bytecnt, pos, offset);
+  retval = (char *) malloc(bytecnt+1);
+  if (retval == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }
+  if (offset) {
+    for (i = 0; i < bytecnt; i++) {
+      retval[i] = (char) gagbb(pos + i, offset, 8);
+    }
+  } else {
+    memcpy(retval, pos, bytecnt);
+  }
+  retval[bytecnt] = '\0';
+  if (GABUFR_DEBUG) printf("%s]\n", retval);
+  return retval;
+}
+
+double gabufr_exp10(double mant, gaint exp) {
+  gaint i;
+  if (exp > 0) {
+    for (i = 0; i < exp; i++) {
+      mant /= 10;
+    }
+  } else {
+    for (i = 0; i > exp; i--) {
+      mant *= 10;
+    }
+  }    
+  return mant;
+}
+
+gaint gabufr_parseval(gabufr_parseinf *inf, gaint x, gaint y, gabufr_val * val) {
+  gabufr_varinf * varinf;
+  long packedval;
+
+  varinf = gabufr_get_varinf(x, y);
+  if (varinf->width == 0) {
+    printf("error: no entry for descriptor (0, %d, %d)\n", x, y);
+    return GABUFR_ERR;
+  }
+
+  if (varinf->datatype == GABUFR_STR_TYPE) {
+    val->sval = 
+      gabufr_readbits2str(inf->datapos, inf->databits, varinf->width);
+    val->val = DBL_MIN;
+  } else {
+    packedval = 
+      (double) gabufr_readbits2num(inf->datapos, inf->databits, varinf->width);
+
+    if (packedval == gabufr_all_ones(varinf->width)) {
+	val->undef = GABUFR_UNDEF;
+	if (GABUFR_DEBUG) printf("missing data flag set\n");
+      } else {
+	val->undef = GABUFR_DEF;
+      }
+
+    val->val = gabufr_exp10(packedval + varinf->offset, varinf->scale);
+    if (GABUFR_DEBUG) printf("unpacking: ( %d + %d ) / 10^%d -> %g\n",
+			     (gaint) packedval, 
+			     varinf->offset, 
+			     varinf->scale, 
+			     val->val);
+    val->sval = NULL;
+  } 
+  
+  val->x = x;
+  val->y = y;
+  val->z = inf->z;
+  gabufr_seekbits(inf, varinf->width);
+  return GABUFR_OK;
+}
+
+/* adds a new value to the current linked list, creating it if necessary */
+void gabufr_addval(gabufr_parseinf *inf, gabufr_val *val) {
+  if (! inf->curval) {
+    inf->msg->subs[inf->sub] = val;
+  } else {
+    inf->curval->next = val;
+  }    
+  val->next = NULL;
+  inf->curval = val;
+}
+
+gaint gabufr_parsedesc(gabufr_parseinf * inf, gaint f, gaint x, gaint y); 
+
+/* reads data associated with a list of (f,x,y) descriptors */
+gaint gabufr_parselist(gabufr_parseinf * inf, gabufr_varid * list) {
+  gabufr_varid * saved;
+  saved = inf->descpos;
+  for(inf->descpos = list; 
+      inf->descpos; 
+      inf->descpos = inf->descpos->next) {
+    if (gabufr_parsedesc(inf, inf->descpos->f, inf->descpos->x, 
+			 inf->descpos->y) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+  }
+  inf->descpos = saved;
+  return GABUFR_OK;
+}  
+
+/* performs replication - parses the next numdesc descriptors in the list, numreps times */
+gaint gabufr_replicate(gabufr_parseinf * inf, gaint numdesc, gaint numreps) {
+  gaint i, z, nestedrep;
+  gabufr_varid * base, * pos, * end, ** pos_addr;
+
+  if (GABUFR_DEBUG) printf("**** replicating %d descriptors %d times\n", 
+			   numdesc, numreps);
+
+    /* NCEP has sequences that just contain a replication factor,
+     * which are supposed to apply to the id that follows after that
+     * sequence.  so we may be inside a sequence with no more id's in
+     * the list.  Thus, we either increment the pointer for the
+     * current list, or the id pointer for the parent list, depending.
+     */
+  if (inf->descpos->next) {
+    if (GABUFR_DEBUG) printf("using descpos (currently %p)\n", inf->descpos);
+    pos_addr = &inf->descpos;
+  } else {
+    if (GABUFR_DEBUG) printf("using parentpos (currently %p)\n", inf->descpos);
+    pos_addr = &inf->parentpos;
+  }
+
+  pos = base = (*pos_addr);
+  for (i = 0; i < numdesc; i++) {
+      pos = pos->next;
+      if (!pos) {
+	printf("error: ran out of descriptors to replicate!\n");
+	return GABUFR_ERR;
+      }
+  }
+  end = pos;
+
+  nestedrep = (inf->z >= 0);
+  if (nestedrep) {
+    /* we handle nested rep fine, except that we don't print out the replication counts */
+    if (GABUFR_DEBUG) printf("warning: nested replication in dataset\n");
+  }
+
+  for (z = 0; z < numreps; z++) {
+    if (GABUFR_DEBUG) printf("\n** rep = %d of %d\n", z, numreps);
+
+    /* increment global var during looping, so that nested loops start 
+     *  from the right place */
+    (*pos_addr) = base;
+
+    if (!nestedrep) {
+      inf->z = z;
+    }
+
+    while ((*pos_addr) != end) {
+      (*pos_addr) = (*pos_addr)->next;
+      if (GABUFR_DEBUG) printf("descpos=%d-%d-%d\n", 
+			       (*pos_addr)->f, (*pos_addr)->x, (*pos_addr)->y);
+      if (gabufr_parsedesc(inf, (*pos_addr)->f, (*pos_addr)->x, 
+			   (*pos_addr)->y) == GABUFR_ERR) {
+	return GABUFR_ERR;
+      }
+    }
+  }
+
+  if (!nestedrep) {
+    inf->z = -1;
+  }
+
+  /* Move pointer to end of replicated descriptors */ 
+  (*pos_addr) = end;
+
+  if (GABUFR_DEBUG) printf("**** done replicating %d descriptors %d times\n\n",
+			   numdesc, numreps);
+  return GABUFR_OK;
+}
+
+gaint gabufr_parse_f0(gabufr_parseinf * inf, gaint x, gaint y) {
+  gabufr_val * val;
+  gabufr_val delrepval;
+  gabufr_varinf * varinf;
+  gaint numdesc, numreps;
+
+  if (x == 0 && y == 0) {
+    if (GABUFR_DEBUG) printf("null descriptor\n");
+    return GABUFR_OK;
+  } else {
+    varinf = gabufr_get_varinf(x, y);
+    if (GABUFR_DEBUG) printf("\t%s\n", varinf->description);
+  }
+
+  if (inf->delrep) {
+    if ( x != 31 ) {
+      printf("error: expected F=0 Y=31 X=... for delayed replication\n");
+      return GABUFR_ERR;
+    }
+    if (gabufr_parseval(inf, x, y, &delrepval) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+    numreps = delrepval.val;
+    numdesc = inf->delrep;
+    inf->delrep = 0;
+    if (gabufr_replicate(inf, numdesc, numreps) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+  } else {
+    val = (gabufr_val *) malloc(sizeof(gabufr_val));
+    if (val == NULL) {
+      printf("Memory allocation failed during parsing\n");
+      return GABUFR_ERR;
+    }
+    if (gabufr_parseval(inf, x, y, val) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+    gabufr_addval(inf, val);
+  }
+  return GABUFR_OK;
+}
+
+gaint gabufr_parse_f1(gabufr_parseinf * inf, gaint x, gaint y) {
+  gaint numdesc, numreps;
+
+  if (GABUFR_DEBUG) printf("\n\n");
+  numdesc = x;
+  if (y > 0) {
+    if (GABUFR_DEBUG) printf("**** normal replication\n");
+    numreps = y;
+    if (gabufr_replicate(inf, numdesc, numreps) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+  } else {
+    if (GABUFR_DEBUG) printf("**** delayed replication\n");
+    inf->delrep = x;
+  }
+  return GABUFR_OK;
+}
+
+
+gaint gabufr_parse_f2(gabufr_parseinf * inf, gaint x, gaint y) {
+  gabufr_val * val;
+  /*  gaint width; if we decide to skip local fields */
+
+  switch (x) {
+  case 4: /* associated field */
+    if (GABUFR_DEBUG) printf("reading %d-bit associated field\n", y);
+    val = (gabufr_val *) malloc(sizeof(gabufr_val));
+    if (val == NULL) {
+      printf("Memory allocation failed during parsing\n");
+      return GABUFR_ERR;
+    }
+    val->x = -1;
+    val->y = -1;
+    val->z = inf->z;
+    val->val = gabufr_readbits2num(inf->datapos, inf->databits, y);
+    val->sval = NULL;
+    gabufr_seekbits(inf, y);
+    gabufr_addval(inf, val);
+    break;
+
+  case 5: /* associated string */
+    if (GABUFR_DEBUG) printf("reading %d-byte associated string\n", y);
+    val = (gabufr_val *) malloc(sizeof(gabufr_val));
+    if (val == NULL) {
+      printf("Memory allocation failed during parsing\n");
+      return GABUFR_ERR;
+    }
+    val->x = -1;
+    val->y = -1;
+    val->z = inf->z;
+    val->sval = gabufr_readbits2str(inf->datapos, inf->databits, y * 8);
+    if (val->sval == NULL) {
+      return GABUFR_ERR;
+    }
+    val->val = DBL_MIN;
+    gabufr_seekbits(inf, y * 8);
+    gabufr_addval(inf, val);
+    break;
+
+  case 6: /* local field length */
+    /*
+      width = y;
+    inf->descpos = inf->descpos->next;
+    if (GABUFR_DEBUG) printf("skipping %d-bit local field F=%d X=%d Y=%d\n",
+	   y, inf->descpos->f, inf->descpos->x, inf->descpos->y);
+    gabufr_seekbits(inf, y);
+    */
+    break;
+
+  default:
+    printf("warning: ignoring unsupported operator F=2 X=%d Y=%d\n", x, y);
+  }
+
+  return GABUFR_OK;
+
+}
+
+gaint gabufr_parse_f3(gabufr_parseinf * inf, gaint x, gaint y) {
+  gabufr_varid * saved;
+  if (GABUFR_DEBUG) 
+    printf("\n==== recursing into table entry for F=3 X=%d Y=%d\n", x, y);
+  /*
+  table_d_entry = gabufr_get_seq(x, y);
+  if (table_d_entry->f == 1 && 
+      table_d_entry->y == 0 &&
+      table_d_entry->next->next == NULL) {
+  */
+    
+  saved = inf->parentpos;
+  inf->parentpos = inf->descpos;
+  for (inf->descpos = gabufr_get_seq(x, y); 
+       inf->descpos; 
+       inf->descpos = inf->descpos->next) {
+    if (gabufr_parsedesc(inf, inf->descpos->f, inf->descpos->x, 
+			 inf->descpos->y) == GABUFR_ERR) {
+      return GABUFR_ERR;
+    }
+  }
+  if (GABUFR_DEBUG) printf("==== finished F=3 X=%d Y=%d\n\n", x, y);
+  inf->descpos = inf->parentpos;
+  inf->parentpos = saved;
+
+  return GABUFR_OK;
+}
+
+gaint gabufr_parsedesc(gabufr_parseinf * inf, gaint f, gaint x, gaint y) {
+  gaint rc = GABUFR_OK;
+  if (GABUFR_DEBUG) printf("descriptor: (%d, %d, %d)\n", f, x, y);
+  switch (f) {
+  case 0: 
+    rc = gabufr_parse_f0(inf, x, y); 
+    break;
+  case 1: 
+    rc = gabufr_parse_f1(inf, x, y); 
+    break;
+  case 2: 
+    rc = gabufr_parse_f2(inf, x, y); 
+    break;
+  case 3: 
+    rc = gabufr_parse_f3(inf, x, y); 
+    break;
+  }
+  return rc;
+}
+
+
+/* parses the raw data for a msg into a list of val structures */
+gaint gabufr_parsevals(gabufr_msg * msg, gaint parse_data) {
+  gabufr_parseinf inf;
+  gabufr_varid * msg_descs;
+  gaint extra;
+
+  inf.delrep = 0;
+  inf.z = -1;
+  inf.datapos = msg->section4 + 4;  
+  inf.databits = 0;
+  inf.msg = msg;
+  msg_descs = gabufr_extract_msg_desc(msg, parse_data);
+  if (msg_descs == NULL) {
+    return GABUFR_ERR;
+  }
+
+  if (parse_data == GABUFR_PARSE_DATA || msg->is_new_tbl) {
+    for (inf.sub = 0; inf.sub < msg->subcnt; inf.sub++) {
+      if (GABUFR_DEBUG) printf("\n\n@@@ parsing subset %d @@@\n", inf.sub);
+      inf.parentpos = NULL;
+      inf.curval = NULL;
+      if (gabufr_parselist(&inf, msg_descs) == GABUFR_ERR) {
+	return GABUFR_ERR;
+      }
+    }
+    if (GABUFR_DEBUG) printf("data position is (%p + %d); end of data is %p\n", 
+			     inf.datapos, inf.databits, inf.msg->end);
+    
+    extra = inf.msg->end - inf.datapos;
+    if (extra > 1) {
+      printf("Corrupt message: %d extra bytes in data section\n", extra);
+      return GABUFR_ERR;
+    }
+  } else {
+    return GABUFR_ERR;
+  }
+
+  gabufr_free_varids(msg_descs);
+  return GABUFR_OK;
+}
+
+/* reads header data (not the descriptor list but the one-off required
+   fields) and creates a new message structure */
+gabufr_msg * gabufr_parsehdr(unsigned char * section0) {
+  gaint section2flag, century;
+  unsigned char *section2;
+  gabufr_msg * msg;
+
+  msg = (gabufr_msg *) malloc(sizeof(gabufr_msg));
+  if (msg == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }
+  
+  msg->next = NULL;
+
+  msg->section0 = section0;
+  
+  msg->section1 = msg->section0 + 8;
+  section2flag = gagbb(msg->section1+7, 0, 1);
+  if (section2flag) {
+    if (GABUFR_DEBUG) printf("found msg->section 2\n");
+    section2 = msg->section1 + gagby(msg->section1, 0, 3);
+    msg->section3 = section2 + gagby(section2, 0, 3);
+  } else {
+    if (GABUFR_DEBUG) printf("no msg->section 2\n");
+    msg->section3 = msg->section1 + gagby(msg->section1, 0, 3);
+  }
+ msg->section4 = msg->section3 + gagby(msg->section3, 0, 3);
+ msg->end = msg->section4 + gagby(msg->section4, 0, 3);
+ 
+ if (GABUFR_DEBUG) printf("sections: %p / %p / %p / %p (end %p)\n",
+			  msg->section0, 
+			  msg->section1, 
+			  msg->section3, 
+			  msg->section4,
+			  msg->end); 
+ 
+ if (GABUFR_DEBUG) printf("lengths: %ld / %ld / %ld / %ld (total %ld)\n",
+			  (galint)(msg->section1 - msg->section0), 
+			  (galint)(msg->section3 - msg->section1), 
+			  (galint)(msg->section4 - msg->section3), 
+			  (galint)(msg->end      - msg->section4),
+			  (galint)(msg->end      - msg->section0)); 
+
+  msg->tbl_inf.bufr_edition = gagby(msg->section0, 7, 1);
+  msg->tbl_inf.master_tbl_num = gagby(msg->section1, 3, 1);
+  msg->tbl_inf.master_tbl_version = gagby(msg->section1, 10, 1);
+  msg->tbl_inf.local_tbl_version = gagby(msg->section1, 11, 1);
+
+  if (GABUFR_DEBUG) 
+    printf ("edition: %d; master #: %d; master v: %d; local v: %d\n",
+	    msg->tbl_inf.bufr_edition, 
+	    msg->tbl_inf.master_tbl_num, 
+	    msg->tbl_inf.master_tbl_version, 
+	    msg->tbl_inf.local_tbl_version);
+
+  msg->is_new_tbl = (gagby(msg->section1, 8, 1) == 11);
+
+/* 
+   Per Jack Woollen, the message section 1 date 
+   has the year broken into two separate bytes. 
+   Byte #13 contains the year of the century.
+   Byte #18 contains the number of the century. 
+   For 1999, the century would be 20, and the year of the century 99
+   For 2000, the century would be 20, and the year of the century 100
+   For 2003, the century would be 21, and the year of the century 1
+*/
+
+  msg->year = gagby(msg->section1, 12, 1);   
+  msg->month = gagby(msg->section1, 13, 1);
+  msg->day = gagby(msg->section1, 14, 1);
+  msg->hour = gagby(msg->section1, 15, 1);
+  msg->min = gagby(msg->section1, 16, 1);
+  msg->subcnt = gagby(msg->section3, 4, 2);
+
+  century = gagby(msg->section1,17,1);     
+  msg->year = msg->year + ((century-1)*100);
+
+  if (msg->subcnt) {
+    msg->subs = (gabufr_val **) calloc(msg->subcnt, sizeof(gabufr_val *));
+    if (msg->subs == NULL) {
+      printf("Memory allocation failed during parsing\n");
+      free(msg);
+      return NULL;
+    }
+  } else {
+    msg->subs = NULL;
+  }
+  if (GABUFR_DEBUG) printf("date: %.2d:%.2d %.2d-%.2d-%.2d   subsets: %d\n", 
+			   msg->hour, msg->min, msg->month, msg->day, 
+			   msg->year, msg->subcnt);
+
+
+  return msg;
+}
+
+/* not currently used */
+gaint gabufr_countmsgs(gabufr_dset *dset) {
+  unsigned char * start, * end, * pos, * endofmsg;
+  gaint msglen;
+  gaint msgcnt;
+  gabufr_msg * current, * next;
+
+  msgcnt = 0;
+  current = next = NULL;
+  pos = start = dset->buf;
+  end = (start + dset->len) - 4; /* stop 4 characters early so
+				      * memcmp() doesn't run off the edge */
+  while (pos < end) {
+
+    /* search for next "BUFR" string */
+    if( memcmp(pos, "BUFR", 4) == 0 ) {
+
+      msglen = gagby(pos, 4, 3);
+      /* if (GABUFR_DEBUG) 
+	 printf("\n\n\n\nfound 'BUFR' at %p followed by length %d; ", 
+	 pos, msglen); */
+      endofmsg = (pos + msglen) - 4;
+
+      if (memcmp(endofmsg, "7777", 4) == 0) {
+
+	/* if (GABUFR_DEBUG) printf("confirmed end of message.\n"); */
+	msgcnt++;
+	pos = endofmsg + 4;
+      } else {
+	/* if (GABUFR_DEBUG) printf("no end of message! got %4c instead\n", 
+	   endofmsg); */
+      }
+    }
+
+    pos++;
+
+  }
+  printf("found %d messages in file\n", msgcnt);
+  return msgcnt;
+}
+
+/* reads data out of a file into a series of message structures */
+gaint gabufr_decode(gabufr_dset *dset, gaint parse_data) {
+  unsigned char * start, * end, * pos, * endofmsg;
+  gaint msglen;
+  gabufr_msg * current, * next;
+
+  /*  gabufr_countmsgs(dset); */
+
+  dset->msgcnt = 0;
+  current = next = NULL;
+  pos = start = dset->buf;
+  end = (start + dset->len) - 4; /* stop 4 characters early so
+				      * memcmp() doesn't run off the edge */
+  while (pos < end) {
+
+    /* search for next "BUFR" string */
+    if( memcmp(pos, "BUFR", 4) == 0 ) {
+
+      msglen = gagby(pos, 4, 3);
+      if (GABUFR_DEBUG) 
+	printf("\n\n\n\nFound 'BUFR' at %p followed by length %d; ", 
+	     pos, msglen);
+      endofmsg = (pos + msglen) - 4;
+      
+      if (memcmp(endofmsg, "7777", 4) == 0) {
+
+	if (GABUFR_DEBUG) printf("confirmed end of message.\n");
+	next = gabufr_parsehdr(pos);
+	if (next) {
+	  next->fileindex = dset->msgcnt;
+
+	  if (next->is_new_tbl) {
+	    if (GABUFR_DEBUG) printf("msg %d contains a new BUFR table\n", 
+				     dset->msgcnt);
+	  } else {
+	    if (GABUFR_DEBUG) printf("msg %d contains data\n",
+				     dset->msgcnt);
+	  }
+	  
+	  if (!gabufr_have_tbl(&next->tbl_inf)) {
+	    if (gabufr_read_tbls(&next->tbl_inf) == GABUFR_ERR) {
+	      return GABUFR_ERR;
+	    }
+	  }
+	  
+	  if (GABUFR_DEBUG) printf("%%%%%%%%%%%%%% processing message %d..\n", 
+				   dset->msgcnt);
+	  if (parse_data == GABUFR_NO_PARSE_DATA)  {
+	    printf("\n\n\n>>> processing message %d\n", dset->msgcnt);
+	  }
+	  
+	  if (gabufr_parsevals(next, parse_data) == GABUFR_OK) {
+
+	    if (next->is_new_tbl) {
+	      gabufr_update_ncep_tbl(dset, next);
+	    }
+	    
+	    if (! current) {
+	      dset->msgs = next;
+	    } else {
+	      current->next = next;
+	    }
+	    
+	    current = next;
+	    dset->msgcnt++;
+
+	  } else {
+	    gabufr_free_msg(next);
+	  }
+
+	}
+
+	pos = endofmsg + 4;
+
+      } else {
+	if (GABUFR_DEBUG) printf("no end of message! got %c%c%c%c instead\n", 
+				 *endofmsg,
+				 *(endofmsg+1),
+				 *(endofmsg+2),
+				 *(endofmsg+3));
+      }
+    }
+
+    pos++;
+
+  }
+
+  return GABUFR_OK;
+}
+
+gabufr_dset * gabufr_open(const char * path) {
+  gabufr_dset * dset;
+
+  dset = (gabufr_dset *) malloc(sizeof(gabufr_dset));
+  if (dset == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }
+  gabufr_reset_tbls();
+  if (gabufr_load2mem(path, dset) == GABUFR_ERR) {
+    return NULL;
+  }
+  if (gabufr_decode(dset, GABUFR_PARSE_DATA) == GABUFR_ERR) {
+    free(dset->buf);
+    free(dset);    
+    return NULL;
+  }
+  free(dset->buf);
+  dset->buf = NULL;
+  return dset;
+}
+
+gabufr_dset * gabufr_scan(const char * path) {
+  gabufr_dset * dset;
+
+  dset = (gabufr_dset *) malloc(sizeof(gabufr_dset));
+  if (dset == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }
+  gabufr_reset_tbls();
+  if (gabufr_load2mem(path, dset) == GABUFR_ERR) {
+    return NULL;
+  }
+  if (gabufr_decode(dset, GABUFR_NO_PARSE_DATA) == GABUFR_ERR) {
+    free(dset->buf);
+    free(dset);    
+    return NULL;
+  }
+  free(dset->buf);
+  dset->buf = NULL;
+  return dset;
+}
diff --git a/src/gabufr.h b/src/gabufr.h
new file mode 100644
index 0000000..1019f21
--- /dev/null
+++ b/src/gabufr.h
@@ -0,0 +1,137 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#ifndef GABUFR_H
+#define GABUFR_H
+
+#define GABUFR_X_BITS 6
+#define GABUFR_Y_BITS 8
+
+#define GABUFR_TBL_SIZE   ((1 << GABUFR_X_BITS) * (1 << GABUFR_Y_BITS))
+
+#define GABUFR_NUM_TYPE 0
+#define GABUFR_STR_TYPE 1
+
+#define GABUFR_DEF 0
+#define GABUFR_UNDEF 1
+
+#include "gatypes.h"
+
+typedef struct {
+  gaint scale;
+  gaint offset;
+  gaint width;
+  gaint datatype; /* flag to indicate numerical or string data */
+  char *description;
+} gabufr_varinf;
+
+typedef struct gabufr_val_struct {
+  struct gabufr_val_struct * next;
+  gaint x;      /* BUFR ID (F,X,Y) */
+  gaint y;      /* BUFR ID (F,X,Y) */
+  gaint z;      /* replication offset (vert. level), if present, or -1 */
+  char undef;   /* set to GABUFR_UNDEF if packed data was all ones */
+  gadouble val; /* data value when datatype is NUM, or DBL_MIN otherwise */
+  char *sval;   /* data value when datatype is STR, or NULL otherwise*/
+} gabufr_val;
+
+typedef struct {
+  gaint bufr_edition;
+  gaint master_tbl_num;
+  gaint master_tbl_version;
+  gaint local_tbl_version;
+} gabufr_tbl_inf;
+
+typedef struct gabufr_msg_struct {
+  struct gabufr_msg_struct * next;
+  gaint year;            /* base time for entire message */
+  gaint month;
+  gaint day;
+  gaint hour;
+  gaint min;
+  gaint subcnt;          /* number of subsets */
+  gabufr_val ** subs;    /* array of linked lists, with size nsub; 
+			    one linked list per subset in message */
+  gaint fileindex;       /* index of message in file, just for reference */
+  gaint is_new_tbl;      /* if 0, message contains data, otherwise it's a
+		            replacement BUFR table */
+  /* remainder for use during parsing */
+  unsigned char *section0;
+  unsigned char *section1;
+  unsigned char *section3;
+  unsigned char *section4;
+  unsigned char *end;
+  gabufr_tbl_inf tbl_inf;
+} gabufr_msg;
+
+typedef struct {
+  gabufr_msg * msgs; /* linked list of decoded messages 
+			(some may be missing if parsing failed */
+  gaint msgcnt;      /* number of messages in file */
+  /* remainder for use during parsing */
+  void * buf; 
+  gaint len;
+} gabufr_dset;
+
+
+/***** external interface ******/
+
+/* Open a BUFR datafile and parse into a gabufr_dset structure */
+gabufr_dset * gabufr_open(const char * path);
+
+/* Open a BUFR datafile and print descriptors. The only data
+ * that are parsed are any replacement tables. */
+gabufr_dset * gabufr_scan(const char * path);
+
+/* Release all memory associated with a parsed dset structure */
+void gabufr_close(gabufr_dset * dset);
+
+/* Free BUFR tables */
+void gabufr_reset_tbls();
+
+/* Set directory where BUFR tables can be found */
+void gabufr_set_tbl_base_path(const char * path);
+
+/***** internals *****/
+
+#define GABUFR_OK 0
+#define GABUFR_ERR 1
+
+gaint gabufr_valid_varid(gaint f, gaint x, gaint y);
+
+typedef struct gabufr_varid_struct {
+  struct gabufr_varid_struct * next;
+  gaint f;
+  gaint x;
+  gaint y;
+} gabufr_varid;
+
+/* Read tables into memory */
+gaint gabufr_read_tbls(gabufr_tbl_inf * tbl_inf);
+
+/* Return a Table B entry */
+gabufr_varinf * gabufr_get_varinf(gaint x, gaint y);
+
+/* Return a Table D entry */
+gabufr_varid * gabufr_get_seq(gaint x, gaint y);
+
+/* Free storage used by parsing results */
+void gabufr_free(gabufr_dset * bufrdata);
+
+/* Extract BUFR table updates from a decoded NCEP BUFR message */
+void gabufr_update_ncep_tbl(gabufr_dset * file, gabufr_msg * msg);
+
+/* Check if table has been loaded */
+gaint gabufr_have_tbl(gabufr_tbl_inf * tbl_inf);
+
+/* Free a list of varids */
+void gabufr_free_varids(gabufr_varid * list);
+
+/* Free BUFR tables */
+void gabufr_reset_tbls();
+
+/* Free all varinfo data */
+void gabufr_reinit();
+
+#endif /* GABUFR_H */
diff --git a/src/gabufrtbl.c b/src/gabufrtbl.c
new file mode 100644
index 0000000..49511d8
--- /dev/null
+++ b/src/gabufrtbl.c
@@ -0,0 +1,610 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by Joe Wielgosz */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "gabufr.h"
+
+#ifndef GABUFR_TBL_DEBUG
+#define GABUFR_TBL_DEBUG 0
+#endif
+
+const char* base_path;
+
+/* Size of buffer for each line of the table text file */
+#define GABUFR_MAX_LINE_LEN 4096
+
+/* Used in parsing */
+#define GABUFR_FIRST_PASS  0
+#define GABUFR_SECOND_PASS 1
+
+/* Length of a filename for a MEL-style plain text BUFR table */
+#define GABUFR_TBL_NAME_LEN 14
+
+/* Static storage for currently loaded tables B and D */
+gabufr_varinf * tbl_b = NULL;
+gabufr_varid ** tbl_d_entries = NULL;
+
+void gabufr_set_tbl_base_path(const char * path) {
+  base_path = path;
+}
+
+gaint gabufr_valid_varid(gaint f, gaint x, gaint y) {
+  return ((f >= 0 && f <= 3)
+	  && (x >= 0 && x < 64)
+	  && (y >= 0 && y < 256));
+}
+
+gaint gabufr_tbl_index(gaint x, gaint y) {
+  return (x << GABUFR_Y_BITS) +  y;
+}
+
+gabufr_varinf * gabufr_get_varinf(gaint x, gaint y) {
+  if (!tbl_b) {
+    return NULL;
+  } else {
+    return &tbl_b[gabufr_tbl_index(x, y)]; 
+  }
+}
+
+gabufr_varid * gabufr_get_seq(gaint x, gaint y) {
+  return tbl_d_entries[gabufr_tbl_index(x, y)]; 
+}
+
+gaint gabufr_have_tbl(gabufr_tbl_inf * tbl_inf) {
+  return (tbl_b && tbl_d_entries);
+}
+
+void gabufr_free_varids(gabufr_varid * entry) {
+  gabufr_varid * next;
+  while (entry) {
+    next = entry->next;
+    free(entry);
+    entry = next;
+  }
+}
+
+void gabufr_reset_tbls() {
+  gaint i;
+
+  if (tbl_b != NULL) {
+    free(tbl_b);
+  }
+  if (tbl_d_entries != NULL) {
+    for (i = 0; i < GABUFR_TBL_SIZE; i++) {
+      gabufr_free_varids(tbl_d_entries[i]);
+    }
+    free(tbl_d_entries);
+  }
+  tbl_b = NULL;
+  tbl_d_entries = NULL;
+}
+
+gaint gabufr_entry_is_text(const char *entry) {
+  gaint i;
+  const char * pos, * endpos, * found;
+  pos = entry;
+  for (i = 0; i < 6; i++) {
+    pos = strchr(pos, ';');
+    pos++;
+  }
+  endpos = strchr(pos, ';');
+  found = strstr(pos, "CCITT_IA5");
+  if (found && 
+      (found < endpos)) {
+    return GABUFR_STR_TYPE;
+  } else {
+    return GABUFR_NUM_TYPE;
+  }
+}
+
+char * gabufr_copy_desc(const char *entry) {
+  gaint i, len;
+  const char * pos, * endpos;
+  char * retval;
+  pos = entry;
+  for (i = 0; i < 7; i++) {
+    pos = strchr(pos, ';');
+    pos++;
+  }
+  endpos = strchr(pos, '\n');
+  len = endpos - pos;
+  retval = (char *) malloc(len + 1);
+  if (retval == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }  
+  strncpy(retval, pos, len);
+  retval[len] = '\0';
+  if (GABUFR_TBL_DEBUG) printf("description: %s\n", retval);
+  return retval;
+}
+
+gaint gabufr_read_tbl_b(const char * tbl_b_path) { 
+  FILE *tbl_b_file;  
+  char line[GABUFR_MAX_LINE_LEN];
+  gaint f, x, y, scale, offset, width;
+  gabufr_varinf * entry;
+  
+  /* allocate memory and initialize to zero */
+  tbl_b = (gabufr_varinf *) calloc(GABUFR_TBL_SIZE, sizeof(gabufr_varinf));
+  if (tbl_b == NULL) {
+    printf("Memory error loading table B\n");
+    return GABUFR_ERR;
+  }
+  
+  /* open file */
+  tbl_b_file = fopen(tbl_b_path, "r");
+  if (tbl_b_file == NULL) {
+    printf ("Error opening table B file (%s): %s\n", 
+	    tbl_b_path, strerror(errno));
+    return GABUFR_ERR;
+  }
+  
+  /* read entries into table array */
+  while ( fgets(line, GABUFR_MAX_LINE_LEN, tbl_b_file) ) {
+    if (GABUFR_TBL_DEBUG) printf("line: %s", line);
+    if (line[0] == '#' || strlen(line) < 2) {
+      continue;
+    }
+    sscanf(line, "%d;%d;%d;%d;%d;%d",
+	   &f, &x, &y, &scale, &offset, &width);
+
+    entry = gabufr_get_varinf(x, y);
+    entry->scale = scale;
+    entry->offset = offset;
+    entry->width = width;
+    entry->datatype = gabufr_entry_is_text(line);
+
+    entry->description = gabufr_copy_desc(line);
+
+    if (GABUFR_TBL_DEBUG) printf("(%d,%d,%d): (val+%d)*%d - %d bits of %s data\n",
+			  f, x, y, offset, scale, width,
+			  (entry->datatype == GABUFR_STR_TYPE) ? 
+			  "text" : "numeric");    
+  }
+  fclose(tbl_b_file);
+
+  return GABUFR_OK;
+} 
+
+gaint gabufr_read_tbl_d(const char * tbl_d_path) { 
+  FILE *tbl_d_file; 
+  gabufr_varid * head, * next;
+  char line[GABUFR_MAX_LINE_LEN];
+  gaint f, x, y, tbl_x, tbl_y;
+  gaint entry_index = 0;
+  gaint line_mode = 0; /* 0 for tbl D index; 
+			1 for list of FXY's;
+		     */
+  
+  head = NULL;
+  tbl_x = tbl_y = 0;
+
+  /* allocate memory and initialize to zero */
+  if( ! (tbl_d_entries = 
+	 (gabufr_varid **) calloc(GABUFR_TBL_SIZE, 
+				  sizeof(gabufr_varid *)))) {
+    printf("Memory error loading table D\n");
+    return GABUFR_ERR;
+  }
+  
+  
+  /* open file */
+  tbl_d_file = fopen(tbl_d_path, "r");
+  if (tbl_d_file == NULL) {
+    printf ("Error opening table D file (%s): %s\n", 
+	    tbl_d_path, strerror(errno));
+    return GABUFR_ERR;
+  }
+
+  /* read entries into table array */
+  while ( fgets(line, GABUFR_MAX_LINE_LEN, tbl_d_file) ) {
+    if (line[0] == '#') {
+      continue;
+    }
+    sscanf(line, "%d %d %d", &f, &x, &y);
+    if (GABUFR_TBL_DEBUG) printf("(%d,%d,%d): ", f, x, y);
+    if (line_mode == 0) {
+      if (f == 3) {
+	tbl_x = x;
+	tbl_y = y;
+	head = NULL;
+	line_mode = 1;
+      } else {
+	if (GABUFR_TBL_DEBUG) printf("\n");
+      }
+    } else {
+      if (f >= 0) {
+	next = (gabufr_varid *) calloc(sizeof(gabufr_varid), 1);
+	if (next == NULL) {
+	  printf("Memory allocation failed during parsing\n");
+	  fclose(tbl_d_file);
+	  return GABUFR_ERR;
+	}
+	next->f = f;
+	next->x = x;
+	next->y = y;
+	if (head) {
+	  head->next = next;
+	} else {
+	  tbl_d_entries[gabufr_tbl_index(tbl_x, tbl_y)] = next;	  
+	}
+	head = next;
+	if (GABUFR_TBL_DEBUG) printf("\t adding (%d, %d) at (%d, %d) [%d]\n", 
+			      x, y, tbl_x, tbl_y, entry_index);
+      } else {
+	if (GABUFR_TBL_DEBUG) printf("finished entry (%d, %d) at %d\n", 
+			      x,y,entry_index);       	
+	line_mode = 0;
+      }
+      entry_index++;
+    }
+  }
+
+  if (GABUFR_TBL_DEBUG) printf("done\n");
+  fclose(tbl_d_file);
+  return GABUFR_OK;
+} 
+
+
+
+gaint gabufr_read_tbls(gabufr_tbl_inf * tbl_inf) {
+  gaint base_path_len;
+  char * tbl_b_path, * tbl_d_path;
+
+  gabufr_reset_tbls();
+  
+  base_path_len = strlen(base_path);
+
+  tbl_b_path = (char *) malloc(base_path_len + GABUFR_TBL_NAME_LEN + 1);
+  if (tbl_b_path == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return GABUFR_ERR;
+  }
+  strncpy(tbl_b_path, base_path, base_path_len);
+  tbl_b_path[base_path_len] = '/';
+  sprintf((tbl_b_path + base_path_len + 1), "B%dM-%.3d-%.3d-B", 
+	  tbl_inf->bufr_edition, 
+	  tbl_inf->master_tbl_num,
+	  tbl_inf->master_tbl_version);
+  if (GABUFR_TBL_DEBUG) printf("reading from table B file %s\n", tbl_b_path);
+
+  tbl_d_path = (char *) malloc(strlen(base_path) + GABUFR_TBL_NAME_LEN + 1);
+  if (tbl_d_path == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return GABUFR_ERR;
+  }
+  strncpy(tbl_d_path, base_path, base_path_len);
+  tbl_d_path[base_path_len] = '/';
+  sprintf((tbl_d_path + base_path_len + 1), "B%dM-%.3d-%.3d-D", 
+	  tbl_inf->bufr_edition, 
+	  tbl_inf->master_tbl_num,
+	  tbl_inf->master_tbl_version);
+  if (GABUFR_TBL_DEBUG) printf("reading from table D file %s\n", tbl_d_path);
+
+  if (gabufr_read_tbl_b(tbl_b_path) == GABUFR_ERR
+      || gabufr_read_tbl_d(tbl_d_path) == GABUFR_ERR) {
+    gabufr_reset_tbls();
+    return GABUFR_ERR;
+  }
+
+  free(tbl_b_path);
+  free(tbl_d_path);
+  return GABUFR_OK;
+}
+
+/* order of events for NCEP encoded BUFR tables:
+ 
+   Table A:
+
+   1-3-0 delayed rep of three descriptors
+   0-31-1 8-bit delayed rep count
+   0-0-1 table A entry
+   0-0-2 table A desc line 1
+   0-0-3 table A desc line 2
+
+   Table B:
+
+   1-1-0 delayed rep of one descriptor
+   0-31-1 8-bit delayed rep count
+   3-0-4
+    3-0-3
+     0-0-10 F descriptor to be added or defined
+     0-0-11 X descriptor to be added or defined
+     0-0-12 Y descriptor to be added or defined
+    0-0-13 Element name, line 1
+    0-0-14 Element name, line 2
+    0-0-15 Units name
+    0-0-16 Units scale sign
+    0-0-17 Units scale
+    0-0-18 Units reference sign
+    0-0-19 Units reference value
+    0-0-20 Element data width
+
+   Table D:
+
+   1-5-0 delayed rep of five descriptors
+   0-31-1 8-bit delayed rep count
+   3-0-3
+     0-0-10 F descriptor to be added or defined
+     0-0-11 X descriptor to be added or defined
+     0-0-12 Y descriptor to be added or defined
+   2-5-64 Add 64-byte associated character field
+   1-1-0 delayed rep of one descriptor
+   0-31-1 8-bit delayed rep count
+   0-0-30 Descriptor defining sequence
+
+   0-0-0  ignore
+*/
+
+gabufr_val * gabufr_update_ncep_tbl_b(gabufr_dset * file, gabufr_msg * msg, gabufr_val * pos) {
+  gabufr_varinf new_entry;
+  gaint new_x, new_y;
+  gaint y_expected, z_expected;
+  char description[65];
+  gabufr_varinf * entry_to_replace;
+ 
+  new_x = new_y = 0;
+
+  description[64] = '\0';
+  z_expected = pos->z;
+  for (y_expected = 11; y_expected <= 20; y_expected++) {
+    if (!pos) {
+      printf("Ran out of data in middle of entry!\n");
+      return pos;
+    }
+    if (pos->y != y_expected) {
+      printf("Expected y = %d; got y = %d\n", y_expected, pos->y);
+      return pos;
+    }
+    if (pos->z != z_expected) {
+      printf("Expected z = %d; got z = %d\n", z_expected, pos->z);
+      return pos;
+    }
+    if (!pos->sval) {
+      printf("Expected string data!\n");
+      return pos;
+    }      
+
+    switch (pos->y) {
+    case 11:
+      new_x = strtol(pos->sval, NULL, 10);
+      break;
+    case 12:
+      new_y = strtol(pos->sval, NULL, 10);
+      break;
+    case 13:
+      memcpy(description, pos->sval, 32);
+      break;
+    case 14:
+      memcpy(description + 32, pos->sval, 32);
+      break;
+    case 15:
+      if (strstr(pos->sval, "CCITT_IA5") 
+	  || strstr(pos->sval, "CCITT IA5")) {
+	new_entry.datatype = GABUFR_STR_TYPE;
+      } else {
+	new_entry.datatype = GABUFR_NUM_TYPE;
+      }
+      break;
+    case 16:
+      if (strchr(pos->sval, '-')) {
+	new_entry.scale = -1;
+      } else if (strchr(pos->sval, '+')) {
+	new_entry.scale = 1;
+      } else {
+	printf("invalid scale sign string: %s\n", pos->sval);
+      }
+      break;
+    case 17:
+      new_entry.scale *= strtol(pos->sval, NULL, 10);
+      break;
+    case 18: 
+      if (strchr(pos->sval, '-')) {
+	new_entry.offset = -1;
+      } else if (strchr(pos->sval, '+')) {
+	new_entry.offset = 1;
+      } else {
+	printf("invalid offset sign string: %s\n", pos->sval);
+      }
+      break;
+    case 19:
+      new_entry.offset *= strtol(pos->sval, NULL, 10);
+      break;
+    case 20:
+      new_entry.width = strtol(pos->sval, NULL, 10);
+      break;
+    } 
+    pos = pos->next;
+  }
+
+  if (GABUFR_TBL_DEBUG) 
+    printf("updated entry: (%d,%d,%d): (val+%d)*%d - %d bits of %s data\n",
+	 0, new_x, new_y, 
+	 new_entry.offset, 
+	 new_entry.scale, 
+	 new_entry.width,
+	 (new_entry.datatype == GABUFR_STR_TYPE) ? 
+	 "text" : "numeric");
+
+  new_entry.description = (char *) malloc(65);
+  if (new_entry.description == NULL) {
+    printf("Memory allocation failed during parsing\n");
+    return NULL;
+  }
+  strcpy(new_entry.description, description);
+
+  if (GABUFR_TBL_DEBUG) printf("\tdescription: %s\n", 
+				 new_entry.description);    
+
+
+  /* copy entry into table */
+  entry_to_replace = gabufr_get_varinf(new_x, new_y);
+  memcpy(entry_to_replace, &new_entry, sizeof(gabufr_varinf));
+
+
+  return pos;
+ 
+}
+
+
+
+gabufr_val * gabufr_update_ncep_tbl_d(gabufr_dset * file, gabufr_msg * msg, 
+				      gabufr_val * pos) {
+  gaint new_x, new_y;
+  gaint y_expected, z_expected;
+  char fstr[2], xstr[3], ystr[4];
+  gabufr_varid * head, * next;
+  gabufr_varid ** entry_ptr;
+
+  new_x = new_y = 0;
+
+  head = NULL;
+  z_expected = pos->z;
+  for (y_expected = 11; y_expected <= 12; y_expected++) {
+    if (!pos) {
+      printf("ran out of data in middle of entry!\n");
+      return pos;
+    }
+    if (pos->y != y_expected) {
+      printf("expected y = %d; got y = %d\n", y_expected, pos->y);
+      return pos;
+    }
+    if (pos->z != z_expected) {
+      printf("expected z = %d; got z = %d\n", z_expected, pos->z);
+      return pos;
+    }
+    if (!pos->sval) {
+      printf("expected string data!\n");
+      return pos;
+    }      
+
+    switch (pos->y) {
+    case 11:
+      new_x = strtol(pos->sval, NULL, 10);
+      break;
+    case 12:
+      new_y = strtol(pos->sval, NULL, 10);
+      break;
+    }
+    pos = pos->next;
+  }
+    
+  if (GABUFR_TBL_DEBUG) printf("new table D entry is (3, %d, %d)\n", 
+				 new_x, new_y);
+  entry_ptr = &tbl_d_entries[gabufr_tbl_index(new_x, new_y)];
+  gabufr_free_varids(*entry_ptr);
+  head = *entry_ptr = NULL;
+
+
+  while (pos) {
+    if (pos->x == -1 && pos->y == -1) {
+      if (GABUFR_TBL_DEBUG) printf("sequence description: [%s]\n", 
+				     pos->sval);
+    } else if (pos->x == 0 && pos->y == 30) {
+      next = (gabufr_varid *) calloc(sizeof(gabufr_varid), 1);
+      if (next == NULL) {
+	printf("Memory allocation failed during parsing\n");
+	return NULL;
+      }
+
+      memcpy(fstr, pos->sval, 1);
+      fstr[1] = '\0';
+      memcpy(xstr, pos->sval+1, 2);
+      xstr[2] = '\0';
+      memcpy(ystr, pos->sval+3, 3);
+      ystr[3] = '\0';
+
+      next->f = strtol(fstr, NULL, 10);
+      next->x = strtol(xstr, NULL, 10);
+      next->y = strtol(ystr, NULL, 10);
+      
+      if (GABUFR_TBL_DEBUG) printf("\tadding (%d, %d, %d) to sequence\n", 
+	     next->f, next->x, next->y);
+
+      if (head) {
+	head->next = next;
+      } else {
+	*entry_ptr = next;
+      }
+      head = next;
+      
+    } else {
+      break;
+    }
+    pos = pos->next;
+  }
+  if (GABUFR_TBL_DEBUG) printf("\n");
+
+  return pos;
+}
+
+
+
+void gabufr_update_ncep_tbl(gabufr_dset * file, gabufr_msg * msg) {
+  gabufr_val * pos;
+  gaint i;
+  long f;
+
+  for (i = 0; i < msg->subcnt; i++) {
+    pos = msg->subs[i];
+    while (pos) {
+      if (pos->x == 0 && pos->y == 10 && pos->sval!=NULL) {
+	f = strtol(pos->sval, NULL, 10);
+	switch (f) {
+	case 0:
+	  pos = gabufr_update_ncep_tbl_b(file, msg, pos->next);
+	  break;
+	case 3:
+	  pos = gabufr_update_ncep_tbl_d(file, msg, pos->next);
+	  break;
+	default:
+	  printf("warning: invalid table definition, f = %ld\n", f);
+	}
+      } else {
+	pos = pos->next;
+      }
+    }
+    
+  }
+}
+
+#ifdef GABUFR_TBL_STANDALONE
+void gabufr_print_tbl_b() {
+  gaint x, y;
+  gabufr_varinf * entry;
+  for (x = 0; x < (1<<6); x++) {
+    for (y = 0; y < (1<<8); y++) {
+      entry = gabufr_get_varinf(x, y);
+      if (entry->width > 0) {
+	printf("(%d,%d,%d): ", 0, x, y);
+	if (entry->datatype == GABUFR_STR_TYPE) {
+	  printf("text: ");
+	} else {
+	  printf("numeric ((%d bits + %d) * 10^%d): ",
+		 entry->width,
+		 entry->offset, 
+		 entry->scale);
+	}
+	printf(entry->description);
+	printf("\n");
+      }
+    }
+  }
+}
+
+gaint main (gaint argc, char *argv[]) {
+  if (argc > 1) {
+    gabufr_read_tbl_b(argv[1]);
+    gabufr_print_tbl_b();
+  }
+  return 0;
+}
+#endif /* GABUFR_TBL_STANDALONE */
diff --git a/src/gacfg.c b/src/gacfg.c
new file mode 100644
index 0000000..634b025
--- /dev/null
+++ b/src/gacfg.c
@@ -0,0 +1,247 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+
+/* file: gacfg.c
+ *
+ *   Prints the configuration options of this build of GrADS.
+ *   This function is invoked at startup and with 'q config'.
+ *
+ *   REVISION HISTORY:
+ *
+ *   09sep97   da Silva   Initial code.
+ *   12oct97   da Silva   Small revisions, use of gaprnt().
+ *   15apr98   da Silva    Added BUILDINFO stuff, made gacfg() void. 
+ *   24jun02   K Komine   Added 64-bit mode . 
+ *
+ *   --
+ *   (c) 1997 by Arlindo da Silva
+ *
+ *   Permission is granted to any individual or institution to use,
+ *   copy, or redistribute this software so long as it is not sold for
+ *   profit, and provided this notice is retained. 
+ *
+ */
+
+/* Include ./configure's header file */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "buildinfo.h"
+
+#if GRIB2==1
+#include "grib2.h"
+#endif
+
+#if USEHDF==1
+#include "mfhdf.h"
+#endif
+
+#if USEHDF5==1
+#include "hdf5.h"
+#endif
+
+#if USENETCDF==1
+#include "netcdf.h"
+const char *nc_inq_libvers(void);
+#endif
+
+#if USEGADAP==1
+const char *libgadap_version(void);
+#endif
+/*
+ * gacfg() - Prints several configuration parameters. 
+ *
+ *           verbose = 0   only config string
+ *                   = 1   config string + verbose description
+ *                   > 1   no screen display.
+ */
+void gaprnt (int, char *);
+void gacfg(int verbose) {
+char cmd[256];
+#if USEHDF==1
+char hdfverstr[1024];
+uint32 majorv=0,minorv=0,release=0;
+#endif
+#if (USEHDF5==1)
+unsigned vmajor=0,vminor=0,vrelease=0;
+#endif
+
+snprintf(cmd,255,"Config: v%s",GRADS_VERSION);
+#if BYTEORDER==1
+ strcat(cmd," big-endian");
+#else
+ strcat(cmd," little-endian");
+#endif
+#if READLINE==1
+ strcat(cmd," readline");
+#endif
+#if GXPNG==1
+ strcat(cmd," printim");
+#endif
+#if GRIB2==1
+ strcat(cmd," grib2");
+#endif
+#if USENETCDF==1
+ strcat(cmd," netcdf");
+#endif
+#if USEHDF==1
+ strcat(cmd," hdf4-sds");
+#endif
+#if USEHDF5==1
+ strcat(cmd," hdf5");
+#endif
+#if USEDAP==1
+ strcat(cmd," opendap-grids");
+#endif
+#if USEGADAP==1
+ strcat(cmd,",stn");
+#endif
+#if USEGUI==1
+ strcat(cmd," athena");
+#endif
+#if GEOTIFF==1
+ strcat(cmd," geotiff");
+#endif
+#if USESHP==1
+ strcat(cmd," shapefile");
+#endif
+ strcat(cmd,"\n");
+ gaprnt(verbose,cmd);
+ 
+ if (verbose==0) {
+   gaprnt(verbose,"Issue 'q config' command for more detailed configuration information\n");
+   return;
+ }
+ 
+ gaprnt (verbose, "Grid Analysis and Display System (GrADS) Version " GRADS_VERSION "\n");
+ gaprnt (verbose, "Copyright (c) 1988-2011 by Brian Doty and the\n");
+ gaprnt (verbose, "Institute for Global Environment and Society (IGES) \n");
+ gaprnt (verbose, "This program is distributed WITHOUT ANY WARRANTY \n");
+ gaprnt (verbose, "See file COPYRIGHT for more information. \n\n");
+ 
+ gaprnt (verbose, buildinfo );
+ 
+ gaprnt(verbose,"\n\nThis version of GrADS has been configured with the following options:\n");
+ 
+#if BYTEORDER==1
+   gaprnt(verbose,"  o Built on a BIG ENDIAN machine\n");
+#else 
+   gaprnt(verbose,"  o Built on a LITTLE ENDIAN machine\n");
+#endif
+
+#if USEGUI==1
+   gaprnt(verbose,"  o Athena Widget GUI ENABLED\n");
+#else
+   gaprnt(verbose,"  o Athena Widget GUI DISABLED\n");
+#endif
+ 
+#if READLINE==1
+   gaprnt(verbose,"  o Command line editing ENABLED \n");
+   gaprnt(verbose,"      http://tiswww.case.edu/php/chet/readline/rltop.html \n");
+#else
+   gaprnt(verbose,"  o Command line editing DISABLED\n");
+#endif
+
+#if GXPNG==1
+   gaprnt(verbose,"  o printim command for image output ENABLED \n");
+   gaprnt(verbose,"      http://www.zlib.net \n");
+   gaprnt(verbose,"      http://www.libpng.org/pub/png/libpng.html \n");
+   gaprnt(verbose,"      http://www.libgd.org/Main_Page \n");
+#else 
+   gaprnt(verbose,"  o printim command DISABLED\n");
+#endif
+
+#if GRIB2==1
+   gaprnt(verbose,"  o GRIB2 interface ENABLED \n");
+   gaprnt(verbose,"      http://www.ijg.org \n");
+   gaprnt(verbose,"      http://www.ece.uvic.ca/~mdadams/jasper \n");
+   gaprnt(verbose,"      http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2 \n");
+   snprintf(cmd,255,   "      %s  \n",G2_VERSION);
+   gaprnt(verbose,cmd);
+#else 
+   gaprnt(verbose,"  o GRIB2 interface DISABLED\n");
+#endif
+ 
+#if USENETCDF==1
+   gaprnt(verbose,"  o NetCDF interface ENABLED \n");
+   gaprnt(verbose,"      http://www.unidata.ucar.edu/software/netcdf  \n");
+   snprintf(cmd,255,   "      netcdf %s  \n",(char*)nc_inq_libvers());
+   gaprnt(verbose,cmd);
+#else 
+   gaprnt(verbose,"  o NetCDF interface DISABLED\n");
+#endif
+ 
+#if USEDAP==1
+   gaprnt(verbose,"  o OPeNDAP gridded data interface ENABLED\n");
+#else
+   gaprnt(verbose,"  o OPeNDAP gridded data interface DISABLED\n");
+#endif
+
+#if USEGADAP==1
+   gaprnt(verbose,"  o OPeNDAP station data interface ENABLED\n");
+   gaprnt(verbose,"      http://iges.org/grads/gadoc/supplibs.html \n");
+   snprintf(cmd,255,   "      %s  \n", libgadap_version());
+   gaprnt(verbose,cmd);
+#else
+   gaprnt(verbose,"  o OPeNDAP station data interface DISABLED\n");
+#endif
+
+#if (USEHDF==1 || USEHDF5==1)
+#if (USEHDF==1 && USEHDF5==1)
+   /* we've got both */
+   gaprnt(verbose,"  o HDF4 and HDF5 interfaces ENABLED \n");
+   gaprnt(verbose,"      http://hdfgroup.org \n");
+   Hgetlibversion(&majorv,&minorv,&release,hdfverstr);
+   snprintf(cmd,255,   "      HDF %d.%dr%d \n",majorv,minorv,release);
+   gaprnt(verbose,cmd);
+   H5get_libversion(&vmajor,&vminor,&vrelease);
+   snprintf(cmd,255,   "      HDF5 %d.%d.%d \n",vmajor,vminor,vrelease);
+   gaprnt(verbose,cmd);
+#else
+#if USEHDF==1
+   /* we've only got hdf4 */
+   gaprnt(verbose,"  o HDF4 interface ENABLED \n");
+   gaprnt(verbose,"      http://hdfgroup.org \n");
+   Hgetlibversion(&majorv,&minorv,&release,hdfverstr);
+   snprintf(cmd,255,   "      HDF %d.%dr%d \n",majorv,minorv,release);
+   gaprnt(verbose,cmd);
+   gaprnt(verbose,"  o HDF5 interface DISABLED \n");
+#else
+   /* we've only got hdf5 */
+   gaprnt(verbose,"  o HDF4 interface DISABLED \n");
+   gaprnt(verbose,"  o HDF5 interface ENABLED \n");
+   gaprnt(verbose,"      http://hdfgroup.org \n");
+   H5get_libversion(&vmajor,&vminor,&vrelease);
+   snprintf(cmd,255,   "      HDF5 %d.%d.%d \n",vmajor,vminor,vrelease);
+   gaprnt(verbose,cmd);
+#endif
+#endif
+#else 
+   gaprnt(verbose,"  o HDF4 and HDF5 interfaces DISABLED\n");
+#endif 
+
+#if GEOTIFF==1
+   gaprnt(verbose,"  o GeoTIFF and KML/TIFF output ENABLED\n");
+   gaprnt(verbose,"      http://www.libtiff.org \n");
+   gaprnt(verbose,"      http://geotiff.osgeo.org \n");
+#else
+   gaprnt(verbose,"  o GeoTIFF and KML/TIFF output DISABLED\n");
+#endif
+   gaprnt(verbose,"  o KML contour output ENABLED\n");
+#if USESHP==1
+   gaprnt(verbose,"  o Shapefile interface ENABLED\n");
+   gaprnt(verbose,"      http://shapelib.maptools.org \n");
+#else
+   gaprnt(verbose,"  o Shapefile interface DISABLED\n");
+#endif
+ 
+ 
+ gaprnt(verbose,"\nFor additional information please consult http://iges.org/grads\n\n");
+ 
+}
+
diff --git a/src/gaddes.c b/src/gaddes.c
new file mode 100644
index 0000000..5654711
--- /dev/null
+++ b/src/gaddes.c
@@ -0,0 +1,3871 @@
+/* Copyright (C) 1988-2011 by Brian Doty and the 
+   Institute of Global Environment and Society (IGES).  
+   See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+/* If autoconfed, only include malloc.h when it's present */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include "grads.h"
+
+extern struct gamfcmn mfcmn;
+static char pout[256];
+static FILE *pdfi;       /* File descriptor for pdef file */
+FILE *descr;             /* File descriptor pointer */
+
+void ll2eg  (gaint, gaint, gadouble *, gadouble, gadouble, gadouble *, gadouble *, gadouble *);
+void ll2pse (gaint, gaint, gadouble *, gadouble, gadouble, gadouble *, gadouble *);
+void ll2ops (gadouble *, gadouble , gadouble , gadouble *, gadouble *);
+
+
+/* Read a GrADS data descriptor file and fill in the information
+   into a gafile structure.  The gafile structure should be
+   allocated and must be initialized by getpfi.  If this routine
+   returns an error, release the pfi structure and allocated
+   storage via frepfi.  mflag indicates whether to read the
+   stnmap/index file; if this routine is being called to
+   preprocess the dd file then this flag should be 0. 
+   A mflag value of 2 will check if the stnmap/index file can be
+   opened, but will not read it; mflag==2 will also turn off 
+   calculation of the pdef interpolation values */
+
+gaint gaddes (char *name, struct gafile *pfi, gaint mflag) {
+  struct gavar *pvar,*pvar2;
+  struct gaens *ens;
+  struct dt tdef,tdefe,tdefi,dt1,dt2;
+  struct gaindx *pindx;
+  struct gaindxb *pindxb;
+  struct gag2indx *g2indx;
+  struct gaattr *attrib;
+  struct gachsub *pchsub;
+  gadouble *vals,sf;
+  gadouble v1,v2,ev1,ev2,temp;
+  FILE *mfile;
+  gafloat fdum;
+  off_t levs,acum,acumvz,recacm;
+  gaint pdefop1=0,pdefop2=0,havesf,haveao;
+  gaint acumstride=0, npairs, idum, reclen;
+  gaint size=0,rc,len,swpflg,cnt,flag,tim1,tim2,ichar;
+  gaint flgs[8],e,t,i,j,ii,jj,err,hdrb,trlb,mflflg,cal365;
+  gaint mcnt,maxlv,foundvar1,foundvar2;
+  size_t sz;
+  char rec[512], mrec[512], *ch, *pos, *sname, *vectorpairs, *pair, *vplist;
+  char pdefnm[256],var1[256],var2[256],ekwrd[6];
+  char *varname,*attrname,*attrtype;
+  unsigned char vermap, urec[8];
+  static char *errs[9] = {"XDEF","YDEF","ZDEF","TDEF","UNDEF",
+			    "DSET","VARS","TITLE","DTYPE"};
+
+ /*mf --- define here vice grads.c for cdunif.c mf*/
+  mfcmn.fullyear=-999; 
+
+  /* initialize variables */
+  hdrb = 0;
+  trlb = 0;
+  pdfi = NULL;
+  mflflg = 0;		
+  mfile = NULL;
+  pfi->mfile = NULL;
+  mcnt = -1;
+  vectorpairs = NULL;
+  pair = NULL;
+  vplist = NULL;
+  varname = attrname = attrtype = NULL;
+  attrib = NULL;
+  sname = NULL;
+  cal365 = 0;
+
+  /* Try to open descriptor file */
+  descr = fopen (name, "r");
+  if (descr == NULL) {
+    /* Try adding default suffix of .ctl */
+    sz = strlen(name)+5;
+    if ((sname = (char *)galloc(sz,"sname2")) == NULL) {
+      gaprnt(0,"memory allocation error in creating date descriptor file name\n");
+      return(1);
+    }
+    for(i=0;i<=strlen(name);i++) *(sname+i)=*(name+i);
+    strcat(sname,".ctl");
+    descr = fopen (sname, "r");
+  }
+
+  /* If still can't open descriptor file, give up */
+  if (descr == NULL) {
+    gaprnt (0,"Open Error:  Can't open description file\n");
+    if (sname) gree(sname,"f172");
+    return(1);
+  }
+
+  /* Copy descriptor file name into gafile structure */
+  if (sname != NULL) {
+    getwrd (pfi->dnam,sname,512);
+    gree(sname,"f173");
+  } else {
+    getwrd (pfi->dnam,name,512);
+  }
+
+  /* initialize error flags */
+  for (i=0;i<8;i++) flgs[i] = 1;
+
+  /* Parse the data descriptor file */
+  while (fgets(rec,512,descr)!=NULL) {
+
+    /* Remove any leading blanks from rec */
+    reclen = strlen(rec);
+    jj = 0;
+    while (jj<reclen && rec[0]==' ') {
+      for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+      jj++;
+    }
+    /* replace newline with null at end of record */
+    for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+      if (rec[ichar] == '\n') {
+	rec[ichar] = '\0' ;
+	break ; 
+      }
+    }
+    /* Keep mixed case and lower case versions of rec handy */
+    strcpy (mrec,rec);   
+    lowcas(rec);
+
+    if (!isalnum(mrec[0])) {
+      /* check if comment contains attribute metadata */
+      if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+      	if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+      }
+
+    } else if (cmpwrd("byteswapped",rec)) {
+      pfi->bswap = 1;
+
+    } else if (cmpwrd("fileheader",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing fileheader length\n");
+      } else {
+        ch = longprs(ch,&(pfi->fhdr));
+        if (ch==NULL) {
+          gaprnt (1,"Fileheader record invalid\n");
+          pfi->fhdr = 0;
+        }
+      }
+
+    } else if (cmpwrd("cachesize",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing cachesize value\n");
+      } else {
+        ch = longprs(ch,&(pfi->cachesize));
+        if (ch==NULL) {
+	  gaprnt (1,"cachesize value invalid\n");
+	  pfi->cachesize = -1;
+        } 
+      }
+
+    } else if (cmpwrd("xyheader",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing xy grid header length\n");
+      } else {
+        ch = longprs(ch,&(pfi->xyhdr));
+        if (ch==NULL) {
+	  gaprnt (1,"xy grid header length invalid\n");
+	  pfi->xyhdr = 0;
+        } else {
+	  pfi->xyhdr = pfi->xyhdr/4;
+	}
+      }
+
+    } else if (cmpwrd("unpack",rec)) {
+      if ( (ch=nxtwrd(mrec))==NULL ) {
+        gaprnt (1,"Descriptor File Warning: Missing attribute names in unpack record\n");
+      } else {
+	havesf = 0; 
+	haveao = 0;
+	/* get the scale factor attribute name */
+	len = 0;
+	while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+	sz = len+3;
+	if ((pfi->scattr = (char *)galloc(sz,"scattr")) == NULL) goto err8;
+	for (i=0; i<len; i++) *(pfi->scattr+i) = *(ch+i);
+	*(pfi->scattr+len) = '\0';
+	havesf = 1;
+	if (!strncmp(pfi->scattr, "NULL", 4) || !strncmp(pfi->scattr, "null", 4)) havesf = 0;
+
+	/* get the offset attribute name */
+	if ( (ch=nxtwrd(ch)) == NULL ) {
+	  gaprnt (1,"Descriptor File Warning: No offset attribute name in unpack record\n");
+	} else {
+	  len = 0;
+	  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+	  sz = len+3;
+	  if ((pfi->ofattr = (char *)galloc(sz,"ofattr")) == NULL) goto err8;
+	  for (i=0; i<len; i++) *(pfi->ofattr+i) = *(ch+i);
+	  *(pfi->ofattr+len) = '\0';
+	  haveao = 1;
+	  if (!strncmp(pfi->ofattr, "NULL", 4) || !strncmp(pfi->ofattr, "null", 4)) haveao = 0;
+	}
+
+	/* set the packflg */
+	if (havesf) {
+	  pfi->packflg = haveao == 1 ? 2 : 1 ;
+	} else {
+	  pfi->packflg = haveao == 1 ? 3 : 0 ;
+	}
+      }
+
+    } else if (cmpwrd("format",rec) || cmpwrd("options",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing options keyword\n");
+      } else {
+        while (ch!=NULL) {
+          if (cmpwrd("sequential",ch)) pfi->seqflg = 1;
+          else if (cmpwrd("yrev",ch)) pfi->yrflg = 1;
+          else if (cmpwrd("zrev",ch)) pfi->zrflg = 1;
+          else if (cmpwrd("template",ch)) pfi->tmplat = 1;
+          else if (cmpwrd("byteswapped",ch)) pfi->bswap = 1;
+#if GRIB2
+          else if (cmpwrd("pascals",ch)) pfi->pa2mb = 1;
+#endif
+          else if (cmpwrd("365_day_calendar",ch)) {
+	    pfi->calendar=1;
+	    cal365=1;
+	  }
+          else if (cmpwrd("big_endian",ch)) {
+	    if (!BYTEORDER) pfi->bswap = 1;
+          }
+          else if (cmpwrd("little_endian",ch)) {
+            if (BYTEORDER) pfi->bswap = 1;
+          }
+	  else {
+	    gaprnt (0,"Open Error:  Data file type invalid\n");
+	    goto err9;
+          }
+          ch = nxtwrd(ch);
+        }
+      }
+
+    } else if (cmpwrd("trailerbytes",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Trailerbytes record invalid\n");
+      } else {
+        ch = intprs(ch,&trlb);
+        if (ch==NULL) {
+          gaprnt (1,"Trailerbytes record invalid\n");
+          trlb = 0;
+        } else {
+          trlb = trlb/4;
+        }
+      }
+
+    } else if (cmpwrd("headerbytes",rec)|| cmpwrd("theader",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"headerbytes/theader record invalid\n");
+      } else {
+        ch = intprs(ch,&hdrb);
+        if (ch==NULL) {
+          gaprnt (1,"headerbytes/theader record invalid\n");
+          hdrb = 0;
+        } else {
+          hdrb = hdrb/4;
+        }
+      }
+
+    /* Handle the chsub records.  time1, time2, then a string,  multiple times */
+    } else if (cmpwrd("chsub",rec)) {
+      /* point to first block in chain */
+      pchsub = pfi->pchsub1;    
+      if (pchsub!=NULL) {
+        while (pchsub->forw!=NULL) {
+          pchsub = pchsub->forw;       /* advance to end of chain */
+        }
+      }
+      flag = 0;
+      ch = mrec;
+      while (1) {
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        flag = 1;
+        if ( (ch = intprs(ch,&tim1)) == NULL) break;
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        if (*ch=='*' && (*(ch+1)==' '||*(ch+1)=='\t')) tim2 = -99;
+        else if ( (ch = intprs(ch,&tim2)) == NULL) break;
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        flag = 0;
+        if (pchsub) {   /* chain exists */
+	  sz = sizeof(struct gachsub);
+          pchsub->forw = (struct gachsub *)galloc(sz,"chsubnew");
+          if (pchsub->forw==NULL) {
+	    gaprnt(0,"Open Error: memory allocation failed for pchsub\n");
+	    goto err8; 
+	  }
+          pchsub = pchsub->forw;
+	  pchsub->forw = NULL;
+        } else {        /* start a new chain */
+	  sz = sizeof(struct gachsub);
+          pfi->pchsub1 = (struct gachsub *)galloc(sz,"chsub1");
+          if (pfi->pchsub1==NULL)  {
+	    gaprnt(0,"Open Error: memory allocation failed for pchsub1\n");
+	    goto err8; 
+	  }
+          pchsub = pfi->pchsub1;
+	  pchsub->forw = NULL;
+        }
+        len = wrdlen(ch);
+	sz = len+1;
+        if ((pchsub->ch = (char *)galloc(sz,"chsubstr")) == NULL) goto err8;
+        getwrd(pchsub->ch,ch,len);
+        pchsub->t1 = tim1;
+        pchsub->t2 = tim2;
+      }
+      if (flag) {
+        gaprnt (1,"Description file warning: Invalid chsub record; Ignored\n");
+      }
+
+    } else if (cmpwrd("dtype",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing data type\n");
+        gaprnt (1,"   Assuming data file type is grid\n");
+      }
+      if (cmpwrd("station",ch)) {
+        pfi->idxflg = 1;
+        pfi->type = 2;
+        flgs[0] = 0;
+        flgs[1] = 0;
+        flgs[2] = 0;
+
+      } else if (cmpwrd("bufr",ch)) {
+	pfi->idxflg = 0;  /* bufr data is not indexed */
+	pfi->type = 2;    /* station data type */
+	mflag = 0;        /* don't try to read a stnmap file */
+	pfi->bufrflg = 1; 
+        flgs[0] = 0;
+        flgs[1] = 0;
+        flgs[2] = 0;
+	/* allocate memory for the bufrinfo structure and the two bufrtimeinfo structures */
+	sz = sizeof(struct bufrinfo);
+	if ((pfi->bufrinfo = (struct bufrinfo *)galloc(sz,"bufrinfo")) == NULL) goto err8;
+	/* initialize with bad values */
+	for (j=0;j<2;j++) {
+	  pfi->bufrinfo->lonxy[j] = pfi->bufrinfo->latxy[j] = -999;;
+	  pfi->bufrinfo->levxy[j] = pfi->bufrinfo->stidxy[j] = -999;;
+	  pfi->bufrinfo->base.yrxy[j] = pfi->bufrinfo->base.moxy[j] = -999;;
+	  pfi->bufrinfo->base.dyxy[j] = pfi->bufrinfo->base.hrxy[j] = -999;;
+	  pfi->bufrinfo->base.mnxy[j] = pfi->bufrinfo->offset.yrxy[j] = -999;;
+	  pfi->bufrinfo->offset.moxy[j] = pfi->bufrinfo->offset.dyxy[j] = -999;;
+	  pfi->bufrinfo->offset.hrxy[j] = pfi->bufrinfo->offset.mnxy[j] = -999;;
+	}
+      } else if (cmpwrd("grib",ch)) {
+        pfi->idxflg = 1;
+        if ( (ch=nxtwrd(ch))!=NULL ) {
+          if ( intprs(ch,&(pfi->grbgrd))==NULL) {
+            gaprnt (1,"Description file warning: Invalid GRIB option\n");
+            pfi->grbgrd = -999;
+          }
+        }
+      }
+#if GRIB2
+      else if (cmpwrd("grib2",ch)) pfi->idxflg = 2;
+#endif
+#if USENETCDF
+      else if (cmpwrd("netcdf",ch)) pfi->ncflg = 1;
+#endif
+#if USEHDF
+      else if (cmpwrd("hdfsds",ch) || cmpwrd("hdf4",ch)) pfi->ncflg = 2;
+#endif
+#if USEHDF5
+      else if (cmpwrd("hdf5_grid",ch)) pfi->ncflg = 3;
+#endif
+      else {
+        gaprnt (0,"Open Error:  Data file type invalid\n");
+        goto err9;
+      }
+
+    } else if (cmpwrd("xvar",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pair for XVAR entry\n");
+      } else {
+        j = 0;
+        while (1) {
+ 	  if ( (ch=intprs(ch,&(pfi->bufrinfo->lonxy[j])))==NULL ) goto err6a;
+          while (*ch==' ') ch++;
+          if (*ch!=',') break;
+          ch++;
+          while (*ch==' ') ch++;
+          j++;
+          if (j>1) goto err6a;
+        }
+	if (pfi->bufrinfo->lonxy[0]==-999 || pfi->bufrinfo->lonxy[1]==-999) goto err6a;
+      }
+  
+    } else if (cmpwrd("yvar",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pair for YVAR entry\n");
+      } else {
+        j = 0;
+        while (1) {
+ 	  if ( (ch=intprs(ch,&(pfi->bufrinfo->latxy[j])))==NULL ) goto err6a;
+          while (*ch==' ') ch++;
+          if (*ch!=',') break;
+          ch++;
+          while (*ch==' ') ch++;
+          j++;
+          if (j>1) goto err6a;
+        }
+	if (pfi->bufrinfo->latxy[0]==-999 || pfi->bufrinfo->latxy[1]==-999) goto err6a;
+      }
+  
+    } else if (cmpwrd("zvar",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pair for ZVAR entry\n");
+      } else {
+        j = 0;
+        while (1) {
+ 	  if ( (ch=intprs(ch,&(pfi->bufrinfo->levxy[j])))==NULL ) goto err6a;
+          while (*ch==' ') ch++;
+          if (*ch!=',') break;
+          ch++;
+          while (*ch==' ') ch++;
+          j++;
+          if (j>1) goto err6a;
+        }
+	if (pfi->bufrinfo->levxy[0]==-999 || pfi->bufrinfo->levxy[1]==-999) goto err6a;
+      }
+  
+    } else if (cmpwrd("tvar",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pairs for TVAR entry\n");
+      } else {
+	while (nxtwrd(ch)!=NULL) {
+	  if (cmpwrd("yr",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR yr entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.yrxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.yrxy[0]==-999 || pfi->bufrinfo->base.yrxy[1]==-999) goto err6a;
+	    }
+
+	  } else if (cmpwrd("mo",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR mo entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.moxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.moxy[0]==-999 || pfi->bufrinfo->base.moxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("dy",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR dy entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.dyxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.dyxy[0]==-999 || pfi->bufrinfo->base.dyxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("hr",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR hr entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.hrxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.hrxy[0]==-999 || pfi->bufrinfo->base.hrxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("mn",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR mn entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.mnxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.mnxy[0]==-999 || pfi->bufrinfo->base.mnxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("sc",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TVAR sc entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->base.scxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->base.scxy[0]==-999 || pfi->bufrinfo->base.scxy[1]==-999) goto err6a;
+	    }
+	  } else {
+	    goto err6a;
+	  }
+	} /* end of while loop */
+      }
+
+    } else if (cmpwrd("toffvar",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pairs for TOFFVAR entry\n");
+      } else {
+	while (nxtwrd(ch)!=NULL) {
+	  if (cmpwrd("yr",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR yr entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.yrxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.yrxy[0]==-999 || pfi->bufrinfo->offset.yrxy[1]==-999) goto err6a;
+	    }
+
+	  } else if (cmpwrd("mo",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR mo entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.moxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.moxy[0]==-999 || pfi->bufrinfo->offset.moxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("dy",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR dy entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.dyxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.dyxy[0]==-999 || pfi->bufrinfo->offset.dyxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("hr",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR hr entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.hrxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.hrxy[0]==-999 || pfi->bufrinfo->offset.hrxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("mn",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR mn entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.mnxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.mnxy[0]==-999 || pfi->bufrinfo->offset.mnxy[1]==-999) goto err6a;
+	    }
+	  } else if (cmpwrd("sc",ch)) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      gaprnt (1,"Description file warning: Missing x,y pair for TOFFVAR sc entry\n");
+	    } else {
+	      j = 0;
+	      while (1) {
+		if ( (ch=intprs(ch,&(pfi->bufrinfo->offset.scxy[j])))==NULL ) goto err6a;
+		while (*ch==' ') ch++;
+		if (*ch!=',') break;
+		ch++;
+		while (*ch==' ') ch++;
+		j++;
+		if (j>1) goto err6a;
+	      }
+	      if (pfi->bufrinfo->offset.scxy[0]==-999 || pfi->bufrinfo->offset.scxy[1]==-999) goto err6a;
+	    }
+	  } else {
+	    goto err6a;
+	  }
+	} /* end of while loop */
+      }
+
+    } else if (cmpwrd("stid",rec)) {
+      if ( (ch=nxtwrd(rec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing x,y pair for STID entry\n");
+      } else {
+        j = 0;
+        while (1) {
+ 	  if ( (ch=intprs(ch,&(pfi->bufrinfo->stidxy[j])))==NULL ) goto err6a;
+          while (*ch==' ') ch++;
+          if (*ch!=',') break;
+          ch++;
+          while (*ch==' ') ch++;
+          j++;
+          if (j>1) goto err6a;
+        }
+	if (pfi->bufrinfo->stidxy[0]==-999 || pfi->bufrinfo->stidxy[1]==-999) goto err6a;
+      }
+
+    } else if (cmpwrd("title",rec)) {
+      if ( (ch=nxtwrd(mrec))==NULL ) {
+        gaprnt (1,"Description file warning: Missing title string\n");
+      } else {
+        getstr (pfi->title,ch,512);
+        flgs[7] = 0;
+      }
+
+    } else if (cmpwrd("dset",rec)) {
+      ch = nxtwrd(mrec);
+      if (ch==NULL) {
+        gaprnt (0,"Descriptor File Error:  Data file name is missing\n");
+        goto err9;
+      }
+      if (*ch=='^' || *ch=='$') {
+        fnmexp (pfi->name,ch,name);
+      } else {
+        getwrd (pfi->name,ch,512);
+      }
+      flgs[5] = 0;
+
+    } else if (cmpwrd("stnmap",rec) || cmpwrd("index",rec)) {
+      ch = nxtwrd(mrec);
+      if (ch==NULL) {
+        gaprnt (0,"Open Error:  Station or Index Map file name is missing\n");
+        goto err9;
+      }
+      if (*ch=='^' || *ch=='$') {
+        fnmexp (pout, ch, name);
+      } else {
+        getwrd (pout, ch, 500);  
+      }
+      len = 0;
+      while (*(pout+len)) len++;
+      sz = len+3;
+      if ((pfi->mnam = (char *)galloc(sz,"mnam")) == NULL) goto err8; 
+      strcpy (pfi->mnam,pout);
+
+    } else if (cmpwrd("toff",rec)) {
+      ch = nxtwrd(rec);
+      if (ch==NULL) {
+        gaprnt (0,"Open Error:  Missing toff value\n");
+        goto err9;
+      }
+      pos = intprs(ch,&(pfi->tlpst));
+      if (pos==NULL || pfi->tlpst>=pfi->dnum[3]) {
+        gaprnt (0,"Open Error:  Invalid toff value\n");
+        goto err9;
+      }
+      pfi->tlpflg = 1;
+
+    }  else if (cmpwrd("undef",rec)) {
+      ch = nxtwrd(mrec);
+      if (ch==NULL) {
+        gaprnt (0,"Open Error:  Missing undef value\n");
+        goto err9;
+      }
+      
+      pos = getdbl(ch,&(pfi->undef));
+      if (pos==NULL) {
+        gaprnt (0,"Open Error:  Invalid undef value\n");
+        goto err9;
+      } 
+
+      /* Get the undef attribute name, if it's there */
+      if ( (ch=nxtwrd(ch))!=NULL ) {
+	len = 0;
+	while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+	sz = len+3;
+	if ((pfi->undefattr = (char *)galloc(sz,"undefattr3")) == NULL) goto err8;
+	for (i=0; i<len; i++) *(pfi->undefattr+i) = *(ch+i);
+	*(pfi->undefattr+len) = '\0';
+	/* Set the undef attribute flag */
+	pfi->undefattrflg = 1;
+      }
+      pfi->ulow = fabs(pfi->undef/EPSILON);
+      pfi->uhi  = pfi->undef + pfi->ulow;
+      pfi->ulow = pfi->undef - pfi->ulow;
+      flgs[4] = 0;
+
+    } else if (cmpwrd("pdef",rec)) {
+      if ((ch = nxtwrd(rec)) == NULL) goto errm;
+      /* parse the i and j dimensions of the pre-projected grid */
+      if ((pos = intprs(ch,&(pfi->ppisiz)))==NULL) goto errm;
+      if ((ch = nxtwrd(ch)) == NULL) goto errm;
+      if ((pos = intprs(ch,&(pfi->ppjsiz)))==NULL) goto errm;
+      if ((ch = nxtwrd(ch)) == NULL) goto errm;
+
+      /* set the pre-projected grid type and wind rotation flags */
+      if (cmpwrd("nps",ch))         {pfi->ppflag=1; pfi->ppwrot=1; cnt=4;}
+      else if (cmpwrd("sps",ch))    {pfi->ppflag=2; pfi->ppwrot=1; cnt=4;}
+      else if (cmpwrd("lcc",ch))    {pfi->ppflag=3; pfi->ppwrot=0; cnt=9;}
+      else if (cmpwrd("lccr",ch))   {pfi->ppflag=3; pfi->ppwrot=1; cnt=9;}
+      else if (cmpwrd("eta.u",ch))  {pfi->ppflag=4; pfi->ppwrot=1; cnt=4;}
+      else if (cmpwrd("pse",ch))    {pfi->ppflag=5; pfi->ppwrot=0; cnt=7;}
+      else if (cmpwrd("ops",ch))    {pfi->ppflag=6; pfi->ppwrot=0; cnt=8;}
+      else if (cmpwrd("bilin",ch))  {pfi->ppflag=7; pfi->ppwrot=1; cnt=0;}
+      else if (cmpwrd("file",ch))   {pfi->ppflag=8; pfi->ppwrot=1; cnt=1; pfi->pdefgnrl=0;}
+      else if (cmpwrd("general",ch)){pfi->ppflag=8; pfi->ppwrot=1; cnt=1; pfi->pdefgnrl=1;}
+      else if (cmpwrd("rotll",ch))  {pfi->ppflag=9; pfi->ppwrot=0; cnt=6;}
+      else if (cmpwrd("rotllr",ch)) {pfi->ppflag=9; pfi->ppwrot=1; cnt=6;}
+      else goto errm;
+      /* parse the pre-projected grid parameters */
+      for (i=0; i<cnt; i++) {
+        if ( (ch = nxtwrd(ch)) == NULL) goto errm;
+        if ( (pos = getdbl(ch,&(pfi->ppvals[i])))==NULL) goto errm;
+      }
+      /* check "num" argument to pdef file/general option */
+      if (pfi->ppflag==8) {
+        i = (gaint)(pfi->ppvals[0]+0.1);
+        if (i<1 || i>9) goto errm;
+      }
+      /* parse file type, byte order, and name for pdef 'bilin' and 'file' and 'general' */
+      if (pfi->ppflag==7 || pfi->ppflag==8) {
+        if ( (ch = nxtwrd(ch)) == NULL) goto errm;
+        if (cmpwrd("stream",ch))             pdefop1 = 1;
+        else if (cmpwrd("sequential",ch))    pdefop1 = 2;
+        else goto errm;
+
+        if ( (ch = nxtwrd(ch)) == NULL) goto errm;
+        if (cmpwrd("binary",ch))             pdefop2 = 1;
+        else if (cmpwrd("binary-big",ch))    pdefop2 = 2;
+        else if (cmpwrd("binary-little",ch)) pdefop2 = 3;
+        else if (cmpwrd("packed",ch))        pdefop2 = 4;
+        else goto errm;
+
+        if ( (ch = nxtwrd(ch)) == NULL) goto errm;
+	ch = mrec + (ch-rec);
+        if (*ch=='^' || *ch=='$') {
+          fnmexp (pdefnm,ch,name);
+        } else {
+          getwrd (pdefnm,ch,256);
+        }
+	/* open the pdef file */
+        pdfi = fopen(pdefnm,"rb");
+        if (pdfi==NULL) {
+          snprintf(pout,255, "  Error opening pdef file:  %s\n",pdefnm);
+          gaprnt (0,pout);
+          goto errm;
+        }
+      }
+
+    }  else if (cmpwrd("vectorpairs",rec)) {
+      if ( (ch=nxtwrd(mrec))==NULL ) {
+        gaprnt (1,"Description file warning: No vector pairs listed\n");
+      } else {
+	sz = strlen(ch)+1;
+	if ((vectorpairs = (char *)galloc(sz,"vecpairs")) == NULL) goto err8;
+        getstr(vectorpairs,ch,strlen(ch)+1);
+      }
+	
+    }  else if (cmpwrd("xdef",rec)) {
+
+      if (pfi->type == 2) continue;
+      if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+      if ( (pos = intprs(ch,&(pfi->dnum[0])))==NULL) goto err1;
+      if (pfi->dnum[0]<1) {
+	snprintf(pout,255,"Warning: Invalid XDEF syntax in %s -- Changing size of X axis from %d to 1 \n",
+		pfi->dnam,pfi->dnum[0]);
+        gaprnt (1,pout);
+	pfi->dnum[0] = 1;
+      }
+      if (*pos!=' ') goto err1;
+      if ( (ch = nxtwrd(ch))==NULL) goto err2;
+      if (cmpwrd("linear",ch)) {
+        rc = deflin(ch, pfi, 0, 0);
+        if (rc==-1) goto err8; 
+        if (rc) goto err9;
+        v2 = *(pfi->grvals[0]);
+        v1 = *(pfi->grvals[0]+1) + v2;
+        temp = v1+((gadouble)(pfi->dnum[0]))*v2;
+        temp=temp-360.0;
+        if (fabs(temp-v1)<0.01) pfi->wrap = 1;
+      }
+      else if (cmpwrd("levels",ch)) {
+        rc = deflev (ch, rec, pfi, 0);
+        if (rc==-1)  goto err8; 
+        if (rc) goto err9;
+      } else goto err2;
+      flgs[0] = 0;
+
+    } else if (cmpwrd("ydef",rec)) {
+      if (pfi->type == 2) continue;
+      if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+      if ( (pos = intprs(ch,&(pfi->dnum[1])))==NULL) goto err1;
+      if (pfi->dnum[1]<1) {
+	snprintf(pout,255,"Warning: Invalid YDEF syntax in %s -- Changing size of Y axis from %d to 1 \n",
+		pfi->dnam,pfi->dnum[1]);
+        gaprnt (1,pout);
+	pfi->dnum[1] = 1;
+      }
+      if (*pos!=' ') goto err1;
+      if ( (ch = nxtwrd(ch))==NULL) goto err2;
+      if (cmpwrd("linear",ch)) {
+        rc = deflin(ch, pfi, 1, 0);
+        if (rc==-1) goto err8; 
+        if (rc) goto err9;
+      } else if (cmpwrd("levels",ch)) {
+        rc = deflev (ch, rec, pfi, 1);
+        if (rc==-1) goto err8;
+        if (rc) goto err9;
+      } else if (cmpwrd("gausr40",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gagaus(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else if (cmpwrd("mom32",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gamo32(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else if (cmpwrd("gaust62",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gagst62(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else if (cmpwrd("gausr30",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gags30(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else if (cmpwrd("gausr20",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gags20(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else if (cmpwrd("gausr15",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3;
+        if ( (pos = intprs(ch,&i))==NULL) goto err3;
+        pfi->grvals[1] = gags15(i,pfi->dnum[1]);
+        if (pfi->grvals[1]==NULL) goto err9;
+        pfi->abvals[1] = pfi->grvals[1];
+        pfi->ab2gr[1] = lev2gr;
+        pfi->gr2ab[1] = gr2lev;
+        pfi->linear[1] = 0;
+      } else goto err2;
+      flgs[1] = 0;
+
+    } else if (cmpwrd("zdef",rec)) {
+      if (pfi->type == 2) continue;
+      if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+      if ( (pos = intprs(ch,&(pfi->dnum[2])))==NULL) goto err1;
+      if (pfi->dnum[2]<1) {
+	snprintf(pout,255,"Warning: Invalid ZDEF syntax in %s -- Changing size of Z axis from %d to 1 \n",
+		pfi->dnam,pfi->dnum[2]);
+        gaprnt (1,pout);
+	pfi->dnum[2] = 1;
+      }
+      if (*pos!=' ') goto err1;
+      if ( (ch = nxtwrd(ch))==NULL) goto err2;
+      if (cmpwrd("linear",ch)) {
+        rc = deflin(ch, pfi, 2, 0);
+        if (rc==-1) goto err8; 
+        if (rc) goto err9;
+      }
+      else if (cmpwrd("levels",ch)) {
+        rc = deflev (ch, rec, pfi, 2);
+        if (rc==-1) goto err8; 
+        if (rc) goto err9;
+      } else goto err2;
+      flgs[2] = 0;
+
+    } else if (cmpwrd("tdef",rec)) {
+      if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+      if ( (pos = intprs(ch,&(pfi->dnum[3])))==NULL) goto err1;
+      if (pfi->dnum[3]<1) {
+	snprintf(pout,255,"Warning: Invalid TDEF syntax in %s -- Changing size of T axis from %d to 1 \n",
+		pfi->dnam,pfi->dnum[3]);
+        gaprnt (1,pout);
+	pfi->dnum[3] = 1;
+      }
+      if (*pos!=' ') goto err1;
+      if ( (ch = nxtwrd(ch))==NULL) goto err2;
+      if (cmpwrd("linear",ch)) {
+        if ( (ch = nxtwrd(ch))==NULL) goto err3a_tdef;
+        tdef.yr = -1000;
+        tdef.mo = -1000;
+        tdef.dy = -1000;
+        if ( (pos = adtprs(ch,&tdef,&dt1))==NULL) goto err3b_tdef;
+        if (*pos!=' ' || dt1.yr == -1000 || dt1.mo == -1000.0 ||
+            dt1.dy == -1000) goto err3c_tdef;
+        if ( (ch = nxtwrd(ch))==NULL) goto err4a_tdef;
+        if ( (pos = rdtprs(ch,&dt2))==NULL) goto err4b_tdef;
+        v1 = (dt2.yr * 12) + dt2.mo;
+        v2 = (dt2.dy * 1440) + (dt2.hr * 60) + dt2.mn;
+	/* check if 0 dt */
+	if ( (v1 == 0) && (v2 == 0) ) goto err4c_tdef;  
+	sz = sizeof(gadouble)*8;
+        if ((vals = (gadouble *)galloc(sz,"tvals5")) == NULL) goto err8; 
+        *(vals) = dt1.yr;
+        *(vals+1) = dt1.mo;
+        *(vals+2) = dt1.dy;
+        *(vals+3) = dt1.hr;
+        *(vals+4) = dt1.mn;
+        *(vals+5) = v1;
+        *(vals+6) = v2;
+        *(vals+7) = -999.9;
+        pfi->grvals[3] = vals;
+        pfi->abvals[3] = vals;
+        pfi->linear[3] = 1;
+      } else goto err2;
+      flgs[3] = 0;
+
+    } else if (cmpwrd("edef",rec)) {
+      /* use mixed case version of record so ensemble names can have upper case letters */
+      if ((ch = nxtwrd(mrec)) == NULL) goto err1;
+      if ((pos = intprs(ch,&(pfi->dnum[4])))==NULL) goto err1;
+      if (pfi->dnum[4]<1) {
+	snprintf(pout,255,"Warning: Invalid EDEF syntax in %s -- Changing size of E axis from %d to 1 \n",
+		pfi->dnam,pfi->dnum[4]);
+        gaprnt (1,pout);
+	pfi->dnum[4] = 1;
+      }
+      /* ensemble dimension is always linear -- set up linear scaling */
+      sz = sizeof(gadouble)*6;
+      if ((vals = (gadouble *)galloc(sz,"evals2")) == NULL) goto err8;
+      ev1=ev2=1;
+      *(vals+1) = ev1 - ev2;
+      *(vals) = ev2;
+      *(vals+2) = -999.9;
+      pfi->grvals[4] = vals;
+      *(vals+4) = -1.0 * ((ev1-ev2)/ev2);
+      *(vals+3) = 1.0/ev2;
+      *(vals+5) = -999.9;
+      pfi->abvals[4] = vals+3;
+      pfi->ab2gr[4] = liconv;
+      pfi->gr2ab[4] = liconv;
+      pfi->linear[4] = 1;
+      size = pfi->dnum[4] * sizeof(struct gaens); 
+      /* set up chain of gaens structures */
+      sz = size;
+      ens = (struct gaens *)galloc(sz,"ens4");
+      if (ens==NULL) {
+	gaprnt(0,"Open Error: memory allocation failed for ens\n");
+	goto err8;
+      }
+      pfi->ens1 = ens;
+      j = 0;
+      ch = nxtwrd(ch);
+      if (ch!=NULL) {
+	/* this is the pathway for keyword "names" followed by list of ensemble members */
+	getwrd(ekwrd,ch,5);
+	lowcas(ekwrd);
+	if (cmpwrd("names",ekwrd)) {
+	  while (j<pfi->dnum[4]) {
+	    if ((ch=nxtwrd(ch))==NULL) {
+	      /* ensemble names are listed in more than one line */
+	      if (fgets(rec,512,descr)==NULL) goto err7a;  /* read line, keep as mixed case */
+	      ch = rec;
+	      while (*ch==' ' || *ch=='\t') ch++;          /* advance through white space */
+	      if (*ch=='\0' || *ch=='\n') goto err7b;      /* nothing there */
+	    }
+	    /* get the ensemble name */
+	    if ((getenm(ens, ch))!=0) goto err7d;
+	    /* initialize remaining fields in ensemble structure */
+	    for (jj=0;jj<4;jj++) ens->grbcode[jj]=-999;  
+	    ens->length=0;
+	    ens->gt=1;
+	    ens->tinit.yr=0;
+	    ens->tinit.mo=0;
+	    ens->tinit.dy=0;
+	    ens->tinit.hr=0;
+	    ens->tinit.mn=0;
+	    j++; ens++;
+	  }
+	} else {
+	  gaprnt(1,"Invalid syntax in EDEF statement: \"names\" not found\n");
+	  goto err7f;
+	}
+      }
+      else {
+	/* this is the pathway for separate lines 
+	   containing name, length, initial time, and optional grib2 codes */
+	while (j<pfi->dnum[4]) {
+	  /* read the record and remove leading blanks */
+	  fgets(rec,512,descr);       
+	  reclen = strlen(rec);
+	  jj = 0;
+	  while (jj<reclen && rec[0]==' ') {
+	    for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	    jj++;
+	  }
+	  /* replace newline with null at end of record */
+	  for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	    if (rec[ichar] == '\n') {
+	      rec[ichar] = '\0' ;
+	      break ; 
+	    }
+	  }
+	  /* Keep mixed case and lower case versions of rec handy */
+	  strcpy (mrec,rec);
+	  lowcas(rec);
+	  /* Allow comments between EDEF and ENDEDEF */
+	  if (!isalnum(*(mrec))) {
+	    /* Parse comment if it contains attribute metadata  */
+	    if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	      if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	      else continue;
+	    }
+	    else continue;
+	  }
+	  if (cmpwrd("endedef",rec)) {
+	    gaprnt (0,"Open Error:  Unexpected ENDEDEF record\n");
+	    snprintf(pout,255, "Was expecting %i records.  Found %i.\n", pfi->dnum[4], j);
+	    gaprnt (2,pout);
+	    goto err9;
+	  }
+	  /* get the ensemble name */
+	  if ((getenm(ens, mrec))!=0) goto err7d;
+	  /* get the length of the time axis */
+	  if ( (ch=nxtwrd(rec))==NULL) goto err7e;
+	  if ( (pos=intprs(ch,&(ens->length)))==NULL ) goto err7e;
+	  /* get the initial time */
+	  if ((ch = nxtwrd(ch))==NULL) goto err7e;
+	  tdef.yr = -1000;
+	  tdef.mo = -1000;
+	  tdef.dy = -1000;
+	  if ((pos = adtprs(ch,&tdef,&ens->tinit))==NULL) goto err7e;
+	  if (ens->tinit.yr == -1000 || 
+	      ens->tinit.mo == -1000 ||
+	      ens->tinit.dy == -1000) goto err7e;
+	  /* get the (optional) grib2 ensemble codes */
+	  for (jj=0;jj<4;jj++) ens->grbcode[jj]=-999; 
+	  if ((ch = nxtwrd(ch))!=NULL) {
+	    jj=0;
+	    while (1) {
+	      if ((ch=intprs(ch,&(ens->grbcode[jj])))==NULL) goto err7c;
+	      while (*ch==' ') ch++;
+	      if (*ch!=',') break;
+	      ch++;
+	      while (*ch==' ') ch++;
+	      if (*ch=='\0' || *ch=='\n') goto err7c;
+	      jj++;
+	      if (jj>3) goto err7c;
+	    }
+	  }
+	  j++; ens++;
+	}
+
+	/* Get ENDEDEF statement and any additional comments */
+	if (fgets(rec,512,descr)==NULL) {
+	  gaprnt (0,"Open Error:  Missing ENDEDEF statement.\n");
+	  goto retrn;
+	}
+	/* Remove any leading blanks from rec */
+	reclen = strlen(rec);
+	jj = 0;
+	while (jj<reclen && rec[0]==' ') {
+	  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	  jj++;
+	}
+	/* replace newline with null at end of record */
+	for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	  if (rec[ichar] == '\n') {
+	    rec[ichar] = '\0' ;
+	    break ; 
+	  }
+	}
+	/* Keep mixed case and lower case versions handy */
+	strcpy (mrec,rec);
+	lowcas(rec);
+	while (!cmpwrd("endedef",rec)) {
+	  
+	  /* see if it's an attribute comment */
+	  if (!isalnum(*(mrec))) {
+	    if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	      if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	    }
+	  } else {
+	    snprintf(pout,255,"Open Error:  Looking for \"ENDEDEF\", found \"%s\" instead.\n",mrec);
+	    gaprnt (0,pout);
+	    goto err9;
+	  }
+	  /* get a new record */
+	  if (fgets(rec,512,descr)==NULL) {
+	    gaprnt (0,"Open Error:  Missing ENDEDEF statement.\n");
+	    goto retrn;
+	  }
+	  /* Remove any leading blanks from rec */
+	  reclen = strlen(rec);
+	  jj = 0;
+	  while (jj<reclen && rec[0]==' ') {
+	    for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	    jj++;
+	  }
+	  /* replace newline with null at end of record */
+	  for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	    if (rec[ichar] == '\n') {
+	      rec[ichar] = '\0' ;
+	      break ; 
+	    }
+	  }
+	  /* Keep mixed case and lower case versions handy */
+	  strcpy (mrec,rec);
+	  lowcas(rec);
+	}
+      }
+	
+    } else if (cmpwrd("vars",rec)) {
+      if ( (ch = nxtwrd(rec)) == NULL) goto err5;
+      if ( (pos = intprs(ch,&(pfi->vnum)))==NULL) goto err5;
+      size = pfi->vnum * (sizeof(struct gavar) + 7 );
+      sz = size;
+      if ((pvar = (struct gavar *)galloc(sz,"pvar2")) == NULL) goto err8;
+      pfi->pvar1 = pvar;
+      i = 0;
+      while (i<pfi->vnum) {
+	/* initialize variables in the pvar structure */
+	pvar->offset = 0; 
+	pvar->recoff = 0;
+	pvar->ncvid = -999;
+	pvar->sdvid = -999;
+	pvar->h5vid = -999;
+	pvar->levels = 0;
+	pvar->dfrm = 0;
+	pvar->var_t = 0;
+	pvar->scale = 1;
+	pvar->add = 0;  
+	pvar->undef= -9.99e8; 
+        pvar->vecpair = -999;
+        pvar->isu = 0;
+	pvar->isdvar = 0;
+	pvar->nvardims = 0; 
+	pvar->g2aflg = 0;
+#if USEHDF5==1
+	pvar->h5varflg=-999;
+	pvar->dataspace=-999;
+#endif
+
+	/* get the complete variable declaration */
+        if (fgets(rec,512,descr)==NULL) {
+          gaprnt (0,"Open Error:  Unexpected EOF reading variables\n");
+          snprintf(pout,255, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+          gaprnt (2,pout);
+          goto retrn;
+        }
+	/* remove any leading blanks from rec */
+	reclen = strlen(rec);
+	jj = 0;
+	while (jj<reclen && rec[0]==' ') {
+	  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	  jj++;
+	}
+	/* replace newline with null at end of record */
+        for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	  if (rec[ichar] == '\n') {
+	    rec[ichar] = '\0' ;
+	    break ; 
+	  }
+        }
+	/* Keep mixed case and lower case versions of rec handy */
+        strcpy (mrec,rec);
+        lowcas(rec);
+	/* Allow comments between VARS and ENDVARS */
+	/* For hdf5 datasets, the varnames may begin with a "/", so along with the 
+	   test for non-alpha-numeric characters, which normally indicate a comment, 
+	   check if first char is not slash, if so, then it's a comment, otherwise  
+	   it's a legitimate hdf5 variable declaration. */
+        if (!isalnum(*(mrec)) && (strncmp("/",mrec,1)!=0)) {
+	  /* Parse comment if it contains attribute metadata  */
+	  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	    if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	    else continue;
+	  }
+  	  else continue;
+	}
+
+        if (cmpwrd("endvars",rec)) {
+          gaprnt (0,"Open Error:  Unexpected ENDVARS record\n");
+          snprintf(pout,255, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+          gaprnt (2,pout);
+          goto err9;
+        }
+	
+	/* get abbrv and full variable name if there */
+        if ((getvnm(pvar, mrec))!=0) goto err6;
+
+	/* parse the levels fields */
+        if ( (ch=nxtwrd(rec))==NULL) goto err6;
+	for (j=0;j<48;j++) pvar->units[j] = -999;
+	/* begin with 8th element of units aray for levels values */
+        j = 8;          
+        while (1) {
+	  if (j==8) {
+	    /* first element is num levels */
+	    if ((ch=intprs(ch,&(pvar->levels)))==NULL) goto err6;      
+	  }
+	  else {
+	    /* remaining elements are grib2 level codes */
+	    if ((ch=getdbl(ch,&(pvar->units[j-1])))==NULL) goto err6;  
+	  }
+	  /* advance through comma-delimited list of levels args */
+          while (*ch==' ') ch++;
+          if (*ch=='\0' || *ch=='\n') goto err6;
+          if (*ch!=',') break;
+          ch++;
+	  while (*ch==',') { ch++; j++;}  /* advance past back to back commas */
+          while (*ch==' ') ch++;
+          if (*ch=='\0' || *ch=='\n') goto err6;
+          j++;
+          if (j>15) goto err6;
+        }
+
+	/* check if this is an extra block of "additional" grib2 codes  */
+	if (*ch=='a') {
+	  pvar->g2aflg = 1;
+	  /* parse the additional codes; begin with 16th element of pvar->units */
+	  j=16; 
+	  ch++;
+          while (1) {
+	    if ((ch=getdbl(ch,&(pvar->units[j])))==NULL) goto err6;  
+	    while (*ch==' ') ch++;
+	    if (*ch=='\0' || *ch=='\n') goto err6;
+	    if (*ch!=',') break;
+	    ch++;
+	    while (*ch==' ') ch++;
+	    if (*ch=='\0' || *ch=='\n') goto err6;
+	    j++;
+	    if (j>47) goto err6;	  
+	  }
+	}
+
+	/* parse the units fields; begin with 0th element for variable units */
+        j = 0;
+	pvar->nvardims=0;
+        while (1) {
+          if (*ch=='x'||*ch=='y'||*ch=='z'||*ch=='t'||*ch=='e') { 
+            if (*(ch+1)!=',' && *(ch+1)!=' ') goto err6;
+            if (*ch=='x') { pvar->units[j] = -100; pvar->nvardims++; }
+            if (*ch=='y') { pvar->units[j] = -101; pvar->nvardims++; }
+            if (*ch=='z') { pvar->units[j] = -102; pvar->nvardims++; }
+            if (*ch=='t') { pvar->units[j] = -103; pvar->nvardims++; }
+            if (*ch=='e') { pvar->units[j] = -104; pvar->nvardims++; }
+            ch++;
+          } else {
+            if ( (ch=getdbl(ch,&(pvar->units[j])))==NULL ) goto err6;
+	    /* no negative array indices for ncflag files */
+	    if ((pfi->ncflg) && (pvar->units[j] < 0))  goto err6;   
+          }
+          while (*ch==' ') ch++;
+          if (*ch=='\0' || *ch=='\n') goto err6;
+          if (*ch!=',') break;
+          ch++;
+          while (*ch==' ') ch++;
+          if (*ch=='\0' || *ch=='\n') goto err6;
+          j++;
+          if (j>8) goto err6;
+        }
+
+	/* parse the variable description */
+        getstr (pvar->varnm,mrec+(ch-rec),140);
+
+	/* var_t is for data files with dimension sequence: X, Y, Z, T, V */
+	if ((pvar->units[0]==-1) && 
+	    (pvar->units[1]==20)) 
+	  pvar->var_t = 1;
+
+	/* non-float data types */
+	if ((pvar->units[0]==-1) && 
+	    (pvar->units[1]==40)) {
+	  if (pvar->units[2]== 1) pvar->dfrm = 1;
+	  if (pvar->units[2]== 2) { pvar->dfrm = 2;
+	    if (pvar->units[3]==-1) pvar->dfrm = -2; }
+	  if (pvar->units[2]== 4) pvar->dfrm = 4;
+	}
+
+        i++; pvar++;
+      }
+
+      /* Get ENDVARS statement and any additional comments */
+      if (fgets(rec,512,descr)==NULL) {
+        gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
+        goto retrn;
+      }
+      /* Remove any leading blanks from rec */
+      reclen = strlen(rec);
+      jj = 0;
+      while (jj<reclen && rec[0]==' ') {
+	for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	jj++;
+      }
+      /* replace newline with null at end of record */
+      for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	if (rec[ichar] == '\n') {
+	  rec[ichar] = '\0' ;
+	  break ; 
+	}
+      }
+      /* Keep mixed case and lower case versions handy */
+      strcpy (mrec,rec);
+      lowcas(rec);
+      while (!cmpwrd("endvars",rec)) {
+	/* see if it's an attribute comment */
+        if (!isalnum(*(mrec))) {
+	  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	    if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	  }
+	}
+        else {
+	  snprintf(pout,255,"Open Error:  Looking for \"endvars\", found \"%s\" instead.\n",rec);
+	  gaprnt (0,pout);
+	  goto err9;
+	}
+	/* get a new record */
+  	if (fgets(rec,512,descr)==NULL) {
+	  gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
+	  goto retrn;
+	}
+	/* Remove any leading blanks from new record */
+	reclen = strlen(rec);
+	jj = 0;
+	while (jj<reclen && rec[0]==' ') {
+	  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	  jj++;
+	}
+	/* replace newline with null at end of record */
+	for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	  if (rec[ichar] == '\n') {
+	    rec[ichar] = '\0' ;
+	    break ; 
+	  }
+	}
+	/* Keep mixed case and lower case versions handy */
+	strcpy (mrec,rec);
+	lowcas(rec);
+      }
+      /* vars block parsed without error */
+      flgs[6] = 0;
+
+    } else {
+      /* parse error of .ctl file */
+      gaprnt (0,"Open Error:  Unknown keyword in description file\n");
+      goto err9;
+    }
+  }
+
+  err=0;
+  for (i=0; i<7; i++) {
+    if (flgs[i]) {
+      snprintf(pout,255,"Open Error:  missing %s record \n",errs[i]);
+      gaprnt (0,pout);
+      err=1;
+    }
+  }
+
+  if (err) goto retrn;
+
+
+  /* Done scanning!
+     Check if scanned stuff makes sense, and then set things up correctly */
+
+  /* Set the default netcdf/hdf5 cache size to be big enough to contain 
+     a global 2D grid of 8-byte data values times the global cache scale factor */
+  if (pfi->cachesize == (long)-1) {
+    sf = qcachesf();
+    sf = sf * 8 * pfi->dnum[0] * pfi->dnum[1];
+    pfi->cachesize = (long)floor(sf) ;
+  }
+  /* set the netCDF-4 cache size */
+  sz = (size_t)pfi->cachesize;
+  set_nc_cache(sz);
+
+  /* If no EDEF entry was found, set up the default values */
+  if (pfi->ens1==NULL) {
+      pfi->dnum[4]=1;
+      /* set up linear scaling */
+      sz = sizeof(gadouble)*6;
+      if ((vals = (gadouble *)galloc(sz,"evals3")) == NULL) goto err8;
+      v1=v2=1;
+      *(vals+1) = v1 - v2;
+      *(vals) = v2;
+      *(vals+2) = -999.9;
+      pfi->grvals[4] = vals;
+      *(vals+4) = -1.0 * ( (v1-v2)/v2 );
+      *(vals+3) = 1.0/v2;
+      *(vals+5) = -999.9;
+      pfi->abvals[4] = vals+3;
+      pfi->ab2gr[4] = liconv;
+      pfi->gr2ab[4] = liconv;
+      pfi->linear[4] = 1;
+      /* Allocate memory and initialize one ensemble structure */
+      sz = sizeof(struct gaens);
+      ens = (struct gaens *)galloc(sz,"ens5");
+      if (ens==NULL) {
+	gaprnt(0,"Open Error: memory allocation failed for default ens\n");
+	goto err8;
+      }
+      pfi->ens1 = ens;
+      snprintf(ens->name,15,"1");
+      ens->length = pfi->dnum[3];
+      ens->gt = 1;
+      gr2t(pfi->grvals[3],1,&ens->tinit);
+      for (j=0;j<4;j++) ens->grbcode[j]=-999;
+  }
+  else {
+    ens=pfi->ens1;
+    j=0;
+    while (j<pfi->dnum[4]) {
+      /* Copy length and time metadata to ensemble members that only have names */
+      if (ens->length == 0) ens->length=pfi->dnum[3];
+      if (ens->tinit.mo == 0) gr2t(pfi->grvals[3],1,&ens->tinit);
+      /* Calculate the grid coordinate for the initial time */
+      ens->gt = t2gr(pfi->abvals[3],&(ens->tinit));
+      /* make sure time axis spans all ensemble members */
+      if (ens->gt - 1 + ens->length > pfi->dnum[3]) {
+	snprintf(pout,255,"Open Error:  ensemble %d (%s) extends beyond the time axis limits\n",j,ens->name);
+	gaprnt(0,pout);
+	goto retrn;
+      }
+      j++; ens++;
+    }
+  }
+
+  /* Rearrange the pvar->units fields for GRIB1 level info so they match GRIB2 */
+  if (pfi->idxflg == 1) {
+    pvar=pfi->pvar1;
+    for (j=1; j<=pfi->vnum; j++) {
+      pvar->units[8]  = pvar->units[1];  
+      pvar->units[9]  = pvar->units[2];  
+      pvar->units[10] = pvar->units[3];  
+      pvar->units[1]  = pvar->units[2] = pvar->units[3] = -999;
+      pvar++;
+    }
+  }
+
+  /* Handle the index file (Station or GRIB) */
+  if (pfi->idxflg && mflag) {
+    mfile = fopen (pfi->mnam, "rb");
+    if (mfile==NULL) {
+      snprintf(pout,255,"Open Error:  Can't open Station/Index map file %s \n",pfi->mnam);
+      gaprnt (0,pout);
+      goto retrn;
+    }
+    if (mflag==2) goto skipread;
+    
+    mflflg = 1;
+    swpflg = 0; 
+      
+    /* GRIB (version 1 or 2) gridded data */
+    if (pfi->type!=2) {
+      /* GRIB version 1 */
+      if (pfi->idxflg==1) {    
+	/* allocate memory for index data */
+	sz = sizeof(struct gaindx);
+	if ((pindx = (struct gaindx *)galloc(sz,"pindx"))==NULL) 
+	  goto err8;
+	pfi->pindx = pindx;
+	/*  check the gribmap version number */
+	fseek(mfile,1,0);
+	rc = fread(&vermap,sizeof(unsigned char),1,mfile);
+	if (rc!=1) { 
+	  gaprnt(0,"Error reading version number from GRIB1 index file\n"); 
+	  goto retrn; 
+	}
+
+	/* gribmap version 2 or 3 */
+	if ((vermap == 2) || (vermap == 3)) {        
+
+	  /* read the header */
+	  fseek(mfile,2,0);
+	  rc = fread(urec,sizeof(unsigned char),4,mfile);
+	  if (rc!=4) { 
+	    gaprnt(0,"Error reading hinum from GRIB1 index file\n"); 
+	    goto retrn; 
+	  }
+	  pindx->hinum=gagby(urec,0,4);
+	  
+	  rc = fread(urec,sizeof(unsigned char),4,mfile);
+	  if (rc!=4) { 
+	    gaprnt(0,"Error reading hfnum from GRIB1 index file\n"); 
+	    goto retrn; 
+	  }
+	  pindx->hfnum=gagby(urec,0,4);
+	  
+	  rc = fread(urec,sizeof(unsigned char),4,mfile);
+	  if (rc!=4) { 
+	    gaprnt(0,"Error reading intnum from GRIB1 index file\n"); 
+	    goto retrn; 
+	  }
+	  pindx->intnum=gagby(urec,0,4);
+	  
+	  rc = fread(urec,sizeof(unsigned char),4,mfile);
+	  if (rc!=4) { 
+	    gaprnt(0,"Error reading fltnum from GRIB1 index file\n"); 
+	    goto retrn; 
+	  }
+	  pindx->fltnum=gagby(urec,0,4);
+	  
+	  if (vermap == 2) {
+	    /* skip the begining time struct info */
+	    /* this not written out in version 3 maps */
+	    rc = fread(urec,sizeof(unsigned char),7,mfile);
+	    if (rc!=7) { 
+	      gaprnt(0,"Error reading time data from GRIB1 index file\n"); 
+	      goto retrn; 
+	    }
+	  }
+
+	  /* read the index data */
+	  pindx->hipnt  = NULL;
+	  pindx->hfpnt  = NULL;
+	  pindx->intpnt = NULL;
+	  pindx->fltpnt = NULL;
+	  if (pindx->hinum>0) {
+	    sz = sizeof(gaint)*pindx->hinum;
+	    if ((pindx->hipnt = (gaint*)galloc(sz,"hipnt"))==NULL) 
+	      goto err8;
+	    for (i=0; i<pindx->hinum; i++) {
+	      rc = fread(urec,sizeof(unsigned char),4,mfile);
+	      if (rc!=4) { 
+		snprintf(pout,255,"Error reading integer %d from header of GRIB1 index file\n",i); 
+		gaprnt(0,pout); 
+		goto retrn; 
+	      }
+	      idum = gagby(urec,0,4);
+	      if (gagbb(urec,0,1)) idum = -idum;
+	      *(pindx->hipnt+i) = idum;
+	    }
+	  }
+
+	  if (pindx->hfnum>0) {
+	    sz = sizeof(gafloat)*pindx->hfnum;
+	    if ((pindx->hfpnt = (gafloat*)galloc(sz,"hfpnt"))==NULL) 
+	      goto err8; 
+	    rc = fread (pindx->hfpnt,sizeof(gafloat),pindx->hfnum,mfile);
+	    if (rc!=pindx->hfnum) { 
+	      gaprnt(0,"Error reading floats from header of GRIB1 index file\n"); 
+	      goto retrn; 
+	    }
+	  }
+
+	  if (pindx->intnum>0) {
+	    sz = sizeof(gaint)*pindx->intnum;
+	    if ((pindx->intpnt = (gaint*)galloc(sz,"intpnt"))==NULL) 
+	      goto err8; 
+	    for (i=0; i<pindx->intnum; i++) {
+	      rc = fread(urec,sizeof(unsigned char),4,mfile);
+	      if (rc!=4) { 
+		snprintf(pout,255,"Error reading integer %d from GRIB1 index file\n",i); 
+		gaprnt(0,pout); 
+		goto retrn; 
+	      }
+	      idum = gagby(urec,0,4);
+	      if (gagbb(urec,0,1)) idum = -gagbb(urec,1,31);
+	      *(pindx->intpnt+i) = idum;
+	    }
+	  }
+
+	  if (pindx->fltnum>0) {
+	    sz = sizeof(gafloat)*pindx->fltnum;
+	    if ((pindx->fltpnt = (gafloat *)galloc(sz,"fltpnt"))==NULL) 
+	      goto err8; 
+	    for (i=0; i<pindx->fltnum; i++) {
+	      rc = fread(urec,sizeof(unsigned char),4,mfile);
+	      if (rc!=4) { 
+		snprintf(pout,255,"Error reading float %d from GRIB1 index file\n",i); 
+		gaprnt(0,pout); 
+		goto retrn; 
+	      }
+	      fdum = ibm2flt(urec);
+	      *(pindx->fltpnt+i) = fdum;
+	    }
+	  }
+	} 
+	else {     
+	  /* other gribmap versions */
+	  fseek (mfile,0L,0);
+	  rc = fread (pindx,sizeof(struct gaindx),1,mfile);
+          if (rc!=1) {
+	    gaprnt(0,"Error reading header from GRIB1 index file\n");
+	    goto retrn;
+          }
+	  if (pindx->type>>24 > 0) swpflg=1;
+	  if (swpflg) gabswp((gafloat *)pindx,5);
+	  pindx->hipnt = NULL;
+	  pindx->hfpnt = NULL;
+	  pindx->intpnt = NULL;
+	  pindx->fltpnt = NULL;
+          if (pindx->type != 1 && pindx->type != 4 ) {
+            snprintf(pout,100,"Invalid version number %i in GRIB index file\n",pindx->type); 
+            gaprnt(0,pout); 
+            goto retrn; 
+          }
+	  if (pindx->hinum>0) {
+	    sz = sizeof(gaint)*pindx->hinum;
+	    if ((pindx->hipnt = (gaint *)galloc(sz,"hipnt2")) == NULL) 
+	      goto err8; 
+	    rc = fread (pindx->hipnt,sizeof(gaint),pindx->hinum,mfile);
+            if (rc!=pindx->hinum) {
+	      gaprnt(0,"Error reading header ints from GRIB1 index file\n");
+	      goto retrn;
+            }
+	    if (swpflg) gabswp((gafloat *)(pindx->hipnt),pindx->hinum);
+	  }
+	  if (pindx->hfnum>0) {
+	    sz = sizeof(gafloat)*pindx->hfnum;
+	    if ((pindx->hfpnt = (gafloat *)galloc(sz,"hfpnt2")) == NULL)
+	      goto err8; 
+	    rc = fread (pindx->hfpnt,sizeof(gafloat),pindx->hfnum,mfile);
+            if (rc!=pindx->hfnum) {
+	      gaprnt(0,"Error reading header floats from GRIB1 index file\n");
+	      goto retrn;
+            }
+	    if (swpflg) gabswp(pindx->hfpnt,pindx->hfnum);
+	  }
+	  if (pindx->intnum>0) {
+	    sz = sizeof(gaint)*pindx->intnum;
+	    if ((pindx->intpnt = (gaint *)galloc(sz,"ipnt2")) == NULL) 
+	      goto err8; 
+	    rc = fread (pindx->intpnt,sizeof(gaint),pindx->intnum,mfile);
+            if (rc!=pindx->intnum) {
+	      gaprnt(0,"Error reading int array from GRIB1 index file\n");
+	      goto retrn;
+            }
+	    if (swpflg) gabswp((gafloat *)(pindx->intpnt),pindx->intnum);
+	  }
+	  if (pindx->fltnum>0) {
+	    sz = sizeof(gafloat)*pindx->fltnum;
+	    if ((pindx->fltpnt = (gafloat *)galloc(sz,"fpnt2")) == NULL)
+	      goto err8; 
+	    rc = fread (pindx->fltpnt,sizeof(gafloat),pindx->fltnum,mfile);
+            if (rc!=pindx->fltnum) {
+	      gaprnt(0,"Error reading float array from GRIB1 index file\n");
+	      goto retrn;
+            }
+	    if (swpflg) gabswp(pindx->fltpnt,pindx->fltnum);
+	  }
+          if (pindx->type == 4) {
+            if (sizeof(off_t)!=8) goto err8a;
+	    sz = sizeof(struct gaindxb);
+	    if ((pindxb = (struct gaindxb *)galloc(sz,"pindxb"))==NULL) goto err8;
+	    pfi->pindxb = pindxb;
+            pindxb->bignum = *(pindx->hipnt + 4); 
+            pindxb->bigpnt = NULL;
+	    if (pindxb->bignum>0) {
+	      sz = sizeof(off_t)*pindxb->bignum;
+	      if ((pindxb->bigpnt = (off_t *)galloc(sz,"offpnt")) == NULL) goto err8; 
+	      rc = fread (pindxb->bigpnt,sizeof(off_t),pindxb->bignum,mfile);
+              if (rc!=pindxb->bignum) {
+	        gaprnt(0,"Error reading off_t array from GRIB1 index file\n");
+	        goto retrn;
+              }
+	      if (swpflg) gabswp8(pindxb->bigpnt,pindxb->bignum);
+	    }
+          }
+	}
+      }
+#if GRIB2
+      /* GRIB Version 2 */
+      else if (pfi->idxflg==2) {   	 
+	/* allocate memory for the grib2 index data */
+	sz = sizeof(struct gag2indx);
+	if ((g2indx = (struct gag2indx *)galloc(sz,"g2indx")) == NULL) 
+	  goto err8;
+	pfi->g2indx = g2indx;
+        g2indx->g2intpnt = NULL;
+        g2indx->g2bigpnt = NULL;
+	/* get the grib2map version number */
+	fseek(mfile,0L,SEEK_SET);
+	rc = fread(&g2indx->version,sizeof(gaint),1,mfile);
+	if (rc!=1) {
+	  gaprnt(0,"Error reading version number from GRIB2 index file\n");
+	  goto retrn;
+	}
+	/* check if we need to byte swap */
+	if (g2indx->version>>24 > 0) swpflg=1;
+	else swpflg=0;
+	if (swpflg) gabswp(&g2indx->version,1);
+	/* get the index values */
+	if (g2indx->version == 1 || g2indx->version == 2) {     
+          if (g2indx->version == 2 && sizeof(off_t)!=8) goto err8a;
+	  rc = fread(&g2indx->g2intnum,sizeof(gaint),1,mfile);
+	  if (rc!=1) {
+	    gaprnt(0,"Error reading index values from GRIB2 index file\n");
+	    goto retrn;
+	  } 
+	  if (swpflg) gabswp(&g2indx->g2intnum,1);
+	  if (g2indx->g2intnum>0) {
+	    sz = sizeof(gaint)*g2indx->g2intnum;
+	    if ((g2indx->g2intpnt = (gaint *)galloc(sz,"g2intpnt")) == NULL) 
+	      goto err8;
+	    rc = fread(g2indx->g2intpnt,sizeof(gaint),g2indx->g2intnum,mfile);
+	    if (rc!=g2indx->g2intnum) {
+	      snprintf(pout,255,"Error reading GRIB2 index file, rc=%d\n",rc);
+	      gaprnt(0,pout);
+	      goto retrn;
+	    }
+	    if (swpflg) gabswp(g2indx->g2intpnt,g2indx->g2intnum);
+            if (g2indx->version == 2) {
+	      sz = sizeof(off_t)*g2indx->g2intnum;
+	      if ((g2indx->g2bigpnt = (off_t *)galloc(sz,"g2bigpnt")) == NULL) 
+	        goto err8;
+	      rc = fread(g2indx->g2bigpnt,sizeof(off_t),g2indx->g2intnum,mfile);
+	      if (rc!=g2indx->g2intnum) {
+	        snprintf(pout,255,"Error reading GRIB2 index file, rc=%d\n",rc);
+	        gaprnt(0,pout);
+	        goto retrn;
+	      }
+	      if (swpflg) gabswp8(g2indx->g2bigpnt,g2indx->g2intnum);
+            }
+	  }
+	}
+	else {     
+	  snprintf(pout,255,"Unknown GRIB2 index version number: %d\n",g2indx->version);
+	  gaprnt(0,pout);
+	  goto retrn;
+	}
+      }
+#endif
+    }  /* end of GRIB index handling */
+    
+    else {
+      /* stnmap file processing */
+      fread(rec,1,16,mfile);  /* minimum map file is 16 bytes */
+      vermap=1;
+      if (strncmp(rec,"GrADS_stnmapV002",16) == 0) {
+	vermap=2;
+      }
+      if (vermap == 2) {
+	fread(urec,sizeof(unsigned char),4,mfile);
+	idum=gagby(urec,0,4);
+	if (gagbb(urec,0,1)) idum=-idum;
+	mcnt=idum;
+	fread(urec,sizeof(unsigned char),4,mfile);
+	idum=gagby(urec,0,4);
+	if (gagbb(urec,0,1)) idum=-idum;
+	maxlv=idum;
+	sz = sizeof(gaint)*mcnt;
+	if ((pfi->tstrt = (gaint *)galloc(sz,"tstrt")) == NULL) goto err8;
+	if ((pfi->tcnt  = (gaint *)galloc(sz,"tcnt")) == NULL) goto err8;
+	for(i=0;i<mcnt;i++) {
+	  fread(urec,sizeof(unsigned char),4,mfile);
+	  idum=gagby(urec,0,4);
+	  if (gagbb(urec,0,1)) idum=-idum;
+	  *(pfi->tstrt+i)=idum;
+	}
+	for(i=0;i<mcnt;i++) {
+	  fread(urec,sizeof(unsigned char),4,mfile);
+	  idum=gagby(urec,0,4);
+	  if (gagbb(urec,0,1)) idum=-idum;
+	  *(pfi->tcnt+i)=idum;
+	}
+      } 
+      else if (vermap ==1) {
+	/* reposition and read two local ints for version 1 map*/
+	fseek (mfile,0L,0);
+	fread (&mcnt,sizeof(gaint),1,mfile);
+	fread (&maxlv,sizeof(gaint),1,mfile);
+	if (maxlv>>24 > 0) swpflg = 1;
+	if (swpflg) {
+	  gabswp((gafloat *)(&mcnt),1);
+	  gabswp((gafloat *)(&maxlv),1);
+	}
+	sz = sizeof(gaint)*mcnt;
+	if ((pfi->tstrt = (gaint *)galloc(sz,"tstrt1")) == NULL) goto err8;
+	if ((pfi->tcnt  = (gaint *)galloc(sz,"tcnt1")) == NULL) goto err8;
+	fread (pfi->tstrt,sizeof(gaint),mcnt,mfile);
+	fread (pfi->tcnt,sizeof(gaint),mcnt,mfile);
+	if (swpflg) {
+	  gabswp((gafloat *)pfi->tstrt,1);
+	  gabswp((gafloat *)pfi->tcnt,1);
+	}
+	pfi->mtype = 1;
+      }
+    }
+
+  skipread:
+    fclose (mfile);
+    mflflg = 0;
+    
+  } /* End of index file handling for grib and station data files */
+
+  
+#if GRIB2
+  /* Check if we need to convert pressure values from Pascals to millibars (GRIB2 only) */
+  /* Leave pressure values in Pascals for pre-processing of descriptor file (i.e. mflag==0 or 2) */
+  if (pfi->pa2mb && mflag==1) {
+    if (pfi->idxflg==2) {
+      for (i=1; i<=pfi->dnum[2]; i++) {
+	*(pfi->grvals[2]+i) = *(pfi->grvals[2]+i)/100;
+      }
+    }
+    else {
+      gaprnt(2,"Do not use Pascals as pressure units unless data format is GRIB2\n");
+      goto err9;
+    }
+  }
+#endif
+
+  /* Parse the vector pairs */
+  npairs = 0;
+  if (vectorpairs) {
+    vplist = vectorpairs; 
+    sz = strlen(vplist)+1;
+    if ((pair = (char *)galloc(sz,"pair")) == NULL) {
+      gaprnt(0,"memory allocation error for list of vector pairs\n");
+      goto err8;
+    } 
+    else {
+      while (1) {
+	/* copy the comma-delimited pair of variable names */
+	getwrd(pair,vplist,strlen(vplist));
+	i=0;
+	while (1) {
+	  if (*(pair+i)==',') {
+
+	    /* get the two variable names that comprise the vector pair */
+	    getstr(var1, pair, i);
+	    getstr(var2, pair+(i+1), strlen(pair)-i+1);
+	    npairs++;
+
+	    /* loop through variable list */
+	    foundvar1=foundvar2=0;
+	    pvar = pfi->pvar1;
+	    for (j=1; j<=pfi->vnum; j++) {
+	      /* if variable names match, set flags */
+	      if (cmpwrd(pvar->abbrv,var1)) foundvar1=j;
+	      if (cmpwrd(pvar->abbrv,var2)) foundvar2=j;
+	      pvar++;
+	    }
+	    if (foundvar1 && foundvar2) {
+	      pvar = pfi->pvar1;
+	      for (j=1; j<=pfi->vnum; j++) {
+		/* if we've found both variables, set pvar->vecpair */
+		if (cmpwrd(pvar->abbrv,var1)) {
+		  pvar->vecpair=npairs;
+		  pvar->isu=1;    /* trip flag for u-component */
+		}
+		if (cmpwrd(pvar->abbrv,var2)) {
+		  pvar->vecpair=npairs;
+		}
+		pvar++;
+	      }
+	    }
+	    else {
+	      snprintf(pout,255,"Warning: VECTORPAIRS variables %s,%s were not found \n",var1,var2);
+	      gaprnt(1,pout);
+	    }
+	    break;
+	  }
+	  i++; 
+	}
+	/* move pointer forward one word */
+	if ((vplist = nxtwrd (vplist)) == NULL) break;
+      }
+    }
+    gree(pair,"f174");
+    gree(vectorpairs,"f175");
+  }
+
+  /* Find u,v variables -- vector pairs that havn't already been flagged */
+  pvar=pfi->pvar1;
+  for (j=1; j<=pfi->vnum; j++) {
+    /* for GRIB2 data sets */
+    if (pfi->idxflg == 2) {
+      /* Look for a variable with units[0-2] == 0,2,2 or 0,2,3  that hasn't been handled yet */
+      if ((pvar->vecpair<0) && 
+	  ((pvar->units[0]==0 && 
+	    pvar->units[1]==2 && 
+	    pvar->units[2]==2) /* variabls is u */ ||   
+	   (pvar->units[0]==0 && 
+	    pvar->units[1]==2 && 
+	    pvar->units[2]==3))) /* variabls is v */ {
+	if (pvar->units[2]==2) 
+	  rc = 3;
+	else 
+	  rc = 2; 
+	/* Look for a matching variable with all units fields equal */
+	pvar2 = pfi->pvar1;
+	i = 0;
+	while (i<pfi->vnum) {
+	  if ((pvar2->vecpair<0) &&        
+	      (pvar2->units[0]==pvar->units[0]) &&
+	      (pvar2->units[1]==pvar->units[1]) &&
+	      (pvar2->units[2]==rc) &&
+	      (pvar2->units[8]==pvar->units[8]) &&
+	      (pvar2->units[9]==pvar->units[9]) &&
+	      (pvar2->units[10]==pvar->units[10])) break;
+	  pvar2++; i++;
+	}	
+	if (i<pfi->vnum) { /* We've got a match! */
+	  npairs++;
+	  /* set the gavar parameters */
+	  pvar->vecpair=npairs;
+	  pvar2->vecpair=npairs;
+	  if (pvar->units[2]==2) 
+	    pvar->isu=1; 
+	  else 
+	    pvar2->isu=1;
+	}      
+      }
+    }
+    /* for GRIB1 and binary data sets */
+    else {
+      /* Look for a variable with units[0]==33,34 that hasn't been handled yet */
+      if ((pvar->units[0]==33 || pvar->units[0]==34) && 
+	  (pvar->vecpair<0)) {
+	if (pvar->units[0]==33) 
+	  rc = 34; 
+	else 
+	  rc = 33;
+	/* Look for a matching variable with all units fields equal */
+	pvar2 = pfi->pvar1;
+	i = 0;
+	while (i<pfi->vnum) {
+	  if ((pvar2->vecpair<0) &&        
+	      (pvar2->units[0]==rc) &&
+	      (pvar2->units[8]==pvar->units[8]) &&
+	      (pvar2->units[9]==pvar->units[9]) &&
+	      (pvar2->units[10]==pvar->units[10])) break;
+	  pvar2++; i++;
+	}
+	if (i<pfi->vnum) { /* We've got a match! */
+	  npairs++;
+	  /* set the gavar parameters */
+	  pvar->vecpair=npairs;
+	  pvar2->vecpair=npairs;
+	  if (pvar->units[0]==33) 
+	    pvar->isu=1;
+	  else 
+	    pvar2->isu=1;
+	}
+      }
+    }
+    pvar++;
+  }
+  if (err) goto retrn;  /* end of vector pair management */
+
+  /* Chect time count in station index file and descriptor file */
+  if (pfi->type>1 && mflag==1) {
+    if (mcnt==-1) {
+      gaprnt (0,"Open Error: missing STNMAP record\n");
+      err=1;
+    } else if (mcnt != pfi->dnum[3]) {
+      gaprnt (0,"Open Error: Inconsistent time count\n");
+      snprintf(pout,255,"  Count in station map file = %i\n",mcnt);
+      gaprnt (0,pout);
+      snprintf(pout,255,"  Count in descriptor file = %i\n",pfi->dnum[3]);
+      gaprnt (0,pout);
+      err=1;
+    }
+  }
+
+  if (err) goto retrn;
+
+  /* Make sure there are no conflicting options and data types */
+  pvar=pfi->pvar1;
+  for (j=1; j<=pfi->vnum; j++) {
+    if (pvar->units[0]==-1 && pvar->units[1]==20) {
+      if (pfi->tmplat) {
+	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions cannot be templated together\n");
+	err=1;
+      }
+      if (hdrb>0) {
+	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with time headers\n");
+	err=1;
+      }
+      if (trlb>0) {
+	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with TRAILERBYTES\n");
+	err=1;
+      }
+    }
+    pvar++;
+  }
+  if (err) goto retrn;
+
+
+  /* Figure out locations of variables within a time group */
+  pvar = pfi->pvar1;
+
+  /* Grid data */
+  if (pfi->type==1) {
+    pfi->gsiz = pfi->dnum[0] * pfi->dnum[1];
+    if (pfi->ppflag) pfi->gsiz = pfi->ppisiz * pfi->ppjsiz;
+    /* add the XY header to gsiz */
+    if (pfi->xyhdr) {
+      if (pvar->dfrm == 1) {
+	pfi->xyhdr = pfi->xyhdr*4/1;          
+      } 
+      else if (pvar->dfrm ==  2 || pvar->dfrm == -2 ) {
+	pfi->xyhdr = pfi->xyhdr*4/2;
+      } 
+      pfi->gsiz = pfi->gsiz + pfi->xyhdr;
+    }
+
+    /* adjust the size of hdrb and trlb for non-float data */
+    if (pvar->dfrm == 1) {
+      hdrb = hdrb*4/1;
+      trlb = trlb*4/1;
+    } 
+    else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
+      hdrb = hdrb*4/2;
+      trlb = trlb*4/2;
+    } 
+    
+    if (pfi->seqflg) {
+      /* pad the grid size with 2 4-byte chunks */
+      if (pvar->dfrm == 1) {
+	pfi->gsiz += 8;
+      } 
+      else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
+	pfi->gsiz += 4;
+      } 
+      else {
+	pfi->gsiz += 2;             
+      }
+      /* pad the header with 2 4-byte chunks*/
+      if (hdrb>0) {
+	if (pvar->dfrm == 1) {
+	  hdrb = hdrb + 8;
+	} 
+	else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
+	  hdrb = hdrb + 4;
+	} 
+	else {
+	  hdrb += 2; 
+	}
+      }
+      /* how far we have to go into the file before getting to 1st var */
+      if (pvar->dfrm == 1) {
+	pvar->offset = 4+hdrb;
+	acum = 4+hdrb;
+      } 
+      else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
+	pvar->offset = 2+hdrb;
+	acum = 2+hdrb;
+      } 
+      else {
+	pvar->offset = 1+hdrb;
+	acum = 1+hdrb;
+      } 
+    }
+    else {
+      /* how far we have to go into the file before getting to 1st var */
+      pvar->offset = hdrb;
+      acum = hdrb;
+    }
+
+    levs = pvar->levels;
+    if (levs==0) levs=1;
+    pvar->recoff = 0;
+    recacm = 0;
+    pvar++;
+    acumvz=acum;
+
+    for (i=1; i<pfi->vnum; i++) {
+      if (pvar->var_t) {   
+	acum = acum + levs*(pfi->gsiz)*(pfi->dnum[3]); 
+      } else {                              
+	acum = acum + (levs*pfi->gsiz);
+	acumstride = acum ;
+      }
+      recacm += levs;
+      pvar->offset = acum;
+      pvar->recoff = recacm;
+      levs = pvar->levels;
+      if (levs==0) levs=1;
+      pvar++;
+    }
+
+    recacm += levs;
+
+    /* last variable */
+    acum = acum + (levs*pfi->gsiz);
+
+    pfi->tsiz = acum;
+    pfi->trecs = recacm;
+    if (pfi->seqflg) pfi->tsiz-=1;
+    pfi->tsiz += trlb;
+    
+  } 
+  else {   /* non grid data */
+
+    for (i=0; i<pfi->vnum; i++) {
+      if (pvar->levels!=0) break;
+      pvar->offset = i;
+      pvar++;
+    }
+    for (j=i; j<pfi->vnum; j++) {
+      if (pvar->levels==0) {
+	if (!(pfi->bufrflg)) {   /* order of variables doesn't matter for BUFR data */
+	  gaprnt (0,"Open Error: Variables out of order\n");
+	  gaprnt (0,"  Non-vertical variables must go first\n");
+	  goto retrn;
+	}
+      }
+      pvar->offset = j-i;
+      pvar++;
+    }
+    pfi->lvnum = pfi->vnum - i;
+    pfi->ivnum = i;
+  }
+
+/* set the global calendar and check if we are trying to change with a new file...
+   we do this here to set the calandar for templating */
+
+  if (mfcmn.cal365<0) {
+    mfcmn.cal365 = cal365;
+  } else {
+    if (cal365 != mfcmn.cal365) {
+      gaprnt(0,"Attempt to change the global calendar...\n");
+      if (mfcmn.cal365) {
+	gaprnt(0,"The calendar is NOW 365 DAYS and you attempted to open a standard calendar file\n");
+      } else {
+	gaprnt(0,"The calendar is NOW STANDARD and you attempted to open a 365-day calendar file\n");
+      }
+      goto retrn;
+    }
+  }
+
+  /* Allocate an I/O buffer.
+     If we're just parsing the descriptor (mflag==0), no need to do this */
+  if (mflag) {
+    if (pfi->type > 1) {
+      /* for station data, the buffer is the size of max levels  */
+      if (pfi->bufrflg) maxlv=1;    /* maxlv not used for BUFR interface, set to 1 */
+      size = maxlv * sizeof(gafloat);
+      sz = size;
+      pfi->sbuf = (gafloat *)galloc(sz,"sbuf1");
+      if (pfi->sbuf==NULL) {
+	gaprnt(0,"Open Error: memory allocation failed for sbuf\n");
+	goto err8;
+      }
+      
+    } else {
+      /* for grids, the buffer is the size of one row */
+      size = pfi->dnum[0] * sizeof(gadouble);
+      sz = size;
+      pfi->rbuf = (gadouble *)galloc(sz,"rbuf1");
+      if (pfi->rbuf==NULL) {
+	gaprnt(0,"Open Error: memory allocation failed for rbuf\n");
+	goto err8;
+      }
+      /* pbuf is used for unpacking grib1 data */
+      if (pfi->idxflg) {
+	pfi->pbuf = (unsigned char *)galloc(sz,"pbuf1");
+	if (pfi->pbuf==NULL)  {
+	  gaprnt(0,"Open Error: memory allocation failed for pbuf\n");
+	  goto err8;
+	}
+      }
+    }
+    pfi->ubuf = (char *)galloc(sz,"ubuf1");
+    if (pfi->ubuf==NULL) {
+      gaprnt(0,"Open Error: memory allocation failed for ubuf\n");
+      goto err8;
+    }
+  }
+
+  /* If a pre-projected grid, set up the interpolation constants. 
+     If we're just checking the descriptor (mflag==2), no need to do this */
+  if (pfi->ppflag && mflag!=2) {
+    rc = gappcn(pfi,pdefop1,pdefop2);
+    if (rc) goto retrn;
+  }
+
+  /* If the file name is a time series template, figure out
+     which times go with which files, so we don't waste a lot
+     of time later opening and closing files unnecessarily. */
+
+  /* BUFR files are treated like templated files, so that the 
+     data file isn't parsed until an I/O request is made */
+
+  if (pfi->tmplat || pfi->bufrflg==1) {
+    /* The fnums array is the size of the time axis 
+       multiplied by the size of the ensemble axis. 
+       It contains the t index which generates the filename 
+       that contains the data for each timestep.
+       If the ensemble has no data file for a given time, 
+       the fnums value will be -1 */
+    sz = sizeof(gaint)*pfi->dnum[3]*pfi->dnum[4];
+    pfi->fnums = (gaint *)galloc(sz,"fnums1");   
+    if (pfi->fnums==NULL) {
+      gaprnt(0,"Open Error: memory allocation failed for fnums\n");
+      goto err8;
+    }
+    /* get dt structure for t=1 */
+    gr2t(pfi->grvals[3],1.0,&tdefi); 
+    /* loop over ensembles */
+    ens=pfi->ens1;
+    e=1;
+    while (e<=pfi->dnum[4]) {
+      j = -1; 
+      t=1;
+      /* set fnums value to -1 for time steps before ensemble initial time */
+      while (t<ens->gt) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      j = ens->gt;
+      /* get dt structure for ensemble initial time */
+      gr2t(pfi->grvals[3],ens->gt,&tdefe);
+      /* get filename for initial time of current ensemble member  */
+      ch = gafndt(pfi->name,&tdefe,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,ens->gt,e,&flag);   
+      if (ch==NULL) {
+	snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,ens->gt);
+	gaprnt(0,pout);
+	goto err8;
+      }
+      /* set the pfi->tmplat flag to the flag returned by gafndt */
+      if (flag==0) {
+	gaprnt(1,"Warning: OPTIONS keyword \"template\" is used, but the \n");
+	gaprnt(1,"   DSET entry contains no substitution templates.\n");
+	pfi->tmplat = 1;
+      } else {
+	pfi->tmplat = flag; 
+      }
+      /* for non-indexed, non-netcdf/hdf, gridded data */
+      if (pfi->type==1) {                /* gridded data   */
+	if (pfi->ncflg==0) {             /* not netcdf/hdf */
+	  if (pfi->idxflg==0) {          /* not indexed    */
+	    if ((flag==1) && (pfi->dnum[4]>1)) {
+	      gaprnt(0,"Open Error: If the data type is gridded binary, \n");
+	      gaprnt(0,"  and the E dimension size is greater than 1 \n");
+	      gaprnt(0,"  and templating in the T dimension is used,\n");
+	      gaprnt(0,"  then templating in the E dimension must also be used.\n");
+	      goto retrn;
+	    }
+	  }
+	  else if (pfi->idxflg==1) {     /* GRIB1 */
+	    if ((flag<2) && (pfi->dnum[4]>1)) {
+	      gaprnt(0,"Open Error: If the data type is GRIB1 \n");
+	      gaprnt(0,"  and the E dimension size is greater than 1 \n");
+	      gaprnt(0,"  then templating in the E dimension must be used.\n");
+	      goto retrn;
+	    }
+	  }
+	}
+      }
+      pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      /* loop over remaining valid times for this ensemble */
+      for (t=ens->gt+1; t<ens->gt+ens->length; t++) {
+	/* get filename for time index=t ens=e */
+	gr2t(pfi->grvals[3],(gadouble)t,&tdef);
+	pos = gafndt(pfi->name,&tdef,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,t,e,&flag);  
+	if (pos==NULL) {
+	  snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,t);
+	  gaprnt(0,pout);
+	  goto err8;
+	}
+	if (strcmp(ch,pos)!=0) {    /* filename has changed */
+	  j = t;   
+	  gree(ch,"f176");
+	  ch = pos;
+	}
+	else {
+	  gree(pos,"f176a");
+	}
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      }
+      gree(ch,"f177");
+
+      /* set fnums value to -1 for time steps after ensemble final time */
+      j = -1;
+      while (t<=pfi->dnum[3]) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      e++; ens++;
+    }
+    pfi->fnumc = 0;
+    pfi->fnume = 0;
+  }
+  fclose (descr);
+  if (pdfi) fclose(pdfi);
+
+  return(0);
+
+ errm:
+  gaprnt(0,"Open Error: Invalid pdef record.\n");
+  pfi->ppflag = 0;
+  goto err9;
+
+ err1:
+  gaprnt (0,"Open Error:  Missing or invalid dimension size.\n");
+  goto err9;
+
+ err2:
+  gaprnt (0,"Open Error:  Missing or invalid dimension");
+  gaprnt (0," scaling type\n");
+  goto err9;
+
+ err3a_tdef:
+  gaprnt (0,"Open Error:  Start Time missing in tdef card");
+  gaprnt (0," starting value\n");
+  goto err9;
+
+ err3b_tdef:
+  gaprnt (0,"Open Error:  Invalid start time in tdef card");
+  gaprnt (0," starting value\n");
+  goto err9;
+
+ err3c_tdef:
+  gaprnt (0,"Open Error:  Missing or invalid dimension");
+  gaprnt (0," starting value\n");
+  goto err9;
+
+ err3:
+  gaprnt (0,"Open Error:  Missing or invalid dimension");
+  gaprnt (0," starting value\n");
+  goto err9;
+
+ err4a_tdef:
+  gaprnt (0,"Open Error:  Time increment missing in tdef\n");
+  gaprnt (0," use 1 for single time data\n");
+  goto err9;
+
+ err4b_tdef:
+  gaprnt (0,"Open Error:  Invalid time increment in tdef\n");
+  gaprnt (0," use 1 for single time data\n");
+  goto err9;
+
+ err4c_tdef:
+  gaprnt (0,"Open Error:  0 time increment in tdef\n");
+  gaprnt (0," use 1 for single time data\n");
+  goto err9;
+
+ err5:
+  gaprnt (0,"Open Error:  Missing or invalid variable");
+  gaprnt (0," count\n");
+  goto err9;
+
+ err6:
+  gaprnt (0,"Open Error:  Invalid variable record\n");
+  goto err9;
+
+ err6a:
+  gaprnt (0,"Open Error:  Invalid x,y pair\n");
+  goto err9;
+
+ err7a: 
+  gaprnt (0,"Open Error:  EOF occurred reading ensemble names\n");
+  goto err9;
+
+ err7b:
+  gaprnt (0,"Open Error:  Blank record found in EDEF data\n");
+  goto err9;
+
+ err7c:
+  gaprnt (0,"Open Error:  Invalid ensemble grib codes\n");
+  goto err9;
+
+ err7d:
+  gaprnt (0,"Open Error:  Invalid ensemble name\n");
+  goto err9;
+
+ err7e:
+  gaprnt (0,"Open Error:  Invalid ensemble record\n");
+  goto err9;
+
+ err7f:
+  gaprnt (0,"Open Error:  Invalid ensemble keyword\n");
+  goto err9;
+
+ err8:
+  gaprnt (0,"Open Error:  Memory allocation Error in gaddes.c\n");
+  goto retrn;
+
+ err8a:
+  gaprnt (0,"Open Error:  Version 4 index file not compatible with size of off_t");
+  goto retrn;
+
+ err9:
+  gaprnt (0,"  --> The invalid description file record is: \n");
+  gaprnt (0,"  --> ");
+  gaprnt (0,mrec);
+  gaprnt (0,"\n");
+
+ retrn:
+  gaprnt (0,"  The data file was not opened. \n");
+  fclose (descr);
+  if (mflflg) fclose(mfile);
+  if (pdfi) fclose(pdfi);
+  return(1);
+
+}
+
+/* Process linear scaling args */
+
+gaint deflin (char *ch, struct gafile *pfi, gaint dim, gaint flag) {
+gadouble *vals,v1,v2;
+size_t sz;
+
+  sz = sizeof(gadouble)*6;
+  vals = (gadouble *)galloc(sz,"vals1");
+  if (vals==NULL) return (-1);
+
+  if ((ch = nxtwrd(ch))==NULL) goto err1;
+  if (getdbl(ch,&v1)==NULL) goto err1;
+  if (flag) v2 = 1.0;
+  else {
+    if ((ch = nxtwrd(ch))==NULL) goto err2;
+    if (getdbl(ch,&v2)==NULL) goto err2;
+  }
+  if (dim!=3 && v2<=0.0) goto err2;
+  *(vals)   = v2;
+  *(vals+1) = v1 - v2;
+  *(vals+2) = -999.9;
+  pfi->grvals[dim] = vals;
+  *(vals+4) = -1.0 * ( (v1-v2)/v2 );
+  *(vals+3) = 1.0/v2;
+  *(vals+5) = -999.9;
+  pfi->abvals[dim] = vals+3;
+  pfi->ab2gr[dim] = liconv;
+  pfi->gr2ab[dim] = liconv;
+  pfi->linear[dim] = 1;
+  return (0);
+
+err1:
+  gaprnt (0,"Open Error:  Missing or invalid dimension");
+  gaprnt (0," starting value\n");
+  gree(vals,"f178");
+  return (1);
+
+err2:
+  gaprnt (0,"Open Error:  Missing or invalid dimension");
+  gaprnt (0," increment value\n");
+  gree(vals,"179");
+  return (1);
+}
+
+/* Process levels values in def record */
+/* Return codes:  -1 is memory allocation error, 1 is other error */
+
+gaint deflev (char *ch, char *rec, struct gafile *pfi, gaint dim) {
+gadouble *vvs,*vals,v1;
+gaint i;
+size_t sz;
+
+  if (pfi->dnum[dim]==1) {
+    i = deflin (ch, pfi, dim, 1);
+    return (i);
+  }
+
+  sz = (pfi->dnum[dim]+5)*sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"vals2");
+  if (vals==NULL) return (-1);
+
+  vvs = vals;
+  *vvs = (gadouble)pfi->dnum[dim];
+  vvs++;
+  for (i=0; i<pfi->dnum[dim]; i++) {
+    if ( (ch = nxtwrd(ch))==NULL) {
+      if (fgets(rec,512,descr)==NULL) goto err2;
+      ch = rec;
+      while (*ch==' ' || *ch=='\t') ch++;
+      if (*ch=='\0' || *ch=='\n') goto err3;
+    }
+    if (getdbl(ch,&v1)==NULL) goto err1;
+    *vvs = v1;
+    vvs++;
+  }
+  *vvs = -999.9;
+  pfi->abvals[dim] = vals;
+  pfi->grvals[dim] = vals;
+  pfi->ab2gr[dim] = lev2gr;
+  pfi->gr2ab[dim] = gr2lev;
+  pfi->linear[dim] = 0;
+  return (0);
+
+err1:
+  gaprnt (0,"Open Error:  Invalid value in LEVELS data\n");
+  gree(vals,"f180");
+  return (1);
+
+err2:
+  gaprnt (0,"Open Error:  Unexpected EOF reading descriptor file\n");
+  gaprnt (0,"   EOF occurred reading LEVELS values\n");
+  gree(vals,"f181");
+  return (1);
+
+err3:
+  gaprnt (0,"Open Error:  Blank Record found in LEVELS data\n");
+  gree(vals,"f182");
+  return (1);
+}
+
+
+/* Process descriptor file attribute metadata. 
+   Return -1 on error. */
+gaint ddfattr (char *ch, struct gafile *pfi) {
+  struct gaattr *newattrib,*attrib;
+  
+  /* check for presence of attribute metadata */
+  if ((ch=nxtwrd(ch))==NULL ) { 
+    gaprnt (2,"Warning: Missing all required attribute fields \n"); 
+    return (-1);
+  } 
+  /* parse the attribute */
+  newattrib = parseattr(ch);
+  if (newattrib == NULL) return (-1);
+  newattrib->fromddf = 1;
+
+  /* hang the new attribute off the gafile structure */
+  if (pfi->attr) {
+    /* advance to end of chain */
+    attrib=pfi->attr;
+    while (attrib->next) attrib = attrib->next;
+    /* add new link */
+    attrib->next = newattrib;
+  }
+  else {
+    /* add first link */
+    pfi->attr = newattrib;
+  } 
+  return(0);
+}
+
+
+/* Parse attribute metadata  
+   Return NULL for error, pointer to gaattr structure if successful */
+struct gaattr *parseattr (char *ch) {
+
+  gaint jj,len,nctype;
+  char varname[512], attrtype[512], attrname[512], attrvalue[512];
+  char *ptr,*cmd;
+  void *value=NULL;
+  gafloat *fvalues;
+  gadouble dval,*dvalues;
+  long *lvalues;
+  short *svalues;
+  gaint ival;
+  struct gaattr *attrib;
+  size_t sz;
+  
+  /* check for presence of attribute metadata */
+  if ((cmd=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing all required attribute fields \n"); 
+    goto err;
+  } 
+  
+  /* get the variable name */
+  len = 0;
+  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+  for (jj=0; jj<len; jj++) varname[jj] = *(ch+jj);
+  varname[len] = '\0';
+  
+  /* get the attribute type */
+  if ( (ch=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing attribute type, name, and value \n"); 
+    goto err;
+  } 
+  len = 0;
+  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+  for (jj=0; jj<len; jj++) attrtype[jj] = *(ch+jj);
+  attrtype[len] = '\0';
+  
+  /* get the attribute name */
+  if ( (ch=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing attribute name and value \n"); 
+    goto err;
+  }
+  len = 0;
+  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+  for (jj=0; jj<len; jj++) attrname[jj] = *(ch+jj);
+  attrname[len] = '\0';
+  
+  /* Set attribute nctype if it matches OPeNDAP/NetCDF data types */
+  if (!(strncmp(attrtype,"Byte",4)) || 
+      !(strncmp(attrtype,"byte",4))) 
+    nctype = 1;
+  else if (!(strncmp(attrtype,"String",6)) || 
+	   !(strncmp(attrtype,"Str",   3)) ||
+	   !(strncmp(attrtype,"Url",   3)) ||
+	   !(strncasecmp(attrtype,"char",4))) 
+    nctype = 2; 
+  else if (!(strncmp(attrtype,"Int16", 5)) || 
+	   !(strncmp(attrtype,"UInt16",6)) || 
+	   !(strncasecmp(attrtype,"short",5))) 
+    nctype = 3;
+  else if (!(strncmp(attrtype,"Int32", 5)) || 
+	   !(strncmp(attrtype,"UInt32",6)) ||
+	   !(strncasecmp(attrtype,"int",3)) || 
+	   !(strncasecmp(attrtype,"long",4))) 
+    nctype = 4;
+  else if (!(strncmp(attrtype,"Float32",7)) ||
+	   !(strncasecmp(attrtype,"float",5))) 
+    nctype = 5;
+  else if (!(strncmp(attrtype,"Float64",7)) ||
+	   !(strncasecmp(attrtype,"double",6))) 
+    nctype = 6;
+  else 
+    nctype = 0;
+  
+  /* get the attribute value */
+  if ( (ch=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing attribute value \n"); 
+    goto err;
+  } 
+  getstr (attrvalue, ch, 512);
+  ptr = ch;
+
+  /* Get attribute length*/  
+  if (nctype <= 2) {
+    len=strlen(attrvalue);
+  }
+  else {
+    /* find total number of comma-delimited numerals */
+    jj = 0;          
+    while (1) {
+      if ((ptr=getdbl(ptr,&dval))==NULL) break;      
+      jj++;  
+      /* advance through comma-delimited list of levels args */
+      while (*ptr==' ') ptr++;               /* advance past whitespace */
+      if (*ptr=='\0' || *ptr=='\n') break;   
+      if (*ptr!=',') break;
+      ptr++;                                /* advance past comma */
+      while (*ptr==' ') ptr++;               /* advance past whitespace */
+      if (*ptr=='\0' || *ptr=='\n') break;
+    }
+    len = jj;
+  }
+
+  /* allocate space for the attribute value */
+  if (nctype <= 2) {
+    sz = (len+1) * sizeof(char);
+    if ((value = (void *)galloc(sz,"valuec")) == NULL) {
+       gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+       goto err;
+    }
+    strcpy(value,attrvalue);
+  } else if (nctype == 3) {
+    sz = len * sizeof(short);
+    if ((svalues = (short *)galloc(sz,"values")) == NULL) {
+       gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+       goto err;
+    }
+    value = (void*)svalues;
+    ptr = &attrvalue[0];  
+    for (jj=0;jj<len;jj++) {
+      if ((ptr=intprs(ptr,&ival)) == NULL) {
+       gaprnt (0,"Error: failed to parse int attribute metadata\n");
+       goto err;
+      }
+      *svalues = (short)ival;
+      svalues++;
+      ptr++;    /* advance past the comma */
+    }
+  } else if (nctype == 4) {
+    sz = len * sizeof(long);
+    if ((lvalues = (long *)galloc(sz,"valuel")) == NULL) {
+       gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+       goto err;
+    }
+    value = (void*)lvalues;
+    ptr = &attrvalue[0];  
+    for (jj=0;jj<len;jj++) {
+      if ((ptr=intprs(ptr,&ival)) == NULL) {
+       gaprnt (0,"Error: failed to parse int attribute metadata\n");
+       goto err;
+      }
+      *lvalues = (long)ival;
+      lvalues++;
+      ptr++;    /* advance past the comma */
+    }
+  } else if (nctype == 5) {
+    sz = len * sizeof(gafloat);
+    if ((fvalues = (gafloat *)galloc(sz,"valuef")) == NULL) {
+       gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+       goto err;
+    }
+    value = (void*)fvalues;
+    ptr = &attrvalue[0];  
+    for (jj=0;jj<len;jj++) {
+      if ((ptr=getdbl(ptr,&dval)) == NULL) {
+       gaprnt (0,"Error: failed to parse float attribute metadata\n");
+       goto err;
+      }
+      *fvalues = (gafloat)dval;
+      fvalues++;
+      ptr++;    /* advance past the comma */
+    }
+  } else if (nctype == 6) {
+    sz = len * sizeof(gadouble);
+    if ((dvalues = (void *)galloc(sz,"valued")) == NULL) {
+       gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+       goto err;
+    }
+    value = (void*)dvalues;
+    ptr = &attrvalue[0];  
+    for (jj=0;jj<len;jj++) {
+      if ((ptr=getdbl(ptr,&dval)) == NULL) {
+       gaprnt (0,"Error: failed to parse double attribute metadata\n");
+       goto err;
+      }
+      *dvalues = dval;
+      dvalues++;
+      ptr++;    /* advance past the comma */
+    }
+  } 
+  else {
+    snprintf(pout,255,"Error: attribute data type not handled: nctype = %d \n",nctype);
+    gaprnt(0,pout);
+    goto err;
+  }
+  
+  /* Everything parsed and allocated OK, so allocate and populate a gaattr structure */
+  sz = sizeof(struct gaattr);
+  attrib = (struct gaattr *) galloc(sz,"attrib");
+  if (attrib != NULL) {
+    strcpy(attrib->varname,varname);
+    strcpy(attrib->name,attrname);
+    strcpy(attrib->type,attrtype);
+    attrib->nctype = nctype;
+    attrib->len = len;
+    attrib->value = value;
+    attrib->fromddf = 0;
+    attrib->next = NULL;
+  } else {
+    gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+    goto err;
+  }
+  /* return the pointer to the attribute structure */
+  return attrib;
+
+ err:
+  if (value) gree(value,"f184");
+  return(NULL);
+}
+ 
+
+/* Allocate and initialize a gafile structure */
+
+struct gafile *getpfi (void) {
+struct gafile *pfi;
+gaint i;
+size_t sz;
+
+  sz = sizeof(struct gafile);
+  pfi = (struct gafile *)galloc(sz,"pfi");
+  if (pfi==NULL) return (NULL);
+
+  pfi->type = 1;         /* Assume grid unless told otherwise */
+  pfi->tlpflg = 0;       /* Assume file not circular */
+  pfi->bswap = 0;        /* Assume no byte swapping needed */
+  pfi->seqflg = 0;       /* Assume direct access */
+  pfi->yrflg = 0;        /* Assume south to north */
+  pfi->zrflg = 0;        /* Assume bottom to top */
+  pfi->idxflg = 0;       /* Assume binary */
+  pfi->ncflg = 0;        /* Assume not netcdf */
+  pfi->bufrflg = 0;      /* Assume not bufr */
+  pfi->ncid = -999;      /* No netcdf file open */
+  pfi->sdid = -999;      /* No hdfsds file open */
+  pfi->h5id = -999;      /* No hdf5 file open */
+  pfi->fhdr = 0;         /* Assume no file header */
+  pfi->xyhdr=0;          /* Assume no xyheader */
+  pfi->fseq = -999;      /* No sequence number assigned */
+  pfi->dhandle = -999;   /* Assume not a gadods stn data set */
+  pfi->packflg = 0;      /* Assume data are not packed */
+  pfi->undefattrflg = 0; /* Assume no undef attribute name given */
+  pfi->pa2mb = 0;        /* Assume pressure values are given in mb */
+  pfi->undef = -9.99e8; 
+  pfi->ppisiz = 0;
+  pfi->ppjsiz = 0;
+  pfi->bufrinfo = NULL;
+  pfi->bufrdset = NULL;
+  pfi->attr = NULL;
+  pfi->scattr = NULL;   
+  pfi->ofattr = NULL;   
+  pfi->undefattr = NULL;   
+  pfi->tempname = NULL;
+  pfi->mnam = NULL;
+  pfi->infile = NULL;
+  pfi->rbuf = NULL;
+  pfi->sbuf = NULL;
+  pfi->pbuf = NULL;
+  pfi->bbuf = NULL;
+  pfi->ubuf = NULL;
+  pfi->tstrt = NULL;
+  pfi->tcnt = NULL;
+  pfi->mfile = NULL;
+  pfi->vnum = 0;
+  pfi->pvar1 = NULL;
+  pfi->ens1 = NULL;
+  pfi->pindx = NULL;
+  pfi->pindxb = NULL;
+  pfi->fnums = NULL;
+  pfi->pchsub1 = NULL;
+#if GRIB2
+  pfi->g2indx = NULL;
+#endif
+  pfi->wrap = 0;        /* Assume no wrapping */
+  for (i=0; i<5; i++) pfi->dimoff[i] = 0;
+  pfi->title[0] = '\0';
+  pfi->grvals[0] = NULL;
+  pfi->grvals[1] = NULL;
+  pfi->grvals[2] = NULL;
+  pfi->grvals[3] = NULL;
+  pfi->grvals[4] = NULL;
+  pfi->grbgrd = -999;
+  pfi->tmplat = 0;
+  pfi->errcnt = 0;
+  pfi->errflg = 0;
+  pfi->ppflag = 0;  /* Assume lat-lon grid */
+  pfi->ppwrot = 0;  /* Assume no wind rotataion */
+  pfi->pdefgnrl = 0; 
+  for (i=0; i<9; i++) pfi->ppi[i] = NULL;
+  for (i=0; i<9; i++) pfi->ppf[i] = NULL;
+  pfi->ppw = NULL;
+  pfi->calendar=0;
+  pfi->nsdfdims = 0; 
+  for (i=0; i<100; i++) pfi->sdfdimids[i]=-1;
+  for (i=0; i<100; i++) pfi->sdfdimsiz[i]=-1;
+  for (i=0; i<100; i++) pfi->sdfdimnam[i][0]='\0';
+  pfi->cachesize = -1;   /* if <0, a good default cache size has not been calcuated */
+  return (pfi);
+}
+
+/* Free a gafile structure and associated storage.  If the flag is
+   true, DO NOT free the storage related to scaling transforms,
+   since someone, somewhere,  may still be pointing to that. */
+
+void frepfi (struct gafile *pfi, gaint flag) {
+struct gaattr *attrib, *nextattrib;
+struct gaindx *pindx;
+struct gaindxb *pindxb;
+#if GRIB2
+struct gag2indx *g2indx;
+#endif
+struct gachsub *pchsub,*pch2;
+gaint i;
+
+/* these are listed in the order in which they appear in the pfi declaration in grads.h */
+  if (pfi->tempname) gree(pfi->tempname,"f56");
+  if (pfi->mnam)   gree(pfi->mnam,"f57");
+  if (pfi->rbuf)   gree(pfi->rbuf,"f58");
+  if (pfi->sbuf)   gree(pfi->sbuf,"f58");
+  if (pfi->pbuf)   gree(pfi->pbuf,"f59");
+  if (pfi->bbuf)   gree(pfi->bbuf,"f60");
+  if (pfi->ubuf)   gree(pfi->ubuf,"f61");
+  if (pfi->tstrt)  gree(pfi->tstrt,"f62");
+  if (pfi->tcnt)   gree(pfi->tcnt,"f63");
+  if (pfi->pvar1)  gree(pfi->pvar1,"f64");
+  if (pfi->ens1)   gree(pfi->ens1,"f65");
+  for (i=0; i<9; i++) if (pfi->ppi[i]) gree(pfi->ppi[i],"f66");
+  for (i=0; i<9; i++) if (pfi->ppf[i]) gree(pfi->ppf[i],"f67");
+  if (pfi->ppw) gree(pfi->ppw,"f68");
+  if (!flag) for (i=0; i<5; i++) {
+    if (pfi->grvals[i]) gree(pfi->grvals[i],"f69");
+  }
+  if (pfi->pindx) {
+    pindx = pfi->pindx;
+    if (pindx->hipnt)  gree(pindx->hipnt,"f70");
+    if (pindx->hfpnt)  gree(pindx->hfpnt,"f71");
+    if (pindx->intpnt) gree(pindx->intpnt,"f72");
+    if (pindx->fltpnt) gree(pindx->fltpnt,"f73");
+    gree(pindx,"f74");
+  }
+  if (pfi->pindxb) {
+    pindxb = pfi->pindxb;
+    if (pindxb->bigpnt)  gree(pindxb->bigpnt,"b98");
+    gree(pindxb,"b99");
+  }
+#if GRIB2
+  if (pfi->g2indx) {
+    g2indx = pfi->g2indx;
+    if (g2indx->g2intpnt) gree(g2indx->g2intpnt,"f75");
+    if (g2indx->g2bigpnt) gree(g2indx->g2bigpnt,"b75");
+    gree(g2indx,"f76");
+  }
+#endif
+  if (pfi->fnums)  gree(pfi->fnums,"f77");
+  pchsub = pfi->pchsub1;
+  while (pchsub) {
+    if (pchsub->ch) gree(pchsub->ch,"f78");
+    pch2 = pchsub->forw;
+    gree(pchsub,"f79");
+    pchsub = pch2;
+  }
+  if (pfi->scattr) gree(pfi->scattr,"f80");
+  if (pfi->ofattr) gree(pfi->ofattr,"f81");
+  if (pfi->undefattr) gree(pfi->undefattr,"f82");
+  if (pfi->bufrinfo) gree(pfi->bufrinfo,"f83");
+#ifndef STNDALN
+  if (pfi->bufrdset) gabufr_close(pfi->bufrdset);
+#endif
+  while (pfi->attr != NULL) {
+    /* point to first block in chain */
+    attrib = pfi->attr;  
+    if (attrib->next == NULL) {
+      /* first block is only block */
+      pfi->attr = NULL; 
+    }
+    else {
+      /* move start of chain from 1st to 2nd block */
+      nextattrib = attrib->next;
+      pfi->attr = nextattrib;
+    }
+    /* release memory from 1st block */
+    if (attrib->value) gree(attrib->value,"f85");
+    gree(attrib,"f86");
+  }
+  gree(pfi,"f87");
+}
+
+
+/* Routine to calculate or input the interpolation constants needed for
+   the implicit interpolation from pre-projected grids to lat-lon. */
+
+gaint gappcn (struct gafile *pfi, gaint pdefop1, gaint pdefop2) {
+gaint size,i,j,ii,jj;
+gadouble lat,lon,rii,rjj;
+gadouble *dx, *dy, *dw, dum;
+gadouble pi;
+gafloat *fvals=NULL;
+gaint *ioff, rdw, rc, pnum, wflg;
+size_t sz;
+
+  dw=NULL;
+  size = pfi->dnum[0]*pfi->dnum[1];
+
+  /* Allocate space needed for the ppi and ppf grids */
+  if (pfi->ppflag != 8) {
+    sz = sizeof(gaint)*size;
+    if ((pfi->ppi[0] = (gaint*)galloc(sz,"ppi0")) == NULL) goto merr;
+    sz = sizeof(gadouble)*size;
+    if ((pfi->ppf[0] = (gadouble*)galloc(sz,"ppf0")) == NULL) goto merr;
+    sz = sizeof(gadouble)*size;
+    if ((pfi->ppf[1] = (gadouble*)galloc(sz,"ppf1")) == NULL) goto merr;
+    if (pfi->ppwrot) {
+      sz = sizeof(gadouble)*size;
+      if ((pfi->ppw  = (gadouble *)galloc(sz,"ppw")) == NULL) goto merr;
+    }
+  }
+
+  /* pdef bilin */
+  if (pfi->ppflag==7) {
+    /* allocate memory to temporarily store array of floats to be read from pdef file */
+    sz = sizeof(gafloat)*size;
+    if ((fvals = (gafloat*)galloc(sz,"ppfvals")) == NULL) goto merr;
+
+    if (pdefop1==2) {  /* sequential -- read the 4-byte header */
+      rc = fread(&rdw, sizeof(gaint), 1, pdfi);
+      if (rc!=1) goto merr2;
+    }
+
+    /* read the grid of pdef ivals into fvals array */
+    rc = fread(fvals, sizeof(gafloat), size, pdfi); if (rc!=size) goto merr2; 
+    /* byte swap if necessary */
+    if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) gabswp (fvals,size);
+    /* cast to doubles */
+    for (i=0; i<size; i++) *(pfi->ppf[0]+i) = (gadouble)fvals[i];
+
+    if (pdefop1==2) {  /* sequential -- read the 4-byte footer and next header */
+      rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2;
+      rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2;
+    }
+ 
+    /* read the grid of pdef jvals into fvals array */
+    rc = fread(fvals, sizeof(gafloat), size, pdfi); if (rc!=size) goto merr2;
+    /* byte swap if necessary */
+    if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) gabswp (fvals,size);
+    /* cast to doubles */
+    for (i=0; i<size; i++) *(pfi->ppf[1]+i) = (gadouble)fvals[i];
+
+    if (pdefop1==2) {  /* sequential -- read the 4-byte footer and next header */
+      rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2;
+      rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2;
+    }
+
+    /* read the grid of wind rotation vals */
+    rc = fread(fvals, sizeof(gafloat), size, pdfi); if (rc!=size) goto merr2;
+    /* byte swap if necessary */
+    if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) gabswp (fvals,size);
+    /* cast to doubles */
+    for (i=0; i<size; i++) *(pfi->ppw+i) = (gadouble)fvals[i];
+
+    /* Fill grids of file offsets and weights (dx,dy) for pdef grid interpolation */
+    ioff = pfi->ppi[0];
+    dx = pfi->ppf[0];
+    dy = pfi->ppf[1];
+    dw = pfi->ppw;
+    wflg = 0;
+    for (j=0; j<pfi->dnum[1]; j++) {
+      for (i=0; i<pfi->dnum[0]; i++) {
+        if (*dx < 0.0) *ioff = -1;
+        else {
+	  /* ii and jj are integer parts of i and j values read from pdef bilin file */
+          ii = (gaint)(*dx);
+          jj = (gaint)(*dy);
+	  /* dx and dy are now the remainder after the integer part is subtracted out */
+          *dx = *dx - (gadouble)ii;
+          *dy = *dy - (gadouble)jj;
+	  /* if ii and jj values are outside the native grid, they are not used */
+          if (ii<1 || ii>pfi->ppisiz-1 || jj<1 || jj>pfi->ppjsiz-1) {
+            *ioff = -1;
+          } else {
+	    /* ioff index values (pfi->ppi) start from 0 instead of 1 */
+            *ioff = (jj-1)*pfi->ppisiz + ii - 1;
+          }
+        }
+        if (fabs(*dw) > 0.00001) wflg = 1;
+        ioff++; dx++; dy++, dw++;
+      }
+    }
+    pfi->ppwrot = wflg;
+
+  /* When pdef is a file, read in the offsets of the points to use and their weights, 
+     as well as the array of wind rotation values to use */
+
+  } else if (pfi->ppflag==8) {
+    pnum = (gaint)(pfi->ppvals[0]+0.1);
+    /* allocate memory for array of floats to be read from pdef file */
+    sz = sizeof(gafloat)*size;
+    if ((fvals = (gafloat*)galloc(sz,"ppfvals")) == NULL) goto merr;
+
+    /* get weights and offsets from pdef file */
+    for (i=0; i<pnum; i++) {
+      /* allocate memory for the array of offsets */
+      sz = sizeof(gaint)*size;
+      if ((pfi->ppi[i] = (gaint*)galloc(sz,"ppi3")) == NULL) goto merr;
+      /* sequential -- header */
+      if (pdefop1==2) { rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2; }
+      /* read the offsets */
+      rc = fread(pfi->ppi[i], sizeof(gaint), size, pdfi); if (rc!=size) goto merr2;
+      /* byte swap if necessary */
+      if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) 
+	gabswp((gafloat *)(pfi->ppi[i]),size);
+      /* sequential -- footer */
+      if (pdefop1==2) { rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2; }
+ 
+      /* allocate memory for array of weights */
+      sz = sizeof(gadouble)*size;
+      if ((pfi->ppf[i] = (gadouble*)galloc(sz,"ppf2")) == NULL) goto merr;
+      /* sequential -- header */
+      if (pdefop1==2) { rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2; }
+      /* read the floating-point weights */
+      rc = fread(fvals, sizeof(gafloat), size, pdfi); if (rc!=size) goto merr2;
+      /* byte swap if necessary */
+      if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) gabswp(fvals,size);
+      /* cast to doubles */
+      for (j=0; j<size; j++) *(pfi->ppf[i]+j) = (gadouble)fvals[j];
+      /* sequential -- footer */
+      if (pdefop1==2) { rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2; }
+    }
+
+    /* allocate memory and read in the wind rotation values */
+    sz = sizeof(gadouble)*size;
+    if ((pfi->ppw = (gadouble *)galloc(sz,"ppw2")) == NULL) goto merr;
+    /* sequential -- header */
+    if (pdefop1==2) { rc = fread(&rdw, sizeof(gaint), 1, pdfi); if (rc!=1) goto merr2; }
+    rc = fread(fvals, sizeof(gafloat), size, pdfi); if (rc!=size) goto merr2;
+    /* byte swap if necessary */
+    if ((pdefop2==2 && !BYTEORDER) || (pdefop2==3 &&  BYTEORDER)) gabswp(fvals,size);
+    /* cast to doubles */
+    for (i=0; i<size; i++) *(pfi->ppw+i) = (gadouble)fvals[i];
+
+    /* set wind rotation flag */
+    dw = pfi->ppw;
+    wflg = 0;
+    for (i=0; i<size; i++) {
+      if (fabs(*dw) > 0.00001) wflg = 1;
+      dw++;
+    }
+    pfi->ppwrot = wflg;
+    
+    /* If native data is grib, and the "pdef file" keyword is used,
+       then the offsets in the file are assumed to be 0-based.
+       The code in gaprow() expects 1-based offsets, so we add 1
+       and check to make sure offsets don't exceed isize*jsize. */
+    if (pfi->idxflg && pfi->type==1 && pfi->pdefgnrl==0) {
+      for (i=0; i<pnum; i++) {
+	for (j=0; j<size; j++) {
+	  if (*(pfi->ppi[i]+j) == pfi->ppisiz * pfi->ppjsiz) {
+	    gaprnt (0,"PDEF FILE Error: The offsets in the pdef file for native \n");
+	    gaprnt (0,"  GRIB data must be 0-based (i.e., >= 0 and < isize*jsize). \n"); 
+	    gaprnt (0,"  Use the PDEF GENERAL keyword for 1-based file offsets.\n"); 
+	    goto err;
+	  }
+	  *(pfi->ppi[i]+j) = 1 + *(pfi->ppi[i]+j);
+	}
+      }
+    }
+    /* If native data is NOT grib, and the "pdef file" keyword is used,
+       then the offsets in the file are assumed to be 1-based.
+       The code in gaprow() expects 1-based offsets, so we just
+       check to make sure offsets don't equal 0. */
+    if (pfi->idxflg==0 && pfi->type==1 && pfi->pdefgnrl==0) {
+      for (i=0; i<pnum; i++) {
+	for (j=0; j<size; j++) {
+	  if (*(pfi->ppi[i]+j) == 0) {
+	    gaprnt (0,"PDEF FILE Error: The offsets in the pdef file \n");
+	    gaprnt (0,"  must be 1-based (i.e., > 0 and <= isize*jsize). \n"); 
+	    goto err;
+	  }
+	}
+      }
+    }
+    /* The "pdef general" keyword means the offsets in the file are always 1-based.
+       Check to make sure offsets don't equal 0. */
+    if (pfi->pdefgnrl==1) {
+      for (i=0; i<pnum; i++) {
+	for (j=0; j<size; j++) {
+	  if (*(pfi->ppi[i]+j) == 0) {
+	    gaprnt (0,"PDEF GENERAL Error: The offsets in the pdef file \n");
+	    gaprnt (0,"  must be 1-based (i.e., > 0 and <= isize*jsize). \n"); 
+	    goto err;
+	  }
+	}
+      }
+    }
+
+  } /* matches  else if (pfi->ppflag==8) */
+
+  else {
+
+    /* When a supported projection is specified, calculate 
+       three constants at each lat-lon grid point: offset 
+       of the ij gridpoint, and the delta x and delta y values. */
+    
+    pi = M_PI;
+    ioff = pfi->ppi[0];
+    dx = (gadouble*)pfi->ppf[0];
+    dy = (gadouble*)pfi->ppf[1];
+    if (pfi->ppwrot) dw = (gadouble*)pfi->ppw;
+    /* get i,j values in preprojected grid for each lat/lon point */
+    for (j=0; j<pfi->dnum[1]; j++) {
+      lat = pfi->gr2ab[1](pfi->grvals[1],(gadouble)(j+1));
+      for (i=0; i<pfi->dnum[0]; i++) {
+        lon = pfi->gr2ab[0](pfi->grvals[0],(gadouble)(i+1));
+	if (pfi->ppflag==3) {             
+	  if (pfi->ppwrot) {               /* PDEF lccr */
+	    ll2lc (pfi->ppvals, lat, lon, &rii, &rjj, dw);   
+	  } 
+	  else {                           /* PDEF lcc */
+	    ll2lc (pfi->ppvals, lat, lon, &rii, &rjj, &dum);
+	  }
+        } 
+	else if (pfi->ppflag==4) {         /* PDEF eta.u */
+          ll2eg (pfi->ppisiz,pfi->ppjsiz,pfi->ppvals, lon, lat, &rii, &rjj, dw);
+        } 
+	else if (pfi->ppflag==5) {         /* PDEF pse */
+          ll2pse (pfi->ppisiz,pfi->ppjsiz,pfi->ppvals, lon, lat, &rii, &rjj);
+        } 
+	else if (pfi->ppflag==6) {         /* PDEF ops */  
+          ll2ops (pfi->ppvals, lon, lat, &rii, &rjj);
+        } 
+	else if (pfi->ppflag==9) {         
+	  if(pfi->ppwrot) {                /* PDEF rotllr */
+	    ll2rotll (pfi->ppvals, lat, lon, &rii, &rjj, dw);
+	  } else {                         /* PDEF rotll */
+	    ll2rotll (pfi->ppvals, lat, lon, &rii, &rjj, &dum);
+	  }
+	}
+	else {                             /* PDEF nps and sps */
+	  w3fb04(lat, -1.0*lon, pfi->ppvals[3], -1.0*pfi->ppvals[2], &rii, &rjj);
+          rii = rii + pfi->ppvals[0];  /* Normalize based on pole point */ 
+          rjj = rjj + pfi->ppvals[1];
+          *dw = (pfi->ppvals[2]-lon) * pi/180.0;  /* wind rotation amount */
+          if (pfi->ppflag==2) *dw = pi - *dw;
+        }
+        ii = (gaint)rii;
+        jj = (gaint)rjj;
+        *dx = rii - (gadouble)ii;
+        *dy = rjj - (gadouble)jj;
+        if (ii<1 || ii>pfi->ppisiz-1 || 
+	    jj<1 || jj>pfi->ppjsiz-1) {
+          *ioff = -1;
+        } else {
+          *ioff = (jj-1)*pfi->ppisiz + ii - 1;
+        }
+	ioff++; dx++; dy++;
+        if (pfi->ppwrot) dw++;
+      }
+    }
+  }
+  if (fvals!=NULL) gree(fvals,"f80g");
+  return(0);
+
+merr:
+  gaprnt (0,"Open Error:  Memory allocation error in pdef handler\n");
+  goto err;
+merr2:
+  gaprnt (0,"Open Error:  I/O Error on pdef file read\n");
+  goto err;
+
+err:
+  if (pfi->ppi[0]!=NULL) gree(pfi->ppi[0],"f80a");
+  if (pfi->ppf[0]!=NULL) gree(pfi->ppf[0],"f80c");
+  if (pfi->ppf[1]!=NULL) gree(pfi->ppf[1],"f80d");
+  if (pfi->ppwrot && pfi->ppw!=NULL) gree(pfi->ppw,"f80e");
+  if (fvals!=NULL) gree(fvals,"f80f");
+  return(1);
+
+}
+
+void w3fb04 (gadouble alat, gadouble along, gadouble xmeshl, gadouble orient,
+     gadouble *xi, gadouble *xj) {
+
+/*
+C
+C SUBPROGRAM: W3FB04         LATITUDE, LONGITUDE TO GRID COORDINATES
+C   AUTHOR: MCDONELL,J.      ORG: W345       DATE: 90-06-04
+C
+C ABSTRACT: CONVERTS THE COORDINATES OF A LOCATION ON EARTH FROM THE
+C   NATURAL COORDINATE SYSTEM OF LATITUDE/LONGITUDE TO THE GRID (I,J)
+C   COORDINATE SYSTEM OVERLAID ON A POLAR STEREOGRAPHIC MAP PRO-
+C   JECTION TRUE AT 60 DEGREES N OR S LATITUDE. W3FB04 IS THE REVERSE
+C   OF W3FB05.
+C
+C PROGRAM HISTORY LOG:
+C   77-05-01  J. MCDONELL
+C   89-01-10  R.E.JONES   CONVERT TO MICROSOFT FORTRAN 4.1
+C   90-06-04  R.E.JONES   CONVERT TO SUN FORTRAN 1.3
+C   93-01-26  B. Doty     converted to C
+C
+C USAGE:  CALL W3FB04 (ALAT, ALONG, XMESHL, ORIENT, XI, XJ)
+C
+C   INPUT VARIABLES:
+C     NAMES  INTERFACE DESCRIPTION OF VARIABLES AND TYPES
+C     ------ --------- -----------------------------------------------
+C     ALAT   ARG LIST  LATITUDE IN DEGREES (<0 IF SH)
+C     ALONG  ARG LIST  WEST LONGITUDE IN DEGREES
+C     XMESHL ARG LIST  MESH LENGTH OF GRID IN KM AT 60 DEG LAT(<0 IF SH)
+C                   (190.5 LFM GRID, 381.0 NH PE GRID,-381.0 SH PE GRID)
+C     ORIENT ARG LIST  ORIENTATION WEST LONGITUDE OF THE GRID
+C                   (105.0 LFM GRID, 80.0 NH PE GRID, 260.0 SH PE GRID)
+C
+C   OUTPUT VARIABLES:
+C     NAMES  INTERFACE DESCRIPTION OF VARIABLES AND TYPES
+C     ------ --------- -----------------------------------------------
+C     XI     ARG LIST  I OF THE POINT RELATIVE TO NORTH OR SOUTH POLE
+C     XJ     ARG LIST  J OF THE POINT RELATIVE TO NORTH OR SOUTH POLE
+C
+C   SUBPROGRAMS CALLED:
+C     NAMES                                                   LIBRARY
+C     ------------------------------------------------------- --------
+C     COS SIN                                                 SYSLIB
+C
+C   REMARKS: ALL PARAMETERS IN THE CALLING STATEMENT MUST BE
+C     REAL. THE RANGE OF ALLOWABLE LATITUDES IS FROM A POLE TO
+C     30 DEGREES INTO THE OPPOSITE HEMISPHERE.
+C     THE GRID USED IN THIS SUBROUTINE HAS ITS ORIGIN (I=0,J=0)
+C     AT THE POLE IN EITHER HEMISPHERE, SO IF THE USER'S GRID HAS ITS
+C     ORIGIN AT A POINT OTHER THAN THE POLE, A TRANSLATION IS NEEDED
+C     TO GET I AND J. THE GRIDLINES OF I=CONSTANT ARE PARALLEL TO A
+C     LONGITUDE DESIGNATED BY THE USER. THE EARTH'S RADIUS IS TAKEN
+C     TO BE 6371.2 KM.
+C
+C ATTRIBUTES:
+C   LANGUAGE: SUN FORTRAN 1.4
+C   MACHINE:  SUN SPARCSTATION 1+
+C*/
+
+static gadouble d2r = M_PI/180.0;
+static gadouble earthr = 6371.2;
+
+gadouble re,xlat,wlong,r;
+
+      re   = (earthr * 1.86603) / xmeshl;
+      xlat = alat * d2r;
+
+      if (xmeshl>0.0) {
+        wlong = (along + 180.0 - orient) * d2r;
+        r     = (re * cos(xlat)) / (1.0 + sin(xlat));
+        *xi    = r * sin(wlong);
+        *xj    = r * cos(wlong);
+
+      } else {
+
+        re    = -re;
+        xlat =  -xlat;
+        wlong = (along - orient) * d2r;
+        r     = (re * cos(xlat)) / (1.0+ sin(xlat));
+        *xi   =  r * sin(wlong);
+        *xj   = -r * cos(wlong);
+      }
+}
+
+/* Lambert conformal conversion */
+
+void ll2lc (gadouble *vals, gadouble grdlat, gadouble grdlon, gadouble *grdi, gadouble *grdj, gadouble *wrot) {
+
+/*  Subroutine to convert from lat-lon to lambert conformal i,j.
+    Provided by NRL Monterey; converted to C 6/15/94.
+
+c          SUBROUTINE: ll2lc
+c
+c          PURPOSE: To compute i- and j-coordinates of a specified
+c                   grid given the latitude and longitude points.
+c                   All latitudes in this routine start
+c                   with -90.0 at the south pole and increase
+c                   northward to +90.0 at the north pole.  The
+c                   longitudes start with 0.0 at the Greenwich
+c                   meridian and increase to the east, so that
+c                   90.0 refers to 90.0E, 180.0 is the inter-
+c                   national dateline and 270.0 is 90.0W.
+c
+c          INPUT VARIABLES:
+c
+c  vals+0    latref: latitude at reference point (iref,jref)
+c 		    
+c  vals+1    lonref: longitude at reference point (iref,jref)
+c 		    
+c  vals+2    iref:   i-coordinate value of reference point
+c 		    
+c  vals+3    jref:   j-coordinate value of reference point
+c 		    
+c  vals+4    stdlt1: standard latitude of grid (S True lat)
+c 		    
+c  vals+5    stdlt2: second standard latitude of grid (only required
+c                    if igrid = 2, lambert conformal) (N True lat)
+c 		    
+c  vals+6    stdlon: standard longitude of grid (longitude that
+c                     points to the north)
+c 		    
+c  vals+7    delx:   grid spacing of grid in x-direction
+c                    for igrid = 1,2,3 or 4, delx must be in meters
+c                    for igrid = 5, delx must be in degrees
+c 		    
+c  vals+8    dely:   grid spacing (in meters) of grid in y-direction
+c                    for igrid = 1,2,3 or 4, delx must be in meters
+c                    for igrid = 5, dely must be in degrees
+c
+c            grdlat: latitude of point (grdi,grdj)
+c
+c            grdlon: longitude of point (grdi,grdj)
+c
+c            grdi:   i-coordinate(s) that this routine will generate
+c                    information for
+c
+c            grdj:   j-coordinate(s) that this routine will generate
+c                    information for
+c
+*/
+
+  gadouble pi, pi2, pi4, d2r, r2d, radius, omega4;
+  gadouble gcon,ogcon,H,deg,cn1,cn2,cn3,cn4,rih,xih,yih,rrih,check;
+  gadouble alnfix,alon,x,y,windrot;
+  gadouble latref,lonref,iref,jref,stdlt1,stdlt2,stdlon,delx,dely;
+
+  pi = M_PI;
+  pi2 = pi/2.0;
+  pi4 = pi/4.0;
+  d2r = pi/180.0;
+  r2d = 180.0/pi;
+  radius = 6371229.0;
+  omega4 = 4.0*pi/86400.0;
+
+  latref = *(vals+0);    
+  lonref = *(vals+1);    
+  iref   = *(vals+2);    
+  jref   = *(vals+3);    
+  stdlt1 = *(vals+4);    
+  stdlt2 = *(vals+5);    
+  stdlon = *(vals+6);    
+  delx   = *(vals+7);    
+  dely   = *(vals+8);    
+                    
+/* case where standard lats are the same */
+/* corrected by Dan Geiszler of NRL; fabs of the 
+   lats was required for shem cases */
+
+  if (stdlt1 == stdlt2) {
+    gcon = sin(d2r*(fabs(stdlt1)));
+  } else {
+    gcon = (log(sin((90.0-fabs(stdlt1))*d2r))
+	   -log(sin((90.0-fabs(stdlt2))*d2r)))
+          /(log(tan((90.0-fabs(stdlt1))*0.5*d2r))
+           -log(tan((90.0-fabs(stdlt2))*0.5*d2r)));
+  }
+  ogcon = 1.0/gcon;
+  H = fabs(stdlt1)/(stdlt1);        /* 1 for NHem, -1 for SHem */
+  cn1 = sin((90.0-fabs(stdlt1))*d2r);
+  cn2 = radius*cn1*ogcon;
+  deg = (90.0-fabs(stdlt1))*d2r*0.5;
+  cn3 = tan(deg);
+  deg = (90.0-fabs(latref))*d2r*0.5;
+  cn4 = tan(deg);
+  rih = cn2*pow((cn4/cn3),gcon);
+
+  xih =  rih*sin((lonref-stdlon)*d2r*gcon);
+  yih = -rih*cos((lonref-stdlon)*d2r*gcon)*H;
+  deg = (90.0-grdlat*H)*0.5*d2r;
+  cn4 = tan(deg);
+  rrih = cn2*pow((cn4/cn3),gcon);
+  check  = 180.0-stdlon;
+  alnfix = stdlon+check;
+  alon   = grdlon+check;
+
+  while (alon<  0.0) alon = alon+360.0;
+  while (alon>360.0) alon = alon-360.0;
+
+  deg = (alon-alnfix)*gcon*d2r;
+  x =  rrih*sin(deg);
+  y = -rrih*cos(deg)*H;
+  *grdi = iref + (x-xih)/delx;
+  *grdj = jref + (y-yih)/dely;
+  /* mf 20040630 -- use ftp://grads.iges.org/grads/src/grib212.f to calc rotation factor */
+  windrot=gcon*(stdlon-grdlon)*d2r;
+  *wrot=windrot;
+}
+
+/* NMC eta ll to xy map  */
+
+void ll2eg (gaint im, gaint jm, gadouble *vals,  gadouble grdlon, gadouble grdlat,
+	    gadouble *grdi, gadouble *grdj, gadouble *alpha) {
+
+/*  Subroutine to convert from lat-lon to NMC eta i,j.
+
+    Provided by Eric Rogers NMC; 
+    Converted to C 3/29/95 by Mike Fiorino
+    Modified 9/2004 by J.M.Adams to correct grdi/j and alpha calculations
+
+c          SUBROUTINE: ll2eg
+c
+c          PURPOSE: To compute i- and j-coordinates of a specified
+c                   grid given the latitude and longitude points.
+c                   All latitudes in this routine start
+c                   with -90.0 at the south pole and increase
+c                   northward to +90.0 at the north pole.  The
+c                   longitudes start with 0.0 at the Greenwich
+c                   meridian and increase to the east, so that
+c                   90.0 refers to 90.0E, 180.0 is the inter-
+c                   national dateline and 270.0 is 90.0W.
+c
+c          INPUT VARIABLES:
+c
+c  vals+0    tlm0d: longitude of the reference center point
+c  vals+1    tph0d: latitude of the reference center point
+c  vals+2    dlam:  dlon grid increment in deg
+c  vals+3    dphi:  dlat grid increment in deg
+c
+c            grdlat: latitude of point (grdi,grdj)
+c            grdlon: longitude of point (grdi,grdj)
+c            grdi:   i-coordinate(s) that this routine will generate
+c                    information for
+c            grdj:   j-coordinate(s) that this routine will generate
+c                    information for
+*/
+
+  gadouble d2r,r2d, earthr;
+  gadouble tlm0d,tph0d,dlam,dphi;
+  gadouble phi,lam,lam0,phi0;
+  gadouble x,y,z,xx,bigphi,biglam;
+  gadouble dlmd,dphd,wbd,sbd;
+
+  d2r = M_PI/180.0;
+  r2d = 1.0/d2r;
+  earthr = 6371.2;
+
+  tlm0d = -*(vals+0); /* convert + W to + E, the grads standard for longitude */
+  tph0d =  *(vals+1);
+  dlam  = (*(vals+2))*0.5;
+  dphi  = (*(vals+3))*0.5;
+
+  /* convert to radians */
+  phi   =  grdlat*d2r;          /* grid latitude */
+  lam   = -grdlon*d2r;          /* grid longitude, convert +W to +E, the grads standard */
+  phi0  = tph0d*d2r;            /* center latitude  */
+  lam0  = tlm0d*d2r;            /* center longitude */
+
+  /* Transform grid lat/lon */
+  x = cos(phi0)*cos(phi)*cos(lam-lam0)+sin(phi0)*sin(phi);
+  y = -cos(phi)*sin(lam-lam0);
+  z = -sin(phi0)*cos(phi)*cos(lam-lam0)+cos(phi0)*sin(phi);
+  biglam = atan2(y,x)/d2r;                  /* transformed lon in degrees */
+  bigphi = atan2(z,sqrt(x*x+y*y))/d2r;      /* transformed lat in degrees */
+
+  /* Convert transformed lat/lon -> i,j */
+  dlmd  = (*(vals+2));
+  dphd  = (*(vals+3));
+  wbd = (-1)*0.5*(im-1)*dlmd;               /* western boundary of transformed grid */
+  sbd = (-1)*0.5*(jm-1)*dphd;               /* southern boundary of transformed grid */
+  *grdi = 1.0 + (biglam-wbd)/dlmd;
+  *grdj = 1.0 + (bigphi-sbd)/dphd;
+
+  /* params for wind rotation alpha, alpha>0 ==> counter clockwise rotation */
+  xx=sin(phi0)*sin(biglam*d2r)/cos(phi);
+  if (xx < -1.0) xx = -1.0;
+  else if (xx > 1.0) xx = 1.0;
+  *alpha = (-1)*asin(xx);
+
+}
+
+void ll2pse (gaint im, gaint jm, gadouble *vals, gadouble lon, gadouble lat,
+	     gadouble *grdi, gadouble *grdj) {
+
+
+  /* Convert from geodetic latitude and longitude to polar stereographic
+     grid coordinates.  Follows mapll by V. J. Troisi.         */
+  /* Conventions include that slat and lat must be absolute values */
+  /* The hemispheres are controlled by the sgn parameter */
+  /* Bob Grumbine 15 April 1994. */
+
+  const gadouble rearth = 6378.273e3;
+  const gadouble eccen2 = 0.006693883;
+  const gadouble pi = M_PI;
+
+  gadouble cdr, alat, along, e, e2;
+  gadouble t, x, y, rho, sl, tc, mc;
+  gadouble slat,slon,xorig,yorig,sgn,polei,polej,dx,dy;
+
+  slat=*(vals+0);
+  slon=*(vals+1);
+  polei=*(vals+2);
+  polej=*(vals+3);
+  dx=*(vals+4)*1000;
+  dy=*(vals+5)*1000;
+  sgn=*(vals+6);
+
+  xorig = -polei*dx;
+  yorig = -polej*dy;
+
+  cdr   = 180./pi;
+  alat  = lat/cdr;
+  along = lon/cdr;
+  e2 = eccen2;
+  e  = sqrt(eccen2);
+
+  if ( fabs(lat) > 90.)  {
+    *grdi = -1;
+    *grdj = -1;
+    return;
+  }
+  else {
+    t = tan(pi/4. - alat/2.) /
+      pow( (1.-e*sin(alat))/(1.+e*sin(alat)) , e/2.);
+
+    if ( fabs(90. - slat) < 1.E-3) {
+      rho = 2.*rearth*t/
+	pow( pow(1.+e,1.+e) * pow(1.-e,1.-e) , e/2.);
+    }
+    else {
+      sl = slat/cdr;
+      tc = tan(pi/4.-sl/2.) /
+	pow( (1.-e*sin(sl))/(1.+e*sin(sl)), (e/2.) );
+      mc = cos(sl)/ sqrt(1.-e2*sin(sl)*sin(sl) );
+      rho = rearth * mc*t/tc;
+    }
+
+    x = rho*sgn*cos(sgn*(along+slon/cdr));
+    y = rho*sgn*sin(sgn*(along+slon/cdr));
+
+    *grdi = (x - xorig)/dx+1;
+    *grdj = (y - yorig)/dy+1;
+
+    return;
+  }
+
+}
+
+void ll2ops(gadouble *vals, gadouble lni, gadouble lti, gadouble *grdi, gadouble *grdj) {
+
+  const gadouble radius = 6371229.0 ;
+
+  gadouble stdlat, stdlon, xref, yref, xiref, yjref, delx , dely;
+  gadouble plt,pln;
+  double pi180,c1,c2,c3,c4,c5,c6,arg2a,bb,plt1,alpha, pln1,plt90,argu1,argu2;
+  double hsign,glor,rstdlon,glolim,facpla,x,y;
+
+  stdlat = *(vals+0);
+  stdlon = *(vals+1);
+  xref = *(vals+2);
+  yref = *(vals+3);
+  xiref = *(vals+4);
+  yjref = *(vals+5);
+  delx = *(vals+6);
+  dely = *(vals+7);
+
+  c1=1.0 ;
+  pi180 = asin(c1)/90.0;
+
+  /* set flag for n/s hemisphere and convert longitude to <0 ; 360> gainterval */
+  if (stdlat >= 0.0) {
+    hsign= 1.0 ;
+  } else {
+    hsign=-1.0 ;
+  }
+
+  /* set flag for n/s hemisphere and convert longitude to <0 ; 360> interval */
+  glor=lni ;
+  if (glor <= 0.0) glor=360.0+glor ;
+  rstdlon=stdlon;
+  if (rstdlon < 0.0) rstdlon=360.0+stdlon;
+
+  /* test for a n/s pole case */
+  if (stdlat == 90.0) {
+    plt=lti ;
+    pln=fmod(glor+270.0,360.0) ;
+    goto l2000;
+  }
+
+  if (stdlat == -90.0) {
+    plt=-lti ;
+    pln=fmod(glor+270.0,360.0) ;
+    goto l2000;
+  }
+
+  /* test for longitude on 'greenwich or date line' */
+  if (glor == rstdlon) {
+    if (lti > stdlat) {
+      plt=90.0-lti+stdlat;
+      pln=90.0;
+    } else {
+      plt=90.0-stdlat+lti;
+      pln=270.0;;
+    }
+    goto l2000;
+  }
+
+  if (fmod(glor+180.0,360.0) == rstdlon) {
+    plt=stdlat-90.0+lti;
+    if (plt < -90.0) {
+      plt=-180.0-plt;
+      pln=270.0;
+    } else {
+      pln= 90.0;
+    }
+    goto l2000 ;
+  }
+
+  /* determine longitude distance relative to rstdlon so it belongs to
+     the absolute interval 0 - 180 */
+  argu1 = glor-rstdlon;
+  if (argu1 > 180.0) argu1 = argu1-360.0;
+  if (argu1 < -180.0) argu1 = argu1+360.0;
+
+  /* 1. get the help circle bb and angle alpha (legalize arguments) */
+
+  c2=lti*pi180 ;
+  c3=argu1*pi180 ;
+  arg2a = cos(c2)*cos(c3) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = max1(arg2a,-c1)  */
+  if (  c1 < arg2a ) arg2a = c1 ; /* min1(arg2a, c1)         */
+  bb = acos(arg2a) ;
+
+  c4=hsign*lti*pi180 ;
+  arg2a = sin(c4)/sin(bb) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a = c1  ; /* arg2a = dmin1(arg2a, c1) */
+  alpha = asin(arg2a) ;
+
+  /* 2. get plt and pln (still legalizing arguments) */
+  c5=stdlat*pi180 ;
+  c6=hsign*stdlat*pi180 ;
+  arg2a = cos(c5)*cos(bb) + sin(c6)*sin(c4) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a = c1  ; /* arg2a = dmin1(arg2a, c1) */
+  plt1   = asin(arg2a) ;
+
+  arg2a = sin(bb)*cos(alpha)/cos(plt1) ;
+
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+  pln1   = asin(arg2a) ;
+
+
+  /* test for passage of the 90 degree longitude (duallity in pln)
+     get plt for which pln=90 when lti is the latitude */
+  arg2a = sin(c4)/sin(c6) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+  plt90 = asin(arg2a) ;
+
+  /* get help arc bb and angle alpha */
+  arg2a = cos(c5)*sin(plt90) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+  bb    = acos(arg2a) ;
+
+  arg2a = sin(c4)/sin(bb) ;
+  if ( -c1 > arg2a ) arg2a = -c1 ; /* arg2a = dmax1(arg2a,-c1) */
+  if (  c1 < arg2a ) arg2a =  c1 ; /* arg2a = dmin1(arg2a, c1) */
+  alpha = asin(arg2a) ;
+
+  /* get glolim - it is nesc. to test for the existence of solution */
+  argu2  = cos(c2)*cos(bb) / (1.-sin(c4)*sin(bb)*sin(alpha)) ;
+  if ( fabs(argu2) > c1 ) {
+    glolim = 999.0;
+  } else {
+    glolim = acos(argu2)/pi180;
+  }
+
+  /* modify (if nesc.) the pln solution */
+  if ( ( fabs(argu1) > glolim && lti <= stdlat ) || ( lti > stdlat ) ) {
+    pln1 = pi180*180.0 - pln1;
+  }
+
+  /* the solution is symmetric so the direction must be if'ed */
+  if (argu1 < 0.0) {
+    pln1 = -pln1;
+  }
+
+  /* convert the radians to degrees */
+  plt = plt1/pi180 ;
+  pln = pln1/pi180 ;
+
+  /* to obtain a rotated value (ie so x-axis in pol.ste. points east) 
+     add 270 to longitude */
+  pln=fmod(pln+270.0,360.0) ;
+
+ l2000:
+
+/*
+c     this program convert polar stereographic coordinates to x,y ditto
+c     longitude:   0 - 360  ; positive to the east
+c     latitude : -90 -  90  ; positive for northern hemisphere
+c     it is assumed that the x-axis point towards the east and
+c     corresponds to longitude = 0
+c
+c     tsp 20/06-89
+c
+c     constants and functions
+*/
+  facpla = radius*2.0/(1.0+sin(plt*pi180))*cos(plt*pi180);
+  x = facpla*cos(pln*pi180) ;
+  y = facpla*sin(pln*pi180)  ;
+
+  *grdi=(x-xref)/delx + xiref;
+  *grdj=(y-yref)/dely + yjref;
+
+  return;
+
+}
+
+
+/* Projection definition for rotated lat/lon
+ *
+ * The transformation is done as described in the 
+ * COSMO documentation, Part 1, chapter 3.3.
+ * http://www.cosmo-model.org/public/documentation.htm
+ */
+
+void ll2rotll( gadouble *vals, gadouble grdlat, gadouble grdlon,
+		        gadouble *grdi, gadouble *grdj,  gadouble *wrot ) {
+
+  const gadouble pi = M_PI;
+  gadouble lon_pole;      /* longitude of the pole in radiants */
+  gadouble lat_pole;      /* latitude of the pole in radiants */
+  gadouble dlon;          /* longitude increment in radiants */
+  gadouble dlat;          /* latitude increment in radiants */
+  gadouble lon_ll_corner; /* longitude of the lower left corner in radiants */
+  gadouble lat_ll_corner; /* latitude of the lower left corner in radiants */
+  gadouble lon_rotated;   /* rotated longitude in radiants */
+  gadouble lat_rotated;   /* rotated latitude in radiants */
+  gadouble lon_RW;        /* real world longitude in radiants */
+  gadouble lat_RW;        /* real world latitude in radiants */
+
+  /* grab projection parameters from the pdef line */
+  lon_pole      = *(vals+0)/180.0*pi;
+  lat_pole      = *(vals+1)/180.0*pi;
+  dlon          = *(vals+2)/180.0*pi;
+  dlat          = *(vals+3)/180.0*pi;
+  lon_ll_corner = *(vals+4)/180.0*pi;
+  lat_ll_corner = *(vals+5)/180.0*pi;
+
+  lat_RW = grdlat/180*pi;
+  lon_RW = grdlon/180*pi;
+
+  /* calculate rotated longitude and latitude */
+  lat_rotated = asin(
+                   sin( lat_RW )*sin( lat_pole )
+                 + cos( lat_RW )*cos( lat_pole )
+		  *cos( lon_RW - lon_pole )
+               );
+  lon_rotated = atan(
+                   cos( lat_RW )*sin( lon_RW - lon_pole )
+		/( cos( lat_RW )*sin( lat_pole )
+		  *cos( lon_RW - lon_pole )
+                 - sin( lat_RW )*cos( lat_pole ) )
+               );
+
+  /* calculate grid point number */
+  *grdj = ( lat_rotated - lat_ll_corner )/dlat + 1;
+  *grdi = ( lon_rotated - lon_ll_corner )/dlon + 1;
+
+  /* calculate wind rotation angle */
+  *wrot = -atan(
+                cos( lat_pole )*sin( lon_pole - lon_RW )
+                /(   cos( lat_RW )*sin( lat_pole )
+                   - sin( lat_RW )*cos( lat_pole )*cos( lon_pole - lon_RW )
+                )
+              );
+}
+
diff --git a/src/gaexpr.c b/src/gaexpr.c
new file mode 100644
index 0000000..aa9c71c
--- /dev/null
+++ b/src/gaexpr.c
@@ -0,0 +1,1412 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "grads.h"
+
+static char pout[256];     /* Build error msgs here */
+static gaint pass=0;  /* Internal pass number */
+
+/* Debugging routine to print the current stack */
+
+/*
+void stkdmp (struct smem *, gaint);
+
+void stkdmp (struct smem *stack, gaint curr) {
+struct gagrid *pgr;
+gaint i;
+
+  printf ("Stack: %i\n",curr);
+  for (i=0;i<=curr;i++) {
+    printf ("->");
+    if (stack[i].type==0) {
+      pgr = stack[i].obj.pgr;
+      printf ("  Grid %g \n",*pgr->grid);
+    } else if (stack[i].type==1) {
+      printf ("  Oper %i \n",stack[i].obj.op);
+    } else if (stack[i].type==2) {
+      printf ("  Right Paren \n");
+    } else if (stack[i].type==3) {
+      printf ("  Left Paren \n");
+    } else printf ("  Unknown %i \n",stack[i].type);
+  }
+}
+*/
+
+/* Evaluate a GrADS expression.  The expression must have
+   blanks removed.  The expression is evaluated with respect
+   to the environment defined in the status block (pst).
+   This routine is invoked recursively from functions in order
+   to evaluate sub-expressions.                                  */
+
+gaint gaexpr (char *expr, struct gastat *pst) {
+struct gagrid *pgr;
+struct gastn *stn;
+struct smem *stack;
+char *ptr, *pos;
+gadouble val;
+gaint cmdlen,i,j,rc,curr;
+gaint state,cont,err;
+gaint size;
+
+  if (gaqsig()) return(1);
+  pass++;
+
+  cmdlen = strlen(expr);
+/*   size = cmdlen * ( 7 + sizeof(struct smem) ); */
+  size = sizeof(struct smem[cmdlen+10]);
+  stack = (struct smem *)malloc(size);
+  if (stack==NULL) {
+    gaprnt (0,"Memory Allocation Error:  parser stack\n");
+    return (1);
+  }
+
+  state=1;
+  curr = -1;
+  pos = expr;
+
+  cont=1; err=0;
+  while (cont) {                     /* Loop while parsing exprssn  */
+
+    if (state) {                     /* Expect operand or '('       */
+
+      if (*pos=='(') {               /* Handle left paren           */
+        curr++;
+        stack[curr].type = 2;
+        pos++;
+      }
+
+      else if (*pos=='-') {          /* Handle unary '-' operator   */
+        curr++;
+        stack[curr].type = -1;
+        stack[curr].obj.pgr = gagrvl(-1.0);
+        curr++;
+        stack[curr].type=1;  stack[curr].obj.op = 0;
+        pos++;
+      }
+
+      else if (*pos>='0' && *pos<='9') {  /* Handle numeric value   */
+        if ((ptr=getdbl(pos,&val))==NULL) {
+          cont=0; err=1;
+          i = 1 + pos - expr;
+          gaprnt (0,"Syntax Error:  Invalid numeric value\n");
+        } else {
+          curr++;
+          stack[curr].type = -1;
+          stack[curr].obj.pgr  = gagrvl(val);
+   /*     stkdmp(stack,curr);  */
+          rc = eval(0, stack, &curr);
+          if (rc) {
+            err=1; cont=0;
+          }
+          state = 0;
+          pos=ptr;
+        }
+      }
+
+      else if (*pos>='a' && *pos<='z') {  /* Handle variable        */
+        if ((ptr=varprs(pos, pst))==NULL) {
+          cont=0; err=1;
+        } else {
+          curr++;
+          if (pst->type) {
+            stack[curr].type = -1;
+            stack[curr].obj.pgr  = pst->result.pgr;
+          } else {
+            stack[curr].type = -2;
+            stack[curr].obj.stn  = pst->result.stn;
+          }
+  /*      stkdmp(stack,curr);  */
+          rc = eval(0, stack, &curr);
+          if (rc) {
+            err=1; cont=0;
+          }
+          state = 0;
+          pos=ptr;
+        }
+      }
+
+      else {
+        cont=0; err=1;
+        gaprnt (0,"Syntax Error:  Expected operand or '('\n");
+      }
+
+    } else {                         /* Expect operator or ')'      */
+
+      if (*pos==')') {               /* Handle right paren          */
+        curr++;
+        stack[curr].type = 3;
+        pos++;
+        rc = eval(0, stack, &curr);  /* Process stack         */
+        if (rc) {
+          err=1; cont=0;
+          pos--;
+        }
+      }
+
+                                     /* Handle operator             */
+
+      else if ( (*pos=='*')||(*pos=='/')||(*pos=='+')||(*pos=='-') ) {
+        curr++;
+        stack[curr].type=1;
+        if (*pos=='*') stack[curr].obj.op=0;
+        if (*pos=='/') stack[curr].obj.op=1;
+        if (*pos=='+') stack[curr].obj.op=2;
+        if (*pos=='-') {
+          stack[curr].obj.op=2;
+          curr++;
+          stack[curr].type = -1;
+          stack[curr].obj.pgr = gagrvl(-1.0);
+          curr++;
+          stack[curr].type=1;  stack[curr].obj.op = 0;
+        }
+   /*   stkdmp(stack,curr);  */
+        pos++;
+        state=1;
+      }
+
+      else {
+        gaprnt (0,"Syntax Error:  Expected operator or ')'\n");
+        cont=0; err=1;
+      }
+    }
+    if (*pos=='\0'||*pos=='\n') cont=0;
+  }
+
+  if (!err) {
+    rc = eval(1, stack, &curr);
+/*  stkdmp(stack,curr);  */
+    if (rc) {
+      err=1;
+    } else {
+      if (curr==0) {
+        if (stack[0].type == -1) {
+          pst->type = 1;
+          pst->result.pgr = stack[0].obj.pgr;
+        } else if (stack[0].type == -2) {
+          pst->type = 0;
+          pst->result.stn = stack[0].obj.stn;
+        } else {
+          gaprnt (0,"GAEXPR Logic Error Number 29\n");
+          err=1;
+        }
+      }
+      else {
+        gaprnt (0,"Syntax Error:  Unmatched Parens\n");
+        err=1;
+      }
+    }
+  }
+
+  if (err) {
+    if (pass==1) {
+      i = 1 + pos - expr;
+      snprintf(pout,255,"  Error ocurred at column %i\n",i);
+      gaprnt (0,pout);
+    }
+
+/*  release any memory still hung off the stack  */
+    for (i=0; i<curr; i++) {
+      if (stack[i].type==-1) {
+        pgr = stack[i].obj.pgr;
+        gagfre(pgr);
+      } else if (stack[i].type==-2) {
+        stn = stack[i].obj.stn;
+        for (j=0; j<BLKNUM; j++) {
+          if (stn->blks[j] != NULL) free(stn->blks[j]);
+        }
+        free(stn);
+      }
+    }
+  }
+
+  free(stack);
+  pass--;
+  return (err);
+}
+
+
+/* Evaluate the stack.  If the state is zero, then don't go
+   past an addition operation unless enclosed in parens.
+   If state is one, then do all operations to get the result.
+   If we hit an error, set up the stack pointer to insure
+   everything gets released properly.                                   */
+
+gaint eval (gaint state, struct smem *stack, gaint *cpos) {
+gaint cont,op,pflag,err,rc;
+gaint curr,curr1,curr2;
+
+  curr = *cpos;
+  err = 0;
+  cont = 1;
+  pflag = 0;
+  while (curr>0 && cont) {
+
+    /* Handle an operand in the stack.  An operand is preceded by
+       either a left paren, or an operator.  We will do an operation
+       if it is * or /, or if it is enclosed in parens, or if we
+       have hit the end of the expression.                           */
+
+    if (stack[curr].type<0) {          /* Operand?                   */
+      curr2 = curr;                    /* Remember operand           */
+      curr--;                          /* Look at prior item         */
+      if (stack[curr].type==2) {       /* Left paren?                */
+        if (pflag) {                   /* Was there a matching right?*/
+          stack[curr].type = stack[curr2].type; /* Yes, restack oprnd*/
+          stack[curr].obj = stack[curr2].obj;
+          pflag=0;                     /* Have evaluated parens      */
+        } else {                       /* If not,                    */
+          cont = 0;                    /*  stop here,                */
+          curr++;                      /*  leaving operand on stack  */
+        }
+      } else if (stack[curr].type==1) {  /* Prior item an operator?  */
+        op = stack[curr].obj.op;       /* Remember operator          */
+        curr--;                        /* Get other operand          */
+        if (stack[curr].type>0) {      /* Better be an operand       */
+          cont = 0;                    /* If not then an error       */
+          err = 1;
+          gaprnt (0,"Internal logic check 12 \n");
+        } else {                       /* Is an operand...           */
+          curr1 = curr;                /* Get the operand            */
+          if ( op<2 || pflag || state ) {             /* Operate?    */
+            rc = gaoper(stack,curr1,curr2,curr,op);   /* Yes...      */
+            if (rc) {                  /* Did we get an error?       */
+              cont = 0; err = 1;       /* Yes...  don't continue     */
+              curr+=2;                 /* Leave ptr so can free ops  */
+            }
+          } else {                     /* Don't operate...           */
+            curr+=2;                   /* Leave stuff stacked        */
+            cont = 0;                  /* Won't continue             */
+          }
+        }
+      } else {                         /* Prior item invalid         */
+        gaprnt (0,"Internal logic check 14 \n");
+        cont = 0; err = 1;
+      }
+
+    } else if (stack[curr].type==3) {  /* Current item right paren?  */
+      pflag=1;                         /* Indicate we found paren    */
+      curr--;                          /* Unstack it                 */
+
+    } else { cont=0; err=1; }          /* Invalid if not op or paren */
+  }
+  *cpos = curr;
+  return (err);
+}
+
+/* Perform an operation on two data objects.  Determine what class
+   of data we are working with and call the appropriate routine     */
+
+gaint gaoper (struct smem *stack, gaint c1, gaint c2, gaint c, gaint op) {
+struct gagrid *pgr=NULL;
+struct gastn *stn;
+
+  /* If both grids, do grid-grid operation */
+  if (stack[c1].type==-1 && stack[c2].type==-1) {
+    pgr = NULL; 
+    pgr = gagrop(stack[c1].obj.pgr, stack[c2].obj.pgr, op, 1);
+    if (pgr==NULL) return (1);
+    stack[c].type = -1;
+    stack[c].obj.pgr = pgr;
+    return (0);
+  }
+
+  /* If both stns, do stn-stn operation */
+
+  if (stack[c1].type==-2 && stack[c2].type==-2) {
+    stn = NULL; 
+    stn = gastop(stack[c1].obj.stn, stack[c2].obj.stn, op, 1);
+    if (stn==NULL) return (1);
+    stack[c].type = -2;
+    stack[c].obj.stn = stn;
+    return (0);
+  }
+
+  /* Operation between grid and stn is invalid -- unless the grid
+     is really a constant.  Check for this.  */
+
+  if (stack[c1].type == -1) pgr=stack[c1].obj.pgr;
+  if (stack[c2].type == -1) pgr=stack[c2].obj.pgr;
+  if (pgr->idim == -1 && pgr->jdim == -1) {
+    if (stack[c1].type == -2) {
+      stn = gascop (stack[c1].obj.stn, pgr->rmin, op, 0);
+    } else {
+      stn = gascop (stack[c2].obj.stn, pgr->rmin, op, 1);
+    }
+    if (stn==NULL) return (1);
+    gagfre (pgr);
+    stack[c].type = -2;
+    stack[c].obj.stn = stn;
+  } else {
+    gaprnt (0,"Operation Error: Incompatable Data Types\n");
+    gaprnt (0,"  One operand was stn data, other was grid\n");
+    return (1);
+  }
+  return (0);
+}
+
+/* Perform the operation between two grid data objects.
+   Varying dimensions must match.  Grids with fewer varying dimensions
+   are 'expanded' to match the larger grid as needed.                 */
+
+struct gagrid *gagrop (struct gagrid *pgr1, struct gagrid *pgr2,
+                       gaint op, gaint rel) {
+
+gadouble *val1, *val2;
+gaint dnum1,dnum2;
+struct gagrid *pgr;
+gaint incr,imax,omax;
+gaint i,i1,i2,swap;
+char *uval1,*uval2;
+
+  /* Figure out how many varying dimensions for each grid.            */
+
+  val1 = pgr1->grid;
+  uval1 = pgr1->umask;
+  dnum1 = 0;
+  if (pgr1->idim > -1) dnum1++;
+  if (pgr1->jdim > -1) dnum1++;
+
+  val2 = pgr2->grid;
+  uval2 = pgr2->umask;
+  dnum2 = 0;
+  if (pgr2->idim > -1) dnum2++;
+  if (pgr2->jdim > -1) dnum2++;
+
+  /* Force operand 1 (pgr1, dnum1, etc.) to have fewer varying dims.  */
+  swap = 0;
+  if (dnum2<dnum1) {
+    pgr = pgr1;
+    pgr1 = pgr2;
+    pgr2 = pgr;
+    val1 = pgr1->grid;
+    val2 = pgr2->grid;
+    uval1 = pgr1->umask;
+    uval2 = pgr2->umask;
+    swap = 1;
+    i = dnum1; dnum1 = dnum2; dnum2 = i;
+  }
+
+  /* Check the validity of the operation (same dimensions varying;
+     same absolute dimension ranges.    First do the case where there
+     are the same number of dimensions varying (dnum1=dnum2=0,1,2).   */
+
+  if (dnum1==dnum2) {
+    if (pgr1->idim != pgr2->idim || pgr1->jdim!=pgr2->jdim) goto err1;
+    i = pgr1->idim;
+    if (dnum1>0 && gagchk(pgr1,pgr2,pgr1->idim)) goto err2;
+    i = pgr1->jdim;
+    if (dnum1>1 && gagchk(pgr1,pgr2,pgr1->jdim)) goto err2;
+    incr = 0;
+    imax = pgr1->isiz * pgr1->jsiz;
+
+  /* Case where dnum1=0, dnum2=1 or 2.  */
+
+  } else if (dnum1==0) {
+    incr = pgr2->isiz * pgr2->jsiz;
+    imax = 1;
+
+  /* Case where dnum1=1, dnum2=2.  */
+
+  } else {
+    i = pgr1->idim;
+    if (gagchk(pgr1,pgr2,pgr1->idim)) goto err2;
+    if (pgr1->idim==pgr2->idim) {
+      incr = 0;
+      imax = pgr1->isiz;
+    } else if (pgr1->idim==pgr2->jdim) {
+      incr = pgr2->isiz;
+      imax = pgr1->isiz;
+    } else goto err1;
+  }
+  omax = pgr2->isiz * pgr2->jsiz;
+
+  /* Perform the operation.  Put the result in operand 2 (which is
+     always the operand with the greater number of varying
+     dimensions).  The smaller grid is 'expanded' by using incrementing
+     variables which will cause the values in the smaller grid to be
+     used multiple times as needed.                                   */
+
+  i1 = 0; i2 = 0;
+  for (i=0; i<omax; i++) {
+    if (*uval1==0 || *uval2==0) {
+      *uval2=0;
+    }
+    else {
+      if (op==2) *val2 = *val1 + *val2;
+      else if (op==0) *val2 = *val1 * *val2;
+      else if (op==1) {
+        if (swap) {
+          if (dequal(*val1,0.0,1e-08)==0) {
+	    *uval2 = 0;
+	  }
+          else {
+	    *val2 = *val2 / *val1;
+	  }
+        } else {
+          if (dequal(*val2,0.0,1e-08)==0) *uval2 = 0;
+          else *val2 = *val1 / *val2;
+        }
+      } else if (op==10) {
+        if (swap) *val2 = pow(*val2,*val1);
+        else *val2 = pow(*val1,*val2);
+      } else if (op==11)  *val2 = hypot(*val1,*val2);
+      else if (op==12) {
+        if (*val1==0.0 && *val2==0.0) *val2 = 0.0;
+        else {
+        if (swap) *val2 = atan2(*val2,*val1);
+        else *val2 = atan2(*val1,*val2);
+        }
+      } else if (op==13) {
+        if (swap) {
+          if (*val1<0.0) *uval2 = 0;
+        } else {
+          if (*val2<0.0) *uval2 = 0;
+          else *val2 = *val1;
+        }
+      }
+      else {
+        gaprnt (0,"Internal logic check 17: invalid oper value\n");
+        return (NULL);
+      }
+    }
+    val2++; uval2++; i2++;
+    if (i2>=incr) {i2=0; val1++; uval1++; i1++;}        /* Special increment for*/
+    if (i1>=imax) {i1=0; val1=pgr1->grid; uval1=pgr1->umask;}     /*   the smaller grid   */
+  }
+
+  /* If requested, release the storage for operand 1 (which does not
+     contain the result).  Note that this refers to operand 1 AFTER
+     the possible grid swap earlier in the routine.                   */
+
+  if (rel) {
+    gagfre(pgr1);
+  }
+
+  return (pgr2);
+
+  err1:
+    gaprnt (0,"Operation error:  Incompatable grids \n");
+    gaprnt (1,"   Varying dimensions are different\n");
+    snprintf(pout,255,"  1st grid dims = %i %i   2nd = %i %i \n",
+            pgr1->idim, pgr2->idim, pgr1->jdim, pgr2->jdim);
+    gaprnt (2,pout);
+    return (NULL);
+
+  err2:
+    gaprnt (0,"Operation error:  Incompatable grids \n");
+    snprintf(pout,255,"  Dimension = %i\n",i);
+    gaprnt (2, pout);
+    snprintf(pout,255,"  1st grid range = %i %i   2nd = %i %i \n",
+            pgr1->dimmin[i],pgr1->dimmax[i],
+            pgr2->dimmin[i],pgr2->dimmax[i]);
+    gaprnt (2,pout);
+    return (NULL);
+}
+
+
+/* Perform operation on two stn data items.  The operation is done
+   only when the varying dimensions are equal.  Currently, only
+   three station data dimension environments are supported:
+   X,Y varying (X,Y plot), T varying (time series), and Z
+   varying (vertical profile).  This routine will probably need to
+   be rewritten at some point.                                     */
+
+struct gastn *gastop (struct gastn *stn1, struct gastn *stn2,
+                      gaint op, gaint rel) {
+struct gastn *stn;
+struct garpt *rpt1,*rpt2;
+gaint swap,i,j,flag,dimtyp;
+
+  /* Verify dimension environment */
+
+  if (stn1->idim==0 && stn1->jdim==1 && 
+      stn2->idim==0 && stn2->jdim==1) 
+    dimtyp = 1;                                 /* X and Y are varying */
+  else if (stn1->idim==2 && stn1->jdim==-1 && 
+	   stn2->idim==2 && stn2->jdim==-1) 
+    dimtyp = 2;                                 /* Z is varying */
+  else if (stn1->idim==3 && stn1->jdim==-1 && 
+	   stn2->idim==3 && stn2->jdim==-1) 
+    dimtyp = 3;                                 /* T is varying */
+  else {
+    gaprnt (0,"Invalid dimension environment for station data");
+    gaprnt (0," operation\n");
+    return (NULL);
+  }
+
+  /* Set it up so first stn set has fewer stations */
+
+  swap=0;
+  if (stn1->rnum > stn2->rnum) {
+    stn=stn1;
+    stn1=stn2;
+    stn2=stn;
+    swap=1;
+  }
+
+  /* Loop through stations of 1st station set.  Find matching
+     stations in 2nd station set.  If a match, perform operation.
+     Any duplicates in the 2nd station set get ignored.      */
+
+  rpt1 = stn1->rpt;
+  for (i=0; i<stn1->rnum; i++,rpt1=rpt1->rpt) {
+    if (rpt1->umask == 0) continue;
+    flag = 0;
+    rpt2 = stn2->rpt;
+    for (j=0; j<stn2->rnum; j++,rpt2=rpt2->rpt) {
+      if (rpt2->umask == 0) continue;
+      if (dimtyp==1 && dequal(rpt1->lat,rpt2->lat,1e-08)!=0) continue;
+      if (dimtyp==1 && dequal(rpt1->lon,rpt2->lon,1e-08)!=0) continue;
+      if (dimtyp==2 && dequal(rpt1->lev,rpt2->lev,1e-08)!=0) continue;
+      if (dimtyp==3 && dequal(rpt1->tim,rpt2->tim,1e-08)!=0) continue;
+      if (op==2) 
+	rpt1->val = rpt1->val + rpt2->val;
+      else if (op==0) 
+	rpt1->val = rpt1->val * rpt2->val;
+      else if (op==1) {
+        if (swap) {
+          if (dequal(rpt1->val,0.0,1e-08)==0) rpt1->umask = 0;
+          else rpt1->val = rpt2->val / rpt1->val;
+        } else {
+          if (dequal(rpt2->val,0.0,1e-08)==0) rpt1->umask = 0;
+          else rpt1->val = rpt1->val / rpt2->val;
+        }
+      } 
+      else if (op==10) {
+        if (swap) rpt1->val = pow(rpt2->val,rpt1->val);
+        else rpt1->val = pow(rpt1->val,rpt2->val);
+      } 
+      else if (op==11)  
+	rpt1->val = hypot(rpt1->val,rpt2->val);
+      else if (op==12) {
+        if ((dequal(rpt1->val,0.0,1e-08)==0) && (dequal(rpt2->val,0.0,1e-08)==0)) 
+	  rpt1->val = 0.0;
+        else rpt1->val = atan2(rpt1->val,rpt2->val);
+      } 
+      else if (op==13) {
+        if (swap) {
+          if (rpt1->val<0.0) rpt1->umask = 0;
+          else rpt1->val = rpt2->val;
+        } else {
+          if (rpt2->val<0.0) rpt1->umask = 0;
+        }
+      }
+      else {
+        gaprnt (0,"Internal logic check 57: invalid oper value\n");
+        return (NULL);
+      }
+      flag=1;
+      break;
+    }
+    if (!flag) rpt1->umask = 0;
+  }
+
+  /* Release storage if requested then return */
+
+  if (rel) {
+    for (i=0; i<BLKNUM; i++) {
+      if (stn2->blks[i] != NULL) gree(stn2->blks[i],"f168");
+    }
+    gree(stn2,"f169");
+  }
+  return (stn1);
+}
+
+/* Perform operation between a stn set and a constant   */
+
+struct gastn *gascop (struct gastn *stn, gadouble val, gaint op, gaint swap) {
+struct garpt *rpt;
+gaint i;
+
+  /* Loop through stations.  Perform operation.              */
+
+  rpt = stn->rpt;
+  for (i=0; i<stn->rnum; i++,rpt=rpt->rpt) {
+    if (rpt->umask == 0) continue;
+    if (op==2) 
+      rpt->val = rpt->val + val;
+    else if (op==0) 
+      rpt->val = rpt->val * val;
+    else if (op==1) {
+      if (swap) {
+        if (dequal(rpt->val,0.0,1e-08)==0) rpt->umask = 0;
+        else rpt->val = val / rpt->val;
+      } else {
+        if (dequal(val,0.0,1e-08)==0) rpt->umask = 0;
+        else rpt->val = rpt->val / val;
+      }
+    } 
+    else if (op==10) {
+      if (swap) rpt->val = pow(val,rpt->val);
+      else rpt->val = pow(rpt->val,val);
+    } 
+    else if (op==11)  
+      rpt->val = hypot(rpt->val,val);
+    else if (op==12) {
+      if (dequal(rpt->val,0.0,1e-08)==0 && dequal(val,0.0,1e-08)==0) 
+	rpt->val = 0.0;
+      else {
+        if (swap) rpt->val = atan2(val,rpt->val);
+        else rpt->val = atan2(rpt->val,val);
+      }
+    } 
+    else if (op==13) {
+      if (rpt->val<0.0) rpt->umask = 0;
+    }
+    else {
+      gaprnt (0,"Internal logic check 57: invalid oper value\n");
+      return (NULL);
+    }
+  }
+  return (stn);
+}
+
+/* Put a constant value into a grid.  We will change this at
+   some point to have three data types (grid, stn, constant) but
+   for now it is easier to keep the constant grid concept.     */
+
+struct gagrid *gagrvl (gadouble val) {
+struct gagrid *pgr;
+gaint i;
+size_t sz;
+
+  /* Allocate memory */ 
+  sz = sizeof(struct gagrid);
+  pgr = (struct gagrid *)galloc(sz,"pgr1");
+  if (pgr==NULL) {
+    gaprnt (0,"Unable to allocate memory for grid structure \n");
+    return (NULL);
+  }
+  /* Fill in gagrid variables */
+  pgr->pfile = NULL;
+  pgr->undef = -9.99e8;
+  pgr->pvar  = NULL;
+  pgr->idim  = -1;
+  pgr->jdim  = -1;
+  pgr->alocf = 0;
+  for (i=0;i<5;i++) {
+    pgr->dimmin[i]=0;
+    pgr->dimmax[i]=0;
+  }
+  pgr->rmin = val;
+  pgr->rmax = val;
+  pgr->grid = &pgr->rmin;
+  pgr->umin = 1;
+  pgr->umask = &pgr->umin;
+  pgr->isiz = 1;
+  pgr->jsiz = 1;
+  pgr->exprsn = NULL;
+  return (pgr);
+}
+
+/* Handle a variable or function call.  If successful, we return
+   a data object (pointed to by the pst) and a ptr to the first
+   character after the variable or function name.  If an error
+   happens, we return a NULL pointer.                                */
+
+char *varprs (char *ch, struct gastat *pst) {
+struct gagrid *pgr,*pgr2=NULL;
+struct gafile *pfi;
+struct gavar  *pvar, *pvar2, vfake;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble dmin[5],dmax[5],d1,d2;
+gadouble *cvals,*r,*r2;
+gafloat wrot;
+gaint i,fnum,ii,jj,rc,dotflg,idim,jdim,dim,sbu;
+gaint id[5],toff=0;
+gaint size,j,dotest,defined;
+char *ru, *r2u, name[20], vnam[20], *pos;
+size_t sz;
+
+  /* Get the variable or function name.  It must start with a
+     letter, and consist of letters or numbers or underscore.  */
+  i=0;
+  while ( (*ch>='a' && *ch<='z') || (*ch>='0' && *ch<='9' ) || (*ch == '_') ) {
+    name[i] = *ch;
+    vnam[i] = *ch;
+    ch++; i++;
+    if (i>16) break;
+  }
+  name[i] = '\0';
+  vnam[i] = '\0';  /* Save 'i' for next loop */
+
+  /* Check for the data set number in the variable name.  If there,
+     then this has to be a variable name.                            */
+
+  fnum = pst->fnum;
+  dotflg=0;
+  if (*ch == '.') {
+    dotflg=1;
+    ch++;
+    pos = intprs(ch,&fnum);
+    if (pos==NULL || fnum<1) {
+      snprintf(pout,255,"Syntax error: Bad file number for variable %s \n",name);
+      gaprnt (0,pout);
+      return (NULL);
+    }
+    vnam[i] = '.';
+    i++;
+    while (ch<pos) {
+      vnam[i] = *ch;
+      ch++; i++;
+    }
+    vnam[i] = '\0';
+  }
+
+  /* Check for a predefined data object. */
+  pfi = NULL;
+  pvar = NULL;
+  defined=0;
+  if (!dotflg) {
+    pfi = getdfn(name,pst);
+    if (pfi!=NULL) defined=1;
+  }
+
+  /* If not a defined grid, get a pointer to a file structure    */
+  if (pfi==NULL) {
+    if (!dotflg) {
+      pfi = pst->pfid;
+    }
+    else {
+      pfi = pst->pfi1;
+      for (i=1; i<fnum && pfi!=NULL; i++) pfi = pfi->pforw;
+      if (pfi==NULL) {
+        gaprnt (0,"Data Request Error:  File number out of range \n");
+        snprintf(pout,255,"  Variable = %s \n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+    }
+
+    /* Check here for predefined variable name: lat,lon,lev */
+    if ( cmpwrd(name,"lat") ||
+         cmpwrd(name,"lon") ||
+         cmpwrd(name,"lev") ) {
+      pvar = &vfake;
+      vfake.levels = -999;
+      vfake.vecpair = -999;
+      if (cmpwrd(name,"lon")) {vfake.offset = 0; snprintf(vfake.abbrv,5,"lon");}
+      if (cmpwrd(name,"lat")) {vfake.offset = 1; snprintf(vfake.abbrv,5,"lat");}
+      if (cmpwrd(name,"lev")) {vfake.offset = 2; snprintf(vfake.abbrv,5,"lev");}
+      if (pfi->type==2 || pfi->type==3) {
+        snprintf(pout,255,"Data Request Error:  Predefined variable %s\n", vnam);
+        gaprnt (0,pout);
+        gaprnt (0,"   is only defined for grid type files\n");
+        snprintf(pout,255,"   File %i is a station file\n",fnum);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+    } 
+    else {
+      /* See if this is a variable name.  
+	 If not, give an error message (if a file number was specified) 
+	 or check for a function call via rtnprs.   */
+      pvar = pfi->pvar1;
+      for (i=0; (i<pfi->vnum)&&(!cmpwrd(name,pvar->abbrv)); i++) pvar++;
+      if (i>=pfi->vnum) {
+        if (dotflg) {
+          gaprnt (0,"Data Request Error:  Invalid variable name \n");
+          snprintf(pout,255,"  Variable '%s' not found in file %i\n",vnam,fnum);
+          gaprnt (0,pout);
+          return (NULL);
+        } else {
+          ch = rtnprs(ch,name,pst);              /* Handle function call */
+          return (ch);
+        }
+      }
+    }
+  }
+
+  /* It wasn't a function call (or we would have returned).
+     If the variable is to a stn type file, call the parser
+     routine that handles stn requests.                         */
+  if (pfi->type==2 || pfi->type==3) {
+    ch = stnvar (ch, vnam, pfi, pvar, pst);
+    return (ch);
+  }
+
+  /* We are dealing with a grid data request.  We handle this inline.
+     Our default dimension limits are defined in gastat.  These
+     may be modified by the user (by specifying the new settings
+     in parens).  First get grid coordinates of the limits, then
+     figure out if user modifies these.        */
+
+  /* Convert world coordinates in the status block to grid
+     dimensions using the file scaling for this variable.  */
+
+  for (i=0;i<5;i++) {
+    if (i==3) {
+      dmin[i] = t2gr(pfi->abvals[i],&(pst->tmin));
+      dmax[i] = t2gr(pfi->abvals[i],&(pst->tmax));
+    }
+    else {
+      conv  = pfi->ab2gr[i];
+      cvals = pfi->abvals[i];
+      dmin[i] = conv(cvals,pst->dmin[i]);
+      dmax[i] = conv(cvals,pst->dmax[i]);
+    }
+  }
+
+  /* Round varying dimensions 'outwards' to integral grid units. */
+  for (i=0;i<5;i++) {
+    if (i==pst->idim || i==pst->jdim) {
+      dmin[i] = floor(dmin[i]+0.0001);
+      dmax[i] = ceil(dmax[i]-0.0001);
+      if (dmax[i]<=dmin[i]) {
+        gaprnt (0,"Data Request Error: Invalid grid coordinates\n");
+        snprintf(pout,255,"  Varying dimension %i decreases: %g to %g\n",i,dmin[i],dmax[i]);
+        gaprnt (0,pout);
+        snprintf(pout,255,"  Error ocurred getting variable '%s'\n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+    }
+  }
+
+  /* Check for user provided dimension expressions */
+  if (*ch=='(') {
+    ch++;
+    for (i=0;i<5;i++) id[i] = 0;
+    while (*ch!=')') {
+      pos = dimprs(ch, pst, pfi, &dim, &d1, 1, &rc);
+      if (pos==NULL) {
+        snprintf(pout,255,"  Variable name = %s\n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      if (id[dim]) {
+        gaprnt (0,"Syntax Error: Invalid dimension expression\n");
+        gaprnt (0,"  Same dimension specified multiple times ");
+        snprintf(pout,255,"for variable = %s\n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      id[dim] = 1;
+      if ( dim==pst->idim || dim==pst->jdim) {
+        gaprnt (0,"Data Request Error: Invalid dimension expression\n");
+        gaprnt (0,"  Attempt to set or modify varying dimension\n");
+        snprintf(pout,255,"  Variable = %s, Dimension = %i \n",vnam,dim);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      dmin[dim] = d1;
+      dmax[dim] = d1;
+      /* check if we need to set flag for time offset */
+      if (rc>1) {
+	if (defined==1) {
+	  gaprnt (0,"Error: The \"offt\" dimension expression is \n");
+          gaprnt (0,"       not supported for defined variables. \n");
+	  return (NULL);
+	}
+	else toff=1;
+      }
+      ch = pos;
+      if (*ch == ',') ch++;
+    }
+    ch++;
+  }
+
+  /* If request from a defined grid, ignore fixed dimensions
+     in the defined grid */
+
+  if (pfi->type==4) {
+    for (i=0; i<5; i++) {
+      if (pfi->dnum[i]==1) {
+        dmin[i] = 0.0;
+        dmax[i] = 0.0;
+      }
+    }
+  }
+
+  /* All the grid level coordinates are set.  Insure they
+     are integral values, otherwise we can't do it.   The varying
+     dimensions will be integral (since we forced them to be
+     earlier) so this is only relevent for fixed dimensions. */
+
+  for (i=0; i<5; i++) {
+    if (dmin[i]<0.0) 
+      ii = (gaint)(dmin[i]-0.1);
+    else 
+      ii = (gaint)(dmin[i]+0.1);
+    d1 = ii;
+    if (dmax[i]<0.0) 
+      ii = (gaint)(dmax[i]-0.1);
+    else 
+      ii = (gaint)(dmax[i]+0.1);
+    d2 = ii;
+    /* ignore z test if variable has no levels */
+    dotest=1;
+    if(pvar) {
+      if(!pvar->levels && i == 2) dotest=0;
+    }
+    if (( dequal(dmin[i],d1,1e-8)!=0 || dequal(dmax[i],d2,1e-8)!=0) && dotest ) {
+      gaprnt (0,"Data Request Error: Invalid grid coordinates\n");
+      gaprnt (0,"  World coordinates convert to non-integer");
+      gaprnt (0,"  grid coordinates\n");
+      snprintf(pout,255,"    Variable = %s  Dimension = %i \n",vnam,i);
+      gaprnt (0,pout);
+      return (NULL);
+    }
+  }
+  /* Variable has been parsed and is valid, and the ch pointer is
+     set to the first character past it.  We now need to set up
+     the grid requestor block and get the grid.  */
+
+  pgr = NULL; 
+  sz = sizeof(struct gagrid);
+  pgr = (struct gagrid *)galloc(sz,"gpgr");
+  if (pgr==NULL) {
+    gaprnt (0,"Memory Allocation Error:  Grid Request Block\n");
+    return (NULL);
+  }
+
+  /* Fill in gagrid variables */
+
+  idim = pst->idim; 
+  jdim = pst->jdim;
+  pgr->alocf = 0;
+  pgr->pfile = pfi;
+  pgr->undef = pfi->undef;
+  pgr->pvar  = pvar;
+  pgr->idim  = idim;
+  pgr->jdim  = jdim;
+  pgr->iwrld = 0;  
+  pgr->jwrld = 0;
+  pgr->toff  = toff;
+  for (i=0;i<5;i++) {
+    if (dmin[i]<0.0) {
+      pgr->dimmin[i] = (gaint)(dmin[i]-0.1);
+    }
+    else {
+      pgr->dimmin[i] = (gaint)(dmin[i]+0.1);
+    }
+    if (dmax[i]<0.0) {
+      pgr->dimmax[i] = (gaint)(dmax[i]-0.1);
+    }
+    else {
+      pgr->dimmax[i] = (gaint)(dmax[i]+0.1);
+    }
+  }
+  pgr->exprsn = NULL;
+  pgr->ilinr = 1;
+  pgr->jlinr = 1;
+  if (idim>-1 && idim!=3) {  
+    pgr->igrab = pfi->gr2ab[idim];
+    pgr->iabgr = pfi->ab2gr[idim];
+  }
+  if (jdim>-1 && jdim!=3) {
+    pgr->jgrab = pfi->gr2ab[jdim];
+    pgr->jabgr = pfi->ab2gr[jdim];
+  }
+  if (idim>-1 && jdim<=4) {    /* qqqqq xxxxx fix this later ? */
+    pgr->ivals  = pfi->grvals[idim];
+    pgr->iavals = pfi->abvals[idim];
+    pgr->ilinr  = pfi->linear[idim];
+  }
+  if (jdim>-1 && jdim<=4) {    /* qqqqq xxxxx fix this later ? */
+    pgr->jvals  = pfi->grvals[jdim];
+    pgr->javals = pfi->abvals[jdim];
+    pgr->jlinr  = pfi->linear[jdim];
+  }
+  pgr->grid = NULL;
+
+  if (pfi && pvar && pfi->ppflag && pfi->ppwrot && pvar->vecpair>0) {
+    pgr2 = NULL; 
+    sz = sizeof(struct gagrid);
+    pgr2 = (struct gagrid *)galloc(sz,"gpgr2");
+    if (pgr2==NULL) {
+      gaprnt (0,"Memory allocation error: Data I/O \n");
+      gagfre(pgr);
+      return (NULL);
+    }
+    *pgr2 = *pgr;
+  }
+
+  /* Get grid */
+  rc = gaggrd (pgr);
+  if (rc>0) {
+    snprintf(pout,255,"Data Request Error:  Error for variable '%s'\n", vnam);
+    gaprnt (0,pout);
+    gagfre(pgr);
+    return (NULL);
+  }
+  if (rc<0) {
+    snprintf(pout,255,"  Warning issued for variable = %s\n",vnam);
+    gaprnt (2,pout);
+  }
+
+  /* Special test for auto-interpolated data, when the
+     data requested is U or V.  User MUST indicate variable unit
+     number in the descriptor file for auto-rotation to take place */
+
+  if (pfi && pvar && pfi->ppflag && pfi->ppwrot && pvar->vecpair>0) {
+
+    /* Find the matching vector component */
+    if (pvar->isu) sbu=0;    /* if pvar is u, then matching component should not be u */
+    else sbu=1;              /* pvar is v, so matching component should be u */
+    pvar2 = pfi->pvar1;
+    i = 0;
+    while (i<pfi->vnum) {
+      if ((pvar2->vecpair == pvar->vecpair) && 
+	  (pvar2->isu     == sbu)) break;
+      pvar2++; i++;
+    }
+    if (i>=pfi->vnum) { /* didn't find a match */
+      ru = pgr->umask;
+      size = pgr->isiz*pgr->jsiz;
+      for (i=0; i<size; i++) {*ru=0; ru++;}
+    } else {
+      /* get the 2nd grid */
+      pgr2->pvar = pvar2;
+      rc = gaggrd (pgr2);
+      if (rc>0) {
+        snprintf(pout,255,"Data Request Error:  Error for variable '%s'\n", vnam);
+        gaprnt (0,pout);
+        gagfre(pgr);
+        gagfre(pgr2);
+        return (NULL);
+      }
+      /* r is u component, r2 is v component */
+      if (pvar2->isu) { 
+        r = pgr2->grid;
+        r2 = pgr->grid;
+        ru = pgr2->umask;
+        r2u = pgr->umask;
+      } else {
+        r = pgr->grid;
+        r2 = pgr2->grid;
+        ru = pgr->umask;
+        r2u = pgr2->umask;
+      }
+      ii = pgr->dimmin[0];
+      jj = pgr->dimmin[1];
+      for (j=0; j<pgr->jsiz; j++) {
+        if (pgr->idim == 0) ii = pgr->dimmin[0];
+        if (pgr->idim == 1) jj = pgr->dimmin[1];
+        for (i=0; i<pgr->isiz; i++) {
+         if (*ru==0 || *r2u==0) {  /* u or v is undefined */
+            *ru = 0;
+            *r2u = 0;
+          } else {
+            if (ii<1 || ii>pfi->dnum[0] ||
+                jj<1 || jj>pfi->dnum[1]) {   /* outside file's grid dimensions */
+              *ru = 0;
+              *r2u = 0;
+            } else {
+ 	      /* get wrot value for grid element */
+	      wrot = *(pfi->ppw + (jj-1)*pfi->dnum[0] + ii - 1);
+              if (wrot < -900.0) {
+                *ru = 0;
+                *r2u = 0;
+              }
+              else if (wrot != 0.0) {
+                if (pvar2->isu) {
+ 		  *r2 = (*r)*sin(wrot) + (*r2)*cos(wrot); /* display variable is v */
+		  *r2u = 1;
+		}
+                else {
+ 		  *r = (*r)*cos(wrot) - (*r2)*sin(wrot); /* display variable is u */
+		  *ru = 1;
+		}
+              }
+            }
+          }
+          r++; r2++; ru++; r2u++;
+          if (pgr->idim == 0) ii++;
+          if (pgr->idim == 1) jj++;
+        }
+        if (pgr->jdim == 1) jj++;
+      }
+      gagfre(pgr2);
+    }
+  }
+
+  pst->result.pgr = pgr;
+  pst->type = 1;
+  return (ch);
+}
+
+/* Check that a specific dimension range is equivalent
+   between two grids.  The dimension range is defined in the
+   grid descriptor block in terms of grid coordinates, so
+   conversions are made to absolute coordinates to insure
+   equivalence in an absolute sense.
+
+   A true result means the grids don't match.                       */
+
+gaint gagchk (struct gagrid *pgr1, struct gagrid *pgr2, gaint dim) {
+gadouble gmin1,gmax1,gmin2,gmax2,fuz1,fuz2,fuzz;
+gadouble (*conv1) (gadouble *, gadouble);
+gadouble (*conv2) (gadouble *, gadouble);
+gadouble *vals1, *vals2;
+gaint i1,i2,i,siz1,siz2,rc;
+struct dt dtim1,dtim2;
+
+  if (dim<0) return(0);
+
+  if (dim==pgr1->idim) {
+    conv1 = pgr1->igrab;
+    vals1 = pgr1->ivals;
+    i1 = pgr1->ilinr;
+    siz1 = pgr1->isiz;
+  } else if (dim==pgr1->jdim) {
+    conv1 = pgr1->jgrab;
+    vals1 = pgr1->jvals;
+    i1 = pgr1->jlinr;
+    siz1 = pgr1->jsiz;
+  } else return (1);
+
+  if (dim==pgr2->idim) {
+    conv2 = pgr2->igrab;
+    vals2 = pgr2->ivals;
+    i2 = pgr2->ilinr;
+    siz2 = pgr2->isiz;
+  } else if (dim==pgr2->jdim) {
+    conv2 = pgr2->jgrab;
+    vals2 = pgr2->jvals;
+    i2 = pgr2->jlinr;
+    siz2 = pgr2->jsiz;
+  } else return (1);
+
+  if (siz1 != siz2) {
+    gaprnt(0,"Error in gagchk: axis sizes are not the same\n");
+    return(1);
+  }
+
+  gmin1 = pgr1->dimmin[dim];
+  gmax1 = pgr1->dimmax[dim];
+  gmin2 = pgr2->dimmin[dim];
+  gmax2 = pgr2->dimmax[dim];
+
+  if (dim==3) {                         /* Dimension is time.      */
+    rc=0;
+    gr2t (vals1, gmin1, &dtim1);
+    gr2t (vals2, gmin2, &dtim2);
+    if (dtim1.yr != dtim2.yr) rc=1;
+    if (dtim1.mo != dtim2.mo) rc=1;
+    if (dtim1.dy != dtim2.dy) rc=1;
+    if (dtim1.hr != dtim2.hr) rc=1;
+    if (dtim1.mn != dtim2.mn) rc=1;
+    gr2t (vals1, gmax1, &dtim1);
+    gr2t (vals2, gmax2, &dtim2);
+    if (dtim1.yr != dtim2.yr) rc=1;
+    if (dtim1.mo != dtim2.mo) rc=1;
+    if (dtim1.dy != dtim2.dy) rc=1;
+    if (dtim1.hr != dtim2.hr) rc=1;
+    if (dtim1.mn != dtim2.mn) rc=1;
+    if (rc) {
+      gaprnt(0,"Error in gagchk: time axis endpoint values are not equivalent\n");
+      return (1);
+    }
+    return (0);
+  }
+
+  /* Check endpoints.  If unequal, then automatic no match.        */
+
+  fuz1=fabs(conv1(vals1,gmax1)-conv1(vals1,gmin1))*FUZZ_SCALE;
+  fuz2=fabs(conv2(vals2,gmax2)-conv2(vals2,gmin2))*FUZZ_SCALE;
+  fuzz=(fuz1+fuz2)*0.5;
+  
+  rc=0;
+  if ( fabs((conv1(vals1,gmin1)) - (conv2(vals2,gmin2))) > fuzz ) rc=1;
+  if ( fabs((conv1(vals1,gmax1)) - (conv2(vals2,gmax2))) > fuzz ) rc=1;
+  if (rc) {
+    gaprnt(0,"Error in gagchk: axis endpoint values are not equivalent\n");
+    return (1);
+  }
+  if (i1!=i2) {
+    gaprnt(0,"Error in gagchk: one axis is linear and the other is non-linear\n");
+    return (1);
+  }
+  if (i1) return (0);                   /* If linear then matches  */
+
+  /* Nonlinear, but endpoints match.  Check every grid point for a
+     match.  If any non-matches, then not a match.     */
+
+  for (i=0; i<siz1; i++) {
+    if (fabs((conv1(vals1,gmin1+(gadouble)i)) - (conv2(vals2,gmin2+(gadouble)i))) > fuzz ) {
+      gaprnt(0,"Error in gagchk: axis values are not all the same\n");
+      return (1);
+    }
+  }
+  return (0);
+}
+
+/* Check for defined data object. If found, make copy and return descriptor. */
+
+struct gafile *getdfn (char *name, struct gastat *pst) {
+struct gadefn *pdf;
+
+  /* See if the name is a defined grid */
+  pdf = pst->pdf1;
+  while (pdf!=NULL && !cmpwrd(name,pdf->abbrv)) pdf = pdf->pforw;
+  if (pdf==NULL) return (NULL);
+  return (pdf->pfi);
+}
+
+/* Handle a station data request variable.                      */
+
+char *stnvar (char *ch, char *vnam, struct gafile *pfi,
+              struct gavar *pvar, struct gastat *pst) {
+struct gastn *stn;
+gadouble dmin[5],dmax[5],d,radius;
+gaint id[6],dim,i,rc,rflag,sflag;
+char *pos;
+char stid[10];
+size_t sz;
+
+  rflag = 0;
+  sflag = 0;
+  radius = 0;
+
+  /* We want to finish parsing the variable name by looking at
+     any dimension settings by the user.  First initialize the
+     request environment to that found in the pst.             */
+
+  for (i=0;i<3;i++) {
+    dmin[i] = pst->dmin[i];
+    dmax[i] = pst->dmax[i];
+  }
+  dmin[3] = t2gr(pfi->abvals[3],&(pst->tmin));
+  dmax[3] = t2gr(pfi->abvals[3],&(pst->tmax));
+
+  /* Check for user provided dimension expressions */
+  if (*ch=='(') {
+    ch++;
+    for (i=0;i<6;i++) id[i] = 0;
+    while (*ch!=')') {
+      if (!cmpch(ch,"stid=",5)) {   /* special stid= arg */
+        for (i=0; i<8; i++) stid[i] = ' ';
+        stid[8] = '\0';
+        pos = ch+5;
+        i=0;
+        while (*pos!=',' && *pos!=')' && i<8) {
+          stid[i] = *pos;
+          pos++;
+          i++;
+        }
+        if (i==0) {
+          gaprnt (0,"Dimension Expression Error: No stid provided\n");
+          pos=NULL;
+        }
+        if (i>8) {
+          gaprnt (0,"Dimension Expression Error: stid too long\n");
+          pos=NULL;
+        }
+	dim=11; 
+      } else {
+        pos = dimprs(ch, pst, pfi, &dim, &d, 0, &rc);
+      }
+      if (pos==NULL) {
+        snprintf(pout,255,"  Variable name = %s\n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      if (dim<6 && id[dim]>1) {
+        gaprnt (0,"Syntax Error: Invalid dimension expression\n");
+        gaprnt (0,"  Same dimension specified more than twice ");
+        snprintf(pout,255,"for variable = %s\n",vnam);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      if ( dim==pst->idim || dim==pst->jdim ||
+           ( dim>3 && (pst->idim==0 || pst->idim==1 || pst->jdim==1))) {
+        gaprnt (0,"Data Request Error: Invalid dimension expression\n");
+        gaprnt (0,"  Attempt to set or modify varying dimension\n");
+        snprintf(pout,255,"  Variable = %s, Dimension = %i \n",vnam,dim);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      if (dim==10) {
+        rflag = 1;
+        radius = d;
+      } else if (dim==11) {
+        sflag = 1;
+      } else {
+        if (id[dim]==0) dmin[dim] = d;
+        dmax[dim] = d;
+      }
+      ch = pos;
+      if (*ch == ',') ch++;
+      id[dim]++;
+    }
+    ch++;
+  }
+
+  /* Verify that dmin is less than or equal to dmax for all our dims */
+  for (i=0; i<4; i++) {
+    if ((i!=2 && dmin[i]>dmax[i]) || (i==2 && dmax[i]>dmin[i])) {
+      gaprnt (0,"Data Request Error: Invalid grid coordinates\n");
+      snprintf(pout,255,"  Varying dimension %i decreases: %g to %g \n",i,dmin[i],dmax[i]);
+      gaprnt (0,pout);
+      snprintf(pout,255,"  Error ocurred getting variable '%s'\n",vnam);
+      gaprnt (0,pout);
+      return (NULL);
+    }
+  }
+
+  /* Looks like the user specified good stuff, and we are ready to
+     try to get some data.  Allocate and fill in a gastn block.     */
+
+  sz = sizeof(struct gastn);
+  stn = (struct gastn *)galloc(sz,"stn");
+  if (stn==NULL) {
+    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+    return (NULL);
+  }
+ 
+  stn->rnum = 0;
+  stn->rpt = NULL;
+  stn->pfi = pfi;
+  stn->idim = pst->idim;
+  stn->jdim = pst->jdim;
+  stn->undef = pfi->undef;
+  stn->tmin = dmin[3];
+  stn->tmax = dmax[3];
+  stn->ftmin = dmin[3];
+  stn->ftmax = dmax[3];
+  stn->pvar = pvar;
+  for (i=0; i<3; i++) {
+    stn->dmin[i] = dmin[i];
+    stn->dmax[i] = dmax[i];
+  }
+  stn->rflag = rflag;
+  stn->radius = radius;
+  stn->sflag = sflag;
+  if (sflag) {
+    for (i=0; i<8; i++) stn->stid[i] = stid[i];
+  }
+  sz = sizeof(gadouble)*8;
+  stn->tvals = (gadouble *)galloc(sz,"stntvals");
+  if (stn->tvals==NULL) {
+    gree(stn,"f170");
+    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+    return (NULL);
+  }
+  for (i=0; i<8; i++) *(stn->tvals+i) = *(pfi->grvals[3]+i);
+
+  rc = gagstn (stn);
+
+  if (rc) {
+    snprintf(pout,255,"Data Request Error:  Variable is '%s'\n",vnam);
+    gaprnt (0,pout);
+    gree(stn,"f171");
+    return (NULL);
+  }
+  pst->result.stn = stn;
+  pst->type = 0;
+  return (ch);
+}
diff --git a/src/gafunc.c b/src/gafunc.c
new file mode 100644
index 0000000..45d5abc
--- /dev/null
+++ b/src/gafunc.c
@@ -0,0 +1,7236 @@
+/* Copyright (C) 1988-2011 by Brian Doty and the 
+   Institute of Global Environment and Society (IGES).  
+   See file COPYRIGHT for more information.   */
+
+/*  Originally authored by B. Doty.  
+    Some functions provided by others. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "grads.h"
+
+/* expose Mike Fiorino's global struct to these routines for warning level setting */
+extern struct gamfcmn mfcmn;
+
+static struct gaufb *ufba;  /* Anchor for user function defs */
+char *gxgnam(char *);       /* This is also in gx.h */
+
+/* Function routine names.  Add a new function by putting the
+   prototype here and adding to the if tests below.  */
+
+gaint ffsqrt   (struct gafunc *, struct gastat *);
+gaint ffsin    (struct gafunc *, struct gastat *);
+gaint ffcos    (struct gafunc *, struct gastat *);
+gaint fftan    (struct gafunc *, struct gastat *);
+gaint ffasin   (struct gafunc *, struct gastat *);
+gaint ffacos   (struct gafunc *, struct gastat *);
+gaint ffexp    (struct gafunc *, struct gastat *);
+gaint fflog    (struct gafunc *, struct gastat *);
+gaint fflog10  (struct gafunc *, struct gastat *);
+gaint ffabs    (struct gafunc *, struct gastat *);
+gaint ffpow    (struct gafunc *, struct gastat *);
+gaint ffmag    (struct gafunc *, struct gastat *);
+gaint ffatan   (struct gafunc *, struct gastat *);
+gaint ffave    (struct gafunc *, struct gastat *);
+gaint ffgint   (struct gafunc *, struct gastat *);
+gaint ffhdiv   (struct gafunc *, struct gastat *);
+gaint ffhcrl   (struct gafunc *, struct gastat *);
+gaint ffvint   (struct gafunc *, struct gastat *);
+gaint ffelp    (struct gafunc *, struct gastat *);
+gaint fftlp    (struct gafunc *, struct gastat *);
+gaint ffaav    (struct gafunc *, struct gastat *);
+gaint fflterp  (struct gafunc *, struct gastat *);
+gaint ffscor   (struct gafunc *, struct gastat *);
+gaint fftcor   (struct gafunc *, struct gastat *);
+gaint fftmav   (struct gafunc *, struct gastat *);
+gaint ffmask   (struct gafunc *, struct gastat *);
+gaint ffg2s    (struct gafunc *, struct gastat *);
+gaint ffg2s2   (struct gafunc *, struct gastat *);
+gaint fftv2t   (struct gafunc *, struct gastat *);
+gaint fftv2q   (struct gafunc *, struct gastat *);
+gaint ffoacr   (struct gafunc *, struct gastat *);
+gaint ffoabn   (struct gafunc *, struct gastat *); 
+gaint ffsmth   (struct gafunc *, struct gastat *);
+gaint ffsave   (struct gafunc *, struct gastat *);
+gaint ffsmin   (struct gafunc *, struct gastat *);
+gaint ffsmax   (struct gafunc *, struct gastat *);
+gaint ffskip   (struct gafunc *, struct gastat *);
+gaint ffcnst   (struct gafunc *, struct gastat *);
+gaint ffcdif   (struct gafunc *, struct gastat *);
+gaint ffmn     (struct gafunc *, struct gastat *); 
+gaint ffamn    (struct gafunc *, struct gastat *); 
+gaint ffsum    (struct gafunc *, struct gastat *); 
+gaint ffsumg   (struct gafunc *, struct gastat *); 
+gaint ffasum   (struct gafunc *, struct gastat *); 
+gaint ffasumg  (struct gafunc *, struct gastat *); 
+gaint ffatot   (struct gafunc *, struct gastat *); 
+gaint ffamin   (struct gafunc *, struct gastat *);
+gaint ffamax   (struct gafunc *, struct gastat *);
+gaint ffaminlocx (struct gafunc *, struct gastat *);
+gaint ffaminlocy (struct gafunc *, struct gastat *);
+gaint ffamaxlocx (struct gafunc *, struct gastat *);
+gaint ffamaxlocy (struct gafunc *, struct gastat *);
+gaint ffgrarea (struct gafunc *, struct gastat *); 
+gaint ffclgr   (struct gafunc *, struct gastat *);
+gaint ffmin    (struct gafunc *, struct gastat *);
+gaint ffmax    (struct gafunc *, struct gastat *);
+gaint ffminl   (struct gafunc *, struct gastat *);
+gaint ffmaxl   (struct gafunc *, struct gastat *);
+gaint ffflvl   (struct gafunc *, struct gastat *);
+gaint ffsreg   (struct gafunc *, struct gastat *); 
+gaint fftreg   (struct gafunc *, struct gastat *); 
+gaint ffs2g1d  (struct gafunc *, struct gastat *);
+gaint fftv2    (struct gafunc *, struct gastat *, gaint);
+gaint ffsmnx   (struct gafunc *, struct gastat *, gaint);
+gaint tmaskf   (struct gafunc *, struct gastat *, gaint);
+gaint aave     (struct gafunc *, struct gastat *, gaint);  
+gaint ave      (struct gafunc *, struct gastat *, gaint);   
+gaint scorr    (struct gafunc *, struct gastat *, gaint); 
+gaint tvrh2q   (gadouble, gadouble, gadouble, gadouble *, gadouble *);
+gaint fndarg   (char *, gaint *);
+void cosadj  (struct gagrid *);
+char doaave (struct gagrid *, gadouble, gadouble, gadouble, gadouble, gaint, gadouble *);
+gaint mnmx (struct gafunc *, struct gastat *, int);
+
+static char pout[256];   /* Build error msgs here */
+
+char *rtnprs (char *ch, char *name, struct gastat *pst) {
+struct gafunc *pfc;
+struct gastat *pst2;
+struct gaufb *ufb;
+char *pos;
+gaint pdeep,rc;
+size_t sz;
+gaint (*fpntr)(struct gafunc *, struct gastat *)=NULL;
+
+  /* Find this function name and get the function pointer. */
+
+  ufb = ufba;
+  while (ufb) {
+    if (cmpwrd(ufb->name,name)) break;
+    ufb = ufb->ufb;
+  }
+
+  if (ufb==NULL) {
+    fpntr = NULL;
+    if (cmpwrd("sqrt",name)) fpntr = ffsqrt;
+    if (cmpwrd("sin",name)) fpntr = ffsin;
+    if (cmpwrd("cos",name)) fpntr = ffcos;
+    if (cmpwrd("tan",name)) fpntr = fftan;
+    if (cmpwrd("asin",name)) fpntr = ffasin;
+    if (cmpwrd("acos",name)) fpntr = ffacos;
+    if (cmpwrd("exp",name)) fpntr = ffexp;
+    if (cmpwrd("log",name)) fpntr = fflog;
+    if (cmpwrd("log10",name)) fpntr = fflog10;
+    if (cmpwrd("abs",name)) fpntr = ffabs;
+    if (cmpwrd("pow",name)) fpntr = ffpow;
+    if (cmpwrd("ave",name)) fpntr = ffave;
+    if (cmpwrd("mag",name)) fpntr = ffmag;
+    if (cmpwrd("atan2",name)) fpntr = ffatan;
+    if (cmpwrd("hdivg",name)) fpntr = ffhdiv;
+    if (cmpwrd("hcurl",name)) fpntr = ffhcrl;
+    if (cmpwrd("vint",name)) fpntr = ffvint;
+    if (cmpwrd("tloop",name)) fpntr = fftlp;
+    if (cmpwrd("eloop",name)) fpntr = ffelp;
+    if (cmpwrd("aave",name)) fpntr = ffaav;
+    if (cmpwrd("scorr",name)) fpntr = ffscor;
+    if (cmpwrd("tcorr",name)) fpntr = fftcor;
+    if (cmpwrd("tmave",name)) fpntr = fftmav;
+    if (cmpwrd("maskout",name)) fpntr = ffmask;
+    if (cmpwrd("gr2stn",name)) fpntr = ffg2s;
+    if (cmpwrd("tvrh2q",name)) fpntr = fftv2q;
+    if (cmpwrd("tvrh2t",name)) fpntr = fftv2t;
+    if (cmpwrd("gint",name)) fpntr = ffgint;
+    if (cmpwrd("oacres",name)) fpntr = ffoacr;
+    if (cmpwrd("oabin",name)) fpntr = ffoabn;
+    if (cmpwrd("smth9",name)) fpntr = ffsmth;
+    if (cmpwrd("stnave",name)) fpntr = ffsave;
+    if (cmpwrd("stnmin",name)) fpntr = ffsmin;
+    if (cmpwrd("stnmax",name)) fpntr = ffsmax;
+    if (cmpwrd("skip",name)) fpntr = ffskip;
+    if (cmpwrd("const",name)) fpntr = ffcnst;
+    if (cmpwrd("cdiff",name)) fpntr = ffcdif;
+    if (cmpwrd("mean",name)) fpntr = ffmn;    
+    if (cmpwrd("amean",name)) fpntr = ffamn;  
+    if (cmpwrd("sum",name)) fpntr = ffsum;    
+    if (cmpwrd("sumg",name)) fpntr = ffsumg;  
+    if (cmpwrd("asum",name)) fpntr = ffasum;  
+    if (cmpwrd("asumg",name)) fpntr = ffasumg; 
+    if (cmpwrd("atot",name)) fpntr = ffatot; 
+    if (cmpwrd("grarea",name)) fpntr = ffgrarea; 
+    if (cmpwrd("coll2gr",name)) fpntr = ffclgr;
+    if (cmpwrd("min",name)) fpntr = ffmin;
+    if (cmpwrd("max",name)) fpntr = ffmax;
+    if (cmpwrd("minloc",name)) fpntr = ffminl;
+    if (cmpwrd("maxloc",name)) fpntr = ffmaxl;
+    if (cmpwrd("fndlvl",name)) fpntr = ffflvl;
+    if (cmpwrd("sregr",name)) fpntr = ffsreg;  
+    if (cmpwrd("tregr",name)) fpntr = fftreg;  
+    if (cmpwrd("s2g1d",name)) fpntr = ffs2g1d;
+    if (cmpwrd("lterp",name)) fpntr = fflterp;
+    if (cmpwrd("amin",name)) fpntr = ffamin;    
+    if (cmpwrd("amax",name)) fpntr = ffamax;    
+    if (cmpwrd("aminlocx",name)) fpntr = ffaminlocx;    
+    if (cmpwrd("aminlocy",name)) fpntr = ffaminlocy;    
+    if (cmpwrd("amaxlocx",name)) fpntr = ffamaxlocx;    
+    if (cmpwrd("amaxlocy",name)) fpntr = ffamaxlocy;    
+
+    if (fpntr==NULL) {                       /* Didn't find it....      */
+      gaprnt (0,"Syntax Error:  Invalid Operand \n");
+      snprintf(pout,255,"  '%s' not a variable or function name\n",name);
+      gaprnt (0,pout);
+      return (NULL);
+    }
+  }
+
+  /* Allocate storage for gastat and gafunc structures                */
+
+  sz = sizeof(struct gafunc);
+  pfc = (struct gafunc *)galloc(sz,"funccall");
+  sz = sizeof(struct gastat);
+  pst2 = (struct gastat *)galloc(sz,"funcpst");
+
+  *pst2 = *pst;                            /* Provide copy of gastat  */
+
+  /* Parse the argument list                                          */
+
+  pfc->argnum = 0;                         /* Initial arg count       */
+  if (*ch=='(') {                          /* If no leading paren..   */
+    ch++;                                  /* Past the '('            */
+    if (*ch==')') {                        /* Was it '()'???          */
+      ch++;                                /*  Point past this func   */
+    } else {                               /* We have something       */
+      pos = pfc->buff;                     /*  Point to output buffer */
+      pdeep = 0;                           /*  No parens nested yet   */
+      pfc->argpnt[0] = pos;                /*  Start of 1st arg       */
+      while (pdeep!=0 || *ch!=')') {       /*  Until end of args...   */
+        if (*ch=='\0' || *ch=='\n') {      /*   End of string?        */
+          gaprnt (0,"Syntax Error:  Unmatched parens\n");
+          goto err;                        /*    And return           */
+        }                                  /*   Is ok                 */
+        *pos = *ch;                        /*   Move to output buffer */
+        if (*ch=='(') pdeep++;             /*   Track paren nesting   */
+        else if (*ch==')') pdeep--;        /*   ditto                 */
+        else if (pdeep==0 && *ch==',') {   /*   End of an arg?        */
+          *pos = '\0';                     /*    Terminate string     */
+          pfc->argnum++;                   /*    Bump arg counter     */
+          pfc->argpnt[pfc->argnum] = pos+1; /*   Start of next arg    */
+          *(pos+1) = '\0';                 /*    If trailing comma    */
+        }                                  /*   endif                 */
+        pos++; ch++;                       /*   Bump pointers         */
+      }                                    /*  Continue               */
+      *pos = '\0';                         /*  terminate final arg    */
+      pfc->argnum++;                       /*  Count instead of subscr*/
+      ch++;                                /*  Pnt past func call     */
+    }                                      /* X                       */
+  }                                        /* We have args parsed     */
+
+  /* Everything is all set.  Call the function routine.               */
+
+  rc = (*fpntr)(pfc, pst2);           /* Call the function       */
+
+  if (rc==-1) {
+    snprintf(pout,255,"Error in %s : Arg was stn data type\n",name);
+    gaprnt (0,pout);
+  }
+
+  if (rc) {                                /* If an error occurred... */
+    snprintf(pout,255,"Operation Error:  Error from %s function\n",name);
+    gaprnt (0,pout);
+    goto err;
+  }
+  pst->type = pst2->type;
+  pst->result = pst2->result;              /* Return result grid      */
+  gree(pst2,"f404");
+  gree(pfc,"f405");
+  return (ch);                             /* And return new pointer  */
+
+err:
+  gree(pst2,"f406");
+  gree(pfc,"f407");
+  return (NULL);
+
+}
+
+
+/**********************************************************************\
+*                                                                      *
+*  Function routines follow.  To add a funcion routine, add code here, *
+*  and update the gafunc.h file.                                       *
+*                                                                      *
+\**********************************************************************/
+
+gaint ffsqrt (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt,ecnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from SQRT: Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  ecnt=0;
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val  = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) {
+        if (*val<0.0) {
+          *valu = 0;
+          ecnt++;
+        } else {
+	  *val = sqrt(*val);
+	  *valu = 1;
+	}
+      }
+	val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask != 0) {
+        if (rpt->val < 0.0) {
+          rpt->umask = 0;
+          ecnt++;
+        } else rpt->val = sqrt(rpt->val);
+      }
+      rpt=rpt->rpt;
+    }
+  }
+  if (ecnt>0) {
+    snprintf(pout,255,"Warning from SQRT:  Data has %i values < zero \n",ecnt);
+    gaprnt (1,pout);
+    gaprnt (1,"                    These were set to the undefined value \n");
+  }
+  return (0);
+}
+
+gaint ffsin  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from SIN:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) *val = sin(*val);
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) rpt->val = sin(rpt->val);
+      rpt=rpt->rpt;
+    }
+  }
+
+  return (0);
+}
+
+gaint ffcos  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from COS:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) *val = cos(*val);
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) rpt->val = cos(rpt->val);
+      rpt=rpt->rpt;
+    }
+  }
+
+  return (0);
+}
+
+gaint fftan  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from TAN:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) *val = tan(*val);
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) rpt->val = tan(rpt->val);
+      rpt=rpt->rpt;
+    }
+  }
+  return (0);
+}
+
+gaint ffasin  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from ASIN:  Too many or too few args \n");
+    gaprnt (0,"                  One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) {
+        if (*val>1.0 || *val<-1.0) {
+	  *valu = 0;
+	}
+        else {
+	  *val = asin(*val);
+	}
+      }
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) {
+        if (rpt->val>1.0 || rpt->val<-1.0) rpt->umask = 0;
+        else rpt->val = asin(rpt->val);
+      }
+      rpt=rpt->rpt;
+    }
+  }
+  return (0);
+}
+
+gaint ffacos  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from ACOS:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) {
+        if (*val>1.0 || *val<-1.0) {
+	  *valu = 0;
+	}
+        else {
+	  *val = acos(*val);
+	}
+      }
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) {
+        if (rpt->val>1.0 || rpt->val<-1.0) rpt->umask = 0;
+        else rpt->val = acos(rpt->val);
+      }
+      rpt=rpt->rpt;
+    }
+  }
+  return (0);
+}
+
+gaint ffabs (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from ABS:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) *val = fabs(*val);
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) rpt->val = fabs(rpt->val);
+      rpt=rpt->rpt;
+    }
+  }
+
+  return (0);
+}
+
+gaint ffexp  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from EXP:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) *val = exp(*val);
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) rpt->val = exp(rpt->val);
+      rpt=rpt->rpt;
+    }
+  }
+
+  return (0);
+}
+
+gaint fflog  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt,ecnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from LOG:  Too many or too few args \n");
+    gaprnt (0,"                 One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  ecnt=0;
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) {
+        if (*val<=0.0) {
+          *valu = 0;
+          ecnt++;
+        } 
+	else *val = log(*val);
+      }
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) {
+        if (rpt->val<=0.0) {
+          rpt->umask = 0;
+          ecnt++;
+        } else rpt->val = log(rpt->val);
+      }
+      rpt=rpt->rpt;
+    }
+  }
+  if (ecnt>0) {
+    snprintf(pout,255,"Warning from LOG:  Data has %i values <= zero \n",ecnt);
+    gaprnt (1,pout);
+    gaprnt (1,"                   These were set to the undefined value \n");
+  }
+
+  return (0);
+}
+
+gaint fflog10 (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt,ecnt;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val;
+char *valu;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from LOG10:  Too many or too few args \n");
+    gaprnt (0,"                   One argument expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  ecnt=0;
+  if (pst->type==1) {
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    valu = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (*valu!=0) {
+        if (*val<=0.0) {
+          *valu = 0;
+          ecnt++;
+        } else *val = log10(*val);
+      }
+      val++; valu++;
+    }
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask!=0) {
+        if (rpt->val<=0.0) {
+          rpt->umask = 0;
+          ecnt++;
+        } else rpt->val = log10(rpt->val);
+      }
+      rpt=rpt->rpt;
+    }
+  }
+  if (ecnt>0) {
+    snprintf(pout,255,"Warning from LOG10:  Data has %i values <= zero \n",ecnt);
+    gaprnt (1,pout);
+    gaprnt (1,"                     These were set to the undefined value \n");
+  }
+
+  return (0);
+}
+
+gaint ffpow (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+gaint rc;
+
+  if (pfc->argnum!=2) { 
+    gaprnt (0,"Error from POW:  Too many or too few args \n");
+    gaprnt (0,"                 Two arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  pst2 = *pst;
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) {
+    gafree (pst);
+    return (rc);
+  }
+
+  rc = gafopr (pst, &pst2, 10);
+  if (rc) {
+    gafree (pst);
+    gafree (&pst2);
+  }
+
+  return (rc);
+}
+
+gaint ffmag (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+gaint rc;
+
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from MAG:  Too many or too few args \n");
+    gaprnt (0,"                 Two arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  pst2 = *pst;
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) {
+    gafree (pst);
+    return (rc);
+  }
+
+  rc = gafopr (pst, &pst2, 11);
+  if (rc) {
+    gafree (pst);
+    gafree (&pst2);
+  }
+  return (rc);
+}
+
+/* Perform atan2 function */
+
+gaint ffatan (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+gaint rc;
+
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from ATAN2:  Too many or too few args \n");
+    gaprnt (0,"                   Two arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  pst2 = *pst;
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) {
+    gafree (pst);
+    return (rc);
+  }
+
+  rc = gafopr (pst, &pst2, 12);
+  if (rc) {
+    gafree (pst);
+    gafree (&pst2);
+  }
+  return (rc);
+}
+
+/* Performs a bi-linear interpolation between two grids, 
+   adapted from the external UDF lterp.
+*/ 
+gaint fflterp (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+struct gagrid *pgr1,*pgr2;
+gadouble (*i1conv) (gadouble *, gadouble);
+gadouble (*i2conv) (gadouble *, gadouble);
+gadouble *x1=NULL,*x2=NULL,*y1=NULL,*y2=NULL;
+gadouble *x1b=NULL,*x2b=NULL,*y1b=NULL,*y2b=NULL;
+gadouble *gr1,*gr2,*gxout=NULL,*gyout=NULL,*area1=NULL,*area2=NULL;
+gadouble rad,w1,w2=0,alo,ahi,pct,minpct,tscl;
+gaint rc,i,ii,j,jj,i2,ij,ij1,ij2,j2,error=0,opt;
+gaint pxgbflg,pygbflg; 
+gaint ib,ie,jb,je,maxgrid,icnt,indx,flag;
+gadouble *area_box=NULL,*fld_box=NULL,tot_fld,tot_area;
+char *gr1u,*gr2u;
+struct gafile *pfi1,*pfi2;
+gaint ic,jc,k,jcm1,jcp1,jcp2,bessel;
+gadouble r,s,r1,r2,r3,s1,s2,s3,fijm1,fij,fijp1,fijp2,u,fr[4],del,del2,del3;
+char uijm1,uij,uijp1,uijp2;
+struct dt t1g1;
+gadouble tval;
+/* only needed for legacy bilin code */
+/* gadouble xd,yd,rd,t1,t2;   */
+/* gaint i1,j1,idir2,jdir2; */
+  
+  rad = M_PI/180.0;
+
+  if (pfc->argnum<2 || pfc->argnum>4) {
+    gaprnt (0,"Error from LTERP:  Too many or too few args \n");
+    gaprnt (0,"                    2 to 4 arguments expected \n");
+    return (1);
+  }
+
+  if (pfc->argnum>=3) {
+    if (strcmp("bilin",pfc->argpnt[2])==0)  {opt = 0; bessel=0;}  /* bilinear interpolation */
+    if (strcmp("bessel",pfc->argpnt[2])==0) {opt = 0; bessel=1;}  /* bilinear interpolation with bessel */
+    if (strcmp("aave" ,pfc->argpnt[2])==0)   opt = 1;             /* area average */
+    if (strcmp("amean",pfc->argpnt[2])==0)   opt = 2;             /* area mean */
+
+    if (pfc->argnum==4) {
+      if (getdbl(pfc->argpnt[3],&minpct)==NULL) {
+	gaprnt (0,"Error from LTERP:  4th argument must be a real number between 0 and 100 \n");
+	return(1);
+      }
+      if (minpct<0 || minpct>100) {
+	gaprnt (0,"Error from LTERP:  4th argument must be between 0 and 100 \n");
+	return(1);
+      }
+    }
+    else minpct=50.0;
+  }
+  else {
+    opt=0;         /* bilin without bessel is the default */
+    bessel=0;
+  }
+
+
+   /* Evaluate the 2nd expression, the destination grid */
+  pst2=*pst;
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) { 
+    gaprnt (0,"Error from LTERP: Failed to evaluate 2nd expression \n"); 
+    error=1; goto err; 
+  }
+  if (pst->type!=1) {
+    gaprnt (0,"Error from LTERP: The 2nd argument is not a grid expression \n"); 
+    error=1; goto err;
+  }
+
+  /* Check environment */
+  if (pst->idim==-1) {
+    gaprnt (0,"Error from LTERP: The destination grid is a constant \n"); 
+    error=1; goto err;
+  }
+  if (pst->idim==2 || pst->idim==4 || pst->jdim==2 || pst->jdim==4) {
+    gaprnt (0,"Error from LTERP: The grids cannot vary in Z or E \n"); 
+    error=1; goto err;
+  }
+  if (opt==1 || opt==2) {
+    if (pst->idim!=0 || pst->jdim!=1) {
+    gaprnt (0,"Error from LTERP: The grids must vary in X and Y when using aave or amean\n");
+    error=1; goto err;
+    }
+  }
+ 
+  /* Evaluate the 1st expression, the data values to be interpolated */
+  rc = gaexpr(pfc->argpnt[0],&pst2);
+  if (rc) { 
+    gaprnt (0,"Error from LTERP: Failed to evaluate 1st expression \n");
+    error=1; goto err; 
+  }
+  if (pst2.type!=1) {
+    gaprnt (0,"Error from LTERP: The 1st argument is not a grid expression \n");
+    error=1; goto err;
+  }
+
+  /* Verify that the varying dimensions are equivalent */
+  if (pst->idim!=pst2.idim || pst->jdim!=pst2.jdim) {
+    gaprnt (0,"Error from LTERP: Grids have different varying dimensions \n");
+    error=1; goto err;
+  }
+
+  /* Get the grids */
+  pgr1 = pst2.result.pgr;     /* data source grid (input)  */
+  pgr2 = pst->result.pgr;     /* destination grid (result) */
+  gr1  = pgr1->grid;
+  gr1u = pgr1->umask;
+  gr2  = pgr2->grid;
+  gr2u = pgr2->umask;
+  pfi1 = pgr1->pfile;
+  pfi2 = pgr2->pfile;
+
+  /* If the time dimension varies, the time increment must be equivalent 
+     (we won't interpolate from months to minutes) */
+  if (pst->idim==3) {
+    if ((*(pgr1->ivals+6)<0.5 && *(pgr2->ivals+6)>0.8) || 
+	(*(pgr1->ivals+6)>0.8 && *(pgr2->ivals+6)<0.5)) {
+      gaprnt (0,"Error from LTERP: Grids do not have matching time increments \n");
+      error=1; goto err;
+    }
+  }
+  if (pst->jdim==3) {
+    if ((*(pgr1->jvals+6)<0.5 && *(pgr2->jvals+6)>0.8) || 
+	(*(pgr1->jvals+6)>0.8 && *(pgr2->jvals+6)<0.5)) {
+      gaprnt (0,"Error from LTERP: Grids do not have matching time increments \n");
+      error=1; goto err;
+    }
+  }
+
+  /* get coordinate information (grid box centers and edges) for both grids, 
+     source input grid 1 and destination output grid 2 */
+
+  if (pgr1->idim>-1) {
+    /* x1  is for the longitude of source grid box centers */
+    /* x1b is for the longitude of source grid box boundaries */
+    x1 = (gadouble *)galloc(sizeof(gadouble)*pgr1->isiz,"x1");
+    if (x1==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for x1\n");
+      error=1; goto err; 
+    }
+    if (pgr1->idim==3) {
+      /* don't need to get the boundaries for time interpolation */
+      j=0;
+      for (i=pgr1->dimmin[pgr1->idim];i<=pgr1->dimmax[pgr1->idim];i++) {
+	*(x1+j) = (gadouble)i;
+	j++;
+      }
+    } else {
+      /* one extra point in the boundary array */
+      x1b = (gadouble *)galloc(sizeof(gadouble)*(pgr1->isiz+1),"x1b");  
+      if (x1b==NULL) { 
+	gaprnt (0,"Error from LTERP: Unable to allocate memory for x1b\n");
+	error=1; goto err; 
+      }
+      i1conv = pgr1->igrab;
+      j=0;
+      for (i=pgr1->dimmin[pgr1->idim];i<=pgr1->dimmax[pgr1->idim];i++) {
+	*(x1+j)  = i1conv(pgr1->ivals,(gadouble)i);         /* grid box centers */
+	*(x1b+j) = i1conv(pgr1->ivals,(gadouble)(i-0.5));   /* grid box edges */
+	j++;
+      }
+      *(x1b+j) = i1conv(pgr1->ivals,(gadouble)(i-0.5));  /* final edge */
+    }
+  }
+
+  if (pgr2->idim>-1) {
+    /* x2  is for the longitude of destination grid box centers */
+    /* x2b is for the longitude of destination grid box boundaries */
+    x2 = (gadouble *)galloc(sizeof(gadouble)*pgr2->isiz,"x2");
+    if (x2==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for x2\n");
+      error=1; goto err; 
+    }
+    if (pgr2->idim==3) {
+      /* don't need to get the boundaries for time interpolation */
+      j=0;
+      for (i=pgr2->dimmin[pgr2->idim];i<=pgr2->dimmax[pgr2->idim];i++) {
+	*(x2+j) = (gadouble)i;
+	j++;
+      }
+    } else {
+      x2b = (gadouble *)galloc(sizeof(gadouble)*(pgr2->isiz+1),"x2b");
+      if (x2b==NULL) { 
+	gaprnt (0,"Error from LTERP: Unable to allocate memory for x2b\n");
+	error=1; goto err; 
+      }
+      i2conv = pgr2->igrab;
+      j=0;
+      for (i=pgr2->dimmin[pgr2->idim];i<=pgr2->dimmax[pgr2->idim];i++) {
+	*(x2+j)  = i2conv(pgr2->ivals,(gadouble)i);        /* grid box centers */
+	*(x2b+j) = i2conv(pgr2->ivals,(gadouble)(i-0.5));  /* grid box edges */
+	j++;
+      }
+      *(x2b+j) = i2conv(pgr2->ivals,(gadouble)(i-0.5));  /* final edge */
+    }
+  }
+
+  if (pgr1->jdim>-1) {
+    /* y1  is for the latitude of source grid box centers */
+    /* y1b is for the latitude of source grid box boundaries */
+    y1 = (gadouble *)galloc(sizeof(gadouble)*pgr1->jsiz,"y1");
+    if (y1==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for y1\n");
+      error=1; goto err; 
+    }
+    if (pgr1->jdim==3) {
+      /* don't need to get the boundaries for time interpolation */
+      j=0;
+      for (i=pgr1->dimmin[pgr1->jdim];i<=pgr1->dimmax[pgr1->jdim];i++) {
+	*(y1+j) = (gadouble)i;
+	j++;
+      }
+    } else {
+      y1b = (gadouble *)galloc(sizeof(gadouble)*(pgr1->jsiz+1),"y1b");
+      if (y1b==NULL) { 
+	gaprnt (0,"Error from LTERP: Unable to allocate memory for y1b\n");
+	error=1; goto err; 
+      }
+      i1conv = pgr1->jgrab;
+      j=0;
+      for (i=pgr1->dimmin[pgr1->jdim];i<=pgr1->dimmax[pgr1->jdim];i++) {
+	*(y1+j)  = i1conv(pgr1->jvals,(gadouble)i);         /* grid box centers */
+	*(y1b+j) = i1conv(pgr1->jvals,(gadouble)(i-0.5));   /* grid box edges */
+	j++;
+       }
+      *(y1b+j) = i1conv(pgr1->jvals,(gadouble)(i-0.5));  /* final edge */
+    }
+  }
+
+  if (pgr2->jdim>-1) {
+    /* y2  is for the latitude of destination grid box centers */
+    /* y2b is for the latitude of destination grid box boundaries */
+    y2 = (gadouble *)galloc(sizeof(gadouble)*pgr2->jsiz,"y2");
+    if (y2==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for y2\n");
+      error=1; goto err; 
+    }
+    if (pgr2->jdim==3) {
+      /* don't need to get the boundaries for time interpolation */
+      j=0;
+      for (i=pgr2->dimmin[pgr2->jdim];i<=pgr2->dimmax[pgr2->jdim];i++) {
+	*(y2+j) = (gadouble)i;
+	j++;
+      }
+    } else {
+      y2b = (gadouble *)galloc(sizeof(gadouble)*(pgr2->jsiz+1),"y2b");
+      if (y2==NULL) { 
+	gaprnt (0,"Error from LTERP: Unable to allocate memory for y2b\n");
+	error=1; goto err; 
+      }
+      i2conv = pgr2->jgrab;
+      j=0;
+      for (i=pgr2->dimmin[pgr2->jdim];i<=pgr2->dimmax[pgr2->jdim];i++) {
+	*(y2+j)  = i2conv(pgr2->jvals,(gadouble)i);         /* grid box centers */
+	*(y2b+j) = i2conv(pgr2->jvals,(gadouble)(i-0.5));   /* grid box edges */
+	j++;
+      }
+      *(y2b+j) = i2conv(pgr2->jvals,(gadouble)(i-0.5));   /* final edge */  
+    }
+  }
+
+  /* Normalize the time coordinates.  We want the grid time values to
+     be the same coordinate system for each grid.  */
+  if (pst->idim==3 || pst->jdim==3) {
+
+    /* get world coordinate value of initial t for grid 2 (destination grid) */
+    gr2t (pfi2->grvals[3],pgr2->dimmin[3],&t1g1);
+    /* find the t value for this time in the axis of grid 1 (src grid) */
+    tval = t2gr(pfi1->abvals[3], &t1g1);
+
+    if (pst->idim==3) {
+      /* the i dimension is T-varying */
+      /* determine scaling factor */
+      if (pgr1->ivals[6]>0.8) 
+	tscl = pgr2->ivals[6] / pgr1->ivals[6] ;
+      else
+	tscl = pgr2->ivals[5] / pgr1->ivals[5] ;
+      /* normalize */
+      for (i=0; i<pgr2->isiz; i++) *(x2+i) = tval + tscl*(gadouble)i;
+    }
+    else {
+      /* the j dimension is T-varying */
+      /* determine scaling factor */
+      if (pgr1->jvals[6]>0.8)
+	tscl = pgr2->jvals[6] / pgr1->jvals[6] ;
+      else
+	tscl = pgr2->jvals[5] / pgr1->jvals[5] ;
+      /* normalize */
+      for (i=0; i<pgr2->jsiz; i++) *(y2+i) = tval + tscl*(gadouble)i;
+    }
+  }
+
+  if (opt==1 || opt==2) {
+    /* for aave and amean, 
+       gxout/gyout contain real-valued locations of output grid box EDGES in i/j-axis of input grid, 
+       and whole integer values of gxout/gyout correspond to input grid point boundaries */
+    
+    /* allocate memory with one extra point in array size for final boundary value */
+    gxout = (gadouble *)galloc((pgr2->isiz+1)*sizeof(gadouble),"gxout");
+    if (gxout==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for gxout\n"); error=1; goto err; 
+    }
+    gyout = (gadouble *)galloc((pgr2->jsiz+1)*sizeof(gadouble),"gyout");
+    if (gyout==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for gyout\n"); error=1; goto err; 
+    }
+    /* loop over i dimension for output grid boundaries */
+    for (i2=0; i2<=pgr2->isiz; i2++) {  
+      /* check if this output grid point lies inside the longitude range of input grid */
+      if ((*(x2b+i2) >= *(x1b+0)) && (*(x2b+i2) <= *(x1b+pgr1->isiz))){
+	/* loop over i dimension for input grid boundaries */
+	for (i=0; i<pgr1->isiz; i++) {
+	  if (*(x2b+i2) >= *(x1b+i) && *(x2b+i2) <= *(x1b+i+1)) {
+	    *(gxout+i2) = (gadouble)i + (*(x2b+i2)-*(x1b+i))/(*(x1b+i+1)-*(x1b+i));
+	    break;
+	  }
+	}
+      }
+      else {
+	/* output grid point is outside the longitude range of input grid */
+	if (*(x2b+i2) < *(x1b+0)) 
+	  *(gxout+i2) = 0.0;
+	else 
+	  *(gxout+i2) = (gadouble)pgr1->isiz;
+      }
+    }
+    /* loop over j dimension for output grid boundaries */
+    for (j2=0; j2<=pgr2->jsiz; j2++) {
+      /* check if this output grid point lies inside the latitude range of input grid */
+      if (*(y2b+j2) >= *(y1b+0) && *(y2b+j2) <= *(y1b+pgr1->jsiz)) {
+	/* loop over j dimension for input grid boundaries */
+	for (j=0; j<pgr1->jsiz; j++) {
+	  if (*(y2b+j2) >= *(y1b+j) && *(y2b+j2) <= *(y1b+j+1)) {
+	    *(gyout+j2) = (gadouble)j + (*(y2b+j2)-*(y1b+j))/(*(y1b+j+1)-*(y1b+j));
+	    break;
+	  }
+	}
+      }
+      else {
+	/* output grid point is outside the longitude range of input grid */
+	if (*(y2b+j2) < *(y1b+0))  
+	  *(gyout+j2) = 0.0;
+	else 
+	  *(gyout+j2) = (gadouble)pgr1->jsiz;
+      }
+    }
+  }
+  else {
+    /* for bilin (opt==0), 
+       gxout/gyout contain real-valued locations of output grid box CENTERS in i/j-axis of input grid, 
+       and whole integer values of gxout/gyout correspond to input grid point centers */
+    
+    /* allocate memory */
+    gxout = (gadouble *)galloc((pgr2->isiz)*sizeof(gadouble),"gxout");
+    if (gxout==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for gxout\n"); error=1; goto err; 
+    }
+    /* loop over i dimension for output grid centers */
+    for (i2=0; i2<pgr2->isiz; i2++) {  
+      /* initialize -- destination grid points outside range of input grid will have gxout=-999 */
+      *(gxout+i2)=-999;   
+      /* check if this output grid point lies inside the longitude range of input grid box centers */
+      if ((*(x2+i2) >= *(x1+0)) && (*(x2+i2) <= *(x1+pgr1->isiz-1))){
+	/* loop over i dimension for input grid box centers */
+	for (i=0; i<pgr1->isiz-1; i++) {
+	  if (*(x2+i2) >= *(x1+i) && *(x2+i2) <= *(x1+i+1)) {
+	    *(gxout+i2) = (gadouble)i + (*(x2+i2)-*(x1+i))/(*(x1+i+1)-*(x1+i));
+	    break;
+	  }
+	}
+      }
+    }
+    if (pgr1->jdim>0) {
+      /* allocate memory */
+      gyout = (gadouble *)galloc((pgr2->jsiz)*sizeof(gadouble),"gyout");
+      if (gyout==NULL) { 
+	gaprnt (0,"Error from LTERP: Unable to allocate memory for gyout\n"); error=1; goto err; 
+      }
+      /* loop over j dimension for output grid boundaries */
+      for (j2=0; j2<pgr2->jsiz; j2++) {
+	/* initialize -- destination grid points outside range of input grid will have gyout=-999 */
+	*(gyout+j2)=-999; 
+	/* check if this output grid point lies inside the latitude range of input grid */
+	if (*(y2+j2) >= *(y1+0) && *(y2+j2) <= *(y1+pgr1->jsiz-1)) {
+	  /* loop over j dimension for input grid boundaries */
+	  for (j=0; j<pgr1->jsiz-1; j++) {
+	    if (*(y2+j2) >= *(y1+j) && *(y2+j2) <= *(y1+j+1)) {
+	      *(gyout+j2) = (gadouble)j + (*(y2+j2)-*(y1+j))/(*(y1+j+1)-*(y1+j));
+	      break;
+	    }
+	  }
+	}
+      }
+    }
+  }
+
+  /* calculate the area of each grid box for the input and output grids */
+  /* areas are weighted by latitude if using aave, but not if using amean */
+  /* don't bother to calculate areas if using bilin */
+  if (opt==1 || opt==2) {
+    area1 = (gadouble *)galloc(pgr1->isiz*pgr1->jsiz*sizeof(gadouble),"area1");
+    if (area1==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for area1\n"); error=1; goto err; 
+    }
+    for (j=0; j<pgr1->jsiz; j++) {
+      alo = *(y1b+j);
+      ahi = *(y1b+j+1);
+      if (alo < -90.0) alo = -90.0; if (alo > 90.0) alo = 90.0;
+      if (ahi < -90.0) ahi = -90.0; if (ahi > 90.0) ahi = 90.0;
+      if (opt==1) 
+	w1 = fabs(sin(ahi*rad)-sin(alo*rad));  /* length is weighted by latitude (aave) */
+      else 
+	w1 = fabs((ahi-alo)*rad);              /* length is not weighted by latitude (amean) */
+      for (i=0; i<pgr1->isiz; i++) {
+	ij = j*pgr1->isiz+i;  
+	alo = *(x1b+i);
+	ahi = *(x1b+i+1);
+	w2 = fabs((ahi-alo)*rad);              /* w2 is the width of grid box  */
+	*(area1+ij) =  w1 * w2;
+      }
+    }
+    area2 = (gadouble *)galloc(pgr2->isiz*pgr2->jsiz*sizeof(gadouble),"area2");
+    if (area2==NULL) { 
+      gaprnt (0,"Error from LTERP: Unable to allocate memory for area2\n"); error=1; goto err; 
+    }
+    for (j=0; j<pgr2->jsiz; j++) {
+      alo = *(y2b+j);
+      ahi = *(y2b+j+1);
+      if (alo < -90.0) alo = -90.0; if (alo > 90.0) alo = 90.0;
+      if (ahi < -90.0) ahi = -90.0; if (ahi > 90.0) ahi = 90.0;
+      if (opt==1) 
+	w1 = fabs(sin(ahi*rad)-sin(alo*rad));  /* length is weighted by latitude (aave) */
+      else 
+	w1 = fabs((ahi-alo)*rad);              /* length is not weighted by latitude (amean) */
+      for (i=0; i<pgr2->isiz; i++) {
+	ij = j*pgr2->isiz+i;  
+	alo = *(x2b+i);
+	ahi = *(x2b+i+1);
+	w2 = fabs((ahi-alo)*rad);              /* w2 is the width of grid box  */
+	*(area2+ij) =  w1 * w2;
+      }
+    }
+  }
+
+  /* Finally, we're ready to perform the interpolation */
+  if (opt==1 || opt==2) {
+    /* box averaging, based on doaave, regrid2.f and re.c */
+
+    /* loop over output grid points */
+    for (j=0; j<pgr2->jsiz; j++) {
+      for (i=0; i<pgr2->isiz; i++) {
+	ij = j*pgr2->isiz+i;  
+	if (*(area2+ij) > 0) {
+	  /* whole integer values of gxout and gyout correspond to the boundaries of input grid boxes */
+	  ib = (int)*(gxout+i);
+	  ie = (int)*(gxout+i+1);
+	  jb = (int)*(gyout+j);
+	  je = (int)*(gyout+j+1);
+	  /* allocate memory for group of input grid boxes within a single output grid box */
+	  maxgrid = (ie-ib+1)*(je-jb+1);
+	  area_box = (gadouble *)galloc(sizeof(gadouble)*maxgrid,"area_box");
+	  fld_box  = (gadouble *)galloc(sizeof(gadouble)*maxgrid,"fld_box");
+	  if (area_box==NULL || fld_box==NULL) {
+	    gaprnt (0,"Error from LTERP: memory allocation error for box_averaging \n");
+	    error=1; goto err;
+	  }      
+	  /* Now loop over all input grid boxes that lie within the output grid box.
+	     Figure out area of of each, whether whole or partial. 
+	     Start with the length along the latitude axis. 
+	     If input grid box is partially inside output grid box, we need to recalculate w1 */
+	  icnt=0;   /* initialize the counter for input grid boxes that are within output grid box */
+	  for (jj=jb; jj<=je; jj++) {
+	    pygbflg=0;                 /* not a partial grid box in y */
+	    if (jb!=je && jj==jb) { 
+	      /* more than one in y range, and this grid box is at bottom of y range */
+	      /* re-calculate length of partial grid box */
+	      pygbflg=1;
+	      alo = *(y2b+j);
+	      ahi = *(y1b+jb+1);
+	      if (alo < -90.0) alo = -90.0; if (alo > 90.0) alo = 90.0;
+	      if (ahi < -90.0) ahi = -90.0; if (ahi > 90.0) ahi = 90.0;
+	      /* don't let alo be less than min lat of source grid */
+	      if (jb==0 && alo<*(y1b)) alo = *(y1b);
+	      if (opt==1)
+		w1 = fabs(sin(ahi*rad)-sin(alo*rad)); 
+	      else 
+		w1 = fabs((ahi-alo)*rad);
+	    }
+	    else if (je!=jb && jj==je) {                     
+	      /* more than one in y range, and this grid box is at top of y range */
+	      /* re-calculate length of partial grid box */
+	      pygbflg=1;
+	      alo = *(y1b+je);
+	      ahi = *(y2b+j+1);
+	      if (alo < -90.0) alo = -90.0; if (alo > 90.0) alo = 90.0;
+	      if (ahi < -90.0) ahi = -90.0; if (ahi > 90.0) ahi = 90.0;
+	      /* don't let ahi be more than max lat of source grid */
+	      if (je==pgr1->jsiz && ahi>*(y1b+je)) ahi=*(y1b+je);
+	      if (opt==1) 
+		w1 = fabs(sin(ahi*rad)-sin(alo*rad));
+	      else 
+		w1 = fabs((ahi-alo)*rad);
+	    }
+	    else {
+	      /* only one box in y range, or this box is in the middle of the y range. 
+		 either way, we will use entire length of output grid box (pygblfg is still 0) */
+	      /* get length anyway in case we have a partial overlap in the x dimension */
+	      alo = *(y1b+jj);
+	      ahi = *(y1b+jj+1);
+	      if (alo < -90.0) alo = -90.0; if (alo > 90.0) alo = 90.0;
+	      if (ahi < -90.0) ahi = -90.0; if (ahi > 90.0) ahi = 90.0;
+	      if (opt==1) 
+		w1 = fabs(sin(ahi*rad)-sin(alo*rad));
+	      else 
+		w1 = fabs((ahi-alo)*rad);
+	    }
+	    /* Now get the width along the longitude axis.
+	       If input grid box is partially inside the output grid box, we need to recalculate w2 */
+	    for (ii=ib; ii<=ie; ii++) {
+	      pxgbflg=0;                 /* not a partial grid box in x */   
+	      if (ib!=ie && ii==ib) {
+		/* more than one in x range, and this grid box is at left edge of range */
+		pxgbflg=1;
+		alo = *(x2b+i);
+		ahi = *(x1b+ib+1);
+		/* don't let alo be less than min lon of source grid */
+		if (ib==0 && alo<*(x1b)) alo = *(x1b);
+		w2 = fabs((ahi-alo)*rad);
+	      }
+	      else if (ie!=ib && ii==ie) {
+		/* more than one in x range, and this grid box is at right edge of range */
+		pxgbflg=1;
+		alo = *(x1b+ie);
+		ahi = *(x2b+i+1);
+		/* don't let ahi be more than max lon of source grid */
+		if (ie==pgr1->isiz && ahi>*(x1b+ie)) ahi=*(x1b+ie);
+		w2 = fabs((ahi-alo)*rad);
+	      }
+	      else {
+		/* only one box in x range, or this box is in the middle of the x range. 
+		   either way, we'll use entire width of output grid box (pxgbflg is 0) */
+		if (pygbflg) {
+		  /* get width because we have a partial overlap in the y dimension */
+		  alo = *(x1b+ii);
+		  ahi = *(x1b+ii+1);
+		  w2 = fabs((ahi-alo)*rad);
+		}
+	      }	
+	      /* Set the area and data value for each non-missing input grid box in range */
+	      indx = jj*pgr1->isiz+ii;
+	      if ((*(gr1u+indx)==1) && (*(area1+indx)>0)) {
+		if (pygbflg || pxgbflg) {
+		  /* recalculate area of partial grid box, as long as length and width are non-zero */
+		  if (w1>0 && w2>0) {
+		    *(area_box+icnt) = w1 * w2; 
+		    *(fld_box+icnt)  = *(gr1+indx);
+		    icnt++;
+		  } 
+		}
+		else {
+		  /* the entire input grid box is within output grid, use area1 (already calculated) */
+		  *(area_box+icnt) = *(area1+indx);
+		  *(fld_box+icnt)  = *(gr1+indx);
+		  icnt++;
+		} 
+	      }		
+	      if (icnt > maxgrid) { 
+		gaprnt (0,"Error from LTERP: icnt>maxgrid \n");
+		error=1; goto err; 
+	      }
+	    }
+	  }
+	  /* Now integrate over all the input boxes within the output box */
+	  tot_fld = 0.0;
+	  tot_area = 0.0;
+	  for (ii=0; ii<icnt; ii++) {
+	    tot_fld  = tot_fld + (*(fld_box+ii) * *(area_box+ii));
+	    tot_area = tot_area + *(area_box+ii);
+	  }
+	  /* Calculate the percentage of the output grid box area that contains valid data */
+	  pct = 100*(tot_area/(*(area2+ij)));
+	  if (pct>minpct) {
+	    *(gr2u+ij) = 1;
+	    *(gr2+ij) = tot_fld/tot_area;
+	  }
+	  else {
+	    *(gr2u+ij) = 0;
+	  }
+	  /* release memory */
+	    if (fld_box)  gree(fld_box,"399a");
+	    if (area_box) gree(area_box,"399b");
+	    fld_box = area_box = NULL;
+	} /* matches if *(area2+ij)>0 */
+      }
+    }
+  } /* matches if (opt==1 || opt==2) (for box averaging) */
+  
+  else {
+    /* bilinear interpolation based on regrid2.f and re.c */
+    /* bilinear/bessel interpolation based on the FNOC routine bssl5 by D. Hensen, FNOC */
+    
+    /* 1D */
+    if (pgr1->jdim<0) {
+      /* loop over all points in destination output grid */
+      for (i=0; i<pgr2->isiz; i++) { 	
+	/* check if this destination grid point is outside the source grid */
+	if (gxout[i]<0) {
+	  *(gr2u+i) = 0;
+	}
+	else {
+	  /* ic is index values for nearest input source grid point */
+	  ic = (int) gxout[i];
+	  r = gxout[i] - ic;
+	  /* if we're at the edge of the grid, and endpoints of both grids have the same value,
+	     we'll use the endpoints in the result grid -- tweak ic, and r to enable this. */
+	  if ((ic==pgr1->isiz-1) && x1[ic]==x2[i]) {
+	    ic--;
+	    r=1;
+	  }
+	  /* make sure surrounding points are valid */
+	  if (*(gr1u+ic) == 1 && *(gr1u+ic+1) == 1) {
+	    *(gr2u+i) = 1;
+	    *(gr2+i) = *(gr1+ic)*(1-r) + *(gr1+ic+1)*r;
+	  } 
+	  else {
+	    *(gr2u+i) = 0;
+	  }
+	}
+      }
+    }
+    /* 2D */
+    else {
+      /* loop over all points in destination output grid */
+      for (j=0; j<pgr2->jsiz; j++) {
+	for (i=0; i<pgr2->isiz; i++) {
+	  ij2=i+j*pgr2->isiz;
+	  /* check if this destination grid point is outside the source grid */
+	  if (gxout[i]<0 || gyout[j]<0) {
+	    *(gr2u+ij2) = 0;
+	  } 
+	  else {
+	    /* ic and jc are index values for input source grid point at bottom left of 4 nearest neighbors */
+	    ic = (int) gxout[i];
+	    jc = (int) gyout[j];
+	    r = gxout[i] - ic;
+	    s = gyout[j] - jc;			
+	    /* if we're at the top/right edge of the grid, and endpoints of both grids have the same value,
+	       we'll use the endpoints in the result grid -- tweak ic, jc, r, and s to enable this. */
+	    if ((ic==pgr1->isiz-1) && x1[ic]==x2[i]) {
+	      ic--;
+	      r=1;
+	    }
+	    if ((jc==pgr1->jsiz-1) && y1[jc]==y2[j]) {
+	      jc--;
+	      s=1;
+	    }
+	    ij1=ic+jc*pgr1->isiz;
+	    /* make sure surrounding points are valid */
+	    if (*(gr1u+ij1) == 1 && 
+		*(gr1u+ij1+1) == 1 && 
+		*(gr1u+ij1+pgr1->isiz) == 1 && 
+		*(gr1u+ij1+pgr1->isiz+1) == 1) {
+	      *(gr2u+ij2) = 1;
+	      *(gr2+ij2) = (1-s)*(*(gr1+ij1)*(1-r) + *(gr1+ij1+1)*r) + 
+		s*(*(gr1+ij1+pgr1->isiz)*(1-r) + *(gr1+ij1+pgr1->isiz+1)*r);
+	    } 
+	    else {
+	      *(gr2u+ij2) = 0;
+	    }
+	    
+	    if (bessel==1) {
+	      /* refine interpolation with bessel algorithm */
+	      /* interpolate 4 columns (i-1,i,i+1,i+2) to j+s and store in fr[0] through fr[3]*/
+	      r1 = r - 0.5;
+	      r2 = r * (r-1) * 0.5;
+	      r3 = r1 * r2 * (1/3);
+	      s1 = s - 0.5;
+	      s2 = s * (s-1) * 0.5;
+	      s3 = s1 * s2 * (1/3);
+	      k = 0;
+	      flag=1;
+	      for (ii=ic-1; ii<=ic+2; ii++) {
+		/* make sure we're far enough away from the grid edges */
+		if (ic==0 || jc==0) { flag=0; break; }
+		if (ic>pgr1->isiz-3 || jc>pgr1->jsiz-3) { flag=0; break; }
+		
+		/* set up indices and values for secondary ring -- the nearest 16 grid points */
+		jcp1 = jc+1;
+		jcp2 = jc+2;
+		jcm1 = jc-1;
+		
+		fijm1 = *(gr1+ii + jcm1 * pgr1->isiz);
+		fij   = *(gr1+ii + jc   * pgr1->isiz);
+		fijp1 = *(gr1+ii + jcp1 * pgr1->isiz);
+		fijp2 = *(gr1+ii + jcp2 * pgr1->isiz);
+		
+		uijm1 = *(gr1u+ii + jcm1 * pgr1->isiz);
+		uij   = *(gr1u+ii + jc   * pgr1->isiz);
+		uijp1 = *(gr1u+ii + jcp1 * pgr1->isiz);
+		uijp2 = *(gr1u+ii + jcp2 * pgr1->isiz);
+		
+		/* exit if any value undefined */
+		if (uijm1 == 0 || uij == 0 || uijp1 == 0 || uijp2 == 0) { flag=0; break; }
+		u = (fij + fijp1) * 0.5;
+		del = fijp1 - fij;
+		del2 = (fijp2 - fijp1 + fijm1 - fij) * 0.5;
+		del3 = fijp2 - fijp1 - del * 2 + fij - fijm1;
+		fr[k] = u + s1*del + s2*del2 + s3*del3;
+		k++;
+	      }
+	      
+	      /* interpolate the fr row to ii+r */
+	      if (flag) {
+		u = (fr[1] + fr[2]) * 0.5;
+		del = fr[2] - fr[1];
+		del2 = (fr[3] - fr[2] + fr[0] - fr[1]) * 0.5;
+		del3 = fr[3] - fr[2] - del*2 + fr[1] - fr[0];
+		*(gr2+ij2) = u + r1*del + r2*del2 + r3*del3;
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+
+/* Alternaive bilinear interpolation from Brian Doty's lterp code */
+/*     /\* see which way x y vary with i*\/ */
+/*     if (pgr2->ilinr == 0) { */
+/*       idir2 = -1; */
+/*       if (*(x2+1) > *x2) idir2 = 1; */
+/*     } else { */
+/*       idir2 = 1; */
+/*     } */
+/*     if (pgr2->jlinr == 0) { */
+/*       jdir2 = -1; */
+/*       if (*(y2+1) > *y2) jdir2 = 1; */
+/*     } else { */
+/*       jdir2 = 1; */
+/*     } */
+/*     if (pgr1->jdim<0) { */
+/*       /\* 1D *\/ */
+/*       i1 = -1; */
+/*       for (i2=0; i2<pgr2->isiz; i2++) { */
+/* 	if (idir2 == 1) { */
+/* 	  while (i1<pgr1->isiz-1 && *(x1+i1+1)<=*(x2+i2)) i1++; */
+/* 	} else { */
+/* 	  while (i1<pgr1->isiz-1 && *(x1+i1+1)>=*(x2+i2)) i1++; */
+/* 	}  */
+/* 	if (i1==pgr1->isiz-1 && *(x1+i1)==*(x2+i2)) i1--; */
+/* 	if (i1<0 || i1>pgr1->isiz-2 || *(gr1u+i1)==0 || *(gr1u+i1+1)==0) { */
+/* 	  *(gr2u+i2) = 0; */
+/* 	} */
+/* 	else { */
+/* 	  xd = *(x1+i1+1) - *(x1+i1); */
+/* 	  rd = *(gr1+i1+1) - *(gr1+i1); */
+/* 	  *(gr2+i2) = *(gr1+i1)+(*(x2+i2)-*(x1+i1))*rd/xd; */
+/* 	  *(gr2u+i2) = 1; */
+/* 	} */
+/*       } */
+/*     } else { */
+/*       /\* 2D *\/ */
+/*       j1 = -1; */
+/*       for (j2=0; j2<pgr2->jsiz; j2++) { */
+/* 	if (jdir2 == 1) { */
+/* 	  while (j1<pgr1->jsiz-1 && *(y1+j1+1)<=*(y2+j2)) j1++; */
+/* 	} else { */
+/* 	  while (j1<pgr1->jsiz-1 && *(y1+j1+1)>=*(y2+j2)) j1++; */
+/* 	} */
+/* 	if (j1==pgr1->jsiz-1 && *(y1+j1)==*(y2+j2)) j1--; */
+/* 	i1 = -1; */
+/* 	for (i2=0; i2<pgr2->isiz; i2++) { */
+/* 	  if(idir2 == 1) { */
+/* 	    while (i1<pgr1->isiz-1 && *(x1+i1+1)<=*(x2+i2)) i1++; */
+/* 	  } else { */
+/* 	    while (i1<pgr1->isiz-1 && *(x1+i1+1)>=*(x2+i2)) i1++; */
+/* 	  }  */
+/* 	  if (i1==pgr1->isiz-1 && *(x1+i1)==*(x2+i2)) i1--; */
+/* 	  ij1 = j1*pgr1->isiz+i1; */
+/* 	  ij2 = j2*pgr2->isiz+i2; */
+/* 	  if ( i1<0 || i1>pgr1->isiz-2 ||  */
+/* 	       j1<0 || j1>pgr1->jsiz-2 || */
+/* 	       *(gr1u+ij1)==0 ||           */
+/* 	       *(gr1u+ij1+1)==0 || */
+/* 	       *(gr1u+ij1+pgr1->isiz)==0 ||  */
+/* 	       *(gr1u+ij1+pgr1->isiz+1)==0 ) { */
+/* 	    *(gr2u+ij2) = 0; */
+/* 	  } */
+/* 	  else { */
+/* 	    yd = *(y1+j1+1) - *(y1+j1); */
+/* 	    rd = *(gr1+ij1+pgr1->isiz) - *(gr1+ij1); */
+/* 	    t1 = *(gr1+ij1) + (*(y2+j2)-*(y1+j1))*rd/yd; */
+/* 	    rd = *(gr1+ij1+pgr1->isiz+1) - *(gr1+ij1+1); */
+/* 	    t2 = *(gr1+ij1+1) + (*(y2+j2)-*(y1+j1))*rd/yd; */
+/* 	    xd = *(x1+i1+1) - *(x1+i1); */
+/* 	    *(gr2+ij2) = t1 + (*(x2+i2)-*(x1+i1))*(t2-t1)/xd; */
+/* 	    *(gr2u+ij2) = 1; */
+/* 	  } */
+/* 	} */
+/*       } */
+/*     } */
+
+err:
+
+  /* release memory */
+  gafree (&pst2);
+  if (error) if (pst!=NULL) gafree (pst); 
+  if (x1!=NULL) gree(x1,"f400");
+  if (x2!=NULL) gree(x2,"f401");
+  if (y1!=NULL) gree(y1,"f402");
+  if (y2!=NULL) gree(y2,"f403");
+  if (x1b!=NULL) gree(x1b,"f400b");
+  if (x2b!=NULL) gree(x2b,"f401b");
+  if (y1b!=NULL) gree(y1b,"f402b");
+  if (y2b!=NULL) gree(y2b,"f403b");
+  if (gxout!=NULL) gree(gxout,"f400c");
+  if (gyout!=NULL) gree(gyout,"f401c");
+  if (area1!=NULL) gree(area1,"f402b");
+  if (area2!=NULL) gree(area2,"f403b");
+  if (fld_box!=NULL) gree(fld_box,"399a");
+  if (area_box!=NULL) gree(area_box,"399b");
+  if (error) 
+    return 1;
+  else 
+    return 0;
+}
+
+/* Perform a two-operand operation which may have both grid or
+   stn data types involved.  */
+
+gaint gafopr (struct gastat *pst1, struct gastat *pst2, gaint op) {
+struct gagrid *pgr;
+struct gastn *stn;
+
+  /* Check for grid-grid operation */
+  pgr=NULL;
+  if (pst1->type == 1 && pst2->type==1) {
+    pgr = gagrop(pst1->result.pgr, pst2->result.pgr, op, 1);
+    if (pgr==NULL) return (1);
+    pst1->type = 1;
+    pst1->result.pgr = pgr;
+    return (0);
+  }
+
+  /* If both stns, do stn-stn operation */
+  if (pst1->type==0 && pst2->type==0 ) {
+    stn = gastop(pst1->result.stn, pst2->result.stn, op, 1);
+    if (stn==NULL) return (1);
+    pst1->type = 0;
+    pst1->result.stn = stn;
+    return (0);
+  }
+
+  /* Operation between grid and stn is invalid -- unless the grid
+     is really a constant.  Check for this.  */
+  if (pst1->type == 1) pgr=pst1->result.pgr;
+  if (pst2->type == 1) pgr=pst2->result.pgr;
+  if (pgr->idim == -1 && pgr->jdim == -1) {
+    if (pst1->type == 0) {
+      stn = gascop (pst1->result.stn, pgr->rmin, op, 0);
+    } else {
+      stn = gascop (pst2->result.stn, pgr->rmin, op, 1);
+    }
+    if (stn==NULL) return (1);
+    gagfre (pgr);
+    pst1->type = 0;
+    pst1->result.stn = stn;
+  } else {
+    gaprnt (0,"Operation Error: Incompatable Data Types\n");
+    gaprnt (0,"  One operand was stn data, other was grid\n");
+    return (1);
+  }
+  return (0);
+}
+
+char *aavenam[5] = {"AAVE","AMEAN","ASUM","ASUMG","ATOT"};
+
+gaint ffaav (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = aave (pfc, pst, 1);
+   return (rc);
+}
+
+gaint ffamn (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = aave (pfc, pst, 2);
+   return (rc);
+}
+
+gaint ffasum (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = aave (pfc, pst, 3);
+   return (rc);
+}
+
+gaint ffasumg (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = aave (pfc, pst, 4);
+   return (rc);
+}
+
+gaint ffatot (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = aave (pfc, pst, 5);
+   return (rc);
+}
+
+gaint aave (struct gafunc *pfc, struct gastat *pst, int sel) {
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*jconv) (gadouble *, gadouble);
+struct gagrid *pgr;
+struct gafile *pfi;
+gadouble res=-999,x1,x2,y1,y2;
+gaint dim,wflag,rc,gflag=0;
+char *ch,*fnam,resu;
+
+  fnam = aavenam[sel-1];
+
+  /* Check for valid number of args       */
+  if (pfc->argnum==2 && !strncmp(pfc->argpnt[1],"global",1)) gflag=1;
+  if (pfc->argnum!=5 && !gflag) {
+    snprintf(pout,255,"Error from %s:  Too many or too few args\n",fnam);
+    gaprnt(0,pout);
+    gaprnt (0,"                  5 arguments expected \n");
+    return (1);
+  }
+
+  /* Check environment.  Z or T or E can't vary.  */
+  if (pst->idim>1 || pst->jdim>1) {
+    snprintf(pout,255,"Error from %s  Invalid environment.  ",fnam);
+    gaprnt(0,pout);
+    gaprnt (0,"Z, T, or E can't vary.\n");
+    return (1);
+  }
+
+  /* Parse the dimension expressions */
+  pfi = pst->pfid;
+  if (gflag) {
+    ch = dimprs ("lon=0", pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x1 = x1 - 0.5;
+    ch = dimprs ("lon=360", pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x2 = x2 + 0.5;
+    ch = dimprs ("lat=-90", pst, pfi, &dim, &y1, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y1 = y1 - 0.5;
+    ch = dimprs ("lat=90", pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y2 = y2 + 0.5;
+  } else {
+    pfi = pst->pfid;
+    ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x1 = x1 - 0.5;
+    ch = dimprs (pfc->argpnt[2], pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x2 = x2 + 0.5;
+    ch = dimprs (pfc->argpnt[3], pst, pfi, &dim, &y1, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y1 = y1 - 0.5;
+    ch = dimprs (pfc->argpnt[4], pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y2 = y2 + 0.5;
+  }
+
+  /* Set up pst block properly to get the grid */
+  iconv = pfi->gr2ab[0];
+  pst->dmin[0] = iconv(pfi->grvals[0],x1);
+  pst->dmax[0] = iconv(pfi->grvals[0],x2);
+  jconv = pfi->gr2ab[1];
+  pst->dmin[1] = jconv(pfi->grvals[1],y1);
+  pst->dmax[1] = jconv(pfi->grvals[1],y2);
+  
+  pst->idim = 0;
+  pst->jdim = 1;
+
+  /* Get the grid */
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type!=1) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Average over the grid  */
+  resu = doaave(pgr,pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],sel,&res);
+  gafree (pst);
+  pgr = gagrvl(res);
+  pgr->umin = resu;
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  return (0);
+
+err1:
+  snprintf(pout,255,"Error from %s:  Invalid dimension expression \n",fnam);
+  gaprnt(0,pout);
+  return (1);
+}
+
+char *mnmxnam[6] = {"AMIN","AMAX","AMINLOCX","AMINLOCY","AMAXLOCX", "AMAXLOCY"};
+
+gaint ffamin (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 1);
+   return (rc);
+}
+
+gaint ffamax (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 2);
+   return (rc);
+}
+
+gaint ffaminlocx (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 3);
+   return (rc);
+}
+
+gaint ffaminlocy (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 4);
+   return (rc);
+}
+
+gaint ffamaxlocx (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 5);
+   return (rc);
+}
+
+gaint ffamaxlocy (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = mnmx (pfc, pst, 6);
+   return (rc);
+}
+
+gaint mnmx (struct gafunc *pfc, struct gastat *pst, int sel) {
+  gadouble (*iconv) (gadouble *, gadouble);
+  gadouble (*jconv) (gadouble *, gadouble);
+  struct gagrid *pgr;
+  struct gafile *pfi;
+  gadouble res=-999,x1,x2,y1,y2,min,max,minx,maxx,miny,maxy;
+  gaint dim,wflag,rc,gflag=0,i,j,x,y,cnt;
+  char *ch,*fnam,resu;
+  gadouble *gr;
+  char *gru;
+  
+  fnam = mnmxnam[sel-1];
+  
+  /* Check for valid number of args       */
+  if (pfc->argnum==2 && !strncmp(pfc->argpnt[1],"global",1)) gflag=1;
+  if (pfc->argnum!=5 && !gflag) {
+    snprintf(pout,255,"Error from %s:  Too many or too few args\n",fnam);
+    gaprnt(0,pout);
+    gaprnt (0,"                  5 arguments expected \n");
+    return (1);
+  }
+
+  /* Check environment.  Z or T or E can't vary.  */
+  if (pst->idim>1 || pst->jdim>1) {
+    snprintf(pout,255,"Error from %s  Invalid environment.  ",fnam);
+    gaprnt(0,pout);
+    gaprnt (0,"Z, T, or E can't vary.\n");
+    return (1);
+  }
+
+  /* Parse the dimension expressions */
+  pfi = pst->pfid;
+  if (gflag) {
+    ch = dimprs ("lon=0", pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x1 = x1 - 0.5;
+    ch = dimprs ("lon=360", pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x2 = x2 + 0.5;
+    ch = dimprs ("lat=-90", pst, pfi, &dim, &y1, 1, &wflag); 
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y1 = y1 - 0.5;
+    ch = dimprs ("lat=90", pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y2 = y2 + 0.5;
+  } else {
+    pfi = pst->pfid;
+    ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x1 = x1 - 0.5;
+    ch = dimprs (pfc->argpnt[2], pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag && sel!=4) x2 = x2 + 0.5;
+    ch = dimprs (pfc->argpnt[3], pst, pfi, &dim, &y1, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y1 = y1 - 0.5;
+    ch = dimprs (pfc->argpnt[4], pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag && sel!=4) y2 = y2 + 0.5;
+  }
+
+  /* Set up pst block properly to get the grid */
+  iconv = pfi->gr2ab[0];
+  pst->dmin[0] = iconv(pfi->grvals[0],x1);
+  pst->dmax[0] = iconv(pfi->grvals[0],x2);
+  jconv = pfi->gr2ab[1];
+  pst->dmin[1] = jconv(pfi->grvals[1],y1);
+  pst->dmax[1] = jconv(pfi->grvals[1],y2);
+  
+  pst->idim = 0;
+  pst->jdim = 1;
+
+  /* Get the grid */
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type!=1) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Get the area min/max and its location */
+  min =  9.99e35;
+  max = -9.99e35;
+  minx = maxx = miny = maxy = -1; 
+  gr  = pgr->grid;
+  gru = pgr->umask;
+  cnt = 0;
+  for (j=0; j<pgr->jsiz; j++) {
+    y = (gadouble)(j+pgr->dimmin[1]);
+    for (i=0; i<pgr->isiz; i++) {
+      x = (gadouble)(i+pgr->dimmin[0]);
+      if (*gru == 1) {
+	cnt++;
+	if (min>*gr) { min = *gr; minx = x; miny = y; }
+	if (max<*gr) { max = *gr; maxx = x; maxy = y; }
+      }
+      gr++; gru++;
+    }
+  }
+  if (cnt==0) {
+    resu = 0;
+    res = pgr->undef; 
+  } 
+  else {
+    resu = 1;
+    if      (sel==1) res = min;
+    else if (sel==2) res = max; 
+    else if (sel==3) res = minx; 
+    else if (sel==4) res = miny;
+    else if (sel==5) res = maxx; 
+    else if (sel==6) res = maxy;
+  }
+
+  gafree (pst);
+  pgr = gagrvl(res);
+  pgr->umin = resu;
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  return (0);
+
+err1:
+  snprintf(pout,255,"Error from %s:  Invalid dimension expression \n",fnam);
+  gaprnt(0,pout);
+  return (1);
+}
+
+
+
+gaint ffscor (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = scorr (pfc, pst, 1);
+   return (rc);
+}
+
+gaint ffsreg (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = scorr (pfc,pst,2);
+  return (rc);
+}
+
+gaint scorr (struct gafunc *pfc, struct gastat *pst, gaint sel) {
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*jconv) (gadouble *, gadouble);
+struct gagrid *pgr,*pgr2;
+struct gafile *pfi;
+struct gastat pst2;
+gadouble *gr1, *gr2, *gr3, *grid3;
+gadouble res,x1,x2,y1,y2,mn1,mn2,s1,s2,ss,cov;
+gaint i,dim,wflag,rc,cnt,gflag=0;
+char *ch,*gr1u,*gr2u,*grid3u,*gr3u,s1u,s2u,mn1u,mn2u,resu,covu;
+size_t sz;
+
+   mn1=mn2=s1=s2=cov=ss=res=0;   
+
+  /* Check for valid number of args       */
+  if (pfc->argnum==3 && !strncmp(pfc->argpnt[2],"global",1)) gflag=1;
+  if (pfc->argnum!=6 && !gflag) {
+    gaprnt (0,"Error from SCORR:  Too many or too few args \n");
+    gaprnt (0,"                   6 arguments expected \n");
+    return (1);
+  }
+
+  /* Check environment.  Z or T or E can't vary.  */
+  if (pst->idim>1 || pst->jdim>1) {
+    gaprnt (0,"Error from SCORR:  Invalid environment.  ");
+    gaprnt (0,"Z, T, or E cannot vary.\n");
+    return (1);
+  }
+
+  /* Parse the dimension expressions */
+  pfi = pst->pfid;
+  if (gflag) {
+    ch = dimprs ("lon=0", pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag) x1 = x1 - 0.5;
+    ch = dimprs ("lon=360", pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag) x2 = x2 + 0.5;
+    ch = dimprs ("lat=-90", pst, pfi, &dim, &y1, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag) y1 = y1 - 0.5;
+    ch = dimprs ("lat=90", pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag) y2 = y2 + 0.5;
+  } else {
+    ch = dimprs (pfc->argpnt[2], pst, pfi, &dim, &x1, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag) x1 = x1 - 0.5;
+    ch = dimprs (pfc->argpnt[3], pst, pfi, &dim, &x2, 1, &wflag);
+    if (ch==NULL || dim!=0) goto err1;
+    if (!wflag) x2 = x2 + 0.5;
+    ch = dimprs (pfc->argpnt[4], pst, pfi, &dim, &y1, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag) y1 = y1 - 0.5;
+    ch = dimprs (pfc->argpnt[5], pst, pfi, &dim, &y2, 1, &wflag);
+    if (ch==NULL || dim!=1) goto err1;
+    if (!wflag) y2 = y2 + 0.5;
+  }
+
+  /* Set up pst block properly to get the grids */
+  iconv = pfi->gr2ab[0];
+  pst->dmin[0] = iconv(pfi->grvals[0],x1);
+  pst->dmax[0] = iconv(pfi->grvals[0],x2);
+  jconv = pfi->gr2ab[1];
+  pst->dmin[1] = jconv(pfi->grvals[1],y1);
+  pst->dmax[1] = jconv(pfi->grvals[1],y2);
+  pst->idim = 0;
+  pst->jdim = 1;
+  pst2 = *pst;
+
+  /* Get the first grid */
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type!=1) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Get the 2nd grid */
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) return (rc);
+  if (pst2.type!=1) {
+    gafree (&pst2);
+    gafree (pst);
+    return (-1);
+  }
+  pgr2 = pst2.result.pgr;
+
+  /* Verify that the grids are compatible for operations */
+  if (gagchk(pgr,pgr2,0) || gagchk(pgr,pgr2,1)) {
+    gaprnt (0,"Error from SCORR:  Incompatable grids\n");
+    gafree (&pst2);
+    gafree (pst);
+    return (1);
+  }
+
+  /* Force missing data values to be reflected in each grid.  */
+  cnt = pgr->isiz * pgr->jsiz;
+  gr1 = pgr->grid;
+  gr2 = pgr2->grid;
+  gr1u = pgr->umask;
+  gr2u = pgr2->umask;
+  for (i=0; i<cnt; i++) {
+    if (*gr1u==0 || *gr2u==0) {
+      *gr1u = 0;
+      *gr2u = 0;
+    }
+    gr1++;  gr2++;
+    gr1u++; gr2u++;
+  }
+
+  /* Obtain areal average over each grid */
+  mn1u = doaave(pgr, pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],1,&mn1);
+  mn2u = doaave(pgr2,pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],1,&mn2);
+
+  /* result from doaave was undefined */
+  if (mn1u==0 || mn2u==0) {
+    resu = 0;
+  } 
+  else {
+
+    /* Remove the mean from the fields */
+    gr1 = pgr->grid;
+    gr2 = pgr2->grid;
+    gr1u = pgr->umask;
+    gr2u = pgr2->umask;
+    for (i=0; i<cnt; i++) {
+      if (*gr1u!=0) *gr1 = *gr1 - mn1;
+      if (*gr2u!=0) *gr2 = *gr2 - mn2;
+      gr1++;  gr2++;
+      gr1u++; gr2u++;
+    }
+
+    /* Get gr1 * gr2; stash in a safe place.  Also get the squares of each variable. */
+    sz = sizeof(gadouble)*cnt;
+    grid3 = (gadouble *)galloc(sz,"scorr3");
+    if (grid3==NULL) {
+      gafree (pst);
+      gafree (&pst2);
+      gaprnt (0,"Error from SCORR:  Memory Allocation \n");
+      return (1);
+    }
+    sz = sizeof(char)*cnt;
+    grid3u = (char *)galloc(sz,"scorr3u");
+    if (grid3u==NULL) {
+      if (grid3) gree(grid3,"f408");
+      gafree (pst);
+      gafree (&pst2);
+      gaprnt (0,"Error from SCORR:  Memory Allocation \n");
+      return (1);
+    }
+    gr1 = pgr->grid;
+    gr2 = pgr2->grid;
+    gr3 = grid3;
+    gr1u = pgr->umask;
+    gr2u = pgr2->umask;
+    gr3u = grid3u;
+    for (i=0; i<cnt; i++) {
+      if (*gr1u!=0 && *gr2u!=0) {
+	*gr3 = *gr1 * *gr2;
+	*gr3u = 1;
+      }
+      else {
+	*gr3u = 0;
+      }
+      if (*gr1u!=0) *gr1 = *gr1 * *gr1;
+      if (*gr2u!=0) *gr2 = *gr2 * *gr2;
+      gr1++;  gr2++;  gr3++;
+      gr1u++; gr2u++; gr3u++;
+    }
+
+    /* Get the areal average of the squares, then the
+       areal average of gr1 * gr2, then the final result */
+    /* hard wire to 1 for now as this is the default behaviour */
+    s1u = doaave(pgr, pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],1,&s1);
+    s2u = doaave(pgr2,pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],1,&s2);
+    gr1 = pgr->grid;
+    gr1u = pgr->umask;
+    gr3 = grid3;
+    gr3u = grid3u;
+    for (i=0; i<cnt; i++) {
+      if (*gr3u!=0) {
+	*gr1 = *gr3;
+	*gr1u = 1;
+      }
+      else {
+	*gr1u=0;
+      }
+      gr1++;  gr3++;
+      gr1u++; gr3u++;
+    }
+    covu = doaave(pgr,pst->dmin[0],pst->dmax[0],pst->dmin[1],pst->dmax[1],1,&cov);
+    if (sel == 1) ss = sqrt(s1*s2);
+    if (sel == 2) ss = sqrt(s1*s1);
+    if (ss>0.0) {
+      res = cov/ss;
+      resu = 1;
+    }
+    else resu = 0;
+    gree(grid3,"f408a");
+    gree(grid3u,"f408c");
+  }
+
+  gafree (pst);
+  gafree (&pst2);
+  pgr = gagrvl(res);
+  pgr->umin = resu;
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  return (0);
+
+err1:
+  gaprnt (0,"Error from SCORR:  Invalid dimension expression \n");
+  return (1);
+}
+
+/* Function that actually does area average over a grid */
+
+char doaave(struct gagrid *pgr, gadouble dmin0, gadouble dmax0,
+		gadouble dmin1, gadouble dmax1, gaint sel, gadouble *result) {
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*jconv) (gadouble *, gadouble);
+gadouble *ivals, *jvals, *gr;
+gadouble d2r,sum,w1,w2=0,y1,x1,abs,alo,ahi,alen,wt;
+gaint i,j;
+char *gru,sumu=0;
+
+  d2r = M_PI/180.0;
+  iconv = pgr->igrab;
+  jconv = pgr->jgrab;
+  ivals = pgr->ivals;
+  jvals = pgr->jvals;
+  sum = 0.0; 
+  wt = 0.0;
+  gr  = pgr->grid;
+  gru = pgr->umask;
+
+  for (j=0; j<pgr->jsiz; j++) {
+    y1 = (gadouble)(j+pgr->dimmin[1]);
+    abs = jconv(jvals, y1);
+    alo = jconv(jvals, y1-0.5);
+    ahi = jconv(jvals, y1+0.5);
+    alen=fabs(ahi-alo);                /* length of the grid side in world coord */
+    if (alo < dmin1) alo = dmin1;
+    if (alo > dmax1) alo = dmax1;
+    if (ahi < dmin1) ahi = dmin1;
+    if (ahi > dmax1) ahi = dmax1;
+    if (alo < -90.0) alo = -90.0; if (ahi < -90.0) ahi = -90.0;
+    if (alo >  90.0) alo =  90.0; if (ahi >  90.0) ahi =  90.0;
+    w1 = 1.0;
+    if (sel==1 || sel==5) {
+      w1 = fabs(sin(ahi*d2r)-sin(alo*d2r));  /* for aave and atot, area weighting by latitude */
+    } 
+    else if (sel==2) { 
+      w1 = fabs(ahi-alo);           /* for amean, weight is length of interval in world coords */
+    } 
+    else if (sel==3) {
+      if (alen > FUZZ_SCALE) {    /* grid weighting (asum), weighted by length of interval in grid coords */
+	w1=fabs(ahi-alo)/alen;                 
+      } 
+      else {
+	w1=0.0;
+      }
+    }
+    for (i=0; i<pgr->isiz; i++) {
+      x1 = (gadouble)(i+pgr->dimmin[0]);
+      alo = iconv(ivals, x1-0.5);
+      ahi = iconv(ivals, x1+0.5);
+      alen=fabs(ahi-alo);
+      if (alo < dmin0) alo = dmin0;
+      if (alo > dmax0) alo = dmax0;
+      if (ahi < dmin0) ahi = dmin0;
+      if (ahi > dmax0) ahi = dmax0;
+
+      if (sel==1 || sel==2) {
+	w2 = ahi - alo;                      /* for aave and amean */
+      } 
+      else if (sel==5) {
+	w2 = d2r*(ahi - alo);                /* for atot */
+      } 
+      else if (sel==3) {
+	if (alen > FUZZ_SCALE) {             /* grid weighting (asum) */
+	  w2=fabs(ahi-alo)/alen;                 
+	} 
+	else {
+	  w2=0.0;
+	}
+      } 
+      else if (sel==4) {
+	w2=1.0;              /* no weighting (asumg) */
+      }
+
+      if (*gru != 0) {
+	if (sel==4) {
+	  sum = sum + *gr;    /* no weighting for asumg */   
+	}
+	else {
+	  sum = sum + (*gr * w1 * w2);  /* otherwise apply weights */
+	} 
+        wt = wt + (w1 * w2);
+      }
+      gr++; gru++;
+    }
+  }
+  if (wt>0.0) {
+    sumu = 1;
+    if (sel<=2 ) {
+      sum = sum / wt;
+    }
+  } 
+  else {
+    sumu = 0;
+    sum = pgr->undef;
+  }
+  *result = sum;
+  return (sumu);
+}
+
+
+/* Time correlation */
+
+gaint fftcor (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = tmaskf (pfc, pst, 2);
+   return (rc);
+}
+
+/* Time regression */  /* Timlin */
+
+gaint fftreg (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = tmaskf (pfc,pst,3);
+  return (rc);
+}
+
+/* Time mean, masked and arbitrarily weighted. */
+
+gaint fftmav (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = tmaskf (pfc, pst, 1);
+   return (rc);
+}
+
+char *tmnam[3] = {"TMAVE","TCORR","TREGR"};
+
+/* Following function does time series operations that
+   involve a mask grid, where if the first mask grid
+   is undefined, the 2nd grid is not even accessed.
+   This saves processing time for composite means and
+   such.  Variable sel determines the function operation:
+
+     sel = 1:  time mean.
+     sel = 2:  time correlation.
+     sel = 3:  time regression.     */
+
+gaint tmaskf (struct gafunc *pfc, struct gastat *pst, gaint sel) {
+struct gafile *pfi;
+struct gagrid *pgr;
+gadouble *gr, *mn1, *mn2, *cnt, *s1, *s2, *cov, *wt;
+gadouble t1,t2,vv,res=0,v1,v2;
+gaint dim,wflag=0,d1,d2,d,rc,i,siz,size=0;
+char *ch,*fnam, uu, *gru, *mn1u, *mn2u, *cntu, *s1u, *s2u, *covu, resu=0;
+size_t sz;
+
+  cov=s2=s1=cnt=mn2=wt=0;
+  s1u=mn2u=mn1u=NULL;
+
+  fnam = tmnam[sel-1];
+  /* Check for valid number of args       */
+  if (pfc->argnum!=4) {
+    snprintf(pout,255,"Error from %s:  Too many or too few args\n",fnam);
+    gaprnt (0,pout);
+    gaprnt (0,"                   4 arguments expected \n");
+    return (1);
+  }
+
+  /* Parse the dimension expression       */
+  pfi = pst->pfid;
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim, &t1, 1, &wflag);
+  if (ch==NULL || dim!=3 || wflag==2) {
+    snprintf(pout,255,"Error from %s:  1st dimension expr invalid\n",fnam);
+    gaprnt (0,pout);
+    if (dim!=3) gaprnt (0,"  expr does not describe time dimension\n");
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Now parse the 2nd dimension expression.  */
+  ch = dimprs (pfc->argpnt[3], pst, pfi, &dim, &t2, 1, &wflag);
+  if (ch==NULL || dim!=3 || t2<t1 || wflag==2) {
+    snprintf(pout,255,"Error from %s:  2nd dimension expr invalid\n",fnam);
+    gaprnt (0,pout);
+    if (dim!=3) gaprnt (0,"  expr does not describe time dimension\n");
+    if (t2<t1)  gaprnt (0,"  end time is earlier than start time\n");
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Loop through all times and get means */
+  if (pst->jdim==dim) pst->jdim = -1;
+  d1 =  ceil(t1-0.001);          /* Loop limits are integers    */
+  d2 = floor(t2+0.001);          /* No weighting  */
+  snprintf(pout,255,"%s:  dim = %i, start = %i, end = %i\n", fnam, dim, d1, d2);
+  gaprnt (2,pout);
+
+  rc = 0;
+  mn1 = NULL;
+  for (d=d1; d<=d2 && !rc; d++) {
+    gr2t (pfi->grvals[3],d,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (rc) goto err2;
+    if (!rc && pst->type==0) {
+      gafree (pst);
+      goto err3;
+    }
+    pgr = pst->result.pgr;
+    if (pgr->idim != -1 || pgr->isiz!=1 || pgr->jsiz!=1) {
+      snprintf(pout,255,"Error from %s:  1st arg must be 0-D\n",fnam);
+      gaprnt (0,pout);
+      gafree (pst);
+      goto err2;
+    }
+    vv = pgr->rmin;
+    uu = pgr->umin;
+    gafree (pst);
+    if (uu!=0) {
+      rc = gaexpr(pfc->argpnt[1],pst);
+      if (rc) goto err2;
+      if (!rc && pst->type==0) {
+        gafree (pst);
+        goto err3;
+      }
+      pgr = pst->result.pgr;
+      siz = pgr->isiz * pgr->jsiz;
+      if (mn1==NULL) {
+        i = 2;
+        if (sel==2 || sel==3) i = 6;
+	sz = sizeof(gadouble)*siz*i;
+        mn1 = (gadouble *)galloc(sz,"tmaskmn1");
+        if (mn1==NULL) {
+          gafree (pst);
+          goto err1;
+        }
+	sz = sizeof(char)*siz*i;
+        mn1u = (char *)galloc(sz,"tmaskmn1u");
+        if (mn1u==NULL) {
+          gafree (pst);
+          goto err1;
+        }
+        if (sel==1) {
+          wt = mn1 + siz;
+          for (i=0; i<siz; i++) { 
+	    *(mn1+i)=0.0; 
+	    *(wt+i)=0.0; 
+	  }
+        }
+        if (sel==2 || sel==3) {
+          mn2  = mn1  + siz;       /* these are data grids */
+          cnt = mn2 + siz;
+          s1  = cnt + siz;
+          s2  = s1 + siz;
+          cov = s2 + siz;
+
+	  mn2u = mn1u + siz;       /* these are undef masks */
+          cntu = mn2u + siz;
+          s1u  = cntu + siz;
+          s2u  = s1u + siz;
+          covu = s2u + siz;
+
+          for (i=0; i<siz; i++) {
+            *(mn1+i) = 0.0; 
+	    *(mn2+i) = 0.0;
+            *(cnt+i) = 0.0;
+            *(s1+i)  = 0.0; 
+	    *(s2+i)  = 0.0;
+            *(cov+i) = 0.0;
+          }
+        }
+        size = siz;
+      }
+      if (size != siz) {
+        gafree (pst);
+        goto err2;
+      }
+      gr  = pgr->grid;
+      gru = pgr->umask;
+      for (i=0; i<siz; i++) {
+        if (uu!=0 && *gru!=0) {
+          if (sel==1) {
+            *(mn1+i) += *gr * vv;
+            *(wt+i) += vv;
+          }
+          if (sel==2 || sel==3) {
+            *(mn1+i) += vv;
+            *(mn2+i) += *gr;
+            *(cnt+i) += 1.0;
+          }
+        }
+        gr++; gru++;
+      }
+      gafree (pst);
+    }
+  }
+
+  /* Calculate mean of each time series */
+
+  if (mn1) {
+    if (sel==1) {
+      for (i=0; i<size; i++) {
+        if (*(wt+i)>0.0) {
+          *(mn1+i) = *(mn1+i) / *(wt+i);
+	  *(mn1u+i) = 1;
+        } else {
+          *(mn1u+i) = 0;
+        }
+      }
+    }
+    if (sel==2 || sel==3) {
+      for (i=0; i<size; i++) {
+        if (*(cnt+i)>0.0) {
+          *(mn1+i) = *(mn1+i) / *(cnt+i);
+          *(mn2+i) = *(mn2+i) / *(cnt+i);
+	  *(mn1u+i) = 1;
+	  *(mn2u+i) = 1;
+        } else {
+          *(mn1u+i) = 0;
+          *(mn2u+i) = 0;
+        }
+      }
+    }
+  }
+
+  /* Loop through time again if needed; do squares and cov.
+     Less error checking this time through. */
+
+  if ((sel==2 || sel==3) && mn1) {
+    rc = 0;
+    for (d=d1; d<=d2 && !rc; d++) {
+      gr2t (pfi->grvals[3],d,&(pst->tmin));
+      pst->tmax = pst->tmin;
+      rc = gaexpr(pfc->argpnt[0],pst);
+      if (rc) goto err2;
+      pgr = pst->result.pgr;
+      vv = pgr->rmin;
+      uu = pgr->umin;
+      gafree (pst);
+      rc = gaexpr(pfc->argpnt[1],pst);
+      if (rc) goto err2;
+      pgr = pst->result.pgr;
+      gr  = pgr->grid;
+      gru = pgr->umask;
+      for (i=0; i<size; i++) {
+        if (uu!=0 && *gru!=0) {
+          if (*(cnt+i) > 0.0) {
+            v1 = vv - *(mn1+i);
+            *(s1+i) += v1*v1;
+            v2 = *gr - *(mn2+i);
+            *(s2+i) += v2*v2;
+            *(cov+i) += v1*v2;
+          }
+        }
+        gr++; gru++;
+      }
+      gafree (pst);
+    }
+
+    for (i=0; i<size; i++) {
+      if (*(cnt+i) > 0.0) {
+        *(s1+i) = *(s1+i) / *(cnt+i);
+        *(s2+i) = *(s2+i) / *(cnt+i);
+        *(cov+i) = *(cov+i) / *(cnt+i);
+        if (sel==2) {
+	  res = sqrt(*(s1+i) * *(s2+i));
+	  resu = 1;
+	}
+        if (sel==3) {
+	  res = sqrt(*(s1+i) * *(s1+i));
+	  resu = 1;
+	}
+        if (res==0.0) {
+	  resu = 0;
+	}
+        else {
+	  res = *(cov+i)/res;
+	  resu = 1;
+	}
+      } else resu = 0;
+      *(s1+i)  = res;
+      *(s1u+i) = resu;
+    }
+  }
+
+  /* Get one final grid, and use it to return the result. */
+
+  gr2t (pfi->grvals[3],d1,&(pst->tmin));
+  pst->tmax = pst->tmin;
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) goto err2;
+  if (!rc && pst->type==0) {
+    gafree (pst);
+    goto err3;
+  }
+  pgr = pst->result.pgr;
+  siz = pgr->isiz * pgr->jsiz;
+  gr  = pgr->grid;
+  gru = pgr->umask;
+  if (mn1) {
+    if (size != siz) {
+      gafree (pst);
+      goto err2;
+    }
+    if (sel==1) {
+      for (i=0; i<siz; i++) {
+	if (*(mn1u+i)!=0) {
+	  *(gr+i) = *(mn1+i);
+	  *(gru+i) = 1;
+	}
+	else {
+	  *(gru+i) = 0;
+	}
+      }
+    }
+    if (sel==2 || sel==3) {
+      for (i=0; i<siz; i++) {
+	if (*(s1u+i)!=0) {
+	  *(gr+i) = *(s1+i);
+	  *(gru+i) = 1;
+	}
+	else {
+	  *(gru+i) = 0;
+	}
+      }
+    }
+    gree(mn1,"f409");
+    gree(mn1u,"f410");
+  } else {
+    for (i=0; i<siz; i++) *(gru+i) = 0;
+  }
+  return (0);
+
+err1:
+  snprintf(pout,255,"Error from %s:  Memory allocation error\n",fnam);
+  gaprnt (0,pout);
+  if (mn1) gree(mn1,"f411");
+  if (mn1u) gree(mn1u,"f412");
+  return (1);
+err2:
+  snprintf(pout,255,"Error from %s:  Error getting grids\n",fnam);
+  gaprnt (0,pout);
+  if (mn1) gree(mn1,"f413");
+  if (mn1u) gree(mn1u,"f414");
+  return (1);
+err3:
+  snprintf(pout,255,"Error from %s:  Args must be grid data\n",fnam);
+  gaprnt (0,pout);
+  if (mn1) gree(mn1,"f415");
+  if (mn1u) gree(mn1u,"416");
+  return (1);
+}
+
+
+char *avenam[8] = {"AVE","MEAN","SUM","SUMG","MIN","MAX","MINLOC","MAXLOC"};
+
+gaint ffave (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 1);
+   return (rc);
+}
+
+gaint ffmn (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 2);
+   return (rc);
+}
+
+gaint ffsum (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 3);
+   return (rc);
+}
+
+
+gaint ffsumg (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 4);
+   return (rc);
+}
+
+gaint ffmin (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 5);
+   return (rc);
+}
+
+gaint ffmax (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 6);
+   return (rc);
+}
+
+gaint ffminl (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 7);
+   return (rc);
+}
+
+gaint ffmaxl (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+   rc = ave (pfc, pst, 8);
+   return (rc);
+}
+
+
+gaint ave (struct gafunc *pfc, struct gastat *pst, gaint sel) {
+struct gagrid *pgr1, *pgr2, *pgr;
+struct gafile *pfi;
+struct dt tinc;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble gr1, gr2, *sum, *cnt, *val;
+gadouble alo, ahi, alen, wlo=0, whi=0, rd1;
+gadouble d2r, wt, wt1, abs;
+gaint mos, mns, wflag=0;
+gaint i, rc, siz, dim, d, d1, d2, dim2, ilin, incr, bndflg;
+char *ch,*fnam,*sumu,*cntu,*valu;
+
+  d2r = M_PI/180;
+  fnam=avenam[sel-1];
+
+  /* Check for valid number of args */
+  if (pfc->argnum<3 || pfc->argnum>5) {
+    snprintf(pout,255,"Error from %s:  Too many or too few args \n",fnam);
+    gaprnt(0,pout);
+    gaprnt (0,"                 3 to 5 arguments expected \n");
+    return (1);
+  }
+
+  /* Parse the 1st dimension expression */
+  pfi = pst->pfid;
+  ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &gr1, 1, &wflag);
+  if (ch==NULL || wflag==2) {
+    snprintf(pout,255,"Error from %s:  1st dimension expression invalid\n",fnam);
+    gaprnt(0,pout);
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Parse the 2nd dimension expression */
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim2, &gr2, 1, &wflag);
+  if (ch==NULL || dim2!=dim || gr2<gr1 || wflag==2) {
+    snprintf(pout,255,"Error from %s:  2nd dimension expression invalid\n",fnam);
+    gaprnt(0,pout);
+    if (dim2!=dim) gaprnt (0,"  start and end points have different dimensions\n");
+    if (gr2<gr1)   gaprnt (0,"  end grid point is less than start grid point \n");
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Check for 4th argument.  Could be a time increment, or it may
+     be option flags.  Time increment only valid for time averaging */
+  bndflg = 0;
+  incr = 1;
+  if (pfc->argnum == 4) {
+    if (*(pfc->argpnt[3]) == '-') {    /* Option flags? */
+      if (*(pfc->argpnt[3]+1) == 'b') bndflg = 1;
+      else {
+        snprintf(pout,255,"Error from %s: Invalid option flags\n",fnam);
+        gaprnt(0,pout);
+        return(1);
+      }
+    } else {                           
+      /* Must be time increment */
+      if (dim!=3) {
+        snprintf(pout,255,"Error from %s: Invalid usage of increment value\n",fnam);
+        gaprnt(0,pout);
+        gaprnt (0,"                Can only be used with time averaging\n");
+        return (1);
+      }
+      ch = intprs(pfc->argpnt[3],&incr);
+      if (ch==NULL) goto err3;
+
+      /* If a relative date/time was given, the increment is obtained
+         by looking at the default file structure (which assumes
+         knowledge of how date/time conversions are done) */
+      if (*ch!='\0') {
+        ch = rdtprs(pfc->argpnt[3],&tinc);
+        if (ch==NULL) goto err3;
+        mos = tinc.yr*12 + tinc.mo;
+        mns = tinc.dy*1140 + tinc.hr*60 + tinc.mn;
+        val = pfi->grvals[3];
+        if (mos>0 && *(val+5)>0) {
+          incr = mos / (*(val+5));
+          if (mos!=incr*(*(val+5))) goto err3;
+        }
+        else if (mns>0 && *(val+6)>0) {
+          incr = mns / (*(val+6));
+          if (mns!=incr*(*(val+6))) goto err3;
+        }
+        else goto err3;
+      }
+    }
+  }
+  if (pfc->argnum == 5) {
+    if (*(pfc->argpnt[4]) == '-' &&
+        *(pfc->argpnt[4]+1) == 'b') bndflg = 1;
+    else {
+      snprintf(pout,255,"Error from %s: Invalid option flags\n",fnam);
+      gaprnt(0,pout);
+      return(1);
+    }
+  }
+
+  /* Get the first two grids */
+
+  if (pst->idim==dim) {          /* Fewer varying dims if user */
+    pst->idim = pst->jdim;       /* averaging over varying dim */
+    pst->jdim = -1;
+  }
+  ilin = pfi->linear[dim];
+  if (pst->jdim==dim) pst->jdim = -1;
+  d1 = ceil(gr1-0.001);          /* Ave limits are integers    */
+  d2 = floor(gr2+0.001);
+  if (bndflg) {
+    d1 = floor(gr1+0.5);
+    d2 = ceil(gr2-0.5);
+    if (dim!=3) {
+      conv = pfi->gr2ab[dim];
+      wlo = conv(pfi->grvals[dim],gr1);
+      whi = conv(pfi->grvals[dim],gr2);
+    }
+  }
+
+  if(mfcmn.warnflg > 0) {
+    if (sel == 1) {
+      snprintf(pout,255,"Averaging.  dim = %i, start = %i, end = %i\n", dim, d1, d2);
+    } else {
+      snprintf(pout,255,"%sing.  dim = %i, start = %i, end = %i\n", fnam, dim, d1, d2);
+    }
+    gaprnt (2,pout);
+  }
+
+  /* Figure out weights for 1st grid */
+  wt1 = 1.0;                     
+
+  /*-----  time */
+  if (dim==3) {
+    gr2t (pfi->grvals[3],d1,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    if (bndflg) {
+      rd1 = d1;
+      if (gr1 < rd1+0.5) wt1 = (rd1+0.5)-gr1;
+      if (gr2 > rd1-0.5) wt1 = gr2 + 0.5 - rd1;
+      if (wt1<0.0) wt1=0.0;
+    }
+  } 
+  /*-----  lon,lat,lev,ens */
+  else {
+    conv = pfi->gr2ab[dim];
+    abs = conv(pfi->grvals[dim],d1);
+    alo = conv(pfi->grvals[dim],d1-0.5);
+    ahi = conv(pfi->grvals[dim],d1+0.5);
+    alen=fabs(ahi-alo);
+    pst->dmin[dim] = abs;
+    pst->dmax[dim] = abs;
+    if (bndflg) {
+      if (whi<wlo) {
+        if (alo > wlo) alo = wlo;
+        if (ahi > wlo) ahi = wlo;
+        if (alo < whi) alo = whi;
+        if (ahi < whi) ahi = whi;
+      } else {
+        if (alo < wlo) alo = wlo;
+        if (ahi < wlo) ahi = wlo;
+        if (alo > whi) alo = whi;
+        if (ahi > whi) ahi = whi;
+      }
+    }
+    /*-----  lat scaling */
+    if (dim==1) {
+      if (alo >  90.0) alo =  90.0;
+      if (ahi >  90.0) ahi =  90.0;
+      if (alo < -90.0) alo = -90.0;
+      if (ahi < -90.0) ahi = -90.0;
+      if (sel==1) {                                                   /* ave */
+	wt1 = fabs(sin(ahi*d2r)-sin(alo*d2r));
+      } else if (sel==2) {                                            /* mean */
+	wt1 = fabs(ahi-alo);
+      } else if (sel==3) {                                            /* sum */
+	if (alen > FUZZ_SCALE) {
+	  wt1=fabs(ahi-alo)/alen;
+	} else {
+	  wt1=0.0;
+	}
+      } else if (sel==4) {                                            /* sumg */
+	wt1=1.0;
+      }
+    } 
+    /* -----   lon,lev,ens scaling */
+    else {
+      if(sel<=2) {                                        /* ave, mean */
+	wt1 = ahi - alo;
+      } else if (sel==3) {                                /* sum */
+	if (alen > FUZZ_SCALE) {
+	  wt1=fabs(ahi-alo)/alen;
+	} else {
+	  wt1=0.0;
+	}
+      } else if (sel==4) {                                /* sumg */
+	wt1=1.0;
+      }
+    } 
+  }
+  
+  /* Get first grid */
+  rc = gaexpr(pfc->argpnt[0],pst);     
+  if (rc) return (rc);
+  if (pst->type == 0) {
+    gafree (pst);
+    return(-1);
+  }
+  pgr1 = pst->result.pgr;
+
+  d = d1 + incr;                       /* If only grid, just return */
+  if (d>d2)  {
+    if (sel==7 || sel==8) {
+      siz = pgr1->isiz * pgr1->jsiz;
+      sum  = pgr1->grid;
+      sumu = pgr1->umask;
+      for (i=0; i<siz; i++) {
+        if (*sumu != 0) *sum = d1;
+        sum++; sumu++;
+      }
+    }
+    return (0); 
+  }
+
+  /* Figure out weights for 2nd grid */
+  wt = 1.0;                    
+
+  /*-----    time 22222222222222 */
+  if (dim==3) {
+    gr2t (pfi->grvals[3],d,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    if (bndflg) {
+      rd1 = d;
+      if (gr1 < rd1+0.5) wt = (rd1+0.5)-gr1;
+      if (gr2 > rd1-0.5) wt = gr2 + 0.5 - rd1;
+      if (wt<0.0) wt=0.0;
+    }
+  } 
+  /*----- lon,lat,lev,ens 22222222222 */
+  else {
+    conv = pfi->gr2ab[dim];
+    abs = conv(pfi->grvals[dim],d);
+    alo = conv(pfi->grvals[dim],d-0.5);
+    ahi = conv(pfi->grvals[dim],d+0.5);
+    alen=fabs(ahi-alo);
+    pst->dmin[dim] = abs;
+    pst->dmax[dim] = abs;
+    if (bndflg) {
+      if (whi<wlo) {
+        if (alo > wlo) alo = wlo;
+        if (ahi > wlo) ahi = wlo;
+        if (alo < whi) alo = whi;
+        if (ahi < whi) ahi = whi;
+      } else {
+        if (alo < wlo) alo = wlo;
+        if (ahi < wlo) ahi = wlo;
+        if (alo > whi) alo = whi;
+        if (ahi > whi) ahi = whi;
+      }
+    }
+    /* ---- lat scaling 2222222222222*/
+    if (dim==1) {
+      if (alo >  90.0) alo =  90.0;
+      if (ahi >  90.0) ahi =  90.0;
+      if (alo < -90.0) alo = -90.0;
+      if (ahi < -90.0) ahi = -90.0;
+      if(sel==1) {                                                 /* ave */
+	wt = fabs(sin(ahi*d2r)-sin(alo*d2r));
+      } else if (sel==2) {                                         /* mean */
+	wt = fabs(ahi-alo);
+      } else if (sel==3) {                                         /* sum */
+	if(alen > FUZZ_SCALE) {
+	  wt=fabs(ahi-alo)/alen;
+	} else  {
+	  wt=0.0;
+	}
+      } else if (sel==4) {                                         /* sumg */
+	wt=1.0;
+      }
+    } 
+    /* ---- lon,lev,ens  scaling 2222222222222*/
+    else {
+      if(sel<=2) {                                  /* ave, mean */
+	wt = ahi - alo;
+      } else if(sel==3) {                           /* sum */
+	if(alen > FUZZ_SCALE) {
+	  wt=fabs(ahi-alo)/alen;
+	} else {
+	  wt=0.0;
+	}
+      } else if(sel==4) {                           /* sumg */
+	wt=1.0;
+      }
+    }
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);    /* Get 2nd grid */
+  if (rc) {
+    gagfre(pgr1);
+    return (rc);
+  }
+  if (pst->type==0) {
+    gafree(pst);
+    gagfre(pgr1);
+    return (-1);
+  }
+  pgr2 = pst->result.pgr;
+
+
+  /* We will sum into the first grid, and keep the
+     count in the 2nd grid.  Set this up...        */
+
+  siz = pgr1->isiz * pgr1->jsiz;
+  sum  = pgr1->grid;
+  cnt  = pgr2->grid;
+  sumu = pgr1->umask;
+  cntu = pgr2->umask;
+  for (i=0; i<siz; i++) {
+    if (sel>=5 && sel<=8) {
+      if (*sumu==0 || *cntu==0) {  
+        if (*cntu!=0) {
+	  *sum = *cnt; 
+	  *sumu = 1;
+	  *cnt = d;
+	}
+        else if (*sumu!=0) {
+	  *cnt = d1;
+	  *cntu = 1;
+	}
+      } 
+      else {
+        if (sel==5 || sel==7) {
+          if (*cnt < *sum) {*sum = *cnt; *cnt = d;} 
+          else *cnt = d1;
+        }
+        if (sel==6 || sel==8) {
+          if (*cnt > *sum) {*sum = *cnt; *cnt = d;}
+          else *cnt = d1;
+        }
+      }
+    }
+    else {
+      if (*sumu==0) {
+        if (*cntu==0) {
+	  *cnt = 0.0;
+	  *cntu = 1;
+	}
+        else {
+    	  if (sel<=3) {                                          /* ave, mean sum */
+	    *sum = *cnt*wt;
+	    *sumu = 1;
+	    *cnt = wt;
+          } 
+	  else if (sel==4) {                                   /* sumg */
+	    *sum = *cnt;
+	    *sumu = 1;
+          }
+        }
+      } 
+      else if (*cntu==0 && (sel<=3) ) {              /* ave, mean sum */
+        *cnt = wt1;
+	*cntu = 1;
+        *sum = *sum*wt1; 
+      } else {
+        if (sel<=3) {
+          *sum = *sum*wt1 + *cnt*wt;                            /* ave, mean sum */
+        } 
+	else if (sel==4) {
+          *sum = *sum + *cnt;
+        }
+        *cnt = wt1 + wt;
+	*cntu = 1;
+      }
+    }
+    cnt++;  sum++;
+    cntu++; sumu++;
+  }
+
+  /* Now sum the rest of the grids */
+  d+=incr;
+  rc = 0;
+  for (d=d; d<=d2 && !rc; d+=incr) {
+    /* Get weight for this grid */
+    wt = 1.0;          
+    
+    /*---- time 3333333*/
+    if (dim==3) {
+      gr2t (pfi->grvals[3],d,&(pst->tmin));
+      pst->tmax = pst->tmin;
+      if (bndflg) {
+	rd1 = d;
+	if (gr1 < rd1+0.5) wt = (rd1+0.5)-gr1;
+	if (gr2 > rd1-0.5) wt = gr2 + 0.5 - rd1;
+	if (wt<0.0) wt=0.0;
+      }
+    } 
+    /*---- lat,lon,lev,ens 3333333*/
+    else {
+      conv = pfi->gr2ab[dim];
+      abs = conv(pfi->grvals[dim],d);
+      alo = conv(pfi->grvals[dim],d-0.5);
+      ahi = conv(pfi->grvals[dim],d+0.5);
+      alen=fabs(ahi-alo);
+      pst->dmin[dim] = abs;
+      pst->dmax[dim] = abs;
+      if (bndflg) {
+	if (whi<wlo) {
+	  if (alo > wlo) alo = wlo;
+	  if (ahi > wlo) ahi = wlo;
+	  if (alo < whi) alo = whi;
+	  if (ahi < whi) ahi = whi;
+	} else {
+	  if (alo < wlo) alo = wlo;
+	  if (ahi < wlo) ahi = wlo;
+	  if (alo > whi) alo = whi;
+	  if (ahi > whi) ahi = whi;
+	}
+      }
+      /*---- lat 3333333*/
+      if (dim==1) {
+	if (alo >  90.0) alo =  90.0;
+	if (ahi >  90.0) ahi =  90.0;
+	if (alo < -90.0) alo = -90.0;
+	if (ahi < -90.0) ahi = -90.0;
+	if(sel==1) {                                                  /* ave */
+	  wt = fabs(sin(ahi*d2r)-sin(alo*d2r));
+	} else if (sel==2) {                                          /* mean */
+	  wt = fabs(ahi-alo);
+	} else if (sel==3) {                                          /* sum */
+	  if(alen > FUZZ_SCALE) {
+	    wt=fabs(ahi-alo)/alen;
+	  } else  {
+	    wt=0.0;
+	  }
+	} else if (sel==4) {                                          /* sumg */
+	  wt=1.0;
+	}
+      } 
+      /*---- lon,lev,ens 3333333*/
+      else {
+	if(sel<=2) {                        /* ave, mean */
+	  wt = ahi - alo;
+	} else if(sel==3) {                 /* sum */
+	  if(alen > FUZZ_SCALE) {
+	    wt=fabs(ahi-alo)/alen;
+	  } else {
+	    wt=0.0;
+	  }
+	} else if(sel==4) {                 /* sumg */
+	  wt=1.0;
+	}
+      }
+    }
+    
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (!rc && pst->type==0) rc = -1;
+    if (!rc) {
+      pgr = pst->result.pgr;
+      val = pgr->grid;
+      cnt = pgr2->grid;
+      sum = pgr1->grid;
+      valu = pgr->umask;
+      cntu = pgr2->umask;
+      sumu = pgr1->umask;
+      for (i=0; i<siz; i++) {
+	if (sel>=5 && sel<=8) {
+	  if (*sumu==0 || *valu==0) {  
+	    if (*valu!=0) {
+	      *sum = *val; 
+	      *cnt = d;
+	      *sumu = 1;
+	      *cntu = 1;
+	    }
+	  } 
+	  else {
+	    if ((sel==5 || sel==7) && *val < *sum) {*sum = *val; *cnt = d;} 
+	    if ((sel==6 || sel==8) && *val > *sum) {*sum = *val; *cnt = d;}
+	  }
+	} else {
+	  if (*valu!=0) {
+	    /* weight for ave,mean,sum  for sumg just accum */
+	    if (sel<=3) {
+	      *val = *val*wt;
+	    }
+	    if (*sumu==0) {
+	      *sum = *val;
+	      *sumu = 1;
+	      *cnt += wt;
+	    } else {
+	      *sum += *val;
+	      *cnt += wt;
+	    }
+	  }
+	}
+	sum++;  cnt++;  val++;
+	sumu++; cntu++; valu++;
+      }
+      gagfre(pgr);
+    }
+  }
+  
+  if (rc) {
+    if (rc==-1) gafree (pst);
+    gagfre(pgr1);
+    gagfre(pgr2);
+    snprintf(pout,255,"Error from %s:  Error getting grids \n",fnam);
+    gaprnt(0,pout);
+    return (rc);
+  } else {
+    cnt = pgr2->grid;         /* Normalize if needed */
+    sum = pgr1->grid;
+    cntu = pgr2->umask;
+    sumu = pgr1->umask;
+    if (sel==1 || sel==2 || sel==7 || sel==8) {
+      for (i=0; i<siz; i++) {
+        if (*sumu!=0) {
+          if (sel < 3 && *cnt==0.0) {
+            snprintf(pout,255,"Error from %s:  Internal logic check 100\n",fnam);
+            gaprnt(0,pout);
+            return (1);
+          }
+          if (sel > 6 && *cntu==0) {
+            snprintf(pout,255,"Error from %s:  Internal logic check 101\n",fnam);
+            gaprnt(0,pout);
+            return (1);
+          }
+          if (sel==1 || sel==2) {
+	    *sum = *sum / *cnt;
+          } else {
+            *sum = *cnt;
+          }
+        }
+        sum++;  cnt++;
+        sumu++; cntu++;
+      }
+    }
+  }
+
+  gagfre(pgr2);
+
+  pst->type = 1;
+  pst->result.pgr = pgr1;
+
+  return (0);
+
+err3:
+  snprintf(pout,255,"Error from %s: Invalid time increment argument\n",fnam);
+  gaprnt(0,pout);
+  return (1);
+}
+
+
+gaint ffgint (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr1, *pgr;
+struct gafile *pfi;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble gr1,gr2,*sum, *val;
+gadouble wt, abs, abslo, abshi, d2r;
+gaint i, rc, siz, dim, d, d1, d2, dim2, ilin, bndflg, wflag=0;
+char *ch,*sumu,*valu;
+
+  d2r = M_PI/180;
+
+  /* Check for valid number of args       */
+  if (pfc->argnum<3 || pfc->argnum>4) {
+    gaprnt (0,"Error from GINT:  Too many or too few args \n");
+    gaprnt (0,"                  3 or 4 arguments expected \n");
+    return (1);
+  }
+
+  /* Parse the dimension expression       */
+  pfi = pst->pfid;
+  ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &gr1, 1, &wflag);
+  if (ch==NULL || wflag==2) {
+    gaprnt (0,"Error from GINT:  1st dimension expression invalid\n");
+    if (wflag==2) gaprnt (0,"  offt expression not supported as an arg to GINT\n");
+    return (1);
+  }
+
+  /* Now parse the 2nd dimension expression.  */
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim2, &gr2, 1, &wflag);
+  if (ch==NULL || dim2!=dim || gr2<gr1 || wflag==2) {
+    gaprnt(0,"Error from GINT:  2nd dimension expression invalid\n");
+    if (dim2!=dim) gaprnt (0,"  start and end points have different dimensions\n");
+    if (gr2<gr1)   gaprnt (0,"  end grid point is less than start grid point \n");
+    if (wflag==2)  gaprnt (0,"  offt expression not supported as an arg to GINT\n");
+    return (1);
+  }
+
+  /* Check for 4th argument.  Should be flags.  */
+  bndflg = 0;
+  if (pfc->argnum == 5) {
+    if (*(pfc->argpnt[4]) == '-' &&
+        *(pfc->argpnt[4]+1) == 'b') bndflg = 1;
+    else {
+      gaprnt (0,"Error from GINT: Invalid option flags\n");
+      return(1);
+    }
+  }
+
+  /* Get the first grid.             */
+  if (pst->idim==dim) {          /* Fewer varying dims if user */
+    pst->idim = pst->jdim;       /* integrating over varng dim */
+    pst->jdim = -1;
+  }
+  ilin = pfi->linear[dim];
+  if (pst->jdim==dim) pst->jdim = -1;
+  d1 = ceil(gr1-0.001);          /* dim limits must be integer */
+  d2 = floor(gr2+0.001);
+
+  if(mfcmn.warnflg > 0) {
+    snprintf(pout,255,"Integrating.  dim = %i, start = %i, end = %i\n", dim, d1, d2);
+    gaprnt (2,pout);
+  }
+
+  wt = 1.0;                     /* Figure out weight for 1st grid */
+  if (dim==3) {
+    gr2t (pfi->grvals[3],d1,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    wt = *(pfi->grvals[3]+5) + *(pfi->grvals[3]+6);
+  } else {
+    conv = pfi->gr2ab[dim];
+    abs = conv(pfi->grvals[dim],d1);
+    pst->dmin[dim] = abs;
+    pst->dmax[dim] = abs;
+    abslo = conv(pfi->grvals[dim],d1-0.5);
+    abshi = conv(pfi->grvals[dim],d1+0.5);
+    wt = abshi - abslo;
+    wt = fabs(wt);
+    if (dim==0 || dim==1) wt = wt*6.37E6*d2r;
+  }
+  if (bndflg) wt = wt*0.5;
+
+  rc = gaexpr(pfc->argpnt[0],pst);     /* Get first grid */
+  if (rc) return (rc);
+  if (pst->type == 0) {
+    gafree (pst);
+    return(-1);
+  }
+  pgr1 = pst->result.pgr;
+
+  if (dim==0) {                        /* Adjust weights if needed  */
+    if (pgr1->idim==1) cosadj(pgr1);
+    else wt = wt * cos(pst->dmin[1]*d2r);
+  }
+
+  siz = pgr1->isiz * pgr1->jsiz;       /* Apply weights to this grid */
+  sum  = pgr1->grid;
+  sumu = pgr1->umask;
+  for (i=0; i<siz; i++) {
+    if (*sumu!=0) *sum = *sum * wt;
+    sum++; sumu++;
+  }
+
+  d = d1 + 1;
+  if (d>d2) return(0);                 /* If only one grid, return  */
+
+  /* Now sum the rest of the grids into the first grid */
+
+  rc = 0;
+  for (d=d; d<=d2 && !rc; d++) {
+    wt = 1.0;
+    if (dim==3) {
+      gr2t (pfi->grvals[3],d,&(pst->tmin));
+      pst->tmax = pst->tmin;
+      wt = *(pfi->grvals[3]+5) + *(pfi->grvals[3]+6);
+    } else {
+      conv = pfi->gr2ab[dim];
+      abs = conv(pfi->grvals[dim],d);
+      pst->dmin[dim] = abs;
+      pst->dmax[dim] = abs;
+      abslo = conv(pfi->grvals[dim],d-0.5);
+      abshi = conv(pfi->grvals[dim],d+0.5);
+      wt = abshi - abslo;
+      wt = fabs(wt);
+      if (dim==0 || dim==1) wt = wt*6.37E6*d2r;
+    }
+    if (d==d2 && bndflg) wt = wt*0.5;
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (!rc && pst->type==0) rc = -1;
+    if (!rc) {
+      pgr = pst->result.pgr;
+      if (dim==0) {                   /* Adjust weights if needed  */
+        if (pgr->idim==1) cosadj(pgr);
+        else wt = wt * cos(pst->dmin[1]*d2r);
+      }
+      val  = pgr->grid;
+      valu = pgr->umask;
+      sum  = pgr1->grid;
+      sumu = pgr1->umask;
+      for (i=0; i<siz; i++) {
+        if (*valu!=0) {
+          *val = *val*wt;
+          if (*sumu==0) {
+	    *sum  = *val;
+	    *sumu = 1;
+	  }
+          else *sum += *val;
+        }
+        sum++;  val++;
+        sumu++; valu++;
+      }
+      gagfre(pgr);
+    }
+  }
+
+  if (rc) {
+    if (rc==-1) gafree (pst);
+    gagfre(pgr1);
+    gaprnt (0,"Error from GINT:  Error getting grids \n");
+    return (rc);
+  }
+
+  pst->type = 1;
+  pst->result.pgr = pgr1;
+
+  return (0);
+}
+
+void cosadj (struct gagrid *pgr) {
+gadouble *ltvals;
+gadouble (*ltconv) (gadouble *, gadouble);
+gadouble lat,*gr,d2r;
+gaint i,j;
+char *gru;
+  d2r = M_PI/180;
+  ltvals = pgr->ivals;
+  ltconv = pgr->igrab;
+  gr = pgr->grid;
+  gru = pgr->umask;
+  for (j=0; j<pgr->jsiz; j++) {
+    for (i=0; i<pgr->isiz; i++) {
+      lat  = ltconv(ltvals,(gadouble)(i+pgr->dimmin[1]))*d2r;
+      if (*gru!=0) *gr = *gr * cos(lat);
+      gr++; gru++;
+    }
+  }
+}
+
+gaint ffhdiv (struct gafunc *pfc, struct gastat *pst) {
+gaint rc,size,i,j;
+struct gagrid *pgr1, *pgr2;
+gadouble *result;
+gadouble *p1, *p2, *p3, *p4, *p;
+gadouble lat2, lat4, lat, lon1, lon3, ri, rj, temp, d2r;
+gadouble *lnvals, *ltvals;
+gadouble (*lnconv) (gadouble *, gadouble);
+gadouble (*ltconv) (gadouble *, gadouble);
+char *resultu, *p1u, *p2u, *p3u, *p4u, *pu;
+size_t sz;
+
+  d2r = M_PI/180;
+  result = NULL;
+  resultu = NULL;
+
+  /* Check for user errors */
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from HDIVG:  Too many or too few args \n");
+    gaprnt (0,"                   Two arguments expected \n");
+    return (1);
+  }
+  if (pst->idim!=0 || pst->jdim!=1) {
+    gaprnt (0,"Error from HDIVG:  Invalid dimension environment\n");
+    gaprnt (0,"  Horizontal environment (X, Y Varying) is required\n");
+    return (1);
+  }
+
+  /* Get the u and v fields.  User responsible for validity. */
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr1 = pst->result.pgr;
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) {
+    gagfre(pgr1);
+    return (rc);
+  }
+  if (pst->type==0) {
+    gafree (pst);
+    gagfre(pgr1);
+    return (-1);
+  }
+  pgr2 = pst->result.pgr;
+
+  /* Check that an operation between these grids is valid */
+  if (gagchk(pgr1,pgr2,pst->idim) ||
+      gagchk(pgr1,pgr2,pst->jdim) ) {
+    gaprnt (0,"Error from HDIVG:  Incompatable grids \n");
+    gaprnt (0,"                   Dimension ranges unequal \n");
+    goto erret;
+  }
+
+  /* Get memory for result grid and umask */
+  size = pgr1->isiz * pgr1->jsiz;
+  sz = size*sizeof(gadouble);
+  result = (gadouble *)galloc(sz,"hdivres");
+  if (result==NULL) {
+    gaprnt (0,"Memory Allocation Error:  HDIVG function \n");
+    goto erret;
+  }
+  sz = size*sizeof(char);
+  resultu = (char *)galloc(sz,"hdivresu");
+  if (resultu==NULL) {
+    gaprnt (0,"Memory Allocation Error:  HDIVG function \n");
+    goto erret;
+  }
+
+  /* Perform the divergence calculation except at grid borders */
+  for (i=0; i<size; i++) *(resultu+i) = 0;
+
+  lnvals = pgr1->ivals;
+  ltvals = pgr1->jvals;
+  lnconv = pgr1->igrab;
+  ltconv = pgr1->jgrab;
+
+  /*             p4
+                 |
+             p1--p--p3
+                 |
+                 p2                           */
+
+  p = result + (pgr1->isiz + 1);
+  p1 = pgr1->grid + pgr1->isiz;
+  p2 = pgr2->grid + 1;
+  p3 = p1 + 2;
+  p4 = p2 + (2 * pgr1->isiz);
+
+  pu = resultu + (pgr1->isiz + 1);
+  p1u = pgr2->umask + pgr2->isiz;
+  p2u = pgr1->umask + 1;
+  p3u = p1u + 2;
+  p4u = p2u + (2 * pgr1->isiz);
+
+  for (j=(pgr1->dimmin[1]+1); j<pgr1->dimmax[1]; j++) {
+    rj = (gadouble)j;
+    lat  = ltconv(ltvals,rj    ) * d2r;
+    lat2 = ltconv(ltvals,rj-1.0) * d2r;
+    lat4 = ltconv(ltvals,rj+1.0) * d2r;
+    for (i=(pgr1->dimmin[0]+1); i<pgr1->dimmax[0]; i++) {
+      if (*p1u!=0 && 
+	  *p2u!=0 &&
+          *p3u!=0 && 
+	  *p4u!=0 ) {
+        ri = (gadouble)i;
+        lon1 = lnconv(lnvals,ri-1.0) * d2r;
+        lon3 = lnconv(lnvals,ri+1.0) * d2r;
+        *p = (*p3 - *p1)/(lon3-lon1);
+        *p = *p + (*p4*cos(lat4) - *p2*cos(lat2))/(lat4-lat2);
+        temp = 6.37E6 * cos(lat);
+        if (temp>1E-10) {
+	  *p = *p / temp;
+	  *pu = 1;
+	}
+        else *pu = 0;
+      }
+      p++; p1++; p2++; p3++; p4++;
+      pu++; p1u++; p2u++; p3u++; p4u++;
+    }
+    p+=2; p1+=2; p2+=2; p3+=2; p4+=2;
+    pu+=2; p1u+=2; p2u+=2; p3u+=2; p4u+=2;
+  }
+  gree(pgr1->grid,"f417");
+  gree(pgr1->umask,"f418");
+  gagfre(pgr2);
+  pgr1->grid = result;
+  pgr1->umask = resultu;
+  pst->type = 1;
+  pst->result.pgr = pgr1;
+  return (0);
+
+erret:
+  if (result) gree(result,"f419");
+  gagfre(pgr1);
+  gagfre(pgr2);
+  return (1);
+
+}
+
+gaint ffhcrl (struct gafunc *pfc, struct gastat *pst) {
+gaint rc,size,i,j;
+struct gagrid *pgr1, *pgr2;
+gadouble *result=NULL;
+gadouble *p1, *p2, *p3, *p4, *p;
+gadouble lat2, lat4, lat, lon1, lon3, ri, rj, temp, d2r;
+gadouble *lnvals, *ltvals;
+gadouble (*lnconv) (gadouble *, gadouble);
+gadouble (*ltconv) (gadouble *, gadouble);
+char *p1u, *p2u, *p3u, *p4u, *pu, *resultu;
+size_t sz;
+
+  d2r = M_PI/180;
+
+  /* Check for user errors */
+
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from HCURL:  Too many or too few args \n");
+    gaprnt (0,"                   Two arguments expected \n");
+    return (1);
+  }
+  if (pst->idim!=0 || pst->jdim!=1) {
+    gaprnt (0,"Error from HCURL:  Invalid dimension environment\n");
+    gaprnt (0,"  Horizontal environment (X, Y Varying) is required\n");
+    return (1);
+  }
+
+  /* Get the u and v fields.  User responsible for validity. */
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gafree (pst);
+    return(-1);
+  }
+  pgr1 = pst->result.pgr;
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) {
+    gagfre(pgr1);
+    return (rc);
+  }
+  if (pst->type==0) {
+    gafree (pst);
+    gagfre(pgr1);
+    return (-1);
+  }
+  pgr2 = pst->result.pgr;
+
+  /* Check that an operation between these grids is valid */
+
+  if (gagchk(pgr1,pgr2,pst->idim) ||
+      gagchk(pgr1,pgr2,pst->jdim) ) {
+    gaprnt (0,"Error from HCURL:  Incompatable grids \n");
+    gaprnt (0,"                   Dimension ranges unequal \n");
+    goto erret;
+  }
+
+  /* Get memory for result grid and umask */
+  size = pgr1->isiz * pgr1->jsiz;
+  sz = size*sizeof(gadouble);
+  result = (gadouble *)galloc(sz,"hcurlres");
+  if (result==NULL) {
+    gaprnt (0,"Memory Allocation Error:  HCURL function\n");
+    goto erret;
+  }
+  sz = size*sizeof(char);
+  resultu = (char *)galloc(sz,"hcurlresu");
+  if (resultu==NULL) {
+    gaprnt (0,"Memory Allocation Error:  HCURL function\n");
+    goto erret;
+  }
+
+  /* Perform the vorticity calculation except at grid borders */
+  for (i=0; i<size; i++) *(resultu+i) = 0;
+
+  lnvals = pgr1->ivals;
+  ltvals = pgr1->jvals;
+  lnconv = pgr1->igrab;
+  ltconv = pgr1->jgrab;
+
+  /*             p4
+                 |
+             p1--p--p3
+                 |
+                 p2                           */
+
+  p  = result  + (pgr1->isiz + 1);
+  p1  = pgr2->grid + pgr2->isiz;
+  p2  = pgr1->grid + 1;
+  p3  = p1 + 2;
+  p4  = p2  + (2 * pgr1->isiz);
+
+  pu = resultu + (pgr1->isiz + 1);
+  p1u = pgr2->umask + pgr2->isiz;
+  p2u = pgr1->umask + 1;
+  p3u = p1u + 2;
+  p4u = p2u + (2 * pgr1->isiz);
+
+  for (j=(pgr1->dimmin[1]+1); j<pgr1->dimmax[1]; j++) {
+    rj = (gadouble)j;
+    lat  = ltconv(ltvals,rj    ) * d2r;
+    lat2 = ltconv(ltvals,rj-1.0) * d2r;
+    lat4 = ltconv(ltvals,rj+1.0) * d2r;
+    for (i=(pgr1->dimmin[0]+1); i<pgr1->dimmax[0]; i++) {
+      if (*p1u!=0 && 
+	  *p2u!=0 &&
+          *p3u!=0 && 
+	  *p4u!=0 ) {
+        ri = (gadouble)i;
+        lon1 = lnconv(lnvals,ri-1.0) * d2r;
+        lon3 = lnconv(lnvals,ri+1.0) * d2r;
+        *p = (*p3 - *p1)/(lon3-lon1);
+        *p = *p - (*p4*cos(lat4) - *p2*cos(lat2))/(lat4-lat2);
+        temp = 6.37E6 * cos(lat);
+        if (temp>1E-10) {
+	  *p = *p / temp;
+	  *pu = 1;
+	}
+        else {
+	  *pu = 0;
+	}
+      }
+      p++;  p1++;  p2++;  p3++;  p4++;
+      pu++; p1u++; p2u++; p3u++; p4u++;
+    }
+    p+=2;  p1+=2;  p2+=2;  p3+=2;  p4+=2;
+    pu+=2; p1u+=2; p2u+=2; p3u+=2; p4u+=2;
+  }
+  gree(pgr1->grid,"f420");
+  gree(pgr1->umask,"f421");
+  gagfre (pgr2);
+  pgr1->grid = result;
+  pgr1->umask = resultu;
+  pst->type = 1;
+  pst->result.pgr = pgr1;
+  return (0);
+
+erret:
+  if (result) gree(result,"f422");
+  gagfre(pgr1);
+  gagfre(pgr2);
+  return (1);
+
+}
+
+gaint fftv2q (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = fftv2 (pfc, pst, 0);
+  return (rc);
+}
+
+gaint fftv2t (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = fftv2 (pfc, pst, 1);
+  return (rc);
+}
+
+gaint fftv2 (struct gafunc *pfc, struct gastat *pst, gaint tflag) {
+struct gagrid *pgrtv, *pgrrh;
+gadouble *lvvals;
+gadouble (*lvconv) (gadouble *, gadouble);
+gaint i,j, rc, errcnt;
+gadouble *tv, *rh, t, q, p;
+char *tvu, *rhu;
+
+  if (pfc->argnum!=2) {
+    if (tflag) {
+      gaprnt (0,"Error from TVRH2T:  Too many or too few args \n");
+    } else {
+      gaprnt (0,"Error from TVRH2Q:  Too many or too few args \n");
+    }
+    gaprnt (0,"                    Two arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type == 0) {
+    gafree (pst);
+    return(-1);
+  }
+  pgrtv = pst->result.pgr;
+
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) return (rc);
+  if (pst->type == 0) {
+    gagfre(pgrtv);
+    gafree (pst);
+    return(-1);
+  }
+  pgrrh = pst->result.pgr;
+
+  if ((pgrrh->idim!=pgrtv->idim) || 
+      (pgrrh->jdim!=pgrtv->jdim) || 
+      (pgrrh->idim>-1 && gagchk(pgrrh,pgrtv,pgrrh->idim)) || 
+      (pgrrh->jdim>-1 && gagchk(pgrrh,pgrtv,pgrrh->jdim)) ) {
+    gaprnt (0,"Error in TVRH2Q: Grids don't have same scaling");
+    gagfre (pgrtv);
+    gagfre (pgrrh);
+    return (1);
+  }
+
+  errcnt = 0;
+  if (pgrrh->idim == 2) {
+    lvconv = pgrrh->igrab;
+    lvvals = pgrrh->ivals;
+    tv = pgrtv->grid;
+    rh = pgrrh->grid;
+    tvu = pgrtv->umask;
+    rhu = pgrrh->umask;
+    for (j=0; j<pgrrh->jsiz; j++) {
+      for (i=0; i<pgrrh->isiz; i++) {
+        if (*rhu==0 || *tvu==0) {
+          *rhu = 0;
+        } else {
+          p = lvconv(lvvals, (gadouble)(i+pgrrh->dimmin[2]));
+          rc = tvrh2q (p, *tv, *rh, &q, &t);
+          if (rc) {
+            *rhu = 0;
+            errcnt++;
+          } else {
+            if (tflag) {
+	      *rh = t;
+	      *rhu = 1;
+	    }
+            else {
+	      *rh = q;
+	      *rhu = 1;
+	    }
+          }
+        }
+        rh++;  tv++;
+        rhu++; tvu++;
+      }
+    }
+  } else if (pgrrh->jdim == 2) {
+    lvconv = pgrrh->jgrab;
+    lvvals = pgrrh->jvals;
+    tv = pgrtv->grid;
+    rh = pgrrh->grid;
+    tvu = pgrtv->umask;
+    rhu = pgrrh->umask;
+    for (j=0; j<pgrrh->jsiz; j++) {
+      p = lvconv(lvvals, (gadouble)(j+pgrrh->dimmin[2]));
+      for (i=0; i<pgrrh->isiz; i++) {
+        if (*rhu==0 || *tvu==0) {
+          *rhu = 0;
+        } else {
+          rc = tvrh2q (p, *tv, *rh, &q, &t);
+          if (rc) {
+            *rhu = 0;
+            errcnt++;
+          } else {
+            if (tflag) {
+	      *rh = t;
+	      *rhu = 1;
+	    }
+            else {
+	      *rh = q;
+	      *rhu = 1;
+	    }
+          }
+        }
+        rh++; tv++;
+        rhu++; tvu++;
+      }
+    }
+  } else {
+    p = pst->dmin[2];
+    snprintf(pout,255," Using fixed pressure level %g mb\n",p);
+    if (tflag) {
+      gaprnt (2,"Notice from TVRH2T:");
+    } else {
+      gaprnt (2,"Notice from TVRH2Q:");
+    }
+    gaprnt (1,pout);
+    tv = pgrtv->grid;
+    rh = pgrrh->grid;
+    tvu = pgrtv->umask;
+    rhu = pgrrh->umask;
+    for (j=0; j<pgrrh->jsiz; j++) {
+      for (i=0; i<pgrrh->isiz; i++) {
+        if (*rhu==0 || *tvu==0) {
+          *rhu = 0;
+        } else {
+          rc = tvrh2q (p, *tv, *rh, &q, &t);
+          if (rc) {
+            *rhu = 0;
+            errcnt++;
+          } else {
+            if (tflag) {
+	      *rh = t;
+	      *rhu = 1;
+	    }
+            else {
+	      *rh = q;
+	      *rhu = 1;
+	    }
+          }
+        }
+        rh++; tv++;
+        rhu++; tvu++;
+      }
+    }
+  }
+
+  if (errcnt) {
+    snprintf(pout,255," Convergence failed for %i grid points\n",errcnt);
+    if (tflag) {
+      gaprnt (1,"Warning from TVRH2T:");
+    } else {
+      gaprnt (1,"Warning from TVRH2Q:");
+    }
+    gaprnt (1,pout);
+  }
+  gagfre (pgrtv);
+  return (0);
+}
+
+/* Routine to convert tv and rh to t and q.  FORTRAN version
+   provided by J. Kinter.  Converted to C by B. Doty.    */
+
+gaint tvrh2q (gadouble p, gadouble tv, gadouble rh, gadouble *qret, gadouble *tret) {
+gadouble eps,a,b,c,t,q,al10,tc,esat,desdt,qr,f,denom,dfdt,fn,qn,tn;
+gaint i;
+
+  eps = 0.622;
+  a = 0.7854;
+  b = 0.03477;
+  c = 0.00412;
+
+  /* Convert rh to fraction.  Convert pressure to pascals. */
+
+  rh = rh * 0.01;
+  p = p*100.0;
+
+  /* Set first guess for t and q */
+
+  t = tv;
+  q = 0.01 * rh * eps;
+
+  /* Iterate to convergence */
+
+  al10 = log(10.0);
+  for (i=0; i<25; i++) {
+
+    /* Set saturation vapor pressure (compute from smisthonian tables)*/
+
+    tc = t - 273.16;
+    esat = 100.0 * exp(al10*(a+b*tc)/(1.0+c*tc));
+    desdt = al10 * esat * (b-a*c)/((1.0+c*tc)*(1.0+c*tc));
+    qr = eps*rh*esat/(p-(1.0-eps)*esat);
+    f = q-qr;
+
+    /* Compute derivative of q wrt q given fixed virtual temp and
+       rh (constant pressure) */
+
+    denom = p-(1.0-eps)*esat;
+    denom = denom * denom;
+    dfdt = eps*rh*((p-(1.0-eps)*esat)*desdt+esat*(1.0-eps)*desdt);
+    dfdt = 1.0-dfdt/denom;
+
+    /* Newton's method */
+
+    fn = f-f/dfdt;
+    qn = fn+qr;
+    tn = eps*tv*((1.0-qn)/(eps*(1.0-qn)+qn*(1.0-eps)));
+
+    /* Test for convergence */
+
+    if (fabs((tn-t)/t) <= 1.0E-6) break;
+    q = qn;
+    t = tn;
+  }
+
+  /* Print results */
+
+  if (i==25) return(1);
+  *qret = qn;
+  *tret = tn;
+  return(0);
+}
+
+gaint ffvint (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgrb, *pgr, *pgrv;
+struct gafile *pfi;
+gadouble *ps, *var, *res;
+gadouble *lvvals;
+gadouble (*lvconv) (gadouble *, gadouble);
+gadouble top,clev,ulev,blev,ulevi,blevi,ulevt,blevt,kgm;
+gaint rc, size, i, j, lvt;
+char *psu, *varu, *resu;
+
+  if (pfc->argnum!=3) {
+    gaprnt (0,"Error from VINT:  Too many or too few args \n");
+    gaprnt (0,"                  Three arguments expected \n");
+    return (1);
+  }
+
+  /* Get top pressure level.  It is a character value in 3rd arg */
+  if (getdbl(pfc->argpnt[2],&top)==NULL) {
+    gaprnt (0,"Error from VINT:  3rd argument invalid. \n");
+    return (1);
+  }
+
+  /* Get the range of levels from the default file.  Set the
+     level in the status block to the first level.  */
+
+  pfi = pst->pfid;
+  lvt = pfi->dnum[2];
+  if (lvt<3) {
+    gaprnt (0,"Error from VINT:  Too few levels in default file \n");
+    return (1);
+  }
+  lvconv = pfi->gr2ab[2];
+  lvvals = pfi->grvals[2];
+  clev = lvconv(lvvals, 1.0);
+  ulev = lvconv(lvvals, 2.0);
+  ulev = clev + ((ulev-clev)/2.0);
+  pst->dmin[2] = clev;
+  pst->dmax[2] = clev;
+  if (pst->idim==2) {
+    pst->idim = pst->jdim;
+    pst->jdim = -1;
+  }
+  if (pst->jdim==2) pst->jdim = -1;
+
+  /* Get the surface pressure field (1st arg).  User is responsible
+     for valid argument.  Then get the lowest level of the
+     field to integrate.  */
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (1);
+  if (pst->type==0) {
+    gafree (pst);
+    return (-1);
+  }
+  pgrb = pst->result.pgr;
+
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) {
+    gagfre (pgrb);
+    return (1);
+  }
+  if (pst->type==0) {
+    gafree (pst);
+    gagfre (pgrb);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Check that the two grids are equivalent.  */
+  if (pgrb->isiz!=pgr->isiz || pgrb->jsiz!=pgr->jsiz) {
+    gaprnt (0,"Error from VINT:  Incompatible grids. \n");
+    goto erret;
+  }
+
+  /* Apply appropriate mass weight (kg/m**2) to first level.
+     It is assumed the vertical coordinate system is mb.    */
+  size = pgr->isiz * pgr->jsiz;
+  kgm = 100.0/9.8;
+  ps  = pgrb->grid; 
+  psu = pgrb->umask;
+  res  = pgr->grid; 
+  resu = pgr->umask;
+  for (i=0; i<size; i++) {
+    if (*psu==0 || *resu==0) {
+      *resu = 0;
+    }
+    else if (*ps < clev) {
+      *resu = 0;
+    }
+    else {
+      *res = *res * kgm * (*ps - ulev);
+      *resu = 1;
+    }
+    ps++; psu++; res++; resu++;
+  }
+
+  /* Go through the intermediate levels and apply mass weight. */
+  for (i=2; i<lvt; i++) {
+    clev = lvconv(lvvals, (gadouble)i);
+    if (clev<top) break;
+    ulev = lvconv(lvvals, (gadouble)(i+1));
+    ulevi = clev + ((ulev-clev)/2.0);
+    blev = lvconv(lvvals, (gadouble)(i-1));
+    blevi = clev + ((blev-clev)/2.0);
+    pst->dmin[2] = clev;
+    pst->dmax[2] = clev;
+    rc = gaexpr(pfc->argpnt[1],pst);
+    if (rc) goto erret;
+    if (pst->type==0) {
+      rc = -1;
+      gafree (pst);
+      goto erret;
+    }
+    pgrv = pst->result.pgr;
+    ps  = pgrb->grid;
+    res = pgr->grid;
+    var = pgrv->grid;
+    psu  = pgrb->umask;
+    resu = pgr->umask;
+    varu = pgrv->umask;
+    for (j=0; j<size; j++) {
+      if ((*psu!=0) && (*varu!=0) && (*ps>=clev)) {
+        ulevt = ulevi;
+        if (top>ulev) ulevt = top;
+        blevt = blevi;
+        if (*ps<blev) blevt = *ps;
+        if (*resu==0) {
+	  *res = *var * kgm * (blevt - ulevt);
+	  *resu = 1;
+	}
+        else {
+	  *res = *res + (*var * kgm * (blevt - ulevt) );
+	  *resu = 1;
+	}
+      }
+      ps++;  res++;  var++;
+      psu++; resu++; varu++;
+    }
+    gafree (pst);
+  }
+
+  /* Do top, and last, level */
+
+  clev = lvconv(lvvals, (gadouble)i);
+  if (top<=clev) {
+    blev = lvconv(lvvals, (gadouble)(i-1));
+    blevi = clev + ((blev-clev)/2.0);
+    pst->dmin[2] = clev;
+    pst->dmax[2] = clev;
+    rc = gaexpr(pfc->argpnt[1],pst);
+    if (rc) goto erret;
+    if (pst->type==0) {
+      rc = -1;
+      gafree (pst);
+      goto erret;
+    }
+    pgrv = pst->result.pgr;
+    ps  = pgrb->grid;
+    res = pgr->grid;
+    var = pgrv->grid;
+    psu  = pgrb->umask;
+    resu = pgr->umask;
+    varu = pgrv->umask;
+    for (i=0; i<size; i++) {
+      if (*psu!=0 && *varu!=0) {
+        blevt = blevi;
+        if (*ps<blev) blevt = *ps;
+        if (*resu==0) {
+	  *res = *var * kgm * (blevt - top);
+	  *resu = 1;
+	}
+        else {
+	  *res = *res + (*var * kgm * (blevt - top) );
+	  *resu = 1;
+	}
+      }
+      ps++; res++; var++;
+      psu++; resu++; varu++;
+    }
+  }
+  gafree (pst);
+
+  /* Release storage and return */
+
+  rc = 0;
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  gagfre (pgrb);
+  return (0);
+
+  /* Error return */
+
+erret:
+
+  gagfre (pgrb);
+  gagfre (pgr);
+  return (rc);
+}
+
+gaint fftlp (struct gafunc *pfc, struct gastat *pst) {
+struct gafile *pfi;
+struct gagrid *pgr, *res;
+gaint size, rc, t1, t2, i, cont;
+gadouble gr1, gr2,*in, *out;
+char *inu, *outu;
+size_t sz;
+
+  /* Check for valid number of args       */
+
+  if (pfc->argnum != 1 ) {
+    gaprnt (0,"Error from TLOOP:  Too many or too few args \n");
+    gaprnt (0,"                   1 argument expected \n");
+    return (1);
+  }
+
+  /* If t is non-varying, treat this as a no-op.  */
+
+  if (pst->idim!=3 && pst->jdim!=3) {
+    rc = gaexpr(pfc->argpnt[0],pst);
+    return (rc);
+  }
+
+  /* Get start and end times in terms of grid space */
+
+  pfi = pst->pfid;
+  gr1 = t2gr(pfi->abvals[3], &pst->tmin);
+  gr2 = t2gr(pfi->abvals[3], &pst->tmax);
+  gr1 = ceil(gr1-0.001);
+  gr2 = floor(gr2+0.001);
+  t1 = (gaint)gr1;
+  t2 = (gaint)gr2;
+  if (t2<t1) t2 = t1;
+
+  /* Get 1st grid. */
+
+  gr2t(pfi->grvals[3], gr1, &pst->tmin);
+  if (pst->idim==3) {
+    pst->idim = pst->jdim;
+    pst->jdim = -1;
+  }
+  if (pst->jdim==3) pst->jdim = -1;
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Check validity of 1st grid.  It should be a 1-D or a 0-D grid,
+     and it should not have a time-varying dimension.  */
+
+  if (pgr->jdim!=-1 || pgr->idim==3) {
+    gaprnt (0,"Error from TLOOP: Internal logic check 36\n");
+    goto err1;
+  }
+
+  /* Create output grid */
+
+  size = sizeof(struct gagrid);
+  sz = size;
+  res = (struct gagrid *)galloc(sz,"tloopres");
+  if (res==NULL) {
+    gaprnt (0,"Memory Allocation Error:  TLOOP function\n");
+    goto err1;
+  }
+  size = 1+t2-t1;
+  size = size * pgr->isiz;
+  if (size>1) {
+    sz = size*sizeof(gadouble);
+    res->grid = (gadouble *)galloc(sz,"tloopgr");
+    if (res->grid==NULL) {
+      gaprnt (0,"Memory Allocation Error:  TLOOP function\n");
+      gree(res,"f423");
+      goto err1;
+    }
+    sz = size*sizeof(char);
+    res->umask = (char *)galloc(sz,"tloopgru");
+    if (res->umask==NULL) {
+      gaprnt (0,"Memory Allocation Error:  TLOOP function\n");
+      gree(res->grid,"f424");
+      gree(res,"f425");
+      goto err1;
+    }
+  } else {
+    res->grid = &(res->rmin);
+    res->umask = &(res->umin);
+  }
+
+  res->alocf = 0;
+  res->pfile = NULL;
+  res->undef = pgr->undef;
+  res->pvar  = NULL;
+  res->exprsn = NULL;
+  for (i=0;i<5;i++) {
+    res->dimmin[i] = 0;
+    res->dimmax[i] = 0;
+  }
+  res->dimmin[3] = t1;
+  res->dimmax[3] = t2;
+  res->jwrld = 0;
+  if (pgr->isiz>1) {
+    res->dimmin[pgr->idim] = pgr->dimmin[pgr->idim];
+    res->dimmax[pgr->idim] = pgr->dimmax[pgr->idim];
+    res->idim = pgr->idim;
+    res->iwrld = pgr->iwrld;
+    res->isiz = pgr->isiz;
+    res->igrab = pgr->igrab;
+    res->ilinr = pgr->ilinr;
+    res->ivals = pgr->ivals;
+    if (t1==t2) {
+      res->jdim = -1;
+      res->jsiz = 1;
+    } else {
+      res->jdim = 3;
+      res->jsiz = 1+t2-t1;
+      res->jvals = pfi->grvals[3];
+      res->jgrab = NULL;
+      res->jlinr = 1;
+    }
+  } else {
+    res->jdim = -1;
+    res->jsiz = 1;
+    if (t1==t2) {
+      res->idim = -1;
+      res->isiz = 1;
+    } else {
+      res->idim = 3;
+      res->isiz = 1+t2-t1;
+      res->ivals = pfi->grvals[3];
+      res->igrab = NULL;
+      res->ilinr = 1;
+    }
+  }
+
+  /* Loop and fill output grid.  */
+
+  cont = 1;
+  out = res->grid;
+  outu = res->umask;
+  while (cont) {
+    in = pgr->grid;
+    inu = pgr->umask;
+    for (i=0; i<pgr->isiz; i++) {
+      if (*inu==0) {
+	*outu=0;
+      }
+      else {
+	*out = *in;
+	*outu = 1;
+      }
+      in++; inu++; out++; outu++;
+    }
+    gagfre(pgr);
+    t1++;
+    if (t1<=t2) {
+      gr2t(pfi->abvals[3], (gadouble)t1, &pst->tmin);
+      pst->tmax = pst->tmin;
+      rc = gaexpr(pfc->argpnt[0],pst);
+      if (rc) goto err2;
+      pgr = pst->result.pgr;
+    } else cont = 0;
+  }
+  pst->result.pgr = res;
+  return (0);
+
+err1:
+  gagfre (pgr);
+  return (1);
+
+err2:
+  gagfre(res);
+  return(1);
+}
+
+gaint ffelp (struct gafunc *pfc, struct gastat *pst) {
+struct gafile *pfi;
+struct gagrid *pgr, *res;
+gaint size, rc, e1, e2, i, cont;
+gadouble gr1, gr2,*in, *out;
+char *inu, *outu;
+size_t sz;
+
+  /* Check for valid number of args       */
+  if (pfc->argnum != 1 ) {
+    gaprnt (0,"Error from ELOOP:  Too many or too few args \n");
+    gaprnt (0,"                   1 argument expected \n");
+    return (1);
+  }
+
+  /* If e is non-varying, treat this as a no-op.  */
+  if (pst->idim!=4 && pst->jdim!=4) {
+    rc = gaexpr(pfc->argpnt[0],pst);
+    return (rc);
+  }
+
+  /* Get start and end E indices */
+  pfi = pst->pfid;
+  gr1 = pst->dmin[4];
+  gr2 = pst->dmax[4];
+  gr1 = ceil(gr1-0.001);
+  gr2 = floor(gr2+0.001);
+  e1 = (gaint)gr1;
+  e2 = (gaint)gr2;
+  if (e2<e1) e2 = e1;
+
+  /* Get 1st grid. */
+  pst->dmin[4] = e1;
+  if (pst->idim==4) {
+    pst->idim = pst->jdim;
+    pst->jdim = -1;
+  }
+  if (pst->jdim==4) pst->jdim = -1;
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gafree (pst);
+    return (-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Check validity of 1st grid.  It should be a 1-D or a 0-D grid,
+     and it should not have a ensemble-varying dimension.  */
+  if (pgr->jdim!=-1 || pgr->idim==4) {
+    gaprnt (0,"Error from ELOOP: Internal logic check 36\n");
+    goto err1;
+  }
+
+  /* Create output grid */
+  size = sizeof(struct gagrid);
+  sz = size;
+  res = (struct gagrid *)galloc(sz,"eloopres");
+  if (res==NULL) {
+    gaprnt (0,"Memory Allocation Error:  ELOOP function\n");
+    goto err1;
+  }
+  size = 1+e2-e1;
+  size = size * pgr->isiz;
+  if (size>1) {
+    sz = size*sizeof(gadouble);
+    res->grid = (gadouble *)galloc(sz,"eloopgr");
+    if (res->grid==NULL) {
+      gaprnt (0,"Memory Allocation Error:  ELOOP function\n");
+      gree(res,"f423e");
+      goto err1;
+    }
+    sz = size*sizeof(char);
+    res->umask = (char *)galloc(sz,"eloopgru");
+    if (res->umask==NULL) {
+      gaprnt (0,"Memory Allocation Error:  ELOOP function\n");
+      gree(res->grid,"f424e");
+      gree(res,"f425e");
+      goto err1;
+    }
+  } else {
+    res->grid = &(res->rmin);
+    res->umask = &(res->umin);
+  }
+
+  res->alocf = 0;
+  res->pfile = NULL;
+  res->undef = pgr->undef;
+  res->pvar  = NULL;
+  res->exprsn = NULL;
+  for (i=0;i<5;i++) {
+    res->dimmin[i] = 0;
+    res->dimmax[i] = 0;
+  }
+  res->dimmin[4] = e1;
+  res->dimmax[4] = e2;
+  res->jwrld = 0;
+  if (pgr->isiz>1) {
+    res->dimmin[pgr->idim] = pgr->dimmin[pgr->idim];
+    res->dimmax[pgr->idim] = pgr->dimmax[pgr->idim];
+    res->idim = pgr->idim;
+    res->iwrld = pgr->iwrld;
+    res->isiz = pgr->isiz;
+    res->igrab = pgr->igrab;
+    res->ilinr = pgr->ilinr;
+    res->ivals = pgr->ivals;
+    if (e1==e2) {
+      res->jdim = -1;
+      res->jsiz = 1;
+    } else {
+      res->jdim = 4;
+      res->jsiz = 1+e2-e1;
+      res->jvals = pfi->grvals[4];
+      res->jgrab = NULL;
+      res->jlinr = 1;
+    }
+  } else {
+    res->jdim = -1;
+    res->jsiz = 1;
+    if (e1==e2) {
+      res->idim = -1;
+      res->isiz = 1;
+    } else {
+      res->idim = 4;
+      res->isiz = 1+e2-e1;
+      res->ivals = pfi->grvals[4];
+      res->igrab = NULL;
+      res->ilinr = 1;
+    }
+  }
+
+  /* Loop and fill output grid.  */
+  cont = 1;
+  out = res->grid;
+  outu = res->umask;
+  while (cont) {
+    in = pgr->grid;
+    inu = pgr->umask;
+    for (i=0; i<pgr->isiz; i++) {
+      if (*inu==0) {
+	*outu=0;
+      }
+      else {
+	*out = *in;
+	*outu = 1;
+      }
+      in++; inu++; out++; outu++;
+    }
+    gagfre(pgr);
+    e1++;
+    if (e1<=e2) {
+      pst->dmin[4] = e1;
+      pst->dmax[4] = pst->dmin[4];
+      rc = gaexpr(pfc->argpnt[0],pst);
+      if (rc) goto err2;
+      pgr = pst->result.pgr;
+    } else cont = 0;
+  }
+  pst->result.pgr = res;
+  return (0);
+
+err1:
+  gagfre (pgr);
+  return (1);
+
+err2:
+  gagfre(res);
+  return(1);
+}
+
+gaint ffmask (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+struct gastn *stn;
+struct garpt *rpt;
+char *ch,c1,c2;
+gaint rc,cnt,flag,i;
+
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from MASKOUT:  Too many or too few args \n");
+    gaprnt (0,"                     Two arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type!=0 || *(pfc->argpnt[1])!='\'') {
+
+    pst2 = *pst;
+    rc = gaexpr(pfc->argpnt[1],&pst2);
+    if (rc) {
+      gafree (pst);
+      return (rc);
+    }
+
+    rc = gafopr (pst, &pst2, 13);
+    if (rc) {
+      gafree (pst);
+      gafree (&pst2);
+    }
+
+    /* Handle maskout of stn data by stid */
+
+  } else {
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      ch = pfc->argpnt[1]+1;
+      flag = 1; cnt = 0;
+      while (*ch!='\'' && flag && cnt<8) {
+        if (*ch!='?') {
+          c1 = *ch;
+          c2 = rpt->stid[cnt];
+          i = c1;
+          if (i>64 && i<91) {i+=32; c1=i;}
+          i = c2;
+          if (i>64 && i<91) {i+=32; c2=i;}
+          if (c1 != c2) flag = 0;
+        }
+        ch++; cnt++;
+      }
+      if (flag==0) rpt->umask = 0;
+      rpt=rpt->rpt;
+    }
+  }
+  return (rc);
+}
+
+/* Given a grid and a set of stations, interpolate to the
+   stations and return the set of stations.                       */
+
+gaint ffg2s  (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*jconv) (gadouble *, gadouble);
+gadouble *ivars, *jvars, *p1, *p2, *p3, *p4;
+gadouble gi,gj,w1,w2,lon,lat,lnmin,lnmax,lnscl,ltmin,ltmax,ltscl;
+gadouble w3,w4,wm;
+gaint rc,ig,jg,nearn;
+char *p1u, *p2u, *p3u, *p4u;
+ 
+
+  if (pfc->argnum<2 || pfc->argnum>4) {
+    gaprnt (0,"Error from GR2STN:  Too many or too few args \n");
+    gaprnt (0,"                    2 or 3 or 4 arguments expected \n");
+    return (1);
+  }
+
+  /* If we are doing the form of gr2stn that involves
+     interpolating to a 1-D profile or time series, 
+     branch to a different routine */
+
+  if ( (pst->idim == -1 || pst->idim>1) && pst->jdim == -1) {
+    rc = ffg2s2 (pfc,pst);
+    return (rc);
+  }
+
+  /* Check for nearest neighbor flag -- instead of bilin interp from
+     grid to station, use the nearest grid point to the station. */
+
+  nearn = 0;
+  if (pfc->argnum==3 && strcmp("-n",pfc->argpnt[2])==0) nearn = 1;
+  if (nearn) gaprnt (2,"Notice: Using nearest neighbor instead of bilinear interpolation\n");
+
+  /* Evaluate the grid expression */
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type!=1) {
+    gaprnt (0,"Error from GR2STN: 1st argument is not a grid\n");
+    gafree (pst);
+    return (1);
+  }
+  pgr = pst->result.pgr;
+  if (pgr->idim!=0 || pgr->jdim!=1) {
+    gaprnt (0,"Error from GR2STN: 2-D grid must vary in X and Y\n");
+    gafree (pst);
+    return (1);
+  }
+  if (!pgr->ilinr || !pgr->jlinr) {
+    gaprnt (0,"Error from GR2STN: 2-D grid dimensions must have linear scaling\n");
+    gafree (pst);
+    return (1);
+  }
+
+  /* Evaluate the station expression */
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) {
+    gagfre (pgr);
+    return (rc);
+  }
+  if (pst->type!=0) {
+    gaprnt (0,"Error from GR2STN: 2nd argument is not a station expression\n");
+    gafree (pst);
+    gagfre (pgr);
+    return (1);
+  }
+  stn = pst->result.stn;
+
+  /* Set up scaling for converting lon-lat to grid units */
+  iconv = pgr->igrab;
+  ivars = pgr->ivals;
+  jconv = pgr->jgrab;
+  jvars = pgr->jvals;
+  lnmin = iconv(ivars,(gadouble)pgr->dimmin[0]);
+  lnmax = iconv(ivars,(gadouble)pgr->dimmax[0]);
+  ltmin = iconv(jvars,(gadouble)pgr->dimmin[1]);
+  ltmax = iconv(jvars,(gadouble)pgr->dimmax[1]);
+  lnscl = (lnmax-lnmin)/((gadouble)pgr->isiz-1);
+  ltscl = (ltmax-ltmin)/((gadouble)pgr->jsiz-1);
+
+  /* Now loop through each stn report, convert stn lat/lon to grid
+     units, then interpolate from grid to stn */
+
+  rpt = stn->rpt;
+  while (rpt!=NULL) {
+    lon = rpt->lon;
+    lat = rpt->lat;
+    if (lon<lnmin) lon+=360.0;
+    else if (lon>lnmax) lon-=360.0;
+    if (lon<lnmin || lon>=lnmax || lat<ltmin || lat>=ltmax) {
+      rpt->umask = 0;
+    } else {
+      gi = (lon-lnmin)/lnscl;
+      gj = (lat-ltmin)/ltscl;
+      ig = (gaint)gi; 
+      jg = (gaint)gj;
+      p1 = pgr->grid + jg*pgr->isiz + ig;
+      p1u = pgr->umask + jg*pgr->isiz + ig;
+      p2 = p1+1;
+      p2u = p1u+1;
+      p3 = p2 + pgr->isiz;
+      p3u = p2u + pgr->isiz;
+      p4 = p1 + pgr->isiz;
+      p4u = p1u + pgr->isiz;
+      if (nearn) {                   /* nearest neighbor */
+        gi = gi - (gadouble)ig;
+        gj = gj - (gadouble)jg;
+        w1 = hypot(gi,gj);
+        w2 = hypot(1.0-gi,gj);
+        w3 = hypot(1.0-gi,1.0-gj);
+        w4 = hypot(gi,1.0-gj);
+        wm = 999.0;
+        if (w1<wm) {
+          wm = w1;
+          if (*p1u==0) rpt->umask = 0;
+          else rpt->val = *p1;
+        }
+        if (w2<wm) {
+          wm = w2;
+          if (*p2u==0) rpt->umask = 0;
+          else rpt->val = *p2;
+        }
+        if (w3<wm) {
+          wm = w3;
+          if (*p3u==0) rpt->umask = 0;
+          else rpt->val = *p3;
+        }
+        if (w4<wm) {
+          wm = w4;
+          if (*p4u==0) rpt->umask = 0;
+          else rpt->val = *p4;
+        }
+      } else {                        /* bilinear */
+        if (*p1u==0 || *p2u==0 || *p3u==0 || *p4u==0) {
+          rpt->umask = 0;
+        } else {
+          gi = gi - (gadouble)ig;
+          gj = gj - (gadouble)jg;
+/*
+ Weighted by distance or use bilinear?  bilinear looks to be
+ more valid to me......
+          w1 = 1.0 - hypot(gi,gj);
+          w2 = 1.0 - hypot(1.0-gi,gj);
+          w3 = 1.0 - hypot(1.0-gi,1.0-gj);
+          w4 = 1.0 - hypot(gi,1.0-gj);
+          if (w1<0.0) w1=0.0;
+          if (w2<0.0) w2=0.0;
+          if (w3<0.0) w3=0.0;
+          if (w4<0.0) w4=0.0;
+          rpt->val = *p1*w1 + *p2*w2 + *p3*w3 + *p4*w4;
+          rpt->val = rpt->val / (w1+w2+w3+w4);
+*/
+          w1 = *p1 + (*p2 - *p1)*gi;
+          w2 = *p4 + (*p3 - *p4)*gi;
+          rpt->val = w1 + (w2-w1)*gj;
+        }
+      }
+    }
+    rpt=rpt->rpt;
+  }
+  gagfre (pgr);
+  pst->type = 0;
+  pst->result.stn=stn;
+  return(0);
+}
+
+/* gr2stn where we interpolate to a lat-lon for 
+   a profile or time series */
+
+gaint ffg2s2  (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr, *pgr2;
+struct gastn *stn, *stn2;
+struct garpt *rpt;
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*icnv) (gadouble *, gadouble);
+gadouble (*jcnv) (gadouble *, gadouble);
+gadouble *ivars, lon, lat, *grid, lev=0, val=0;
+gadouble *p1, *p2, *p3, *p4;
+gadouble gi,gj,w1,w2,w3,w4,wm;
+gaint i,rc,gr1,gr2,gr,ig,jg,nearn;
+char *p1u, *p2u, *p3u, *p4u, umask=0;
+size_t sz;
+
+  /* Get lat-lon to interpolate to.  This is either provided
+     as two string arguments, or as a single stn-data argument. */
+
+  iconv = NULL;
+  stn2 = NULL;
+  ivars = 0;
+  nearn = 0;
+  /* Evaluate the 2nd argument  */
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    /* 2nd arg is station expression */
+    stn2 = pst->result.stn;
+    rpt = stn2->rpt;
+    lat = rpt->lat;
+    lon = rpt->lon;
+    /* Check for nearest neighbor flag in 3rd arg */
+    if (pfc->argnum==3 && strcmp("-n",pfc->argpnt[2])==0) nearn = 1;
+  } 
+  else {
+    /* 2nd & 3rd args are lon & lat */
+    pgr = pst->result.pgr;
+    if (pgr->idim!=-1 || pgr->jdim!=-1) {
+      gaprnt (0,"Error in GR2STN:  2nd arg invalid\n");
+      return (1);
+    }
+    lon = pgr->rmin;
+    gafree(pst);
+    if (pfc->argnum<3) {
+      gaprnt(0,"Error in GR2STN:  3rd Argument Required\n");
+      return (1);
+    }
+    if (getdbl(pfc->argpnt[2],&lat)==NULL) {
+      gaprnt (0,"Error from GR2STN:  3rd argument invalid. \n");
+      return (1);
+    }
+    /* Check for nearest neighbor flag in 4th arg */
+    if (pfc->argnum==4 && strcmp("-n",pfc->argpnt[3])==0) nearn = 1;
+  }
+  /* Evaluate the 1st argument */
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type!=1) {
+    gaprnt (0,"Error from GR2STN: 1st argument is not a grid\n");
+    gafree (pst);
+    return (1);
+  }
+  pgr = pst->result.pgr;
+  if (pgr->idim==3) {
+    ivars = pgr->ivals;
+    gr1 = pgr->dimmin[3];
+    gr2 = pgr->dimmax[3];
+  } else if (pgr->idim==2) {
+    iconv = pgr->igrab;
+    ivars = pgr->ivals;
+    gr1 = pgr->dimmin[2];
+    gr2 = pgr->dimmax[2];
+  } else if (pgr->idim== -1) {
+    gr1 = 1;  
+    gr2 = 1;
+  } else if (pgr->idim==4) {
+    gaprnt(0,"Error from GR2STN: 1-D grid may vary only in the Z or T dimension \n");
+    gafree (pst);
+    return (1);
+  } else {
+    gaprnt (0,"Error from GR2STN:  Logic Error 4\n");
+    gafree (pst);
+    return (1);
+  }
+
+  /* Set up stn structure for the returned data */
+  sz = sizeof(struct gastn);
+  stn = (struct gastn *)galloc(sz,"gr2stn");
+  if (stn==NULL) {
+    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+    gagfre (pgr);
+    return (1);
+  }
+  stn->rpt = NULL;
+  stn->rnum = 0;
+  stn->idim = pgr->idim;
+  stn->jdim = pgr->jdim;
+  stn->undef = pgr->undef;
+  stn->pvar = NULL;
+  stn->dmin[0] = lon;  stn->dmax[0] = lon;
+  stn->dmin[1] = lat;  stn->dmax[1] = lat;
+  stn->rflag = 0;
+  stn->radius = 1.0;
+  stn->sflag = 1;
+  if (stn2) {
+    for (i=0; i<8; i++) stn->stid[i] = stn2->stid[i];
+  } else {
+    for (i=0; i<8; i++) stn->stid[i] = 'x';
+  }
+  sz = sizeof(gadouble)*8;
+  stn->tvals = (gadouble *)galloc(sz,"gr2stnt");
+  if (stn->tvals==NULL) {
+    gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+    gree(stn,"f426");
+    gagfre (pgr);
+    return (1);
+  }
+  stn->jdim = -1;
+  if (pgr->idim==3) {                  /* time series */
+    for (i=0; i<8; i++) *(stn->tvals+i) = *(ivars+i);
+    stn->tmin = gr1; stn->tmax = gr2;
+    stn->dmin[2] = pst->dmin[2];
+    stn->dmax[2] = pst->dmin[2];
+    stn->idim = 3;
+  } else if (pgr->idim== -1) {         /* single point */
+    stn->dmin[2] = pst->dmin[2];
+    stn->dmax[2] = pst->dmin[2];
+    stn->tmin = 1; stn->tmax = 1;
+    *(stn->tvals) = pst->tmin.yr;
+    *(stn->tvals+1) = pst->tmin.mo;
+    *(stn->tvals+2) = pst->tmin.dy;
+    *(stn->tvals+3) = pst->tmin.hr;
+    *(stn->tvals+4) = pst->tmin.mn;
+    *(stn->tvals+5) = 0.0;
+    *(stn->tvals+6) = 1.0;
+    *(stn->tvals+7) = -999.9;
+  } else {                             /* vertical profile */
+    stn->dmin[2] = gr1;  
+    stn->dmax[2] = gr2;
+    stn->tmin = 1; 
+    stn->tmax = 1;
+    *(stn->tvals) = pst->tmin.yr;
+    *(stn->tvals+1) = pst->tmin.mo;
+    *(stn->tvals+2) = pst->tmin.dy;
+    *(stn->tvals+3) = pst->tmin.hr;
+    *(stn->tvals+4) = pst->tmin.mn;
+    *(stn->tvals+5) = 0.0;
+    *(stn->tvals+6) = 1.0;
+    *(stn->tvals+7) = -999.9;
+  }
+
+  if (nearn) gaprnt (2,"Notice: Using nearest neighbor instead of bilinear interpolation\n");
+
+  pst->idim = 0;
+  pst->jdim = 1;
+  pst->dmin[0] = lon;
+  pst->dmax[0] = lon + 0.1;
+  pst->dmin[1] = lat;
+  pst->dmax[1] = lat + 0.1;
+  /* loop over grid points in the profile/time series */
+  for (gr=gr1; gr<=gr2; gr++) { 
+    if (pgr->idim==2) {
+      lev = iconv(ivars,(gadouble)gr);
+      pst->dmin[2] = lev;
+      pst->dmax[2] = lev;
+    } else if (pgr->idim==3) {
+      gr2t (ivars, (gadouble)gr, &(pst->tmin));
+      pst->tmax = pst->tmin;
+    }
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (rc) {
+      gagfre(pgr);
+      return (rc);
+    }
+    pgr2 = pst->result.pgr;
+    grid = pgr2->grid;
+    icnv = pgr2->iabgr;
+    jcnv = pgr2->jabgr;
+    gi = icnv(pgr2->iavals,lon) - (gadouble)pgr2->dimmin[0];
+    gj = jcnv(pgr2->javals,lat) - (gadouble)pgr2->dimmin[1];
+    ig = (gaint)gi; 
+    jg = (gaint)gj;
+    p1 = pgr2->grid + jg*pgr2->isiz + ig;
+    p1u = pgr2->umask + jg*pgr2->isiz + ig;
+    p2 = p1+1;
+    p2u = p1u+1;
+    p3 = p2 + pgr2->isiz;
+    p3u = p2u + pgr2->isiz;
+    p4 = p1 + pgr2->isiz;
+    p4u = p1u + pgr2->isiz;
+    if (nearn) {                   /* nearest neighbor */
+      gi = gi - (gadouble)ig;
+      gj = gj - (gadouble)jg;
+      w1 = hypot(gi,gj);
+      w2 = hypot(1.0-gi,gj);
+      w3 = hypot(1.0-gi,1.0-gj);
+      w4 = hypot(gi,1.0-gj);
+      wm = 999.0;
+      if (w1<wm) {
+	wm = w1;
+	if (*p1u==0) umask = 0;
+	else {umask = 1; val = *p1;}
+      }
+      if (w2<wm) {
+	wm = w2;
+	if (*p2u==0) umask = 0;
+	else {umask = 1; val = *p2;}
+      }
+      if (w3<wm) {
+	wm = w3;
+	if (*p3u==0) umask = 0;
+	else {umask = 1; val = *p3;}
+      }
+      if (w4<wm) {
+	wm = w4;
+	if (*p4u==0) umask = 0;
+	else {umask = 1; val = *p4;}
+      }
+    } else {                        /* bilinear */ 
+      if (*p1u==0 || *p2u==0 || *p3u==0 || *p4u==0) {
+	umask = 0;
+      } else {
+	gi = gi - (gadouble)ig;
+	gj = gj - (gadouble)jg;
+	w1 = *p1 + (*p2 - *p1)*gi;
+	w2 = *p4 + (*p3 - *p4)*gi;
+	val = w1 + (w2-w1)*gj;
+	umask = 1;
+      }
+    }
+
+    rpt = gaarpt (stn);
+    if (rpt==NULL) {
+      gaprnt (0,"Memory Allocation Error:  Station Block \n");
+      gagfre(pgr);  
+      gafree(pst); 
+      gasfre(stn);
+      return (1);
+    }
+    rpt->lat = lat;
+    rpt->lon = lon;
+    if (pgr->idim==2) { rpt->lev = lev; rpt->tim = 1; }
+    else { rpt->lev = stn->dmin[2]; rpt->tim = gr; }
+    if (umask==1) {
+      rpt->umask = 1;
+      rpt->val = val;
+    }
+    else {
+      rpt->umask = 0;
+    }  
+    for (i=0; i<8; i++) *(rpt->stid+i) = *(stn->stid+i);
+    stn->rnum++;
+    gafree(pst);
+  }
+
+  gagfre(pgr);  /* Release the grid from evaluating the first argument */
+  pst->result.stn = stn;
+  pst->type = 0;
+  pst->idim = stn->idim;
+  pst->jdim = -1;
+  return (0);
+}
+
+gaint ffclgr (struct gafunc *pfc, struct gastat *pst) {
+  struct gaclct *clct, *clct0;
+  struct gastn *stn;
+  struct garpt *rpt;
+  struct gagrid *pgr=NULL;
+  gadouble *levs, lev, vlo, vhi, uu=0, *gr=NULL;
+  gadouble *iv=NULL,*jv=NULL,diff,lld,lhd,llo,lhi,xdiff;
+  gaint i,j,cnt,lcnt=0,scnt,flag,clnm,dim,lflg,ucnt;
+  gaint noundef;
+  char *gru=NULL;
+  size_t sz;
+
+  lflg = 1;
+  ucnt = 10;
+
+  /* set noundef=1 to use only defined points in vertical interploation
+     default is 0 */
+  noundef=0;
+  
+  if (pfc->argnum>3) {
+    gaprnt (0,"Error from COLL2GR:  Too many args \n");
+    gaprnt (0,"                     One to three arguments expected \n");
+    return (1);
+  }
+  if (intprs(pfc->argpnt[0],&clnm)==NULL) {
+    gaprnt (0,"Error from COLL2GR:  1st argument must be an integer\n");
+    return(1);
+  }
+  if (pfc->argnum>1) {
+    if (cmpwrd("-u",pfc->argpnt[1])) lflg = 2;
+    else if (intprs(pfc->argpnt[1],&i) != NULL) ucnt = i;
+    else gaprnt (1,"COLL2GR Warning:  2nd arg Invalid; Ignored\n");
+  }
+  if (pfc->argnum>2) {
+    if (cmpwrd("-n0",pfc->argpnt[2])) noundef=0;
+    else if (cmpwrd("-n1",pfc->argpnt[2])) noundef=1;
+    else gaprnt (1,"COLL2GR Warning:  3nd arg Invalid; Ignored\n");
+  }
+  clct0 = *(pst->pclct+clnm);
+  clct = clct0;
+  if (clct==NULL) {
+     snprintf(pout,255,"Error from COLL2GR:  Collection %i empty\n",clnm);
+     gaprnt (0,pout);
+     return (1);
+  }
+
+  /* Count number of soundings, number of levels, and check dimension validity */
+  cnt = 0;
+  scnt = 0;
+  dim = -1;
+  while (clct) {
+    stn = clct->stn;
+    cnt += stn->rnum;
+    scnt += 1;
+    if (dim==-1) dim = stn->idim;
+    if (dim != stn->idim) dim = -999;
+    clct = clct->forw;
+  }
+  if (dim == -999 || dim != pst->jdim || pst->idim != 0 || dim<2 || dim>3 ) {
+    gaprnt (0,"Error from COLL2GR:  Invalid dimension environment\n");
+    return (1);
+  }
+  if (dim==3) {
+    gaprnt  (0,"COLL2GR does not yet support time slices\n");
+    return (1);
+  }
+
+
+  /* Obtain sorted list of levels or times, depending on
+     what sort of interpolation was requested */
+  if (lflg==1) cnt = ucnt;
+  sz = sizeof(gadouble)*cnt;
+  levs = (gadouble *)galloc(sz,"clgrlevs");
+  if (levs==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for levels \n");
+    goto err;
+  }
+
+  if (lflg==1) {
+    /* fixed number of levels */
+    vlo = pst->dmin[2];
+    vhi = pst->dmax[2];
+    uu = (vhi - vlo)/((gadouble)cnt-1.0);
+    lev = vlo;
+    for (i=0; i<cnt; i++) {
+      *(levs+i) = lev;
+      lev += uu;
+    }
+    lcnt = cnt;
+  } 
+  else if (lflg==2) {
+    /* union of all levels  */
+    diff = fabs(pst->dmin[2]-pst->dmax[2])/1e4;
+    lcnt = 0;
+    clct = clct0;
+    while (clct) {
+      stn = clct->stn;
+      rpt = stn->rpt;
+      while (rpt) {
+        lev = rpt->lev;
+        i = 0;
+        flag = 1;
+	/* mf 20021016 -- don't use level if undef */
+	if (noundef && (rpt->umask == 0) ) flag = 0;
+        if (lev>pst->dmin[2] || lev<pst->dmax[2]) flag = 0;
+        while (i<lcnt && flag) {
+          if (fabs(*(levs+i)-lev)<diff) {
+            flag = 0;
+            break;
+          }
+          if (*(levs+i)<lev) break;
+          i = i + 1;
+        }
+        if (flag) {
+          if (i<lcnt) {
+            for (j=lcnt; j>i; j--) *(levs+j) = *(levs+j-1);
+          }
+          *(levs+i) = lev;
+          lcnt++;
+        }
+        rpt = rpt->rpt;
+      }
+      clct = clct->forw;
+    }
+  }
+
+  /* Allocate and fill the interpolated grid */
+  sz = sizeof(gadouble)*lcnt*scnt;
+  gr = (gadouble *)galloc(sz,"col2grgr");
+  if (gr==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for collection grid \n");
+    goto err;
+  }
+  sz = sizeof(char)*lcnt*scnt;
+  gru = (char *)galloc(sz,"col2grgru");
+  if (gru==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for collection umask \n");
+    goto err;
+  }
+  clct = clct0;
+  i = 0;
+  while (clct) {
+    stn = clct->stn;
+    if (i==0) uu = stn->undef;
+    for (j=0; j<lcnt; j++) {
+      lev = *(levs+j);
+      rpt = stn->rpt;
+      lld = 9.99e33;
+      lhd = 9.99e33;
+      llo = lev; lhi = lev;
+      vlo = stn->undef;
+      vhi = stn->undef;
+      flag = 0;
+      while (rpt) {
+        if (dequal(rpt->lev,lev,1.0e-8)==0) {
+          flag = 1;
+          break;
+        }
+        if (rpt->lev<lev) {
+	  if (noundef) {
+	    if (lev-rpt->lev<lld && (rpt->umask != 0) ) {
+	      lld = lev-rpt->lev;
+	      llo = rpt->lev;
+	      vlo = rpt->val;
+	    }
+	  } else {
+	    if (lev-rpt->lev<lld) {
+	      lld = lev-rpt->lev;
+	      llo = rpt->lev;
+	      vlo = rpt->val;
+	    }
+          }
+        } else {
+	  if(noundef) {
+	    if (rpt->lev-lev<lhd && (rpt->umask != 0) ) {
+	      lhd = rpt->lev-lev;
+	      lhi = rpt->lev;
+	      vhi = rpt->val;
+	    }
+	  } else {
+	    if (rpt->lev-lev<lhd) {
+	      lhd = rpt->lev-lev;
+	      lhi = rpt->lev;
+	      vhi = rpt->val;
+	    }
+	  }
+	}
+        rpt = rpt->rpt;
+      }
+      if (flag) {
+	*(gr+j*scnt+i) = rpt->val;
+	*(gru+j*scnt+i) = 1;
+      }
+      else {
+        if (dequal(vhi,stn->undef,1.0e-8)==0 || dequal(vlo,stn->undef,1.0e-8)==0) {
+          *(gru+j*scnt+i) = 0;
+        } else {
+          *(gr+j*scnt+i) = vlo + (vhi-vlo)*(lev-llo)/(lhi-llo);
+          *(gru+j*scnt+i) = 1;
+        }
+      }
+    }
+    clct = clct->forw;
+    i++;
+  }
+
+  /* Now create the grid structure for our new grid and
+     chain it in all the right places */
+
+  sz = sizeof(struct gagrid);
+  pgr = (struct gagrid *)galloc(sz,"col2grpgr");
+  if (pgr==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for gagrid structure\n");
+    goto err;
+  }
+
+  pgr->grid = gr;
+  pgr->umask = gru;
+  pgr->undef = uu;
+  pgr->isiz = scnt;
+  pgr->jsiz = lcnt;
+  pgr->idim  = 0;  /* arbitrary */
+  pgr->jdim  = dim;
+  pgr->iwrld = 1; pgr->jwrld = 0;
+  pgr->dimmin[0] = 1; pgr->dimmax[0] = scnt;
+  pgr->dimmin[2] = 1; pgr->dimmax[2] = lcnt;
+  pgr->exprsn = NULL;
+  pgr->ilinr = 0;
+  pgr->jlinr = 0;
+  sz = sizeof(gadouble)*(scnt+2);
+  iv = (gadouble *)galloc(sz,"col2griv");
+  if (iv==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for scnt \n");
+    goto err;
+  }
+  sz = sizeof(gadouble)*(lcnt+2);
+  jv = (gadouble *)galloc(sz,"col2grjv");
+  if (jv==NULL) {
+    gaprnt (0,"Error from COLL2GR: failled to allocate memory for lcnt \n");
+    goto err;
+  }
+  *iv = (gadouble)scnt;
+  *jv = (gadouble)lcnt;
+  xdiff = pst->dmax[0] - pst->dmin[0];
+  xdiff = xdiff / ( (gadouble)(scnt-1) );
+  for (i=1; i<=scnt; i++) *(iv+i) = pst->dmin[0] + (gadouble)(i-1) * xdiff;
+  for (i=0; i<lcnt; i++) *(jv+i+1) = *(levs+i);
+  *(jv+lcnt+1) = -999.9;
+  *(iv+scnt+1) = -999.9;
+  pgr->ivals = iv;
+  pgr->jvals = jv;
+  pgr->iavals = pgr->ivals;
+  pgr->javals = pgr->jvals;
+  pgr->igrab = gr2lev;
+  pgr->jgrab = gr2lev;
+  pgr->iabgr = lev2gr;
+  pgr->jabgr = lev2gr;
+  pgr->alocf = 1; 
+
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  gree(levs,"f428"); 
+  return (0);
+
+ err:
+  if (levs) gree(levs,"f429");
+  if (gr) gree(gr,"f430");
+  if (gru) gree(gru,"f431");
+  if (pgr) gagfre(pgr); 
+  if (iv) gree(iv,"f432");
+  if (jv) gree(jv,"f433");
+  return (1);
+
+
+}
+
+/* Given a grid and a set of stations, interpolate to the
+   grid using cressman technique and return the grid.             */
+
+static gadouble rads[5] = {10.0, 7.0, 4.0, 2.0, 1.0};
+
+gaint ffoacr (struct gafunc *pfc, struct gastat *pst) {
+struct gastat pst2;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble (*iconv) (gadouble *, gadouble);
+gadouble (*jconv) (gadouble *, gadouble);
+gadouble *ivars, *jvars, *gr, *nw, *newbuf, *p1, *p2, *p3, *p4;
+gadouble lon,lat,lnmin,lnmax,lnscl,ltmin,ltmax,ltscl;
+gadouble sum;
+gadouble e1,e2,e,wsum,x,y,xmin,xmax,ymin,ymax,d,d2,rad,rad2,w;
+gaint *flgbuf, *ii;
+gaint rc,i,j,p,siz,icnt,irad,radflg;
+gadouble fgsum=-1e20;
+gadouble radii[30];
+char sumu,*gru,*nwu,*newbufu; 
+size_t sz;
+
+  if (pfc->argnum<2) {
+    gaprnt (0,"Error from OACRES:  Too many or too few args \n");
+    gaprnt (0,"                    Two arguments expected \n");
+    return (1);
+  }
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gaprnt (0,"Error from OACRES: 1st argument must be a grid\n");
+    gafree (pst);
+    return (1);
+  }
+  pgr = pst->result.pgr;
+  if (pgr->idim!=0 || pgr->jdim!=1) {
+    gaprnt (0,"Error from OACRES: Grid must vary in X, Y\n");
+    gafree (pst);
+    return (1);
+  }
+  if (!pgr->ilinr || !pgr->jlinr) {
+    gaprnt (0,"Error from OACRES: Grid must have linear scaling\n");
+    gafree (pst);
+    return (1);
+  }
+  pst2 = *pst;
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) {
+    gafree (pst);
+    return (rc);
+  }
+  if (pst2.type!=0) {
+    gaprnt (0,"Error from OACRES: 2nd argument must be stns\n");
+    gafree (&pst2);
+    gafree (pst);
+    return (1);
+  }
+  stn = pst2.result.stn;
+
+  /* Check for user provided radii */
+  irad = 5;
+  radflg = 0;
+  if (pfc->argnum>2) {
+    radflg = 1;
+    irad = pfc->argnum-2;
+    if (irad>30) {
+      gaprnt (1,"Warning from OACRES:  Using 30 pass radii\n");
+      irad = 30;
+    }
+    for (i=0; i<irad; i++) {
+      if (getdbl(pfc->argpnt[i+2],radii+i)==NULL) {
+        gaprnt (0,"Error from OACRES:  Radii must be constant\n");
+        gaprnt (0,"                    Using default radii\n");
+        radflg = 0;
+        i = irad+1;
+      } else {
+	if (radii[i]<0.0) {
+	  i++;
+	  if(irad != i+1) {
+	    gaprnt (0,"Error from OACRES:  Improper setting of 1st guess\n");
+	    gaprnt (0,"                    Must provide the value or make the value the last argument\n");
+	    gaprnt (0,"                    Using default radii\n");
+	    irad=5;
+	    radflg=0;
+            i=irad+1;
+	  } else if (getdbl(pfc->argpnt[i+2],&fgsum)==NULL) {
+	    gaprnt (0,"Error from OACRES:  Improper setting of 1st guess\n");
+	    gaprnt (0,"                    Bad value\n");
+	    gaprnt (0,"                    Using default radii\n");
+	    irad=5;
+	    radflg=0;
+	    fgsum=-1e20;
+            i=irad+2;
+	  } else {
+	    if(irad<1) radflg=0;
+	    i=irad+2;
+	    irad=irad-2;
+	  }
+
+	}
+        if ((radii[i]<0.01 || radii[i]>50.0) && i<irad) {
+          gaprnt (0,"Error from OACRES:  Radii must be 0<radii<50\n");
+          gaprnt (0,"                    Using default radii\n");
+          radflg = 0;
+          i = irad+1;
+        }
+      }
+    }
+  }
+
+  /* Set up scaling for converting lon-lat to grid units */
+
+  iconv = pgr->igrab;
+  ivars = pgr->ivals;
+  jconv = pgr->jgrab;
+  jvars = pgr->jvals;
+  lnmin = iconv(ivars,(gadouble)pgr->dimmin[0]);
+  lnmax = iconv(ivars,(gadouble)pgr->dimmax[0]);
+  ltmin = iconv(jvars,(gadouble)pgr->dimmin[1]);
+  ltmax = iconv(jvars,(gadouble)pgr->dimmax[1]);
+  lnscl = (lnmax-lnmin)/((gadouble)pgr->isiz-1);
+  ltscl = (ltmax-ltmin)/((gadouble)pgr->jsiz-1);
+
+  /* Now loop through each stn report and convert stn lat/lon to grid coordinates */
+  rpt = stn->rpt;
+  sum = 0.0;
+  icnt = 0;
+  while (rpt!=NULL) {
+    lon = rpt->lon;
+    lat = rpt->lat;
+    if (lon<lnmin) lon+=360.0;
+    else if (lon>lnmax) lon-=360.0;
+    rpt->lon = (lon-lnmin)/lnscl;
+    rpt->lat = (lat-ltmin)/ltscl;
+    i = (gaint)rpt->lon;
+    j = (gaint)rpt->lat;
+    if (i<0 || i>(pgr->isiz-1) || 
+	j<0 || j>(pgr->jsiz-1) ||
+        rpt->umask==0) 
+      rpt->work = -999;
+    else {
+      rpt->work = j*pgr->isiz + i;
+      sum = sum + rpt->val;
+      icnt++;
+      i = (gaint)rpt->lon;
+      j = (gaint)rpt->lat;
+      rpt->lev = rpt->lon - (gadouble)i;
+      rpt->tim = rpt->lat - (gadouble)j;
+    }
+    rpt=rpt->rpt;
+  }
+  if (icnt<2) {
+    gaprnt (1,"Warning from OACRES:  Less than two stations\n");
+    gaprnt (1,"    Grid will be all missing values\n");
+    sumu = 0;
+  } 
+  else {
+    sum = sum/((gadouble)icnt);
+    sumu = 1;
+  }
+
+  /* Need some buffer space */
+  siz = pgr->isiz * pgr->jsiz;
+  sz = sizeof(gadouble)*siz;
+  newbuf = (gadouble *)galloc(sz,"oacrbuf");
+  if (newbuf==NULL) {
+    goto err;
+  }
+  sz = sizeof(char)*siz;
+  newbufu = (char *)galloc(sz,"oacrbufu");
+  if (newbufu==NULL) {
+    gree(newbuf,"f434");
+    goto err;
+  }
+  sz = sizeof(gaint)*siz;
+  flgbuf = (gaint *)galloc(sz,"oacrbuff");
+  if (flgbuf==NULL) {
+    gree(newbuf,"f435");
+    gree(newbufu,"f436");
+    goto err;
+  }
+
+  /* Initial grid values are average of station reports */
+  if (fabs(fgsum) < 1e20 ) {
+    sum=fgsum;
+    sumu=1;
+  }
+  gr = pgr->grid;
+  gru = pgr->umask;
+  nw = newbuf;
+  nwu = newbufu;
+  ii = flgbuf;
+  for (i=0; i<siz; i++) {
+    if (sumu==1) {
+      *gr = sum; *gru = 1;
+      *nw = sum; *nwu = 1;
+    }
+    else {
+      *gru = 0;
+      *nwu = 0;
+    }
+    *ii = 0;
+    ii++; 
+    gr++; gru++; 
+    nw++; nwu++;
+  }
+  if (sumu==0) goto retrn;
+
+  /* Perform the objective analysis */
+  for (p=0; p<irad; p++) {
+    if (radflg) rad = radii[p];
+    else rad = rads[p];
+    rad2 = rad*rad;
+    gr = pgr->grid;
+    nw = newbuf;
+    nwu = newbufu;
+    ii = flgbuf;
+    for (j=0; j<pgr->jsiz; j++) {
+      y = (gadouble)j;
+      ymin = y - rad;
+      ymax = y + rad;
+      for (i=0; i<pgr->isiz; i++) {
+        x = (gadouble)i;
+        xmin = x - rad;
+        xmax = x + rad;
+        sum = 0.0; wsum = 0.0;
+        rpt = stn->rpt;
+        while (rpt) {
+          if (rpt->work==-999 || 
+	      rpt->lon < xmin || rpt->lon > xmax ||
+              rpt->lat < ymin || rpt->lat > ymax ||
+              (d = hypot(x-rpt->lon,y-rpt->lat)) > rad ) rpt = rpt->rpt;
+          else {
+            d2 = d*d;
+            p1 = pgr->grid + rpt->work;
+            p2 = p1+1;
+            p4 = p1 + pgr->isiz;
+            p3 = p4 + 1;
+            e1 = *p1 + ( (*p2 - *p1)*rpt->lev );
+            e2 = *p4 + ( (*p3 - *p4)*rpt->lev );
+            e = e1 + ( (e2 - e1)*rpt->tim );
+            e = rpt->val - e;
+            w = (rad2-d2)/(rad2+d2);
+            sum += e*w;
+            wsum += w;
+            rpt = rpt->rpt;
+          }
+        }
+        if (wsum>1e-6) {
+	  *nw = *gr + sum/wsum;
+	  *nwu = 1; 
+	}
+        else if (p==2) *ii = 1;
+        nw++; nwu++; gr++; ii++;
+      }
+    }
+    nw  = newbuf;
+    nwu = newbufu;
+    gr = pgr->grid;
+    gru = pgr->umask;
+    for (i=0; i<siz; i++) {
+      if (*nwu==1) {
+	*gr = *nw;
+	*gru = 1;
+      }
+      else {
+	*gru = 0;
+      }
+      gr++; gru++; nw++; nwu++;
+    }
+  }
+  ii = flgbuf;
+  gru = pgr->umask;
+  for (i=0; i<siz; i++) {
+    if (*ii) *gru = 0;
+    gru++; ii++;
+  }
+
+  gr  = pgr->grid;
+  gru = pgr->umask;
+
+retrn:
+  gafree (&pst2);
+  gree(newbuf,"f437");
+  gree(newbufu,"f438");
+  gree(flgbuf,"f439");
+  return(0);
+
+err:
+  gaprnt (0,"Error in OACRES:  Unable to allocate memory\n");
+  gafree (&pst2);
+  gafree (pst);
+  return (1);
+}
+
+gaint ffoabn (struct gafunc *pfc, struct gastat *pst) {
+  struct gastat pst2;
+  struct gagrid *pgr;
+  struct gastn *stn;
+  struct garpt *rpt;
+  gadouble (*iconv) (gadouble *, gadouble);
+  gadouble (*jconv) (gadouble *, gadouble);
+  gadouble *ivars, *jvars, *gr;
+  gadouble lon,lat,lnmin,lnmax,lnscl,ltmin,ltmax,ltscl;
+  gaint *cnt, *ii;
+  gaint rc,i,j,siz,icnt,cntflg;
+  char *ch, *gru;
+  size_t sz;
+  
+  if (pfc->argnum<2) {
+    gaprnt (0,"Error from OABIN:  Too many or too few args \n");
+    gaprnt (0,"                   Two arguments expected \n");
+    return (1);
+  }
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gaprnt (0,"Error from OABIN: 1st argument must be a grid\n");
+    gafree (pst);
+    return (1);
+  }
+  pgr = pst->result.pgr;
+  if (pgr->idim!=0 || pgr->jdim!=1) {
+    gaprnt (0,"Error from OABIN: Grid must vary in X, Y\n");
+    gafree (pst);
+    return (1);
+  }
+  if (!pgr->ilinr || !pgr->jlinr) {
+    gaprnt (0,"Error from OABIN: Grid must have linear scaling\n");
+    gafree (pst);
+    return (1);
+  }
+  pst2 = *pst;
+  rc = gaexpr(pfc->argpnt[1],&pst2);
+  if (rc) {
+    gafree (pst);
+    return (rc);
+  }
+  if (pst2.type!=0) {
+    gaprnt (0,"Error from OABIN: 2nd argument must be stns\n");
+    gafree (&pst2);
+    gafree (pst);
+    return (1);
+  }
+  stn = pst2.result.stn;
+
+  cntflg = 0;
+  if (pfc->argnum>2) {
+    ch = pfc->argpnt[2];
+    if      (*ch == '-' && *(ch+1) == 'c') cntflg = 1;
+    else if (*ch == '-' && *(ch+1) == 'f') cntflg = 2;
+    else gaprnt (1,"Warning from OABIN: Invalid flag.  Ignored.\n");
+  }
+
+  /* Set up scaling for converting lon-lat to grid units */
+  iconv = pgr->igrab;
+  ivars = pgr->ivals;
+  jconv = pgr->jgrab;
+  jvars = pgr->jvals;
+  lnmin = iconv(ivars,(gadouble)pgr->dimmin[0]);
+  lnmax = iconv(ivars,(gadouble)pgr->dimmax[0]);
+  ltmin = iconv(jvars,(gadouble)pgr->dimmin[1]);
+  ltmax = iconv(jvars,(gadouble)pgr->dimmax[1]);
+  lnscl = (lnmax-lnmin)/((gadouble)pgr->isiz-1);
+  ltscl = (ltmax-ltmin)/((gadouble)pgr->jsiz-1);
+
+  /* Now loop through each stn report and convert stn lat/lon to grid  coordinates */
+  rpt = stn->rpt;
+  icnt = 0;
+  while (rpt!=NULL) {
+    lon = rpt->lon;
+    lat = rpt->lat;
+    if (lon<lnmin) lon+=360.0;
+    else if (lon>lnmax) lon-=360.0;
+    rpt->lon = (lon-lnmin)/lnscl;
+    rpt->lat = (lat-ltmin)/ltscl;
+    /* nearest grid point center */
+    i = (gaint)(rpt->lon+0.5);
+    j = (gaint)(rpt->lat+0.5);
+    if (i<0 || i>(pgr->isiz-1) || 
+	j<0 || j>(pgr->jsiz-1) ||
+        rpt->umask==0) 
+      rpt->work = -999;
+    else {
+      rpt->work = j*pgr->isiz + i;
+    }
+    rpt=rpt->rpt;
+  }
+
+  /* cnt space */
+  siz = pgr->isiz * pgr->jsiz;
+  sz = sizeof(gaint)*siz;
+  cnt = (gaint *)galloc(sz,"oabincnt");
+  if (cnt==NULL) {
+    goto err;
+  }
+
+  /* initialize cnt and grid to 0.0 for summing */
+  gr=pgr->grid;
+  for(i=0;i<siz;i++) {
+    *gr=0.0;
+    gr++;
+  }
+  ii = cnt;
+  for (i=0; i<siz; i++) {
+    *ii = 0;
+    ii++;
+  }
+
+  /* Perform the bin analysis */
+  rpt = stn->rpt;
+  while (rpt) {
+    gr = pgr->grid;
+    ii = cnt;
+    if (rpt->work==-999) {
+      rpt = rpt->rpt;
+    } 
+    else {
+      gr += rpt->work;
+      ii += rpt->work;
+      if( (cntflg <= 1) || (cntflg == 2 && *ii <= 1)) {
+	*gr += rpt->val;
+	*ii += 1;
+      }
+      rpt = rpt->rpt;
+    }
+  }
+  
+  gr=pgr->grid;
+  gru=pgr->umask;
+  ii=cnt;
+  for(i=0;i<siz;i++) {
+    if(*ii > 0) {
+      *gr=(*gr)/(*ii);
+      if(cntflg==1) *gr=(gadouble)(*ii);
+      *gru = 1;
+    } else {
+      *gru=0;
+    }
+    gr++ ; gru++; ii++;
+  }
+  
+  gafree (&pst2);
+  gree(cnt,"f440");
+  return(0);
+
+err:
+  gaprnt (0,"Error in OABIN:  Unable to allocate memory\n");
+  gafree (&pst2);
+  gafree (pst);
+  return (1);
+}
+
+
+
+/* Nine point smoother */
+
+gaint ffsmth  (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr;
+gadouble *buff, *gr, *nw;
+gadouble w,s,mid,sid,cor;
+gaint i,j,k,rc,siz,p;
+char *gru, *nwu, *buffu;
+size_t sz;
+
+  if (pfc->argnum!=1 && pfc->argnum!=4) {
+    gaprnt (0,"Error from SMTH9:  Too many or too few args \n");
+    gaprnt (0,"                   One or 4 arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type!=1) {
+    gaprnt (0,"Error from SMTH9:  Grid Required\n");
+    gafree (pst);
+    return (1);
+  }
+
+  pgr = pst->result.pgr;
+  siz = pgr->isiz * pgr->jsiz;
+  sz = siz*sizeof(gadouble);
+  buff = (gadouble *)galloc(sz,"sm9buf");
+  if (buff==NULL) {
+    gaprnt (0,"Error from SMTH9:  Unable to allocate memory\n");
+    gafree (pst);
+    return (1);
+  }
+  sz = siz*sizeof(char);
+  buffu = (char *)galloc(sz,"sm9bufu");
+  if (buffu==NULL) {
+    gaprnt (0,"Error from SMTH9:  Unable to allocate memory\n");
+    gafree (pst);
+    return (1);
+  }
+
+  mid = 1.0; sid = 0.5; cor = 0.3;
+  if (pfc->argnum==4) {
+    if (getdbl(pfc->argpnt[1],&mid)==NULL ||
+        getdbl(pfc->argpnt[2],&sid)==NULL ||
+        getdbl(pfc->argpnt[3],&cor)==NULL )  {
+      gaprnt (0,"Error from SMTH9:  Invalid Weight Values\n");
+      gaprnt (0,"  Using defaults:  1.0  0.5  0.3\n");
+      mid = 1.0; sid = 0.5; cor = 0.3;
+    }
+  }
+
+  gr = pgr->grid;
+  gru = pgr->umask;
+  nw = buff;
+  nwu = buffu;
+  k = 0;
+  for (j=0; j<pgr->jsiz; j++) {
+    for (i=0; i<pgr->isiz; i++) {
+      if (*(gru+k)!=0) {
+        s = *(gr+k)*mid;
+        w = mid;
+        if (i!=0 && *(gru+k-1)!=0) { 
+	  s = s + *(gr+k-1)*sid; 
+	  w+=sid;
+	}
+        if (i!=pgr->isiz-1 && *(gru+k+1)!=0) { 
+	  s = s + *(gr+k+1)*sid; 
+	  w+=sid;
+	}
+        if (j!=0) {
+          p = k - pgr->isiz;
+          if (*(gru+p)!=0) { 
+	    s = s + *(gr+p)*sid; 
+	    w+=sid;
+	  }
+          if (i!=0 && *(gru+p-1)!=0) { 
+	    s = s + *(gr+p-1)*cor; 
+	    w+=cor;
+	  }
+          if (i!=pgr->isiz-1 && *(gru+p+1)!=0) { 
+	    s = s + *(gr+p+1)*cor; 
+	    w+=cor;
+	  }
+        }
+        if (j!=pgr->jsiz-1) {
+          p = k + pgr->isiz;
+          if (*(gru+p)!=0) { 
+	    s = s + *(gr+p)*sid; 
+	    w+=sid;
+	  }
+          if (i!=0 && *(gru+p-1)!=0) { 
+	    s = s + *(gr+p-1)*cor; 
+	    w+=cor;
+	  }
+          if (i!=pgr->isiz-1 && *(gru+p+1)!=0) { 
+	    s = s + *(gr+p+1)*cor; 
+	    w+=cor;
+	  }
+        }
+        *nw = s/w;
+	*nwu = 1;
+      } 
+      else {
+	*nwu = 0;
+      }
+      nw++; nwu++; k++;
+    }
+  }
+  gr = pgr->grid;
+  gru = pgr->umask;
+  nw = buff;
+  nwu = buffu;
+  for (i=0; i<siz; i++) {
+    *gr  = *nw;
+    *gru = *nwu; 
+    gr++; gru++; nw++; nwu++;
+  }
+
+  gree(buff,"f441");
+  gree(buffu,"f442");
+  return (0);
+}
+
+/* Station Averaging.  Averaging is done in time only.
+   If there are multiple stations per time, they are
+   averaged with equal weight, then that value for that time
+   is averaged with equal weight with the other times for that
+   station.  The user may specify the number of times required
+   for an average to be reported for a station.    */
+
+gaint ffsave (struct gafunc *pfc, struct gastat *pst) {
+struct gafile *pfi;
+struct gastn *stnr, *stn;
+struct garpt *rpt,*rpt2;
+struct dt tinc,tloc,twrk,tstrt,tend;
+gadouble gr1,gr2,*val,sum,cnt,ttt;
+gaint dim,dim2,rc,d1,d2,d,fflg,i,mcnt,wflag=0;
+gaint mos=0,mns=0,incr;
+char *ch,chs[20],che[20];
+size_t sz;
+
+  /* Check for X, Y varying environment */
+
+  if (pst->idim!=0 || pst->jdim!=1) {
+    gaprnt (0,"Error from STNAVE:  X, Y varying environment required\n");
+    return(1);
+  }
+
+  /* Check for valid number of args       */
+
+  if (pfc->argnum<3 || pfc->argnum>5) {
+    gaprnt (0,"Error from STNAVE:  Too many or too few args \n");
+    gaprnt (0,"                    3 to 5 arguments expected \n");
+    return (1);
+  }
+
+  /* Parse the dimension expression       */
+
+  pfi = pst->pfid;
+  ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &gr1, 1, &wflag);
+  if (ch==NULL || dim!=3 || wflag==2) {
+    gaprnt (0,"Error from STNAVE:  1st dimension expression invalid\n");
+    if (wflag==2) gaprnt (0,"  offt expression not supported as an arg to STNAVE\n");
+    return (1);
+  }
+
+  /* Now parse the 2nd dimension expression.  */
+
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim2, &gr2, 1, &wflag);
+  if (ch==NULL || dim2!=dim || wflag==2) {
+    gaprnt (0,"Error from STNAVE:  2nd dimension expression invalid\n");
+    if (wflag==2) gaprnt (0,"  offt expression not supported as an arg to STNAVE\n");
+    return (1);
+  }
+
+  /* Get optional arguments:  time increment and min number of times 
+     required for a successful average */
+
+  val = pfi->grvals[3];
+  if (*(val+5)>0) { mos = (*(val+5)); mns = 0; }
+  if (*(val+6)>0) { mns = (*(val+6)); mos = 0; }
+
+  mcnt = 1;
+  if (pfc->argnum >= 4) {
+    if (*(pfc->argpnt[3]) == '-') {    /* Option flags? */
+      i = fndarg (pfc->argpnt[3], &mcnt);
+      if (i) return (1);
+    } else {                           /* Assume time increment */
+                               /*  Done differently from grid ave */
+                               /*  to allow increment of 1yr for 
+                                   daily data.  Might want to adopts
+                                   this for grid ave also.  Think about
+                                   a flag to handle leap years?  */
+      ch = intprs(pfc->argpnt[3],&incr);
+      if (ch==NULL) goto err3;
+      if (*(val+5)>0) { mos = incr * (*(val+5)); mns = 0; }
+      if (*(val+6)>0) { mns = incr * (*(val+6)); mos = 0; }
+      if (*ch!='\0') {
+        ch = rdtprs(pfc->argpnt[3],&tinc);
+        if (ch==NULL) goto err3;
+        mos = tinc.yr*12 + tinc.mo;
+        mns = tinc.dy*1140 + tinc.hr*60 + tinc.mn;
+        if (mos>0 && *(val+5)>0) {
+          incr = mos / (*(val+5));
+          if (mos!=incr*(*(val+5))) goto err3;
+        }
+        else if (mos>0 && *(val+6)>0) {
+          incr = mos;  /* not really used */
+        }
+        else if (mns>0 && *(val+6)>0) {
+          incr = mns / (*(val+6));
+          if (mns!=incr*(*(val+6))) goto err3;
+        }
+        else goto err3;
+      }
+    }
+  }
+  if (pfc->argnum == 5) {
+    i = fndarg (pfc->argpnt[4], &mcnt);
+    if (i) return (1);
+  }
+
+  tinc.yr = 0; tinc.mo = mos; tinc.dy = 0; tinc.hr = 0; tinc.mn = mns;
+
+  d1 = ceil(gr1-0.001);          /* Ave limits are integers    */
+  d2 = floor(gr2+0.001);
+
+  /* Set up the result stn block */
+
+  sz = sizeof(struct gastn);
+  stnr = (struct gastn *)galloc(sz,"stnavr");
+  if (stnr==NULL) {
+    gaprnt(0,"Memory allocation error:  station averaging function\n");
+    return(1);
+  }
+
+  /* Loop over time */
+  gr2t (pfi->grvals[3],d1,&tstrt);
+  gr2t (pfi->grvals[3],d2,&tend);
+  gat2ch (&tstrt,5,chs,20);
+  gat2ch (&tend,5,che,20);
+  snprintf(pout,255,"Stn Averaging.  Dim = %i, Start = %s, End = %s Incr(mos,mns) = %i %i\n", 
+	   dim, chs, che, mos, mns);
+  gaprnt (2,pout);
+
+  rc = 0;
+  fflg = 1;
+  d = d1;
+  while (d<=d2 && !rc) {
+    gr2t (pfi->grvals[3],d,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    /* evaluate the expression at this time */
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (rc || pst->type==1) goto err;
+    stn = pst->result.stn;
+    /* set up the block to hold the final result */
+    if (fflg) {
+      fflg = 0;       /* makes sure this is only done once */
+      *stnr = *stn;
+      stnr->rnum = 0;
+      stnr->rpt = NULL;
+      sz = sizeof(gadouble)*8;
+      stnr->tvals = (gadouble *)galloc(sz,"stnavtvals");
+      if (stnr->tvals==NULL) {
+        gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+        goto err;
+      }
+      for (i=0; i<8; i++) *(stnr->tvals+i) = *(stn->tvals+i);
+    }
+
+    /* Average multiple stations for this time, if any.  */
+
+    rpt = stn->rpt;
+    while (rpt) {
+      rpt->work = 1;
+      rpt = rpt->rpt;
+    }
+    rpt = stn->rpt;
+    while (rpt) {
+      if (rpt->work && rpt->umask!=0) {
+        rpt2 = rpt->rpt;
+        sum = rpt->val;
+        cnt = 1.0;
+	/* check for more reports to include in the average for this time */
+        while (rpt2) {
+	  /* additional reports must have same stid and location */
+          if (rpt2->umask!=0 &&           
+              !cmpch(rpt->stid,rpt2->stid,8) &&
+              rpt->lat == rpt2->lat && rpt->lon == rpt2->lon) {
+            sum = sum + rpt2->val;
+            cnt = cnt+1.0;
+            rpt2->work = 0;       /* flag these reports as already used in calculation */
+          }
+          rpt2 = rpt2->rpt;
+        }
+        rpt->val = sum/cnt;       /* rpt->val now has the average of all reports */
+      } 
+      rpt = rpt->rpt;
+    }
+
+    /* Now sum these with the items already in the result list */
+
+    rpt = stn->rpt;
+    while (rpt) {
+      if (rpt->work) {
+        rpt2 = stnr->rpt;  /* this will be NULL for the first time step */
+        while (rpt2) {
+          if (!cmpch(rpt->stid,rpt2->stid,8) &&
+              rpt->lat == rpt2->lat && rpt->lon == rpt2->lon) break;
+          rpt2 = rpt2->rpt;
+        }
+        if (rpt2==NULL) {
+	  /* at first time step, allocate result (rpt2), copy rpt values into it  */
+          rpt2 = gaarpt(stnr);
+          if (rpt2==NULL) goto err;
+          stnr->rnum++;
+          *rpt2 = *rpt;
+          rpt2->rpt = NULL;
+          rpt2->work = 1;
+          if (rpt->umask == 0) rpt2->umask = 0;
+        } else {
+	  /* for subsequent time steps, check if result is undefined */
+          if (rpt2->umask == 0) {
+	    /* no previous result, copy current time's average into result if defined */
+	    if (rpt->umask != 0) {
+              rpt2->val = rpt->val;
+              rpt2->work = 1;
+	      rpt2->umask = 1;
+	    }
+          } else if (rpt->umask != 0) {
+	    /* add current time's average to result, increment work flag */
+            rpt2->val = rpt2->val + rpt->val;
+            rpt2->work++;
+          }
+        }
+      }
+      rpt = rpt->rpt;
+    }
+    gafree(pst);
+   
+    /*  Apply time increment */
+
+    gr2t (pfi->grvals[3],d,&tloc);
+    twrk = tinc;
+    timadd (&tloc, &twrk);
+    ttt = t2gr(pfi->grvals[3],&twrk);
+    d = ttt;
+    if (fabs(((gadouble)d)-ttt) > 0.001) {
+      gaprnt(0,"Logic Error 16 in stnave.  Contact Developer(s).\n");
+      goto err;
+    }
+  }
+
+  /* Calculate final result, return */
+
+  rpt = stnr->rpt;
+  while (rpt) {
+    if (rpt->umask!=0) {
+      if (rpt->work<mcnt) rpt->umask = 0;
+      else {
+        cnt = (gadouble)rpt->work;
+        rpt->val = rpt->val/cnt;
+	rpt->umask = 1;
+      }
+    }
+    rpt = rpt->rpt;
+  }
+  pst->result.stn = stnr;
+  return(0);
+
+err:
+  gaprnt (0,"Error from STNAVE:  Unable to evaluate expression\n");
+  gafree(pst);
+  gasfre(stnr);
+  return(1);
+err3:
+  snprintf(pout,255,"Error from STNAVE: Invalid time increment argument\n");
+  gaprnt(0,pout);
+  return (1);
+}
+
+/* Set every nth grid point value to missing in a grid */
+
+gaint ffskip (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr;
+gaint rc,iskip,jskip,ii,jj,i,j;
+char *uval;
+
+  if (pfc->argnum<2 || pfc->argnum>3) {
+    gaprnt (0,"Error from SKIP:  Too many or too few args \n");
+    gaprnt (0,"                  Two or 3 arguments expected \n");
+    return (1);
+  }
+  if (intprs(pfc->argpnt[1],&iskip)==NULL) {
+    gaprnt (0,"Error from SKIP:  2nd argument must be an integer \n");
+    return(1);
+  }
+  if (pfc->argnum>2) {
+    if (intprs(pfc->argpnt[2],&jskip)==NULL) {
+      gaprnt (0,"Error from SKIP:  3rd argument must be an integer\n");
+      return(1);
+    }
+  } 
+  else jskip = iskip;
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type!=1) {
+    gaprnt (0,"Error from SKIP:  Grid Required\n");
+    gafree (pst);
+    return (1);
+  }
+
+  pgr = pst->result.pgr;
+  uval = pgr->umask;
+  if (pgr->idim==-1) return(0);
+
+  iskip = iskip - 1;
+  jskip = jskip - 1;
+  jj = -1;
+  for (j=0; j<pgr->jsiz; j++) {
+    jj++;
+    if (jj>jskip) jj=0;
+    ii = -1;
+    for (i=0; i<pgr->isiz; i++) {
+      ii++;
+      if (ii>iskip) ii=0;
+      if (ii || jj) *uval = 0;
+      uval++;
+    }
+  }
+  return (0);
+}
+
+gaint ffgrarea (struct gafunc *pfc, struct gastat *pst) {
+  struct gagrid *pgr;
+  gadouble *val;
+  gaint rc,i,j;
+  gadouble (*iconv) (gadouble *, gadouble);
+  gadouble (*jconv) (gadouble *, gadouble);
+  gadouble *ivals, *jvals;
+  gadouble rad,scl,w1,w2,y1,x1,alo,ahi;
+  char *uval;
+
+  if (pfc->argnum>3) {
+    gaprnt (0,"Error from GRAREA:  Too many args \n");
+    gaprnt (0,"                  1 arguments expected \n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type!=1) {
+    gaprnt (0,"Error from GRAREA:  Grid Required\n");
+    gafree (pst);
+    return (1);
+  }
+  pgr = pst->result.pgr;
+  if( (pgr->idim)!=0 || (pgr->jdim)!=1 ) {
+    gaprnt (0,"Error from GRAREA:  XY (lon-lat) grid required\n");
+    gafree (pst);
+    return (1);
+  }
+
+  rad = acos(0.0)/90.0;
+  scl=1.0/720.0;
+  jconv = pgr->jgrab;
+  ivals = pgr->ivals;
+  iconv = pgr->igrab;
+  jvals = pgr->jvals;
+  val = pgr->grid;
+  uval = pgr->umask;
+  for (j=0; j<pgr->jsiz; j++) {
+    y1 = (gadouble)(j+pgr->dimmin[1]);
+    alo = jconv(jvals, y1-0.5);
+    ahi = jconv(jvals, y1+0.5);
+    if (alo < pst->dmin[1]) alo = pst->dmin[1];
+    if (alo > pst->dmax[1]) alo = pst->dmax[1];
+    if (ahi < pst->dmin[1]) ahi = pst->dmin[1];
+    if (ahi > pst->dmax[1]) ahi = pst->dmax[1];
+    if (alo < -90.0) alo = -90.0; if (ahi < -90.0) ahi = -90.0;
+    if (alo >  90.0) alo =  90.0; if (ahi >  90.0) ahi =  90.0;
+    w1 = fabs(sin(ahi*rad)-sin(alo*rad));  /* area weighting (aave) */
+      
+    for (i=0; i<pgr->isiz; i++) {
+      x1 = (gadouble)(i+pgr->dimmin[0]);
+      alo = iconv(ivals, x1-0.5);
+      ahi = iconv(ivals, x1+0.5);
+      if (alo<pst->dmin[0]) alo = pst->dmin[0];
+      if (alo>pst->dmax[0]) alo = pst->dmax[0];
+      if (ahi<pst->dmin[0]) ahi = pst->dmin[0];
+      if (ahi>pst->dmax[0]) ahi = pst->dmax[0];
+      w2 = (ahi - alo)*scl;
+      if (*uval!=0) *val = w1 * w2;
+      val++; uval++;
+    }
+  }
+  return (0);
+}
+
+gaint ffcnst  (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,cnt,flg;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val,cnst;
+char *ch, *uval;
+
+  if (pfc->argnum<2 || pfc->argnum>3) {
+    gaprnt (0,"Error from CONST:  Too many or too few args \n");
+    gaprnt (0,"                   Two or 3 arguments expected \n");
+    return (1);
+  }
+
+  if (getdbl(pfc->argpnt[1],&cnst)==NULL) {
+    gaprnt (0,"Error from CONST:  2nd argument must be a constant\n");
+    return(1);
+  }
+
+  flg = 0;
+  if (pfc->argnum>2) {
+    ch = pfc->argpnt[2];
+    if      (*ch == '-' && *(ch+1) == 'u') flg = 1;
+    else if (*ch == '-' && *(ch+1) == 'a') flg = 2;
+    else gaprnt (1,"Warning from CONST: Invalid flag.  Ignored.\n");
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    /* gridded data */
+    pgr = pst->result.pgr;
+    cnt = pgr->isiz * pgr->jsiz;
+    val = pgr->grid;
+    uval = pgr->umask;
+    for (i=0; i<cnt; i++) {
+      if (flg==0) {
+        if (*uval!=0) {
+	  *val = cnst;
+	}
+      } 
+      else if (flg==1) {
+        if (*uval==0) {
+	  *val = cnst;
+	  *uval = 1;       
+	}
+      } 
+      else if (flg==2) {
+        *val = cnst;
+	*uval = 1;
+      }
+      val++; uval++;
+    }
+  } 
+  else {
+    /* station data */
+    stn = pst->result.stn;
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      if (flg==0) {
+        if (rpt->umask!=0) rpt->val = cnst;
+      } else if (flg==1) {
+        if (rpt->umask==0) rpt->val = cnst;
+      } else if (flg==2) {
+        rpt->val = cnst;
+      }
+      rpt=rpt->rpt;
+    }
+  }
+
+  return (0);
+}
+
+/* Station min or max.  Done over time only.     */
+char *smnxnam[2] = {"STNMIN","STNMAX"};
+
+gaint ffsmin (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = ffsmnx (pfc, pst, 0);
+  return (rc);
+}
+
+gaint ffsmax (struct gafunc *pfc, struct gastat *pst) {
+gaint rc;
+  rc = ffsmnx (pfc, pst, 1);
+  return (rc);
+}
+
+gaint ffsmnx (struct gafunc *pfc, struct gastat *pst, gaint flg) {
+struct gafile *pfi;
+struct gastn *stnr, *stn;
+struct garpt *rpt,*rpt2;
+gadouble gr1,gr2;
+gaint dim,dim2,rc,d1,d2,d,fflg,i,mcnt,wflag=0;
+char *ch,*fnam;
+size_t sz;
+
+  fnam = smnxnam[flg];
+
+  /* Check for X, Y varying environment */
+  if (pst->idim!=0 || pst->jdim!=1) {
+    snprintf(pout,255,"Error from %s:  X, Y varying environment required\n",fnam);
+    gaprnt (0,pout);
+    return(1);
+  }
+
+  /* Check for valid number of args */
+  if (pfc->argnum<3 || pfc->argnum>4) {
+    snprintf(pout,255,"Error from %s:  Too many or too few args \n",fnam);
+    gaprnt (0,pout);
+    gaprnt (0,"                    3 or 4 arguments expected \n");
+    return (1);
+  }
+
+  /* Parse the dimension expression */
+  pfi = pst->pfid;
+  ch = dimprs (pfc->argpnt[1], pst, pfi, &dim, &gr1, 1, &wflag);
+  if (ch==NULL || dim!=3 || wflag==2) {
+    snprintf(pout,255,"Error from %s:  1st dimension expression invalid\n",fnam);
+    gaprnt (0,pout);
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Now parse the 2nd dimension expression. */
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim2, &gr2, 1, &wflag);
+  if (ch==NULL || dim2!=dim || wflag==2) {
+    snprintf(pout,255,"Error from %s:  2nd dimension expression invalid\n",fnam);
+    gaprnt (0,pout);
+    if (wflag==2) {
+      snprintf(pout,255,"  offt expression not supported as an arg to %s\n",fnam);
+      gaprnt (0,pout);
+    }
+    return (1);
+  }
+
+  /* Get the min number of times required for average, if provided */
+  mcnt = 1;
+  if (pfc->argnum==4) {
+    i = fndarg (pfc->argpnt[3], &mcnt);
+    if (i) return (1);
+  }
+  /* Ave limits are integers */
+  d1 = ceil(gr1-0.001);          
+  d2 = floor(gr2+0.001);
+
+  /* Set up the result stn block */
+  sz = sizeof(struct gastn);
+  stnr = (struct gastn *)galloc(sz,"stnminr");
+  if (stnr==NULL) {
+    gaprnt(0,"Memory allocation error:  station averaging function\n");
+    return(1);
+  }
+
+  /* Loop over time */
+  rc = 0;
+  fflg = 1;
+  for (d=d1; d<=d2 && !rc; d+=1) {
+
+    /* Get next set of stations */
+    gr2t (pfi->grvals[3],d,&(pst->tmin));
+    pst->tmax = pst->tmin;
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (rc || pst->type==1) goto err;
+    stn = pst->result.stn;
+    if (fflg) {
+      fflg = 0;
+      *stnr = *stn;
+      stnr->rnum = 0;
+      stnr->rpt = NULL;
+      sz = sizeof(gadouble)*8;
+      stnr->tvals = (gadouble *)galloc(sz,"stnmintv");
+      if (stnr->tvals==NULL) {
+        gaprnt (0,"Memory Allocation Error:  Station Request Block \n");
+        goto err;
+      }
+      for (i=0; i<8; i++) *(stnr->tvals+i) = *(stn->tvals+i);
+    }
+
+    /* Tabulate mins or maxes */
+    rpt = stn->rpt;
+    while (rpt) {
+      rpt2 = stnr->rpt;
+      while (rpt2) {
+        if (!cmpch(rpt->stid,rpt2->stid,8) &&
+            rpt->lat == rpt2->lat && rpt->lon == rpt2->lon) break;
+        rpt2 = rpt2->rpt;
+      }
+      if (rpt2==NULL) {
+        rpt2 = gaarpt(stnr);
+        if (rpt2==NULL) goto err;
+        stnr->rnum++;
+        *rpt2 = *rpt;
+        rpt2->work = 1;
+        rpt2->rpt = NULL;
+        if (rpt->umask == 0) rpt2->umask = 0;
+      } else {
+        if (rpt2->umask == 0) {
+          rpt2->val = rpt->val;
+          rpt2->umask = rpt->umask;
+        } else if (rpt->umask != 0) {
+          if (flg) {
+            if (rpt->val > rpt2->val) rpt2->val = rpt->val;
+          } else {
+            if (rpt->val < rpt2->val) rpt2->val = rpt->val;
+          }
+          rpt2->work++;
+        }
+      }
+      rpt = rpt->rpt;
+    }
+    gafree(pst);
+  }
+
+  /* Check min count if provided */
+  if (mcnt>1) {
+    rpt = stnr->rpt;
+    while (rpt) {
+      if (rpt->work<mcnt) rpt->umask = 0;
+      rpt = rpt->rpt;
+    }
+  }
+
+  /* Return final result. */
+  pst->result.stn = stnr;
+  return(0);
+
+err:
+  snprintf(pout,255,"Error from %s:  Unable to evaluate expression\n",fnam);
+  gaprnt (0,pout);
+  gafree(pst);
+  gasfre(stnr);
+  return(1);
+}
+
+/*  Find args for the stnave, stnmin, and stnmax functions */
+
+gaint fndarg (char *ch, gaint *iv) {
+gaint ival;
+
+   while (*ch==' ') ch++;
+   if (*ch!='-' && *(ch+1)!='m') {
+     gaprnt (0,"Invalid option argument in STN function\n");
+     return (1);
+   }
+
+   ch+=2;
+   while (*ch==' ') ch++;
+
+   ch = intprs(ch,&ival);
+   if (ch==NULL || ival<1) {
+     gaprnt (0,"Invalid option argument in STN function\n");
+     return (1);
+   }
+
+   *iv = ival;
+   return (0);
+}
+
+gaint ffcdif (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr;
+gaint dim,rc,is,siz,i,j,sflag;
+gadouble *res,*rr,*gr;
+char *resundef, *rru, *gru;
+size_t sz;
+
+  /* Check for user errors */
+
+  if (pfc->argnum!=2) {
+    gaprnt (0,"Error from CDIFF:  Too many or too few args \n");
+    gaprnt (0,"                   Two arguments expected \n");
+    return (1);
+  }
+
+  if      (*(pfc->argpnt[1])=='x') dim = 0;
+  else if (*(pfc->argpnt[1])=='y') dim = 1;
+  else if (*(pfc->argpnt[1])=='z') dim = 2;
+  else if (*(pfc->argpnt[1])=='t') dim = 3;
+  else if (*(pfc->argpnt[1])=='e') dim = 4;
+  else {
+    gaprnt (0,"Error from CDIFF:  Invalid dimension argument\n");
+    gaprnt (0,"  2nd argument must be X, Y, Z, T or E\n");
+    return (1);
+  }
+  sflag = 0;
+  if (*(pfc->argpnt[1]+1)=='p') sflag = 1;
+  if (*(pfc->argpnt[1]+1)=='m') sflag = 2;
+  
+
+  /* Get the result grid. */
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+  if (pst->type==0) {
+    gafree (pst);
+    return(-1);
+  }
+  pgr = pst->result.pgr;
+
+  /* Verify that the dimension specified is a varying dimension */
+
+  if (dim!=pgr->idim && dim!=pgr->jdim) {
+    gaprnt (0,"Error from CDIFF:  Specified dimension non varying\n");
+    gafree(pst);
+    return(1);
+  }
+
+  /* Get the output grid and its undef mask */
+
+  siz = pgr->isiz * pgr->jsiz;
+  sz = siz*sizeof(gadouble);
+  res = (gadouble *)galloc(sz,"cdifres");
+  if (res==NULL) {
+    gaprnt (0,"Error from CDIFF:  Memory allocation error\n");
+    gafree(pst);
+    return (1);
+  }
+  sz = siz*sizeof(char);
+  resundef = (char *)galloc(sz,"cdifresu");
+  if (resundef==NULL) {
+    gaprnt (0,"Error from CDIFF:  Memory allocation error\n");
+    gafree(pst);
+    return (1);
+  }
+
+  /* Do the differencing */
+
+  gr = pgr->grid;
+  gru = pgr->umask;
+  rr = res;
+  rru = resundef;
+  is = pgr->isiz;
+  if (dim==pgr->jdim) {
+    for (j=0; j<pgr->jsiz; j++) {
+      for (i=0; i<pgr->isiz; i++) {
+        if (sflag == 0) {
+          if (j==0 || j==pgr->jsiz-1) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru+is)==0 || *(gru-is)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr+is) - *(gr-is);
+	      *rru = 1;
+	    }
+          }
+        } else if (sflag == 1) {
+          if (j==pgr->jsiz-1) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru+is)==0 || *(gru)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr+is) - *(gr);
+	      *rru = 1;
+	    }
+          }
+        } else {
+          if (j==0) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru)==0 || *(gru-is)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr) - *(gr-is);
+	      *rru = 1;
+	    }
+          }
+        }
+        gr++; gru++; rr++; rru++;
+      }
+    }
+  } 
+  else {
+    for (j=0; j<pgr->jsiz; j++) {
+      for (i=0; i<pgr->isiz; i++) {
+        if (sflag==0) {
+          if (i==0 || i==pgr->isiz-1) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru+1)==0 || *(gru-1)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr+1) - *(gr-1);
+	      *rru = 1;
+	    }
+          }
+        } 
+	else if (sflag==1) {
+          if (i==pgr->isiz-1) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru+1)==0 || *(gru)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr+1) - *(gr);
+	      *rru = 1;
+	    }
+          }
+        } 
+	else {
+          if (i==0) {
+	    *rru = 0;
+	  }
+          else {
+            if (*(gru)==0 || *(gru-1)==0) {
+              *rru = 0;
+            } 
+	    else {
+	      *rr = *(gr) - *(gr-1);
+	      *rru = 1;
+	    }
+          }
+        }
+        gr++; gru++; rr++; rru++;
+      }
+    }
+  }
+
+  gree(pgr->grid,"f443");
+  gree(pgr->umask,"f443a");
+  pgr->grid = res;
+  pgr->umask = resundef;
+  return (0);
+}
+
+/* Routine to read the user function definition file, and build
+   the appropriate link list of function definition blocks.
+   The file name is pointed to by the GAFDEF environment variable;
+   if unset then no user functions will be set up */
+
+void gafdef (void) {
+/* struct gaufb *ufb, *oufb=NULL; */
+/* char *cname; */
+/* FILE *cfile; */
+/* char rec[260],*ch; */
+/* gaint i,j,pass; */
+
+  ufba = NULL;
+  return; 
+
+  /* remainder of subroutine commented out pending implementation of DLLs */
+
+
+/*   /\* Make two passes.  First read user function table, then read */
+/*      system function table *\/ */
+
+/*   pass = 0; */
+/*   while (pass<2) { */
+/*     if (pass==0) { */
+/*       cname = getenv("GAUDFT"); */
+/*       if (cname==NULL) { */
+/*         pass++; */
+/*         continue; */
+/*       } */
+/*       cfile = fopen(cname,"r"); */
+/*       if (cfile==NULL) { */
+/*         gaprnt(0,"Error opening user function definition table\n"); */
+/*         snprintf(pout,255,"  File name is: %s\n",cname); */
+/*         gaprnt (0,pout); */
+/*         pass++; */
+/* 	gree(cname,"f300"); */
+/*         continue; */
+/*       } */
+/*     } else { */
+/*       cname = gxgnam("udft"); */
+/*       cfile = fopen(cname,"r"); */
+/*       if (cfile==NULL) { */
+/* 	gree(cname,"f301"); */
+/* 	break; */
+/*       } */
+/*     } */
+
+/*     /\* Read the file. *\/ */
+
+/*     while (1) { */
+/*       ufb = (struct gaufb *)malloc(sizeof(struct gaufb)); */
+/*       if (ufb==NULL) goto memerr; */
+
+/*       /\* Read First record (name and arg types) *\/ */
+
+/*       ch = fgets(rec,256,cfile); */
+/*       if (ch==NULL) break; */
+/*       ch = rec; */
+/*       lowcas(ch); */
+/*       while (*ch==' ') ch++; */
+/*       i = 0; */
+/*       while (*ch!=' ' && *ch!='\0' && *ch!='\n') { */
+/*         if (i<15) { */
+/*           ufb->name[i] = *ch; */
+/*           i++; */
+/*         } */
+/*         ch++; */
+/*       } */
+/*       ufb->name[i] = '\0'; */
+/*       if (*ch!=' ') goto fmterr; */
+/*       while (*ch==' ') ch++; */
+/*       if (intprs(ch,&(ufb->alo))==NULL) goto fmterr; */
+/*       if ( (ch = nxtwrd(ch))==NULL) goto fmterr; */
+/*       if (intprs(ch,&(ufb->ahi))==NULL) goto fmterr; */
+/*       i = 0; */
+/*       while (i<ufb->ahi) { */
+/*         if ( (ch = nxtwrd(ch))==NULL) goto fmterr; */
+/*         if (cmpwrd("expr",ch)) ufb->atype[i]=1; */
+/*         else if (cmpwrd("value",ch)) ufb->atype[i]=2; */
+/*         else if (cmpwrd("char",ch)) ufb->atype[i]=3; */
+/*         else goto fmterr; */
+/*         i++; */
+/*       } */
+
+/*       /\* Read 2nd record -- options *\/ */
+
+/*       ch = fgets(rec,256,cfile); */
+/*       if (ch==NULL) goto rderr; */
+/*       ch = rec; */
+/*       lowcas(ch); */
+/*       while (*ch==' ') ch++; */
+/*       if (*ch=='\n' || *ch=='\0') goto fmterr; */
+/*       while (1) { */
+/*         if (cmpwrd("direct",ch)) ufb->sflg=0; */
+/*         else if (cmpwrd("sequential",ch)) ufb->sflg=1; */
+/*         else goto fmterr; */
+/*         if ( (ch = nxtwrd(ch))==NULL) break; */
+/*       } */
+
+/*       /\* Read 3rd record -- file name of executable *\/ */
+
+/*       ch = fgets(rec,256,cfile); */
+/*       if (ch==NULL) goto rderr; */
+/*       i = 0; */
+/*       while (rec[i]!='\n' && rec[i]!='\0') i++; */
+/*       ufb->fname = (char *)malloc(i+1); */
+/*       if (ufb->fname==NULL) { */
+/*         free(ufb); */
+/*         goto memerr; */
+/*       } */
+/*       for (j=0; j<i; j++) *(ufb->fname+j) = rec[j]; */
+/*       *(ufb->fname+i) = '\0'; */
+
+/*       /\* Read 4th record -- file name of data transfer to user *\/ */
+
+/*       ch = fgets(rec,256,cfile); */
+/*       if (ch==NULL) goto rderr; */
+/*       i = 0; */
+/*       while (rec[i]!='\n' && rec[i]!='\0') i++; */
+/*       ufb->oname = (char *)malloc(i+1); */
+/*       if (ufb->oname==NULL) { */
+/*         free(ufb); */
+/*         goto memerr; */
+/*       } */
+/*       for (j=0; j<i; j++) *(ufb->oname+j) = rec[j]; */
+/*       *(ufb->oname+i) = '\0'; */
+
+/*       /\* Read 5th record -- file name for data transfer from user *\/ */
+
+/*       ch = fgets(rec,256,cfile); */
+/*       if (ch==NULL) goto rderr; */
+/*       i = 0; */
+/*       while (rec[i]!='\n' && rec[i]!='\0') i++; */
+/*       ufb->iname = (char *)malloc(i+1); */
+/*       if (ufb->iname==NULL) { */
+/*         free(ufb); */
+/*         goto memerr; */
+/*       } */
+/*       for (j=0; j<i; j++) *(ufb->iname+j) = rec[j]; */
+/*       *(ufb->iname+i) = '\0'; */
+
+/*       /\* Chain this ufb *\/ */
+
+/*       ufb->ufb = NULL; */
+
+/*       if (ufba==NULL) ufba = ufb; */
+/*       else oufb->ufb = ufb; */
+/*       oufb = ufb; */
+/*     } */
+
+/*     fclose (cfile); */
+/*     if (pass>0 && cname!=NULL) gree(cname,"f306"); */
+/*     pass++; */
+/*   } */
+/*   return; */
+
+/* memerr: */
+/*   gaprnt(0,"Memory allocation error: user defined functions\n"); */
+/*   return; */
+
+/* fmterr: */
+/*   gaprnt(0,"Format error in user defined function table:\n"); */
+/*   snprintf(pout,255,"  Processing function name: %s\n",ufb->name); */
+/*   gaprnt (0,pout); */
+/*   free(ufb); */
+/*   goto wname; */
+
+/* rderr: */
+/*   gaprnt(0,"Read error on user defined function table:\n"); */
+/*   free(ufb); */
+/*   goto wname; */
+
+/* wname: */
+/*   snprintf(pout,255,"  File name is: %s\n",cname); */
+/*   gaprnt (0,pout); */
+/*   if (cname!=NULL) gree(cname,"f309"); */
+/*   return; */
+}
+
+
+gaint ffflvl (struct gafunc *pfc, struct gastat *pst) {
+struct gagrid *pgr1, *pgr2, *pgrv;
+struct gafile *pfi;
+gadouble (*lvconv) (gadouble *, gadouble);
+gadouble levf, levl, *levs, clev, ulev, flev, llev, lev, lev1, lev2;
+gadouble *lvvals, *gr1, *gr2, *grv, *grr, *res;
+gaint rc, i, j, lvt, dim, wflag, cnt, size;
+char *ch, *resundef, *gr1u, *gr2u, *grru;
+size_t sz;
+
+  if (pfc->argnum!=4) {
+    gaprnt (0,"Error from FNDLVL:  Too many or too few args \n");
+    gaprnt (0,"                    Four arguments expected \n");
+    return (1);
+  }
+
+  /* Get 1st and last level.  They are args 3 and 4 and should
+     be valid 'z' dimension expressions. */
+
+  pfi = pst->pfid;
+
+  ch = dimprs (pfc->argpnt[2], pst, pfi, &dim, &levf, 1, &wflag);
+  if (ch==NULL || dim!=2) {
+    gaprnt (0,"Error from FNDLVL:  Arg 3 an invalid Z dimension expression\n");
+    return (1);
+  }
+  ch = dimprs (pfc->argpnt[3], pst, pfi, &dim, &levl, 1, &wflag);
+  if (ch==NULL || dim!=2) {
+    gaprnt (0,"Error from FNDLVL:  Arg 4 an invalid Z dimension expression\n");
+    return (1);
+  }
+
+  /* Determine the levels we need to process, given the range provided
+     by the user and the data levels available in the default file */
+
+  lvt = pfi->dnum[2];
+  if (lvt<3) {
+    gaprnt (0,"Error from FNDLVL:  Too few levels in default file \n");
+    return (1);
+  }
+
+  sz = sizeof(gadouble)*lvt;
+  levs = (gadouble *)galloc(sz,"fndlevs");
+  if (levs==NULL) {
+    gaprnt (0,"Error from FNDLVL:  Memory allocation error \n");
+    return (1);
+  }
+  cnt = 0;
+  
+  lvconv = pfi->gr2ab[2];
+  lvvals = pfi->grvals[2];
+  clev = lvconv(lvvals, 1.0);
+  ulev = lvconv(lvvals, (gadouble)lvt);
+  flev = lvconv(lvvals, levf);
+  llev = lvconv(lvvals, levl);
+
+  if ( (clev<ulev && flev<llev) ||
+       (clev>ulev && flev>llev) ) {  /* User ordering is same as file */
+    for (i=1; i<=lvt; i++) {
+      lev = lvconv(lvvals, (gadouble)i);
+      if ( (flev<llev && (lev>=flev && lev<=llev)) ||
+           (flev>llev && (lev<=flev && lev>=llev)) ) {
+        *(levs+cnt) = lev;  cnt++; 
+      }
+    }
+  } else {                           /* User ordering is reverse of file */
+    for (i=lvt; i>=1; i--) {
+      lev = lvconv(lvvals, (gadouble)i);
+      if ( (flev<llev && (lev>=flev && lev<=llev)) ||
+           (flev>llev && (lev<=flev && lev>=llev)) ) {
+        *(levs+cnt) = lev;  cnt++; 
+      }
+    }
+  }
+
+  /* Insure z is not a varying dimension */
+
+  lev1 = *levs;
+  if (pst->idim==2) {
+    pst->idim = pst->jdim;
+    pst->jdim = -1;
+    pst->dmin[2] = lev1;
+    pst->dmax[2] = lev1;
+  }
+  if (pst->jdim==2) {
+    pst->jdim = -1;
+    pst->dmin[2] = lev1;
+    pst->dmax[2] = lev1;
+  }
+
+  /* Get the level to find (2nd arg).   Must be an expression that 
+     yields the same grid the 1st arg will yield. */                              
+ 
+  rc = gaexpr(pfc->argpnt[1],pst);
+  if (rc) {
+    gree(levs,"f444");
+    return (1);
+  }
+  if (pst->type==0) {
+    gree(levs,"f445");
+    gafree (pst);
+    return (-1);
+  }
+  pgrv = pst->result.pgr;
+
+  /* Get first grid (at 1st level) from 1st arg. */
+
+  pst->dmin[2] = lev1;
+  pst->dmax[2] = lev1;
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) {
+    gree(levs,"f446");
+    gagfre (pgrv);
+    return (1);
+  }
+  if (pst->type==0) {
+    gree(levs,"f447");
+    gafree (pst);
+    gagfre (pgrv);
+    return (-1);
+  }
+  pgr1 = pst->result.pgr;
+
+  /* Check that the two grids are equivalent.  */
+
+  if (pgrv->idim!=pgr1->idim || pgrv->jdim != pgr1->jdim ||
+      gagchk(pgrv,pgr1,pgrv->idim) || gagchk(pgrv,pgr1,pgrv->jdim)) {
+    gaprnt (0,"Error from FNDLVL :  Incompatible grids. \n");
+    gree(levs,"f448");
+    gafree (pst);
+    gagfre (pgrv);
+    return (1);
+  }
+
+  /* Allocate space to hold the result and its undef mask */
+
+  size = pgrv->isiz * pgrv->jsiz;
+  sz = sizeof(gadouble)*size;
+  res = (gadouble *)galloc(sz,"fndlvlres");
+  if (res==NULL) {
+    gaprnt (0,"Error from FNDLVL :  Memory allocation error \n");
+    gree(levs,"f449");
+    gafree (pst);
+    gagfre (pgrv);
+    return (1);
+  }
+  sz = sizeof(char)*size;
+  resundef = (char *)galloc(sz,"fndlvlresu");
+  if (resundef==NULL) {
+    gaprnt (0,"Error from FNDLVL :  Memory allocation error \n");
+    gree(levs,"f450");
+    gafree (pst);
+    gagfre (pgrv);
+    return (1);
+  }
+  for (i=0; i<size; i++) *(resundef+i) = 0;
+
+  /* Loop through the levels and, when appropriate, interpolate to find
+     the level.  */
+
+  for (i=1; i<cnt; i++) {
+    lev2 = *(levs+i);
+    pst->dmin[2] = lev2;
+    pst->dmax[2] = lev2;
+    rc = gaexpr(pfc->argpnt[0],pst);
+    if (rc) {             
+      gree(levs,"f451");
+      gree(res,"f452");
+      gagfre (pgr1);
+      gagfre (pgrv);
+      return (1);
+    }
+    if (pst->type==0) {
+      gree(levs,"f453");
+      gree(res,"f454");
+      gafree (pst);
+      gagfre (pgr1);
+      gagfre (pgrv);
+      return (-1);
+    }
+    pgr2 = pst->result.pgr;
+
+    gr1 = pgr1->grid; gr1u = pgr1->umask;
+    gr2 = pgr2->grid; gr2u = pgr2->umask;
+    grr = res;        grru = resundef;
+    grv = pgrv->grid;
+    for (j=0; j<size; j++) {
+     if (*grru == 0) {                                       /* If we haven't yet found a level...  */
+      if (*gr1u != 0 && *gr2u != 0) {                        /* and data is available... */
+       if ((*gr1 <  *gr2 && *grv >= *gr1 && *grv <= *gr2) ||
+           (*gr1 >= *gr2 && *grv <= *gr1 && *grv >= *gr2)) { /* and the level falls in this layer... */
+         if (fabs(*gr2 - *gr1) < 1e-5) {
+	   *grr = lev1; 
+	   *grru = 1;
+	 }
+         else {
+	   *grr = lev1 + (lev2-lev1)*(*grv - *gr1)/(*gr2 - *gr1);   /* then interpolate. */
+	   *grru = 1;
+	 }
+       }
+      }
+     }
+     gr1++; gr1u++; 
+     gr2++; gr2u++;
+     grr++; grru++;
+     grv++; 
+    }
+    gagfre(pgr1);
+    pgr1 = pgr2;
+    lev1 = lev2;
+  }
+
+  /* Release storage and return */
+  
+  gagfre (pgr1);
+  if (pgrv->idim>-1) gree(pgrv->grid,"f455");
+  if (pgrv->idim==-1) {
+    pgrv->rmin = *res;
+    pgrv->umin = *resundef;
+    gree(res,"f456");
+    gree(resundef,"457");
+  } 
+  else {
+    pgrv->grid = res;
+    pgrv->umask = resundef;
+  }
+
+  pst->type = 1;
+  pst->result.pgr = pgrv;
+  gree(levs,"f458");
+  return (0);
+}
+
+
+/*  Convert a station data time series into a grid; 
+    this allows more graphics operations and 
+    analytical comparisons.  */
+
+gaint ffs2g1d (struct gafunc *pfc, struct gastat *pst) {
+gaint i,rc,size,idim,jdim;
+struct gagrid *pgr;
+struct gastn *stn;
+struct garpt *rpt;
+gadouble *val,*tvals;
+char *valundef;
+size_t sz;
+
+  if (pfc->argnum!=1) {
+    gaprnt (0,"Error from S2G1D: Too many or too few args \n");
+    gaprnt (0,"                  One argument expected \n");
+    return (1);
+  }
+
+  if (pst->idim != 3 || pst->jdim != -1) {
+    gaprnt (0,"Error from S2G1D: Time can be only varying dimension\n");
+    return (1);
+  }
+
+  rc = gaexpr(pfc->argpnt[0],pst);
+  if (rc) return (rc);
+
+  if (pst->type==1) {
+    gaprnt (0,"Error from S2G1D: Station data argument expected\n");
+    return (1);
+  }
+
+  stn = pst->result.stn;
+
+  if (stn->idim != 3 || stn->jdim != -1) {
+    gaprnt (0,"Error from S2G1D: Logic Error 4; contact developer\n");
+    return (1);
+  }
+
+  sz = sizeof(struct gagrid);
+  pgr = (struct gagrid *)galloc(sz,"s2g1dpgr");
+
+  if (pgr==NULL) {
+    gaprnt (0,"Memory Allocation Error:  Grid Request Block\n");
+    return (1);
+  }
+
+  /* Fill in gagrid variables */
+  
+  pgr->pfile = NULL;
+  pgr->undef = stn->undef;
+  pgr->isiz = 1 + stn->tmax - stn->tmin;
+  pgr->jsiz = 1; 
+  idim = stn->idim; jdim = stn->jdim;
+  pgr->exprsn = NULL;
+  pgr->alocf = 1;
+  pgr->pvar  = NULL;
+  pgr->idim  = idim;
+  pgr->jdim  = jdim;
+  pgr->iwrld = 0;  pgr->jwrld = 0;
+  for (i=0;i<3;i++) {
+    pgr->dimmin[i] = 1;
+    pgr->dimmax[i] = 1;
+  }
+  pgr->dimmin[3] = stn->tmin;
+  pgr->dimmax[3] = stn->tmax;
+  pgr->ilinr = 1;
+  pgr->jlinr = 0;
+
+  sz = sizeof(gadouble)*8;
+  tvals = (gadouble *)galloc(sz,"s2g1dtvals");
+  if (tvals == NULL) {
+    gaprnt (0,"Memory Allocation Error: Dimension array\n");
+    gree(pgr,"f459");
+    return (1);
+  }
+
+  for (i=0; i<8; i++) {
+    *(tvals+i) = *(stn->tvals+i);
+  }
+  pgr->ivals = tvals;
+  pgr->iavals = tvals;
+  pgr->jvals = NULL;
+  /* this is for the grid */
+  sz = sizeof(gadouble)*pgr->isiz;
+  pgr->grid = (gadouble *)galloc(sz,"s2g1dgr");
+  if (pgr->grid == NULL) {
+    gaprnt (0,"Memory Allocation Error: Data array\n");
+    gree(pgr,"f460");
+    return (1);
+  }
+  /* this is for the undef mask */
+  sz = sizeof(char)*pgr->isiz;
+  pgr->umask = (char *)galloc(sz,"s2g2dgru");
+  if (pgr->umask == NULL) {
+    gaprnt (0,"Memory Allocation Error: Undef mask array\n");
+    gree(pgr,"f461");
+    return (1);
+  }
+
+  /* pre-fill the grid with undef values */
+  valundef = pgr->umask;
+  size = pgr->isiz;
+  for (i=0; i<size; i++) {
+    *valundef = 0;
+    valundef++;
+  }
+  /* now populate the grid with station values */
+  valundef = pgr->umask;
+  val = pgr->grid;
+  rpt = stn->rpt;
+  while (rpt!=NULL) {
+    if (rpt->val != stn->undef) {
+      i = (gaint)(rpt->tim) - stn->tmin;
+      *(val+i) = rpt->val;
+      *(valundef+i) = 1;
+    }
+    rpt=rpt->rpt;
+  }
+
+  gafree(pst);
+
+  pst->type = 1;
+  pst->result.pgr = pgr;
+  
+  return (0);
+}
+
diff --git a/src/gagmap.c b/src/gagmap.c
new file mode 100644
index 0000000..c91745b
--- /dev/null
+++ b/src/gagmap.c
@@ -0,0 +1,2052 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/*  Values output into the grib1 map file:
+     Header:
+     hipnt info: 0 - version number (1)
+                 1 - number of times in file
+                 2 - number of records per time
+                 3 - Grid type
+                   255 - user defined grid.  descriptor
+                         describes grid exactly; one record
+                         per grid.
+                    29 - Predefined grid set 29 and 30.
+                         Two records per grid.
+     hfpnt info:  None
+     Info:
+     intpnt info (for each mapped grib record) :
+                 0 - position of start of data in file
+                 1 - position of start of bit map in file
+                 2 - number of bits per data element
+     fltpnt info :
+                 0 - decimal scale factor for this record
+                 1 - binary scale factor
+                 2 - reference value
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "grads.h"
+#include "gagmap.h"
+#if GRIB2
+#include "grib2.h"
+void gaseekgb(FILE *, off_t, g2int, off_t *, g2int *);
+#endif
+
+
+/* global variables */
+extern struct gamfcmn mfcmn;
+struct dt rtime;   /* time based on input map */
+struct dt ftime;   /* time based on dd file */
+static off_t flen;
+gaint ng1elems=3;
+gaint ng2elems=2;
+
+/*  Routine to scan a grib1 or grib2 file and output an index (map) file. */
+
+gaint gribmap (void) {
+
+#if GRIB2
+ unsigned char *cgrib=NULL;
+ g2int  listsec0[3],listsec1[13],numlocal,numfields,n;
+ g2int  unpack,expand,lgrib;
+ off_t iseek,lskip;
+ gribfield  *gfld;
+ size_t  lengrib;
+ struct gag2indx *g2indx;
+#endif
+ char *ch=NULL;
+ gaint ret,ierr,flag,rcgr,record;
+ gaint rc,i,e,tmin=0,tmax=0,told,tcur,fnum,didmatch=0;
+ gaint sp,sp2,ioff,eoff,it,write_map;
+ struct gafile *pfi;
+ struct dt dtim,dtimi;
+ struct gaens *ens;
+ struct gaindxb indxbb;
+
+#if GRIB2
+ unpack=0;
+ expand=0;
+#endif
+ mfile=NULL;
+ write_map=1;
+
+ pindxb = &indxbb;
+
+ /* Get the descriptor file name */
+ if (ifile==NULL) {
+   printf ("\n");
+   cnt = nxtcmd (cmd,"Enter name of Data Descriptor file: ");
+   if (cnt==0) return(1);
+   getwrd(crec,cmd,250);
+   ifile = crec;
+ }
+ 
+ /* Allocate memory for gafile structure */
+ pfi = getpfi();
+ if (pfi==NULL) {
+   printf ("gribmap error: unable to allocate memory for gafile structure\n");
+   return(1);
+ }
+
+ /* Parse the descriptor file */
+ rc = gaddes (ifile, pfi, 0);
+ if (rc) return(1);
+
+ /* Check index flags */
+ if (pfi->idxflg!=1 && pfi->idxflg!=2) {
+   printf ("gribmap error: data descriptor file is not for GRIB data\n");
+   return(1);
+ } 
+
+ /* * GRIB1 * */
+ else if (pfi->idxflg==1) {
+
+   /* Allocate memory for gaindx structure */
+   sz = sizeof(struct gaindx);
+   pindx = (struct gaindx *)galloc(sz,"pindxgm");
+   if (pindx==NULL) {
+     printf ("grib1map error: unable to allocate memory for pindx\n");
+     return(1);
+   }
+   
+   /* Save the initial time from the descriptor file for the tau0 option and the map file */
+   btimdd.yr = *(pfi->abvals[3]);
+   btimdd.mo = *(pfi->abvals[3]+1);
+   btimdd.dy = *(pfi->abvals[3]+2);
+   btimdd.hr = *(pfi->abvals[3]+3);
+   btimdd.mn = *(pfi->abvals[3]+4);
+   if (no_min) btimdd.mn = 0;
+   
+   /* Set up for this grid type */
+   if (pfi->grbgrd<-900 || pfi->grbgrd==255) {
+     nrec = 1;
+     gtype[0] = 255;
+   } else if (pfi->grbgrd>-1 && pfi->ppflag) {
+     nrec=1;
+     gtype[0] = pfi->grbgrd;
+   } else if (pfi->grbgrd==29) {
+     nrec = 2;
+     gtype[0] = 29;
+     gtype[1] = 30;
+     if (pfi->dnum[0]!=144 || pfi->dnum[1]!=73 ||
+	 pfi->linear[0]!=1 || pfi->linear[1]!=1 ||
+	 *(pfi->grvals[0])!= 2.5 || *(pfi->grvals[0]+1) != -2.5 ||
+	 *(pfi->grvals[1])!= 2.5 || *(pfi->grvals[1]+1) != -92.5 ) {
+       printf("grib1map error: grid specification for GRIB grid type 29/30.\n");
+       printf("                grid scaling must indicate a 2.5 x 2.5 grid\n");
+       printf("                grid size must be 144 x 73\n");
+       printf("                grid must go from 0 to 357.5 and -90 to 90\n");
+       return(1);
+     }
+   } else {
+     nrec = 1;
+     gtype[0] = pfi->grbgrd;
+   }
+   
+   /* Set up grib1 index and initialize values */
+   pindx->type   = g1ver;
+   pindx->hinum  = 4;
+   if (bigflg) pindx->hinum  = 5;
+   pindx->hfnum  = 0;
+   if (bigflg) pindx->intnum = nrec * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   else pindx->intnum = nrec * ng1elems * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   pindx->fltnum = nrec * ng1elems * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   if (bigflg) pindxb->bignum = 2 * nrec * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   sz = sizeof(gaint)*pindx->hinum;
+   pindx->hipnt  = (gaint *)galloc(sz,"hipntgm");
+   sz = sizeof(gaint)*pindx->intnum;
+   pindx->intpnt = (gaint *)galloc(sz,"intpntgm");
+   sz = sizeof(gafloat)*pindx->fltnum;
+   pindx->fltpnt = (gafloat *)galloc(sz,"fltpntgm");
+   if (pindx->hipnt==NULL || pindx->intpnt==NULL || pindx->fltpnt==NULL) {
+     printf ("grib1map error: unable to allocate memory for index pointers\n");
+     return(1);
+   }
+   if (bigflg) {
+     sz = sizeof(off_t)*pindxb->bignum;
+     pindxb->bigpnt = (off_t *)galloc(sz,"bigpntgm");
+     if (pindxb->bigpnt==NULL) {
+       printf ("grib1map error: unable to allocate memory for index pointers\n");
+       return(1);
+     }
+   }
+   for (i=0; i<pindx->intnum; i++) *(pindx->intpnt+i) = -999;
+   for (i=0; i<pindx->fltnum; i++) *(pindx->fltpnt+i) = -999; 
+   if (bigflg) {
+      for (i=0; i<pindxb->bignum; i++) *(pindxb->bigpnt+i) = (off_t)-999;
+   }
+   *(pindx->hipnt+0) = g1ver;
+   *(pindx->hipnt+1) = pfi->dnum[3];
+   *(pindx->hipnt+2) = pfi->trecs;
+   *(pindx->hipnt+3) = pfi->grbgrd;
+   if (pfi->grbgrd<-900) *(pindx->hipnt+3) = 255;
+   if (bigflg) *(pindx->hipnt+4) = pindxb->bignum;
+
+   /* Loop over all files in the data set */
+   gfile = NULL;
+   for (e=1,ens=pfi->ens1; e<=pfi->dnum[4]; e++,ens++) {
+     tcur = 0;
+     while (1) {    /* loop over all times for this ensemble */
+       if (pfi->tmplat) {
+	 /* make sure no file is open */
+	 if (gfile!=NULL) {
+	   fclose(gfile);
+	   gfile=NULL;
+	 }
+	 /* advance to first valid time step for this ensemble */
+	 if (tcur==0) {
+	   told = 0;
+	   tcur = 1;
+	   while (pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] == -1) tcur++;  
+	 }
+	 else {  /* tcur!=0 */
+	   told = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+	   /* increment time step until fnums changes */
+	   while (told==pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] && tcur<=pfi->dnum[3]) {
+	     tcur++;
+	   }
+	 }
+
+	 /* make sure we haven't advanced past end of time axis */
+	 if (tcur>pfi->dnum[3]) break;
+
+	 /* check if we're past all valid time steps for this ensemble */
+	 if ((told != -1) && (pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] == -1)) break;
+
+	 /* Find the range of t indexes that have the same fnums value.
+	    These are the times that are contained in this particular file */
+	 tmin = tcur;
+	 tmax = tcur-1;
+	 fnum = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+
+	 if (fnum != -1) {
+	   while (fnum == pfi->fnums[(e-1)*pfi->dnum[3]+tmax]) tmax++;
+	   gr2t(pfi->grvals[3], (gadouble)tcur, &dtim); 
+	   gr2t(pfi->grvals[3], ens->gt, &dtimi);
+	   ch = gafndt(pfi->name, &dtim, &dtimi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,tcur,e,&flag);
+	   if (ch==NULL) {
+	     printf(" grib1map error: couldn't determine data file name for e=%d t=%d\n",e,tcur);
+	     return(1);
+	   }
+	 }
+       }
+       else { 
+	 /* Data set is not templated */
+	 ch = pfi->name;
+	 tmin = 1;
+	 tmax = pfi->dnum[3];
+       }
+       
+       /* Open this GRIB file and position to start of first record */
+       if (!quiet) printf(" grib1map:  opening GRIB file: %s \n",ch);
+       gfile = fopen(ch,"rb");
+       if (gfile==NULL) {
+	 if (pfi->tmplat) {
+	   if (!quiet) printf (" grib1map warning: could not open GRIB file: %s\n",ch);
+	   continue;
+	 } else {
+	   printf (" grib1map error: could not open GRIB file: %s\n",ch);
+	   return(1);
+	 }
+       }
+       if (pfi->tmplat) gree(ch,"312");
+       
+       /* Get file size */
+       fseeko(gfile,(off_t)0,2);
+       flen = ftello(gfile);
+       
+       /* Set up to skip appropriate amount and position */
+       if (skip > -1) {
+	 fpos = (off_t)skip;
+       }
+       else {
+	 fseeko (gfile,(off_t)0,0);
+	 rc = fread (rec,1,100,gfile);
+	 if (rc<100) {
+	   printf (" grib1map error: I/O error reading header\n");
+	   return(1);
+	 }
+	 len = gagby(rec,88,4);
+	 fpos = (off_t)(len*2 + 100);
+       }
+       
+       /* Main Loop */
+       irec=1;
+       while (1) {
+	 /* read a grib record */
+	 rc = gribhdr(&ghdr);      
+	 if (rc) break;
+	 /* compare to each 2-d variable in the 5-D data volume
+	    defined by the descriptor file for a match */
+	 rcgr = gribrec(&ghdr,pfi,pindx,tmin,tmax,e);
+	 if (rcgr==0) didmatch=1;
+	 if (rcgr>=100) didmatch=rcgr;
+	 irec++;
+       }
+       
+       /* see how we did */
+       if (rc==50) {
+	 printf (" grib1map error: I/O error reading GRIB file\n");
+	 printf ("                 possible cause is premature EOF\n");
+	 break;
+       }
+       if (rc>1 && rc!=98) {
+	 printf (" grib1map error: GRIB file format error (rc = %i)\n",rc);
+	 return(rc);
+       }
+       
+       /* break out if not templating */
+       if (!pfi->tmplat) break;
+       
+     } /* end of while (1) loop */
+   } /* end of for (e=1; e<=pfi->dnum[4]; e++) loop */
+   
+   if (!quiet) printf (" grib1map:  reached end of files\n");
+   
+   /* check if file closed already for case where template was set,
+      but it was not templated and the template code above closed it. */
+   if (gfile!=NULL) {
+     fclose (gfile);
+     gfile=NULL;
+   }
+   
+   /* open the map file */
+   if (write_map) {
+     mfile = fopen(pfi->mnam,"wb");
+     if (mfile==NULL) {
+       printf (" grib1map error: could not open index file: %s\n",pfi->mnam);
+       return(1);
+     } 
+     else {
+       if (!quiet) printf(" grib1map:  writing the map...\n\n");
+       /* output the map depending on version # */
+       if (g1ver==1 || g1ver==4) {
+	 fwrite (pindx,sizeof(struct gaindx),1,mfile);
+	 if (pindx->hinum>0)  fwrite(pindx->hipnt,sizeof(gaint),pindx->hinum,mfile);
+	 if (pindx->hfnum>0)  fwrite(pindx->hfpnt,sizeof(gafloat),pindx->hfnum,mfile);
+	 if (pindx->intnum>0) fwrite(pindx->intpnt,sizeof(gaint),pindx->intnum,mfile);
+	 if (pindx->fltnum>0) fwrite(pindx->fltpnt,sizeof(gafloat),pindx->fltnum,mfile);
+	 if (g1ver==4) {
+           if (pindxb->bignum>0) fwrite(pindxb->bigpnt,sizeof(off_t),pindxb->bignum,mfile);
+         }
+	 fclose (mfile);
+       }
+       else {
+	 rc = wtgmap();
+	 if (rc == 601) {
+	   printf(" grib1map error: overflow in float -> IBM float conversion\n");
+	   fclose (mfile);
+	   return (601); 
+	 }
+	 fclose (mfile);
+       }
+     }
+   }
+   return (didmatch);
+ }
+
+#if GRIB2
+ else /* GRIB2 */ {
+
+   /* Set up g2index and initialize values */
+   g2indx = (struct gag2indx *)malloc(sizeof(struct gag2indx));
+   if (g2indx==NULL) {
+     printf ("gribmap error: unable to allocate memory for g2indx\n");
+     fflush(stdout);
+     return(1);
+   }
+   if (bigflg) {
+     g2indx->version = 2; 
+     g2indx->g2intnum =  (ng2elems-1) * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   } else {
+     g2indx->version = 1; 
+     g2indx->g2intnum = ng2elems * pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+   }
+   g2indx->g2intpnt = (gaint *)malloc(sizeof(gaint)*g2indx->g2intnum);
+   if (g2indx->g2intpnt==NULL) {
+     printf ("gribmap error: unable to allocate memory for g2indx->g2intpnt\n");
+     fflush(stdout);
+     goto err;
+   }
+   for (i=0; i<g2indx->g2intnum; i++) g2indx->g2intpnt[i] = -999;
+   if (bigflg) {
+     sz = pfi->trecs * pfi->dnum[3] * pfi->dnum[4];
+     g2indx->g2bigpnt = (off_t *)malloc(sizeof(off_t)*sz);
+     if (g2indx->g2bigpnt==NULL) {
+       printf ("gribmap error: unable to allocate memory for g2indx->g2bigpnt\n");
+       fflush(stdout);
+       goto err;
+     }
+     for (i=0; i<sz; i++) g2indx->g2bigpnt[i] = (off_t)-999;
+   }
+
+   /* Break out point for case with E>1 but data files are only templated over T */
+   if (pfi->dnum[4]>1 && pfi->tmplat==1) {
+     /* Loop over all files in the data set */ 
+     gfile=NULL;
+     e=1;
+     ens=pfi->ens1; 
+     tcur = 0;
+     while (1) {  /* loop over all times */
+       /* make sure no file is open */
+       if (gfile!=NULL) {
+	 fclose(gfile);
+	 gfile=NULL;
+       }
+       if (tcur==0) { /* first time step */
+	 told = 0;
+	 tcur = 1;
+       }
+       else {  /* tcur!=0 */
+	 told = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+	 /* increment time step until fnums changes */
+	 while (told==pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] && tcur<=pfi->dnum[3]) {
+	   tcur++;
+	 }
+       }
+       /* make sure we haven't advanced past end of time axis */
+       if (tcur>pfi->dnum[3]) break;
+       
+       
+       /* Find the range of t indexes that have the same fnums value.
+	  These are the times that are contained in this particular file */
+       tmin = tcur;
+       tmax = tcur-1;
+       fnum = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+       if (fnum != -1) {
+	 while (fnum == pfi->fnums[(e-1)*pfi->dnum[3]+tmax]) tmax++;
+	 gr2t(pfi->grvals[3], (gadouble)tcur, &dtim); 
+	 gr2t(pfi->grvals[3], ens->gt, &dtimi);
+	 ch = gafndt(pfi->name, &dtim, &dtimi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,tcur,e,&flag);
+	 if (ch==NULL) {
+	   printf("gribmap error: couldn't determine data file name for e=%d t=%d\n",e,tcur);
+	   fflush(stdout);
+	   goto err;
+	 }
+       }
+       /* Open this GRIB file and position to start of first record (s/b subroutine) */
+       if (!quiet) printf("gribmap: scanning GRIB2 file: %s \n",ch);
+       fflush(stdout);
+       gfile = fopen(ch,"rb");
+       if (gfile==NULL) {
+	 if (!quiet) printf ("gribmap warning: could not open GRIB file: %s\n",ch);
+	 fflush(stdout);
+	 continue;
+       }
+       gree(ch,"f311a");
+       /* Loop over fields in the grib file and find matches */
+       iseek=(off_t)0;
+       record=1;
+       while (1) {
+	 /* move to next grib message in file */
+	 gaseekgb(gfile,iseek,32000,&lskip,&lgrib);
+	 if (lgrib == 0) break;    /* end loop at EOF or problem */
+	 
+	 /* read the message into memory */
+	 sz = lgrib;
+	 cgrib = (unsigned char *)galloc(sz,"cgrib2");
+	 if (cgrib == NULL) {
+	   printf("gribmap error: unable to allocate memory for record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+	 }
+	 ret = fseeko(gfile,lskip,SEEK_SET);
+	 lengrib = fread(cgrib,sizeof(unsigned char),lgrib,gfile);
+	 if (lengrib < lgrib) {
+	   printf("gribmap error: unable to read record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+	 }
+
+         /* Check for ultra long length -- which we do not yet handle */
+
+         if (gagby(cgrib,8,4)!=0 || gagbb(cgrib+12,0,1)!=0) {
+	   printf("gribmap error: grib2 record too long! record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+         }
+	 
+	 /* Get info about grib2 message */
+	 ierr = 0;
+	 ierr = g2_info(cgrib,listsec0,listsec1,&numfields,&numlocal);
+	 if (ierr) {
+	   printf("gribmap error: g2_info failed: ierr=%d\n",ierr); 
+	   fflush(stdout);
+	   goto err;
+	 }
+	 for (n=0; n<numfields; n++) {
+	   ierr = 0;
+	   ierr = g2_getfld(cgrib,n+1,unpack,expand,&gfld);
+	   if (ierr) {
+	     printf("gribmap error: g2_getfld failed: ierr=%d\n",ierr); 
+	     fflush(stdout);
+	     goto err;
+	   }
+	   
+	   /* get statistical process type from grib field */
+	   sp = g2sp(gfld);
+	   sp2 = g2sp2(gfld);
+	   
+	   /* print out useful codes from grib2 field */
+	   if (verb) g2prnt(gfld,record,n+1,sp,sp2);
+	   
+	   /* Check grid properties */
+	   rc = g2grid_check(gfld,pfi,record,n+1);
+	   if (rc) {
+	     if (verb) printf("\n");
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break; 
+	   }
+	   
+	   /* Check time values in grib field */
+	   it = g2time_check(gfld,listsec1,pfi,record,n+1,tmin,tmax);
+	   if (it==-99) {
+	     if (verb) printf("\n");
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break;
+	   }
+	   it = (it-1)*pfi->trecs;  /* number of records per time */
+	   
+	   /* Check if the variable is a match */
+	   ioff = g2var_match(gfld,pfi,sp,sp2);
+	   if (ioff==-999) {
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break;
+	   }
+	   
+	   /* check if ensemble codes match */
+	   e = g2ens_match(gfld,pfi);
+	   if (e==-999) {
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break;
+	   }
+	   eoff = (e-1)*pfi->dnum[3]*pfi->trecs;  /* number of records per ensemble */
+	   
+	   /* fill in the gribmap entry */
+	   if (verb) printf("  MATCH \n");
+	   fflush(stdout);
+	   g2fill (eoff,it+ioff,ng2elems,iseek,n+1,g2indx);
+	   g2_free(gfld); 
+	 }
+	 /* free memory containing grib record */
+	 gree(cgrib,"f310");
+	 cgrib=NULL;
+	 record++;                 /* increment grib record counter */
+	 iseek = lskip+(off_t)lgrib;  /* increment byte offset to next grib msg in file */
+       }  /* end of while(1) loop over all fields in the grib message*/
+     } /* end of while loop over all times */
+     
+   }
+   else {
+   /* All data sets except those that have E>1 but are templated only over T */
+
+   /* Loop over all files in the data set */ 
+   gfile=NULL;
+   for (e=1,ens=pfi->ens1; e<=pfi->dnum[4]; e++,ens++) {
+     tcur = 0;
+     while (1) {  /* loop over all times for this ensemble */
+       if (pfi->tmplat) {
+	 /* make sure no file is open */
+	 if (gfile!=NULL) {
+	   fclose(gfile);
+	   gfile=NULL;
+	 }
+	 /* advance to first valid time step for this ensemble */
+	 if (tcur==0) {
+	   told = 0;
+	   tcur = 1;
+	   while (pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] == -1) tcur++;  
+	 }
+	 else {  /* tcur!=0 */
+	   told = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+	   /* increment time step until fnums changes */
+	   while (told==pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] && tcur<=pfi->dnum[3]) {
+	     tcur++;
+	   }
+	 }
+	 
+	 /* make sure we haven't advanced past end of time axis */
+	 if (tcur>pfi->dnum[3]) break;
+	 
+	 /* check if we're past all valid time steps for this ensemble */
+	 if ((told != -1) && (pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1] == -1)) break;
+	 
+	 /* Find the range of t indexes that have the same fnums value.
+	    These are the times that are contained in this particular file */
+	 tmin = tcur;
+	 tmax = tcur-1;
+	 fnum = pfi->fnums[(e-1)*pfi->dnum[3]+tcur-1];
+	 if (fnum != -1) {
+	   while (fnum == pfi->fnums[(e-1)*pfi->dnum[3]+tmax]) tmax++;
+	   gr2t(pfi->grvals[3], (gadouble)tcur, &dtim); 
+	   gr2t(pfi->grvals[3], ens->gt, &dtimi);
+	   ch = gafndt(pfi->name, &dtim, &dtimi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,tcur,e,&flag);
+	   if (ch==NULL) {
+	     printf("gribmap error: couldn't determine data file name for e=%d t=%d\n",e,tcur);
+	     fflush(stdout);
+	     goto err;
+	   }
+	 }
+       }
+       else {  
+	 /* only one data file to open */
+	 ch = pfi->name;
+	 tmin = 1;
+	 tmax = pfi->dnum[3];
+       }
+       
+       /* Open this GRIB file and position to start of first record (s/b subroutine) */
+       if (!quiet) printf("gribmap: scanning GRIB2 file: %s \n",ch);
+       fflush(stdout);
+       gfile = fopen(ch,"rb");
+       if (gfile==NULL) {
+	 if (pfi->tmplat) {
+	   if (!quiet) printf ("gribmap warning: could not open GRIB file: %s\n",ch);
+	   fflush(stdout);
+	   continue;
+	 }
+	 else {
+	   printf ("gribmap error: could not open GRIB file: %s\n",ch);
+	   fflush(stdout);
+	   goto err;
+	 }
+       }
+       if (pfi->tmplat) gree(ch,"f311");
+       
+       /* Loop over fields in the grib file and find matches */
+       iseek=(off_t)0;
+       record=1;
+       while (1) {
+	 /* move to next grib message in file */
+	 gaseekgb(gfile,iseek,32000,&lskip,&lgrib);
+	 if (lgrib == 0) break;    /* end loop at EOF or problem */
+	 
+	 /* read the message into memory */
+	 sz = lgrib;
+	 cgrib = (unsigned char *)galloc(sz,"cgrib2");
+	 if (cgrib == NULL) {
+	   printf("gribmap error: unable to allocate memory for record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+	 }
+	 ret = fseeko(gfile,lskip,SEEK_SET);
+	 lengrib = fread(cgrib,sizeof(unsigned char),lgrib,gfile);
+	 if (lengrib < lgrib) {
+	   printf("gribmap error: unable to read record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+	 }
+
+         /* Check for ultra long length -- which we do not yet handle */
+         if (gagby(cgrib,8,4)!=0 || gagbb(cgrib+12,0,1)!=0) {
+	   printf("gribmap error: grib2 record length too long! record %d at byte %jd\n",record,(intmax_t)iseek); 
+	   fflush(stdout);
+	   goto err;
+         }
+	 
+	 /* Get info about grib2 message */
+	 ierr = 0;
+	 ierr = g2_info(cgrib,listsec0,listsec1,&numfields,&numlocal);
+	 if (ierr) {
+	   printf("gribmap error: g2_info failed: ierr=%d\n",ierr); 
+	   fflush(stdout);
+	   goto err;
+	 }
+	 for (n=0; n<numfields; n++) {
+	   ierr = 0;
+	   ierr = g2_getfld(cgrib,n+1,unpack,expand,&gfld);
+	   if (ierr) {
+	     printf("gribmap error: g2_getfld failed: ierr=%d\n",ierr); 
+	     fflush(stdout);
+	     goto err;
+	   }
+	   
+	   /* get statistical process type from grib field */
+	   sp = g2sp(gfld);
+	   sp2 = g2sp2(gfld);
+	   
+	   /* print out useful codes from grib2 field */
+	   if (verb) g2prnt(gfld,record,n+1,sp,sp2);
+	     
+	   /* Check grid properties */
+	   rc = g2grid_check(gfld,pfi,record,n+1);
+	   if (rc) {
+	     if (verb) printf("\n");
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break; 
+	   }
+	   
+	   /* Check time values in grib field */
+	   it = g2time_check(gfld,listsec1,pfi,record,n+1,tmin,tmax);
+	   if (it==-99) {
+	     if (verb) printf("\n");
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break;
+	   }
+	   it = (it-1)*pfi->trecs;  /* number of records per time */
+	   
+	   /* Check if the variable is a match */
+	   ioff = g2var_match(gfld,pfi,sp,sp2);
+	   if (ioff==-999) {
+	     fflush(stdout);
+	     g2_free(gfld);   	   
+	     break;
+	   }
+	   if (pfi->tmplat) {
+	     /* make sure grib codes match for this ensemble */
+	     rc = g2ens_check(ens,gfld);
+	     if (rc==1) {
+	       fflush(stdout);
+	       g2_free(gfld);   	   
+	       break;
+	     }
+	   } 
+	   else {
+	     /* check if ensemble codes match */
+	     e = g2ens_match(gfld,pfi);
+	     if (e==-999) {
+	       fflush(stdout);
+	       g2_free(gfld);   	   
+	       break;
+	     }
+	   }
+	   eoff = (e-1)*pfi->dnum[3]*pfi->trecs;  /* number of records per ensemble */
+
+	   /* fill in the gribmap entry */
+	   if (verb) printf("  MATCH \n");
+	   fflush(stdout);
+	   g2fill (eoff,it+ioff,ng2elems,lskip,n+1,g2indx);
+	   g2_free(gfld); 
+
+	 }
+	 /* free memory containing grib record */
+	 gree(cgrib,"f310");
+ 	 cgrib=NULL;
+	 record++;                 /* increment grib record counter */
+	 iseek = lskip+(off_t)lgrib;   /* increment byte offset to next grib msg in file */
+
+       }  /* end of while(1) loop over all fields in the grib message*/
+
+       /* break out if not templating -- only need to scan one grib file */
+       if (!pfi->tmplat) goto done;
+
+     } /* end of while(1) loop over all grib files for a given ensemble member*/
+   } /* end of loop over ensemble members: for (e=1,ens=pfi->ens1; e<=pfi->dnum[4]; e++,ens++) */
+   } /* end of else statement for if (pfi->dnum[4]>1 && pfi->tmplat==1)  */
+   
+   if (!quiet) printf ("gribmap: reached end of files\n");
+   fflush(stdout);
+
+
+done:   
+   /* check if file not closed */
+   if (gfile!=NULL) {
+     fclose (gfile);
+     gfile=NULL;
+   }
+   
+   /* Write out the index file */
+   if (write_map) {
+     rc=wtg2map(pfi,g2indx);
+     if (rc) return (rc);
+   }
+   return(0);
+   
+err: 
+   if (g2indx->g2intpnt) gree(g2indx->g2intpnt,"f314");
+   if (g2indx) gree(g2indx,"f315");
+   if (cgrib) gree(cgrib,"f316");
+   return(1);
+ }
+
+#endif  /* matches #if GRIB2 */
+
+}
+
+
+
+/* Routine to read a GRIB header and process info */
+
+gaint gribhdr (struct grhdr *ghdr) {
+ struct dt atim;
+ unsigned char rec[50000],*ch,*gds;
+ gaint i,len ,rc,sign,mant,longflg=0;
+ off_t cpos;
+ 
+ if (fpos+(off_t)50>=flen) return(1);
+
+ /* look for data between records BY DEFAULT */ 
+ i = 0;
+ fpos += (off_t)i;
+ rc = fseeko(gfile,fpos,0);
+ if (rc) return(50);
+ ch=&rec[0];
+ rc = fread(ch,sizeof(char),4,gfile);
+ while ((fpos < flen-(off_t)4) && (i < scanlim) && 
+	!(*(ch+0)=='G' && 
+	  *(ch+1)=='R' &&
+	  *(ch+2)=='I' &&
+	  *(ch+3)=='B')) {
+   fpos++;
+   i++;
+   rc = fseeko(gfile,fpos,0);
+   if (rc) return(50);
+   rc = fread(ch,sizeof(char),4,gfile);
+   if (rc<4) return(50);
+ } 
+ 
+ if (i == scanlim) {
+   printf("grib1map error: GRIB header not found in scanning between records\n");
+   printf("                try increasing the value of the -s argument\n");
+
+   if (scaneof) return(98);
+   if (scanEOF) return(0);
+   return(52);
+ } 
+ else if (fpos == flen-(off_t)4) {
+   if (scaneof) return(98);
+   if (scanEOF) return(0);
+   return (53);
+ }
+ 
+ /* SUCCESS redo the initial read */    
+ rc = fseeko(gfile,fpos,0);
+ if (rc) return(50);
+ rc = fread(rec,1,8,gfile);
+ if (rc<8) {
+   if (fpos+(off_t)8 >= flen) return(61);
+   else return(62);
+ }
+ 
+ cpos = fpos;
+ ghdr->vers = gagby(rec,7,1);
+ if (ghdr->vers>1) {
+   printf ("grib1map error: file is not GRIB version 0 or 1, version number is %i\n",ghdr->vers);
+   if (scaneof) return(98);
+   return (99);
+ }
+ 
+ if (ghdr->vers==0) {
+   cpos += (off_t)4;
+   rc = fseeko(gfile,cpos,0);
+   if (rc) return(50);
+ } else {
+   ghdr->len = gagby(rec,4,3);
+   longflg = 0;
+   if (ghdr->len & 0x800000) longflg = 1;
+   cpos = cpos + (off_t)8;
+   rc = fseeko(gfile,cpos,0);
+   if (rc) return(50);
+ }
+ 
+ /* Get PDS length, read rest of PDS */
+ rc = fread(rec,1,3,gfile);
+ if (rc<3) return(50);
+ len = gagby(rec,0,3);
+ ghdr->pdslen = len;
+ cpos = cpos + (off_t)len;
+ rc = fread(rec+3,1,len-3,gfile);
+ if (rc<len-3) return(50);
+ 
+ /* Get info from PDS */
+ ghdr->id = gagby(rec,6,1);
+ ghdr->gdsflg = gagbb(rec+7,0,1);
+ ghdr->bmsflg = gagbb(rec+7,1,1);
+ ghdr->parm = gagby(rec,8,1);
+ ghdr->ltyp = gagby(rec,9,1);
+ ghdr->level = gagby(rec,10,2);
+ ghdr->l1 = gagby(rec,10,1);
+ ghdr->l2 = gagby(rec,11,1);
+ if (mpiflg) {                 
+   /* use initial time from the descriptor file instead of base time from grib header */
+   ghdr->btim.yr = *(pfi->abvals[3]);
+   ghdr->btim.mo = *(pfi->abvals[3]+1);
+   ghdr->btim.dy = *(pfi->abvals[3]+2);
+   ghdr->btim.hr = *(pfi->abvals[3]+3);
+   ghdr->btim.mn = *(pfi->abvals[3]+4);
+   if (no_min) ghdr->btim.mn = 0;
+ } else {
+   /* get reference (base) time */
+   ghdr->btim.yr = gagby(rec,12,1);
+   ghdr->btim.mo = gagby(rec,13,1);
+   ghdr->btim.dy = gagby(rec,14,1);
+   ghdr->btim.hr = gagby(rec,15,1);
+   ghdr->btim.mn = gagby(rec,16,1);
+   if (no_min) ghdr->btim.mn = 0;
+ }
+ if (ghdr->btim.hr>23) ghdr->btim.hr = 0;  /* Special for NCAR */
+ if (len>24) {
+   ghdr->cent = gagby(rec,24,1);
+   ghdr->btim.yr = ghdr->btim.yr + (ghdr->cent-1)*100;
+ } else {
+   ghdr->cent = -999;
+   if (!(mpiflg) || !(mfcmn.fullyear)) {
+     if (ghdr->btim.yr>49) ghdr->btim.yr += 1900;
+     if (ghdr->btim.yr<50) ghdr->btim.yr += 2000;
+   }
+ }
+ ghdr->ftu = gagby(rec,17,1);    /* forecast time unit */
+ ghdr->tri = gagby(rec,20,1);    /* time range indicator */
+ /* get P1 and P2 */
+ if (ghdr->tri==10) {
+   /* P1 occupies octets 19 and 20; product valid at reference time + P1 */
+   ghdr->p1 = gagby(rec,18,2);
+   ghdr->p2 = 0;
+ } else {
+   ghdr->p1 = gagby(rec,18,1);
+   ghdr->p2 = gagby(rec,19,1);
+ }
+ 
+ ghdr->fcstt = ghdr->p1;             /* set P1 as forecast time */
+ if (ghdr->tri>1 && ghdr->tri<6) 
+   ghdr->fcstt = ghdr->p2;           /* product considered valid at reference time + P2 */
+ if ((tauave) && (ghdr->tri==3 || ghdr->tri==7)) 
+   ghdr->fcstt = ghdr->p1;           /* Valid time for averages is beginning of period, use P1 */
+
+ /* populate a dt structure with the time to add to base time */
+ atim.yr=0; atim.mo=0; atim.dy=0; atim.hr=0; atim.mn=0;
+ if      (ghdr->ftu== 0) atim.mn = ghdr->fcstt;
+ else if (ghdr->ftu== 1) atim.hr = ghdr->fcstt;
+ else if (ghdr->ftu== 2) atim.dy = ghdr->fcstt;
+ else if (ghdr->ftu== 3) atim.mo = ghdr->fcstt;
+ else if (ghdr->ftu== 4) atim.yr = ghdr->fcstt;
+ else if (ghdr->ftu==10) atim.hr = ghdr->fcstt*3;   /* 3Hr incr */
+ else if (ghdr->ftu==11) atim.hr = ghdr->fcstt*6;   /* 6Hr incr */  
+ else if (ghdr->ftu==12) atim.hr = ghdr->fcstt*12;  /* 12Hr incr */
+ else if (ghdr->ftu==13) atim.mn = ghdr->fcstt*15;  /* 15-minute incr */
+ else if (ghdr->ftu==14) atim.mn = ghdr->fcstt*30;  /* 30-minute incr */
+ else ghdr->fcstt = -999;
+
+ /*  if notau != 0 then FORCE the valid DTG to be the base DTG */ 
+ if (notau) ghdr->fcstt = -999 ;
+ 
+ /*  add the forecast time to the time of this grib field */
+ if (ghdr->fcstt>-900) {
+   if (ghdr->tri==7)
+     timsub(&(ghdr->btim),&atim);
+   else
+     timadd(&(ghdr->btim),&atim);
+   ghdr->dtim.yr = atim.yr;
+   ghdr->dtim.mo = atim.mo;
+   ghdr->dtim.dy = atim.dy;
+   ghdr->dtim.hr = atim.hr;
+   ghdr->dtim.mn = atim.mn;
+ } else {
+   ghdr->dtim.yr = ghdr->btim.yr;
+   ghdr->dtim.mo = ghdr->btim.mo;
+   ghdr->dtim.dy = ghdr->btim.dy;
+   ghdr->dtim.hr = ghdr->btim.hr;
+   ghdr->dtim.mn = ghdr->btim.mn;
+ }
+ if (len>25) {
+   ghdr->dsf = (gafloat)gagbb(rec+26,1,15);
+   i = gagbb(rec+26,0,1);
+   if (i) ghdr->dsf = -1.0*ghdr->dsf;
+   ghdr->dsf = pow(10.0,ghdr->dsf);
+ } else ghdr->dsf = 1.0;
+ 
+ /* If it is there, get info from GDS */
+ if (ghdr->gdsflg) {
+   rc = fread(rec,1,3,gfile);
+   if (rc<3) return(50);
+   len = gagby(rec,0,3);
+   ghdr->gdslen = len;
+   cpos = cpos + (off_t)len;
+   
+   /* handle generic grid where the lon/lats are coded from the GDS */
+   gds = (unsigned char *)malloc(len+3);
+   if (gds==NULL) return(51);
+   rc = fread(gds+3,1,len-3,gfile);
+   if (rc<len-3) return(50);
+   ghdr->gtyp  = gagby(gds,4,1);
+   ghdr->gicnt = gagby(gds,6,2);
+   ghdr->gjcnt = gagby(gds,8,2);
+   ghdr->gsf1  = gagbb(gds+27,0,1);
+   ghdr->gsf2  = gagbb(gds+27,1,1);
+   ghdr->gsf3  = gagbb(gds+27,2,1);
+   free(gds);
+ } 
+ else ghdr->gdslen = 0;
+
+ /* Get necessary info about BMS if it is there */
+ if (ghdr->bmsflg) {
+   rc = fread(rec,1,6,gfile);
+   if (rc<6) return(50);
+   len = gagby(rec,0,3);
+   ghdr->bmsflg = len;
+   ghdr->bnumr = gagby(rec,4,2);
+   ghdr->bpos = (gaint)cpos+6;
+   ghdr->lbpos = cpos+(off_t)6;
+   cpos = cpos + (off_t)len;
+   rc = fseeko(gfile,cpos,0);
+ } 
+ else ghdr->bmslen = 0;
+
+ /* Get necessary info from data header */
+ rc = fread(rec,1,11,gfile);
+ if (rc<11) return(50);
+ len = gagby(rec,0,3);
+ ghdr->bdslen = len;
+ if (longflg && len<120) {   /* ecmwf hack for long records */
+   ghdr->len = (ghdr->len & 0x7fffff) * 120 - len + 4;
+   ghdr->bdslen = ghdr->len - (12 + ghdr->pdslen + ghdr->gdslen + ghdr->bmslen);
+ }
+ ghdr->iflg = gagbb(rec+3,0,2);
+ i = gagby(rec,4,2);
+ if (i>32767) i = 32768-i;
+ ghdr->bsf = pow(2.0,(gafloat)i);
+ 
+ i = gagby(rec,6,1);
+ sign = 0;
+ if (i>127) {
+   sign = 1;
+   i = i - 128;
+ }
+ mant = gagby(rec,7,3);
+ if (sign) mant = -mant;
+ ghdr->ref = (gafloat)mant * pow(16.0,(gafloat)(i-70));
+ 
+ ghdr->bnum = gagby(rec,10,1);
+ ghdr->dpos = (gaint)cpos+11;
+ ghdr->ldpos = cpos+(off_t)11;
+
+ if (ghdr->vers==0) {
+   fpos = fpos + 8 + ghdr->pdslen + ghdr->gdslen +
+     ghdr->bmslen + ghdr->bdslen;
+ } 
+ else fpos = fpos + (off_t)ghdr->len;
+ 
+ return(0);
+ 
+}
+
+/* Routine to determine the location of the GRIB record in terms of the GrADS data set
+   and fill in the proper values at the proper slot location. */
+
+gaint gribrec (struct grhdr *ghdr, struct gafile *pfi, struct gaindx *pindx, 
+	     gaint tmin, gaint tmax, gaint e) {
+ gadouble (*conv) (gadouble *, gadouble);
+ gadouble z,t,v1,delta;
+ struct gavar *pvar;
+ gaint i,ioff,iz,it,joff,nsiz,flag,eoff;
+
+ /* Verify that we are looking at the proper grid type */
+ joff =0;
+ nsiz = nrec * ng1elems ;
+ if (ghdr->iflg) {
+   if (verb) {
+     printf ("GRIB record contains harmonic or complex packing\n");
+     printf ("  Record is skipped.\n");
+     printf ("  Variable is %i\n",ghdr->parm);
+   }
+   return(10);
+ }
+ if (pfi->grbgrd==255 || pfi->grbgrd<-900) {
+   if (!ghdr->gdsflg) {
+     if (verb) {
+       printf ("GRIB record contains pre-defined grid type: "); 
+       printf ("GrADS descriptor specifies type 255\n");
+       gribpr(ghdr);
+     }
+     return(20);
+   } 
+   if ( pfi->ppflag) {
+     if ( ghdr->gicnt != 65535 && 
+	  ((ghdr->gicnt != pfi->ppisiz) || (ghdr->gjcnt != pfi->ppjsiz)) ) {
+       if (verb) {
+	 printf ("GRIB grid size does not match descriptor: "); 
+	 gribpr(ghdr);
+       }
+       return(300);
+     }
+   } else {
+     if (ghdr->gicnt != 65535 && 
+	 ((ghdr->gicnt != pfi->dnum[0]) || (ghdr->gjcnt != pfi->dnum[1]))) {
+       if (verb) {
+	 printf ("GRIB grid size does not match descriptor:");
+	 gribpr(ghdr);
+       }
+       return(301);
+     }
+   }
+ } 
+ else {
+   /* special case for GRIB grid number (dtype grib NNN) == 29 */
+   if (pfi->grbgrd==29) {
+     if (ghdr->id!=29 && ghdr->id!=30) {
+       if (verb) {
+	 printf("Record has wrong GRIB grid type: ") ; 
+	 gribpr(ghdr);
+       }
+       return(400);     
+     }
+     if (ghdr->id==29) joff = ng1elems;
+     nsiz = 2 * ng1elems ;
+   } else {
+     if (ghdr->id != pfi->grbgrd) {
+       if (verb) {
+	 printf("%s","Record has wrong GRIB grid type: "); 
+	 gribpr(ghdr);
+       }
+       return(401);     
+     }
+   }
+ }
+ 
+ /* Calculate the grid time for this record.  
+    If it is non-integer or if it is out of bounds, just return. */
+
+ /* Check for given forecast time, tauoff (the -fhr switch) */
+ if (tauflg && (ghdr->ftu==1 && ghdr->fcstt!=tauoff)) {
+   if (verb) {
+     printf("%s %d","--f-- Forecast Time does not match : ",tauoff);
+     gribpr(ghdr);
+   }
+   return(32);
+ }
+ 
+ /* Check if base time in grib record matches initial time in descriptor file (the -t0 switch) */
+ if (tau0 &&
+     ((ghdr->btim.yr != btimdd.yr) ||
+      (ghdr->btim.mo != btimdd.mo) ||
+      (ghdr->btim.dy != btimdd.dy) ||
+      (ghdr->btim.hr != btimdd.hr) ||
+      (ghdr->btim.mn != btimdd.mn))) {
+   if (verb) {
+     printf("%s","--b-- Base Time does not match Initial Time in DD: "); 
+     gribpr(ghdr);
+   }
+   return(34);
+ }
+
+ /* set threshold for time stamp matches */
+ v1 = *(pfi->abvals[3]+5);  /* v1 is non-zero if time axis unit is months */
+ if (v1>0) 
+   delta = 0.36;  /* large for monthly data, ~10 days */
+ else 
+   delta = 0.01;  /* small for minutes data, the old default */
+
+ /* Check if valid time is within grid time limits */
+ t = t2gr(pfi->abvals[3],&(ghdr->dtim));
+ if (t<(1.0-delta) || t>((gafloat)(pfi->dnum[3])+delta)) {
+   if (verb) {
+     printf("%s","----- Time out of bounds: "); 
+     gribpr(ghdr);
+   }
+   return(36);
+ }
+
+ /* Check if valid time is an integer (+/- the designated threshold) */
+ it = (gaint)(t+0.01);
+ if (fabs((gafloat)it - t) > delta) {
+   if (verb) {
+     printf("----- Time non-integral. %g %g: ",(gafloat)it,t);  
+     gribpr(ghdr);
+   }
+   return(38);
+ }
+
+ /* Check if valid time matches range of times for this file  */
+ if (it<tmin || it>tmax) {
+   if (verb) {
+     printf("----- Time out of file limits: ");  
+     gribpr(ghdr);
+   }
+   return(39);
+ }
+ it = (it-1)*pfi->trecs;
+ eoff = (e-1)*pfi->dnum[3]*pfi->trecs;  /* number of records per ensemble */
+
+ /* See if we can match up this grid with a variable in the data descriptor file */
+ pvar = pfi->pvar1;
+ i = 0;
+ flag=0;
+ while (i<pfi->vnum) {
+   if (pvar->levels>0) {      /* multi level data */
+     if (dequal(pvar->units[0],ghdr->parm,1e-8)==0 && 
+	 dequal(pvar->units[8],ghdr->ltyp,1e-8)==0) {
+       /* look for time range indicator match */
+       if (pvar->units[10] < -900 || dequal(pvar->units[10],ghdr->tri,1e-8)==0) {
+	 conv = pfi->ab2gr[2];
+	 z = conv(pfi->abvals[2],ghdr->level);
+	 if (z>0.99 && z<((gafloat)(pvar->levels)+0.01)) {
+	   iz = (gaint)(z+0.5);
+	   /* check if levels match */
+	   if (fabs(z-(gafloat)iz) < 0.01) {
+	     iz = (gaint)(z+0.5);
+	     ioff = pvar->recoff + iz - 1;
+	     gribfill (eoff,it+ioff,joff,nsiz,ghdr,pindx);
+	     flag=1;
+	     i = pfi->vnum + 1;   /* Force loop to stop */
+	   }
+	 }
+       }
+     }
+   } 
+   else {       /* sfc data */
+     if (dequal(pvar->units[0],ghdr->parm,1e-8)==0 && dequal(pvar->units[8],ghdr->ltyp,1e-8)==0) {
+       if ((pvar->units[10] < -900 && 
+	    dequal(pvar->units[9],ghdr->level,1e-8)==0) ||
+	   (pvar->units[10] > -900 && 
+	    dequal(pvar->units[9],ghdr->l1,1e-8)==0 && dequal(pvar->units[10],ghdr->l2,1e-8)==0) || 
+	   (dequal(pvar->units[10],ghdr->tri,1e-8)==0 && dequal(pvar->units[9],ghdr->level,1e-8)==0)) {
+	 ioff = pvar->recoff;
+	 gribfill (eoff,it+ioff,joff,nsiz,ghdr,pindx);
+	 i = pfi->vnum+1;  /* Force loop to stop */
+	 flag=1;
+       }
+     }
+   }
+   pvar++; i++;
+ }
+ 
+ if (flag && verb) printf("!!!!! MATCH: "); 
+ if (!flag && verb) printf("..... NOOOO: "); 
+ if (verb) gribpr(ghdr); 
+ 
+ return (flag ? 0 : 1);
+ 
+}
+
+
+/* Routine to fill in values for this record, now that we have found how it matches.  
+   We are not handling the time aspect as yet */
+
+void gribfill (gaint eoff, gaint ioff, gaint joff, gaint nsiz, struct grhdr *ghdr, struct gaindx *pindx) {
+gaint boff,koff;
+
+  koff = nsiz*(eoff+ioff) + joff;
+  if (bigflg) {
+    boff = 2*(eoff+ioff) + joff;
+    *(pindxb->bigpnt+boff) = ghdr->ldpos;
+    if (ghdr->bmsflg) *(pindxb->bigpnt+boff+1) = ghdr->lbpos;
+    boff = (eoff+ioff) + joff;
+    *(pindx->intpnt+boff) = ghdr->bnum;
+  } else {
+    *(pindx->intpnt+koff) = ghdr->dpos;
+    if (ghdr->bmsflg) *(pindx->intpnt+koff+1) = ghdr->bpos;
+    *(pindx->intpnt+koff+2) = ghdr->bnum;
+  }  
+  *(pindx->fltpnt+koff)   = ghdr->dsf;
+  *(pindx->fltpnt+koff+1) = ghdr->bsf;
+  *(pindx->fltpnt+koff+2) = ghdr->ref;
+}
+
+
+/* Routine to print out fields from the grib header */
+
+void gribpr(struct grhdr *ghdr) {
+  if (bigflg) {
+    printf ("%6i % 10ld % 3i % 1i % 5i % 4i % 4i %-5i % 10ld % 10ld % 3i  ",
+	    irec,(long)fpos,ghdr->id,ghdr->gdsflg,ghdr->bmsflg,ghdr->parm,ghdr->ltyp,
+	    ghdr->level,(long)ghdr->ldpos,(long)ghdr->lbpos,ghdr->bnum);
+  }
+  else {
+    printf ("%6i % 10ld % 3i % 1i % 5i % 4i % 4i %-5i % 10i % 10i % 3i  ",
+	    irec,(long)fpos,ghdr->id,ghdr->gdsflg,ghdr->bmsflg,ghdr->parm,ghdr->ltyp,
+	  ghdr->level,ghdr->dpos,ghdr->bpos,ghdr->bnum);
+  }
+  printf ("btim: %04i%02i%02i%02i:%02i ",ghdr->btim.yr,
+	  ghdr->btim.mo,ghdr->btim.dy,ghdr->btim.hr,ghdr->btim.mn);
+  printf ("tau: % 6i ",ghdr->fcstt);
+  printf ("dtim: %04i%02i%02i%02i:%02i ",ghdr->dtim.yr,
+	  ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,ghdr->dtim.mn);
+  printf("\n");
+}
+
+
+/* Routine to write out machine independent grib1 map file */
+
+gaint wtgmap(void) {
+gaint i,nb,bcnt,idum;
+gafloat fdum;
+unsigned char *map;
+unsigned char ibmfloat[4];
+ 
+ /* calculate the size of the version==1 index file */
+ nb = 2 + (4*4) +         /* version in byte 2, then 4 ints with number of each data type */
+   pindx->hinum*sizeof(gaint) +
+   pindx->hfnum*sizeof(gaint) +
+   pindx->intnum*sizeof(gaint) +
+   pindx->fltnum*sizeof(gafloat) ;
+ 
+ /* add additional info */
+ if (g1ver==2) {
+   nb=nb+7;      /* base time (+ sec)  for compatibility with earlier version 2 maps */
+   nb=nb+8*4;    /* grvals for time <-> grid conversion */
+ }
+
+ /* allocate space for the map */
+ map = (unsigned char *)malloc(nb);
+ if (map == NULL) {
+   fprintf(stderr,"grib1map error: memory allocation error creating the map\n");
+   return(60);
+ }
+
+ /* write out the version number and the sizes of the header and index arrays */
+ bcnt=0;
+ gapby(0,map,bcnt,1);      bcnt++  ;   /* set the first byte to 0 */
+ gapby(g1ver,map,bcnt,1);  bcnt++  ;   /* set the second byte to the version number */
+ putint(pindx->hinum,map,&bcnt);              /* # ints in header   */
+ putint(pindx->hfnum,map,&bcnt);              /* # floats in header   */
+ putint(pindx->intnum,map,&bcnt);             /* # index ints   */
+ putint(pindx->fltnum,map,&bcnt);             /* # index floats   */
+ 
+ if (g1ver==2) {
+   /* write out base time for consistency with earlier version 2 maps */
+   /* base time not needed for version 3 */
+   gapby(btimdd.yr,map,bcnt,2);  bcnt+=2 ;   /* initial year */
+   gapby(btimdd.mo,map,bcnt,1);  bcnt++  ;   /* initial month */ 
+   gapby(btimdd.dy,map,bcnt,1);  bcnt++  ;   /* initial day */
+   gapby(btimdd.hr,map,bcnt,1);  bcnt++  ;   /* initial hour */
+   gapby(btimdd.mn,map,bcnt,1);  bcnt++  ;   /* initial minute */
+   gapby(0,map,bcnt,1);          bcnt++  ;   /* initial second */
+ } 
+
+ /* write the header */
+ if (pindx->hinum) {
+   for (i=0;i<pindx->hinum;i++) {
+     idum=*(pindx->hipnt+i);
+     putint(idum,map,&bcnt);
+   }
+ }
+
+ /* write the indices */
+ for (i=0;i<pindx->intnum;i++) {
+   idum=*(pindx->intpnt+i);
+   putint(idum,map,&bcnt);
+ }
+ for (i=0;i<pindx->fltnum;i++) {
+   fdum=*(pindx->fltpnt+i);
+   rc=flt2ibm(fdum, ibmfloat); 
+   if (rc<0) return(601);
+   memcpy(&map[bcnt],ibmfloat,4); bcnt+=4;
+ }
+ 
+ if (g1ver==2) {
+   /* write out the factors for converting from grid to absolute time */ 
+   /* the conversion vals are not needed for version 3 */
+   for (i=0;i<8;i++) {
+     fdum=*(pfi->grvals[3]+i);
+     rc=flt2ibm(fdum, ibmfloat); 
+     if (rc<0) return(601);
+     memcpy(&map[bcnt],ibmfloat,4); bcnt+=4;
+   }
+ } 
+
+ /* write to the map file */
+ fwrite(map,1,bcnt,mfile);
+ free(map);
+ return(0);
+
+}
+
+/* Routine to dump a 4 byte int into a character stream */
+
+void putint(gaint dum, unsigned char *buf, gaint *off) {
+ gaint offset;
+
+ offset=*off;
+ if (dum < 0) {
+   dum=-dum;
+   gapby(dum,buf,offset,4);
+   gapbb(1,buf+offset,0,1);
+ } else {
+   gapby(dum,buf,offset,4);
+ }
+ offset+=4;
+ *off=offset;
+ 
+}
+
+
+#if GRIB2
+
+/* Routine to fill in values for grib2 record, now that we know it matches. */
+void g2fill (gaint eoff, gaint ioff, gaint ng2elems, off_t iseek, g2int fldnum, 
+		struct gag2indx *g2indx) {
+gaint joff;
+  if (g2indx->version == 2) {
+    joff = eoff+ioff;
+    ioff = (ng2elems-1)*(eoff+ioff);
+    *(g2indx->g2bigpnt+joff) = iseek;
+    *(g2indx->g2intpnt+ioff) = fldnum;
+  } else {
+    ioff = ng2elems*(eoff+ioff);
+    *(g2indx->g2intpnt+ioff+0) = (gaint)iseek;
+    *(g2indx->g2intpnt+ioff+1) = fldnum;
+  }
+}
+
+/* Routine to write out grib2 index file 
+
+     g2ver=1 : machine dependent. contains the version number, followed by 
+               the array size N, followed by the array of N numbers. 
+               All are 4-byte integers (type gaint). 
+     g2ver=2 : machine dependent. contains the version number, followed by 
+               the array size N, followed by the array of N numbers that are
+               4 byte ints, followed by an array of N numbers that are 8 byte 
+               off_t integers.
+
+     A test to see if byte-swapping is required	to read the index file is done
+     in gaddes.c, when the data descriptor file is opened. 
+*/
+
+
+gaint wtg2map(struct gafile *pfi, struct gag2indx *g2indx) {
+  FILE *mfile;
+  gaint rc;
+  
+  /* open the index file */
+  mfile = fopen(pfi->mnam,"wb");
+  if (mfile==NULL) {
+    printf ("error: Unable to open index file: %s\n",pfi->mnam);
+    fflush(stdout);
+    return(1);
+  } 
+  
+  printf("gribmap: Writing out the index file \n");
+  /* write the version number */
+  rc = fwrite(&g2indx->version, sizeof(gaint),1,mfile);
+  if (rc!=1) {
+    printf("error: Unable to write version number to index file, rc=%d \n",rc);
+    fflush(stdout);
+    return(1);
+  }  
+  /* write the array size */
+  rc = fwrite(&g2indx->g2intnum,sizeof(gaint),1,mfile);
+  if (rc!=1) {
+    printf("error: Unable to write g2intnum to index file, rc=%d \n",rc);
+    fflush(stdout);
+    return(1);
+  }  
+  /* writhe the array of index values */
+  rc = fwrite(g2indx->g2intpnt,sizeof(gaint),g2indx->g2intnum,mfile);
+  if (rc!=g2indx->g2intnum) {
+    printf("error: Unable to write g2intpnt to index file, rc=%d \n",rc);
+    fflush(stdout);
+    return(1);
+  }  
+
+  /* if version 2, write the the array of off_t values */
+  if (g2indx->version==2) {
+    rc = fwrite(g2indx->g2bigpnt,sizeof(off_t),g2indx->g2intnum,mfile);
+    if (rc!=g2indx->g2intnum) {
+      printf("error: Unable to write g2bigpnt to index file, rc=%d \n",rc);
+      fflush(stdout);
+      return(1);
+    }  
+  }
+  fclose(mfile);
+  return(0);
+  
+}
+
+/* Checks grid properties for a grib2 field. 
+   Returns 0 if ok, 1 if doesn't match descriptor */
+
+gaint g2grid_check (gribfield *gfld, struct gafile *pfi, gaint r, gaint f) {
+gaint xsize=0,ysize=0;
+
+  /* Check total number of grid points */
+  if (pfi->grbgrd==255 || pfi->grbgrd<-900) {
+    if (((pfi->ppflag) && (gfld->ngrdpts != pfi->ppisiz * pfi->ppjsiz)) ||
+        ((pfi->ppflag==0) && (gfld->ngrdpts != pfi->dnum[0] * pfi->dnum[1]))) {
+      if (verb) printf ("number of grid points does not match descriptor ");
+      return(1);
+    }
+  } 
+  /* Check nx and ny for Lat/Lon, Polar Stereographic, and Lambert Conformal grids */
+  if (pfi->ppflag) {
+    xsize = pfi->ppisiz;
+    ysize = pfi->ppjsiz;
+  } else {
+    xsize = pfi->dnum[0];
+    ysize = pfi->dnum[1];
+  }
+  if ((gaint)gfld->igdtmpl[7] != -1) {
+    if (gfld->igdtnum==0 || gfld->igdtnum==40 || gfld->igdtnum==20 || gfld->igdtnum==30) {
+      if (gfld->igdtmpl[7] != xsize) {
+	if (verb) printf ("x dimensions are not equal: nx=%d xsize=%d",(gaint)gfld->igdtmpl[7],xsize); 
+	return(1);
+      } 
+      if (gfld->igdtmpl[8] != ysize) {
+	if (verb) printf ("y dimensions are not equal: nx=%d xsize=%d",(gaint)gfld->igdtmpl[8],ysize); 
+	return(1);
+      }
+    }
+  }
+  return(0);
+}
+
+/* Checks time metadata in grib2 message. 
+   Returns integer value of time axis index if ok, -99 if not */
+gaint g2time_check (gribfield *gfld, g2int *listsec1, struct gafile *pfi, 
+		    gaint r, gaint f, gaint tmin, gaint tmax) {
+  struct dt tref,tfld,tvalid;
+  gaint it,tfield,trui_idx,endyr_idx;
+  gafloat t;
+  gadouble v1,delta;
+  /* Get reference time from Section 1 of GRIB message */
+  tref.yr = listsec1[5];
+  tref.mo = listsec1[6];
+  tref.dy = listsec1[7];
+  tref.hr = listsec1[8];
+  tref.mn = listsec1[9];
+  tfield = tfld.yr = tfld.mo = tfld.dy = tfld.hr = tfld.mn = 0;  /* initialize */
+ 	 
+  if (notau) {
+    /* use reference time as valid time */
+    tvalid.yr = tref.yr;
+    tvalid.mo = tref.mo;
+    tvalid.dy = tref.dy;
+    tvalid.hr = tref.hr;
+    tvalid.mn = tref.mn;
+  }
+  else {
+    /* For fields at a point in time (PDT<8 or PDT=15 or PDT=48) */
+    if (gfld->ipdtnum < 8 || gfld->ipdtnum==15 || gfld->ipdtnum==48) {
+      trui_idx=7; 
+      if (gfld->ipdtnum==48) trui_idx=18;
+      if      (gfld->ipdtmpl[trui_idx]== 0) tfld.mn = gfld->ipdtmpl[trui_idx+1];     
+      else if (gfld->ipdtmpl[trui_idx]== 1) tfld.hr = gfld->ipdtmpl[trui_idx+1];
+      else if (gfld->ipdtmpl[trui_idx]== 2) tfld.dy = gfld->ipdtmpl[trui_idx+1];
+      else if (gfld->ipdtmpl[trui_idx]== 3) tfld.mo = gfld->ipdtmpl[trui_idx+1];
+      else if (gfld->ipdtmpl[trui_idx]== 4) tfld.yr = gfld->ipdtmpl[trui_idx+1];	 
+      else if (gfld->ipdtmpl[trui_idx]==10) tfld.hr = gfld->ipdtmpl[trui_idx+1]*3;   /* 3Hr incr */
+      else if (gfld->ipdtmpl[trui_idx]==11) tfld.hr = gfld->ipdtmpl[trui_idx+1]*6;   /* 6Hr incr */  
+      else if (gfld->ipdtmpl[trui_idx]==12) tfld.hr = gfld->ipdtmpl[trui_idx+1]*12;  /* 2Hr incr */
+      else tfield=-99;
+      if (tfield==-99) {
+	/* use reference time as valid time */
+	tvalid = tref;
+      }
+      else {
+	/* add forecast time to reference time to get valid time */
+	timadd(&tref,&tfld);
+	tvalid = tfld;
+      }
+    }
+    /* For fields that are statistically processed over a time interval 
+       e.g. averages, accumulations, extremes, et al. */
+    else if (gfld->ipdtnum == 8 || gfld->ipdtnum==9 || gfld->ipdtnum==11 || gfld->ipdtnum==12) {
+      trui_idx=7; 
+      if      (gfld->ipdtnum==8)  endyr_idx=15;
+      else if (gfld->ipdtnum==9)  endyr_idx=22;
+      else if (gfld->ipdtnum==11) endyr_idx=18;
+      else if (gfld->ipdtnum==12) endyr_idx=17;
+
+      if (tauave==0) {
+	/* valid time is the end of the overall time interval */
+	tvalid.yr = gfld->ipdtmpl[endyr_idx];
+	tvalid.mo = gfld->ipdtmpl[endyr_idx+1];
+	tvalid.dy = gfld->ipdtmpl[endyr_idx+2];
+	tvalid.hr = gfld->ipdtmpl[endyr_idx+3];
+	tvalid.mn = gfld->ipdtmpl[endyr_idx+4];
+      }
+      else {
+	/* valid time is the beginning of the overall time interval */
+	if      (gfld->ipdtmpl[trui_idx]== 0) tfld.mn = gfld->ipdtmpl[trui_idx+1];
+	else if (gfld->ipdtmpl[trui_idx]== 1) tfld.hr = gfld->ipdtmpl[trui_idx+1];
+	else if (gfld->ipdtmpl[trui_idx]== 2) tfld.dy = gfld->ipdtmpl[trui_idx+1];
+	else if (gfld->ipdtmpl[trui_idx]== 3) tfld.mo = gfld->ipdtmpl[trui_idx+1];
+	else if (gfld->ipdtmpl[trui_idx]== 4) tfld.yr = gfld->ipdtmpl[trui_idx+1];
+	else if (gfld->ipdtmpl[trui_idx]==10) tfld.hr = gfld->ipdtmpl[trui_idx+1]*3;   /* 3Hr incr */
+	else if (gfld->ipdtmpl[trui_idx]==11) tfld.hr = gfld->ipdtmpl[trui_idx+1]*6;   /* 6Hr incr */
+	else if (gfld->ipdtmpl[trui_idx]==12) tfld.hr = gfld->ipdtmpl[trui_idx+1]*12;  /* 2Hr incr */
+	else tfield=-99;
+	if (tfield==-99) {
+	  /* unable to get forecast time, so use reference time as valid time */
+	  tvalid = tref;
+	}
+	else {
+	  /* add reference time and forecast time together to get beginnin of overall time interval */
+	  timadd(&tref,&tfld);
+	  tvalid = tfld;
+	}
+      }
+    }
+    else {
+      printf("Product Definition Template %ld not handled \n",gfld->ipdtnum);
+      return(-99);
+    }  
+  }
+  /* Check if valid time is within grid limits */
+  v1 = *(pfi->abvals[3]+5);  /* v1 is non-zero if time axis unit is months */
+  if (v1>0) 
+    delta = 0.36;  /* large for monthly data, ~10 days */
+  else 
+    delta = 0.01;  /* small for minutes data, the old default */
+  t = t2gr(pfi->abvals[3],&tvalid);
+  if (t<(1.0-delta) || t>((gafloat)(pfi->dnum[3])+delta)) {
+    if (verb) printf("valid time %4d%02d%02d%02d:%02d (t=%g) is outside grid limits",
+	   tvalid.yr,tvalid.mo,tvalid.dy,tvalid.hr,tvalid.mn,t);
+    return(-99);
+  }
+  /* Check if valid time is an integer (+/- the designated threshold) */
+  it = (gaint)(t+0.01);
+  if (fabs((gafloat)it - t) > delta) {
+    if (verb) printf("valid time %4d%02d%02d%02d:%02d (t=%g) has non-integer grid index",
+	   tvalid.yr,tvalid.mo,tvalid.dy,tvalid.hr,tvalid.mn,t);
+    return(-99);
+  }
+  /* Check if valid time matches range of times for this file  */
+  if (it<tmin || it>tmax) {
+    if (verb) printf("valid time %4d%02d%02d%02d:%02d (it=%d) is outside file limits (%d-%d)",
+	   tvalid.yr,tvalid.mo,tvalid.dy,tvalid.hr,tvalid.mn,it,tmin,tmax);
+    return(-99);
+  }
+  return (it);
+}
+
+/* Loops over variables in descriptor file, looking for match to current grib2 field. 
+   If variables match, returns offset, if not, returns -999 */
+
+gaint g2var_match (gribfield *gfld, struct gafile *pfi, gaint sp, gaint sp2) {
+  struct gavar *pvar;
+  gadouble lev1,lev2,z,ll,ul;
+  gadouble (*conv) (gadouble *, gadouble);
+  gaint rc1,rc2,rc3,rc4,rc5,rc6,lev_idx,match;
+  gaint i,ioff,iz;
+  
+  lev_idx=9;
+  if (gfld->ipdtnum==48) lev_idx=20;
+
+  /* Get first level values from grib field */
+  lev1 = scaled2dbl(gfld->ipdtmpl[lev_idx+1],gfld->ipdtmpl[lev_idx+2]);
+  /* Check if we've got info on 2nd level */
+  if (gfld->ipdtmpl[lev_idx+3] != 255) 
+    lev2 = scaled2dbl(gfld->ipdtmpl[lev_idx+4],gfld->ipdtmpl[lev_idx+5]);
+  else 
+    lev2 = -999;
+  
+  /* See if we match any variables in the descriptor file */
+  pvar = pfi->pvar1;
+  ioff = -999;
+  i = 0;
+  while (i<pfi->vnum) {
+    if (pvar->levels>0) {      
+      /* Z-varying data */
+      rc1 = (gaint)pvar->units[0]==(gaint)gfld->discipline ? 0 : 1;       /* discipline */
+      rc2 = (gaint)pvar->units[1]==(gaint)gfld->ipdtmpl[0] ? 0 : 1;       /* parameter category */
+      rc3 = (gaint)pvar->units[2]==(gaint)gfld->ipdtmpl[1] ? 0 : 1;       /* parameter number  */
+      rc4 = (gaint)pvar->units[3]==sp  ? 0 : 1;     	                  /* Statistical Process */
+      rc5 = (gaint)pvar->units[4]==sp2 ? 0 : 1;	 	                  /* Spatial Process     */
+      rc6 = (gaint)pvar->units[8]==(gaint)gfld->ipdtmpl[lev_idx] ? 0 : 1; /* LTYPE1     */
+      if (rc1==0 && rc2==0 && rc3==0 && rc4==0 && rc5==0 && rc6==0) {     /* all the above match */
+	/* get a Z value for level 1 */
+	conv = pfi->ab2gr[2];
+	z = conv(pfi->abvals[2],lev1);
+	if (z>0.99 && z<((gadouble)(pvar->levels)+0.01)) {
+	  iz = (gaint)(z+0.5);
+	  /* make sure Z value for level 1 is an integer */
+	  if (fabs(z-(gadouble)iz) < 0.01) {
+	    /* check if additional grib codes match */
+	    if (pvar->g2aflg) {
+	      if ((g2a_check(gfld,pvar))==1) {
+		ioff = pvar->recoff + iz - 1;
+		return(ioff); 
+	      }
+	    }
+	    else {
+	      /* no additional grib codes, so match is OK */
+	      ioff = pvar->recoff + iz - 1;
+	      return(ioff); 
+	    }
+	  }
+	}
+      }
+    }
+    else {       
+      /* non-Z-varying data */
+      rc1 = (gaint)pvar->units[0]==(gaint)gfld->discipline ? 0 : 1;       /* discipline */
+      rc2 = (gaint)pvar->units[1]==(gaint)gfld->ipdtmpl[0] ? 0 : 1;       /* parameter category   */
+      rc3 = (gaint)pvar->units[2]==(gaint)gfld->ipdtmpl[1] ? 0 : 1;       /* parameter number */
+      rc4 = (gaint)pvar->units[3]==sp ? 0 : 1;                            /* Statistical Process */
+      rc5 = (gaint)pvar->units[4]==sp2 ? 0 : 1;                           /* Spatial Process     */
+      rc6 = (gaint)pvar->units[8]==(gaint)gfld->ipdtmpl[lev_idx] ? 0 : 1; /* LTYPE1     */
+      if (rc1==0 && rc2==0 && rc3==0 && rc4==0 && rc5==0 && rc6==0) {     /* all the above match */
+	/* check if level value(s) match those given in descriptor file */
+	if (
+	    (pvar->units[9] < -900)                /* LVAL not given */
+	    ||  
+	    (pvar->units[10] < -900 &&             /* LVAL2 not given */
+	     dequal(pvar->units[9],lev1,1e-8)==0)                 /* and LVAL1 matches */ 
+	    ||  
+	    (pvar->units[10] > -900 &&             /* LVAL2 is given */
+	     dequal(pvar->units[9],lev1,1e-8)==0 &&               /* and LVAL1 matches */
+	     dequal(pvar->units[10],lev2,1e-8)==0)                /* and LVAL2 matches */
+	    ||
+	    (pvar->units[10] > -900 &&             /* LVAL2 is given */
+	     pvar->units[11] > -900 &&             /* LTYPE2 is given */
+	     dequal(pvar->units[9],lev1,1e-8)==0 &&               /* and LVAL1 matches */
+	     dequal(pvar->units[10],lev2,1e-8)==0 &&              /* and LVAL2 matches */
+	     dequal(pvar->units[11],gfld->ipdtmpl[lev_idx+3],1e-8)==0)   /* and LTYPE2 matches */
+	    ) { 
+	  /* check if additional grib codes match */
+	  if (pvar->g2aflg) {
+	    if ((g2a_check(gfld,pvar))==1) {
+	      ioff = pvar->recoff;
+	      return(ioff); 
+	    }
+	  }
+	  else {
+	    /* no additional grib codes, so match is OK */
+	    ioff = pvar->recoff;
+	    return(ioff);
+	  }
+	}
+      }
+    }
+    pvar++; i++;
+  }  /* end of loop over variables in descriptor file */
+  return(ioff);
+}
+
+/* check additional codes that need to be matched for certain PDTs (5, 9, and 48 for now)
+   returns 1 if match is OK, otherwise 0
+*/
+gaint g2a_check (gribfield *gfld, struct gavar *pvar) {
+  gaint match,rc1,rc2,rc3,rc4,rc5,rc6;
+  gadouble ll,ul,s1,s2,w1,w2;
+
+  match=0;
+  /* probability forecasts */
+  if (gfld->ipdtnum==5 || gfld->ipdtnum==9) {
+    ll = scaled2dbl(gfld->ipdtmpl[18],gfld->ipdtmpl[19]);  /* get lower limit */
+    ul = scaled2dbl(gfld->ipdtmpl[20],gfld->ipdtmpl[21]);  /* get upper limit */
+    if ((gaint)pvar->units[16]==(gaint)gfld->ipdtmpl[17]) {     /* probability type matches */
+      if ((gfld->ipdtmpl[17]==0 && dequal(pvar->units[17],ll,1e-8)==0) ||  /* check all cases of prob type */
+	  (gfld->ipdtmpl[17]==1 && dequal(pvar->units[17],ul,1e-8)==0) ||
+	  (gfld->ipdtmpl[17]==2 && dequal(pvar->units[17],ll,1e-8)==0 && dequal(pvar->units[18],ul,1e-8)==0) ||
+	  (gfld->ipdtmpl[17]==3 && dequal(pvar->units[17],ll,1e-8)==0) ||
+	  (gfld->ipdtmpl[17]==4 && dequal(pvar->units[17],ul,1e-8)==0))
+	match=1;
+    }
+  }
+  /* optical properties of aerosol */
+  else if (gfld->ipdtnum==48) {
+    s1 = scaled2dbl(gfld->ipdtmpl[4],gfld->ipdtmpl[5]);
+    s2 = scaled2dbl(gfld->ipdtmpl[6],gfld->ipdtmpl[7]);
+    w1 = scaled2dbl(gfld->ipdtmpl[9],gfld->ipdtmpl[10]);
+    w2 = scaled2dbl(gfld->ipdtmpl[11],gfld->ipdtmpl[12]);
+    if ((gaint)pvar->units[16]==(gaint)gfld->ipdtmpl[2]) {     /* aerosol type matches */
+      if (gfld->ipdtmpl[3]!=255) {  /* size interval type is not missing */
+	if (gfld->ipdtmpl[8]!=255) {  /* wavelength interval type is not missing */
+	  /* we must match 6 codes (size and wavelength )*/
+	  rc1 = dequal(pvar->units[17],(gadouble)gfld->ipdtmpl[3],1e-8);   /* size interval type */
+	  rc2 = dequal(pvar->units[18],s1,1e-8);                           /* size1 */
+	  rc3 = dequal(pvar->units[19],s2,1e-8);                           /* size2 */
+	  rc4 = dequal(pvar->units[20],(gadouble)gfld->ipdtmpl[8],1e-8);   /* wavelength interval type */
+	  rc5 = dequal(pvar->units[21],w1,1e-8);                           /* wavelength1 */
+	  rc6 = dequal(pvar->units[22],w2,1e-8);                           /* wavelength2 */
+	  if (rc1==0 && rc2==0 && rc3==0 && rc4==0 && rc5==0 && rc6==0)    /* all the above match */
+	    match=1;
+	}
+	else {
+	  /* we must match 3 codes (size only) */
+	  rc1 = dequal(pvar->units[17],(gadouble)gfld->ipdtmpl[3],1e-8);   /* size interval type */
+	  rc2 = dequal(pvar->units[18],s1,1e-8);                           /* size1 */
+	  rc3 = dequal(pvar->units[19],s2,1e-8);                           /* size2 */
+	  if (rc1==0 && rc2==0 && rc3==0)                                  /* all the above match */
+	    match=1;
+	}
+      }
+      else {
+	if (gfld->ipdtmpl[8]!=255) {
+	  /* we must match 3 codes (wavelength only) */
+	  rc4 = dequal(pvar->units[20],(gadouble)gfld->ipdtmpl[8],1e-8);   /* wavelength interval type */
+	  rc5 = dequal(pvar->units[21],w1,1e-8);                           /* wavelength1 */
+	  rc6 = dequal(pvar->units[22],w2,1e-8);                           /* wavelength2 */
+	  if (rc4==0 && rc5==0 && rc6==0)                                  /* all the above match */
+	    match=1;
+	}
+	else {
+	  /* only the aerosol type is available for matching; leave this as a non-match for the moment --JMA */
+	}
+      }
+    }
+  }
+  return(match);
+}
+
+/* Loops over ensembles to see if ensemble codes match current grib2 field 
+   If size of ensemble dimension is 1, no checks are done, returns e=1.
+   Returns ensemble index e if codes are present and match, -999 otherwise */
+gaint g2ens_match (gribfield *gfld, struct gafile *pfi) {
+  struct gaens *ens;
+  gaint e;
+  e=1;
+  if (pfi->dnum[4]==1) {
+    e=1;
+    return(e); 
+  }
+  else {
+    for (e=1,ens=pfi->ens1; e<=pfi->dnum[4]; e++,ens++) {
+      /* No grib codes and not an ensemble PDT */
+      if (ens->grbcode[0]==-999 && ens->grbcode[1]==-999 &&
+	  (gfld->ipdtnum!=1 && gfld->ipdtnum!=2 && gfld->ipdtnum!=11 && gfld->ipdtnum!=12)) {    
+	return(e);
+      }
+      if (ens->grbcode[0]>-900) {
+	if (ens->grbcode[1]>-900) {
+	  /* PDT 1 or 11 */
+	  if ((gfld->ipdtnum==1 || gfld->ipdtnum==11) &&
+	      ((ens->grbcode[0] == gfld->ipdtmpl[15]) && 
+	       (ens->grbcode[1] == gfld->ipdtmpl[16]))) {
+	    return(e);
+	  }
+	}
+	else {
+	  /* PDT 2 or 12 */
+	  if ((gfld->ipdtnum==2 || gfld->ipdtnum==12) &&
+	      (ens->grbcode[0] == gfld->ipdtmpl[15])) {
+	    return(e);
+	  }
+	}
+      }
+    }
+    return(-999);
+  }
+}
+
+/* Checks ensemble codes, if provided in descriptor file. 
+   Returns 0 if ok or not provided, 1 if codes don't match. */
+gaint g2ens_check (struct gaens *ens, gribfield *gfld) {
+  if (ens->grbcode[0]>-900) {
+    if (ens->grbcode[1]>-900) {
+      /* PDT 1 or 11 */
+      if ((gfld->ipdtnum==1 || gfld->ipdtnum==11) &&
+	  ((ens->grbcode[0] == gfld->ipdtmpl[15]) && 
+	   (ens->grbcode[1] == gfld->ipdtmpl[16]))) return(0);
+      else return(1);
+    }
+    else {
+      /* PDT 2 or 12 */
+      if ((gfld->ipdtnum==2 || gfld->ipdtnum==12) &&
+	  (ens->grbcode[0] == gfld->ipdtmpl[15])) return(0);
+      else return(1);
+    }
+  }
+  /* No grib codes and not an ensemble PDT */
+  if (ens->grbcode[0]==-999 && ens->grbcode[1]==-999 &&
+      (gfld->ipdtnum!=1 && gfld->ipdtnum!=2 && gfld->ipdtnum!=11 && gfld->ipdtnum!=12)) return(0);  
+  else return(1);
+}
+
+/* Gets the statistical process used to derive a variable.
+   returns -999 for variables "at a point in time" */
+gaint g2sp (gribfield *gfld) {
+  gaint sp;
+  sp = -999;
+  if (gfld->ipdtnum ==  8) sp = gfld->ipdtmpl[23];
+  if (gfld->ipdtnum ==  9) sp = gfld->ipdtmpl[30];
+  if (gfld->ipdtnum == 10) sp = gfld->ipdtmpl[24];
+  if (gfld->ipdtnum == 11) sp = gfld->ipdtmpl[26];
+  if (gfld->ipdtnum == 12) sp = gfld->ipdtmpl[25];
+  if (gfld->ipdtnum == 15) sp = gfld->ipdtmpl[15];
+  if (sp==255) sp = -999;
+  return(sp);
+}
+
+/* get the statistical process used within a spatial area (only for PDT 15) */
+gaint g2sp2(gribfield *gfld) {
+  gaint sp2;
+  sp2 = -999;
+  if (gfld->ipdtnum == 15) sp2 = gfld->ipdtmpl[16];
+  if (sp2==255) sp2 = -999;
+  return(sp2);
+}
+
+/* prints out relevant info from a grib2 record */
+void g2prnt (gribfield *gfld, gaint r, g2int f, gaint sp, gaint sp2) {
+  gaint atyp,styp,wtyp,lev_idx;
+  gadouble ll,ul,s1,s2,w1,w2;
+
+  lev_idx=9;
+  if (gfld->ipdtnum==48) lev_idx=20;
+
+  /* print record/field number */
+  printf("%d.%ld: ",r,f);
+  /* print level info */
+  if (gfld->ipdtmpl[lev_idx+1]==-127) 
+    printf("lev1=%ld ",gfld->ipdtmpl[lev_idx]); /* just print the level1 type */
+  else
+    printf("lev1=%ld,%g ",gfld->ipdtmpl[lev_idx],scaled2dbl(gfld->ipdtmpl[lev_idx+1],gfld->ipdtmpl[lev_idx+2]));
+  
+  if (gfld->ipdtmpl[lev_idx+3]<255) {
+    if (gfld->ipdtmpl[lev_idx+4]==-127) 
+      printf("lev1=%ld ",gfld->ipdtmpl[lev_idx+3]); /* just print the level2 type */
+    else
+      printf("lev2=%ld,%g ",gfld->ipdtmpl[lev_idx+3],scaled2dbl(gfld->ipdtmpl[lev_idx+4],gfld->ipdtmpl[lev_idx+5])); 
+  }
+
+  /* print additional info for probability forecasts (PDTs 5 and 9) */
+  if (gfld->ipdtnum == 5 || gfld->ipdtnum == 9) {
+    /* probability forecasts */
+    ll = scaled2dbl(gfld->ipdtmpl[18],gfld->ipdtmpl[19]);  /* get lower limit */
+    ul = scaled2dbl(gfld->ipdtmpl[20],gfld->ipdtmpl[21]);  /* get upper limit */
+    if (gfld->ipdtmpl[17]==2) {
+      printf ("a%ld,%g,%g ",gfld->ipdtmpl[17],ll,ul);
+    }
+    else if (gfld->ipdtmpl[17]==0 || gfld->ipdtmpl[17]==3) {
+      printf ("a%ld,%g ",gfld->ipdtmpl[17],ll);  
+    }
+    else if (gfld->ipdtmpl[17]==1 || gfld->ipdtmpl[17]==4) {
+      printf ("a%ld,%g ",gfld->ipdtmpl[17],ul);  
+    }
+  }
+
+  /* print additional info for PDT 48 */
+  if (gfld->ipdtnum ==48) {
+    atyp   = gfld->ipdtmpl[2];
+    styp   = gfld->ipdtmpl[3];
+    wtyp   = gfld->ipdtmpl[8];
+    s1 = scaled2dbl(gfld->ipdtmpl[4],gfld->ipdtmpl[5]);
+    s2 = scaled2dbl(gfld->ipdtmpl[6],gfld->ipdtmpl[7]);
+    w1 = scaled2dbl(gfld->ipdtmpl[9],gfld->ipdtmpl[10]);
+    w2 = scaled2dbl(gfld->ipdtmpl[11],gfld->ipdtmpl[12]);
+    if (atyp!=65535) {
+      if (styp!=255) {
+	if (wtyp!=255) {
+	  printf ("a%d,%d,%g,%g,%d,%g,%g ",atyp,styp,s1,s2,wtyp,w1,w2);
+	}
+	else {
+	  printf ("a%d,%d,%g,%g ",atyp,styp,s1,s2);
+	}
+      }
+      else {
+	if (wtyp!=255) {
+	  printf ("a%d,%d,%g,%g ",atyp,wtyp,w1,w2);
+	}
+	else {
+	  printf ("a%d ",atyp);
+	}
+      } 
+    }
+  }
+
+  /* print variable info */
+  if (sp==-999)
+    printf("var=%ld,%ld,%ld ",gfld->discipline,gfld->ipdtmpl[0],gfld->ipdtmpl[1]);
+  else {
+    if (sp2==-999)
+      printf("var=%ld,%ld,%ld,%d ",gfld->discipline,gfld->ipdtmpl[0], gfld->ipdtmpl[1],sp);
+    else 
+      printf("var=%ld,%ld,%ld,%d,%d ",gfld->discipline,gfld->ipdtmpl[0], gfld->ipdtmpl[1],sp,sp2);
+  }
+  /* print ensemble info */
+  if (gfld->ipdtnum==1 || gfld->ipdtnum==11) 
+    printf("ens=%d,%d ",(gaint)gfld->ipdtmpl[15],(gaint)gfld->ipdtmpl[16]);
+  if (gfld->ipdtnum==2 || gfld->ipdtnum==12) 
+    printf("ens=%d ",(gaint)gfld->ipdtmpl[15]);
+}
+
+void gaseekgb(FILE *lugb, off_t iseek, g2int mseek, off_t *lskip, g2int *lgrib)
+//$$$  SUBPROGRAM DOCUMENTATION BLOCK
+//
+// SUBPROGRAM: seekgb         Searches a file for the next GRIB message.
+//   PRGMMR: Gilbert          ORG: W/NP11      DATE: 2002-10-28
+//
+// ABSTRACT: This subprogram searches a file for the next GRIB Message.
+//   The search is done starting at byte offset iseek of the file referenced 
+//   by lugb for mseek bytes at a time.
+//   If found, the starting position and length of the message are returned
+//   in lskip and lgrib, respectively.
+//   The search is terminated when an EOF or I/O error is encountered.
+//
+// PROGRAM HISTORY LOG:
+// 2002-10-28  GILBERT   Modified from Iredell's skgb subroutine
+// 2009-01-16  VUONG     Changed  lskip to 4 instead of sizof(g2int)
+// 2010-03-02  Doty      Modified for off_t sized offsets to support >2GB
+//
+// USAGE:    seekgb(FILE *lugb,g2int iseek,g2int mseek,int *lskip,int *lgrib)
+//   INPUT ARGUMENTS:
+//     lugb       - FILE pointer for the file to search.  File must be
+//                  opened before this routine is called.
+//     iseek      - number of bytes in the file to skip before search
+//     mseek      - number of bytes to search at a time
+//   OUTPUT ARGUMENTS:
+//     lskip      - number of bytes to skip from the beggining of the file
+//                  to where the GRIB message starts
+//     lgrib      - number of bytes in message (set to 0, if no message found)
+//
+// ATTRIBUTES:
+//   LANGUAGE: C
+//
+//$$$
+{
+      g2int  ret;
+      g2int k,k4,nread,lim,start,vers,lengrib;
+      off_t ipos;
+      int    end;
+      unsigned char *cbuf;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+      *lgrib=0;
+      cbuf=(unsigned char *)malloc(mseek);
+      nread=mseek;
+      ipos=iseek;
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+//  LOOP UNTIL GRIB MESSAGE IS FOUND
+
+      while (*lgrib==0 && nread==mseek) {
+
+//  READ PARTIAL SECTION
+
+        ret=fseeko(lugb,ipos,SEEK_SET);
+        nread=fread(cbuf,sizeof(unsigned char),mseek,lugb);
+        lim=nread-8;
+
+//  LOOK FOR 'GRIB...' IN PARTIAL SECTION
+
+        for (k=0;k<lim;k++) {
+          gbit(cbuf,&start,(k+0)*8,4*8);
+          gbit(cbuf,&vers,(k+7)*8,1*8);
+          if (start==1196575042 && (vers==1 || vers==2)) {
+//  LOOK FOR '7777' AT END OF GRIB MESSAGE
+            if (vers == 1) gbit(cbuf,&lengrib,(k+4)*8,3*8);
+            if (vers == 2) gbit(cbuf,&lengrib,(k+12)*8,4*8);
+            ret=fseeko(lugb,ipos+(off_t)(k+lengrib-4),SEEK_SET);
+//          Hard code to 4 instead of sizeof(g2int)
+            k4=fread(&end,4,1,lugb);
+            if (k4 == 1 && end == 926365495) {      //GRIB message found
+                *lskip=ipos+(off_t)k;
+                *lgrib=lengrib;
+                break;
+            }
+          }
+        }
+        ipos=ipos+(off_t)lim;
+      }
+
+      free(cbuf);
+}
+
+#endif  /* matches #if GRIB2 */
diff --git a/src/gagmap.h b/src/gagmap.h
new file mode 100644
index 0000000..cd2da82
--- /dev/null
+++ b/src/gagmap.h
@@ -0,0 +1,128 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#ifndef DRIVER_GAGMAP
+#define WHERE extern
+#else
+#define WHERE
+#endif
+
+WHERE FILE *gfile;
+WHERE FILE *mfile;
+
+/* Following structures hold all the unpacked header info from a grib record. */
+
+struct grhdr {
+  gaint vers;
+  gaint len;
+  gaint pdslen,gdslen,bmslen,bdslen;
+  gaint id;
+  gaint gdsflg,bmsflg;
+  gaint parm;
+  gaint ltyp;
+  gaint level;
+  gaint l1,l2;
+  struct dt dtim;
+  struct dt btim;
+  gaint ftu,p1,p2,tri;
+  gaint fcstu,fcstt;
+  gaint cent;
+  gafloat dsf;
+  gaint gtyp,gicnt,gjcnt,gsf1,gsf2,gsf3;
+  gaint bnumr;
+  gaint bpos;
+  off_t lbpos;
+  gaint iflg;
+  gafloat bsf;
+  gafloat ref;
+  gaint bnum;
+  gaint dpos;
+  off_t ldpos;
+};
+
+struct gr2hdr {
+  gaint discipline,parcat,parnum;     /* Parameter identifiers */
+  gaint yr,mo,dy,hr,mn,sc;            /* Reference Time */
+  gaint sig;                          /* Significance of Reference Time */
+  gaint numdp;                        /* Number of data points */
+  gaint gdt;                          /* Grid Definition Template */
+  gaint pdt;                          /* Product Definition Template */
+  gaint drt;                          /* Data Representation Template */
+  gaint trui;                         /* Time range units indicator */
+  gaint ftime;                        /* Forecast time */
+  gaint lev1type,lev1sf,lev1;         /* Level 1 type, scale factor, scaled value */
+  gaint lev2type,lev2sf,lev2;         /* Level 2 type, scale factor, scaled value */
+  gaint enstype,enspertnum,ensderiv;  /* Ensemble metadata */
+  gaint comptype;                     /* Compression type (for JPEG2000 compression) */
+};
+
+/* ---------------- global variables ------------------- */
+ 
+WHERE off_t fpos;           /* File pointer into GRIB file */
+WHERE gaint verb;           /* Verbose option */
+WHERE gaint bigflg;         /* Use 8 byte "off_t" pointers for >2GB file sizes */
+WHERE gaint no_min;	    /* ignore minutes if == 1 */
+WHERE gaint quiet;          /* quiet option */
+WHERE gaint g1ver,g2ver;    /* version numbers */
+WHERE gaint diag;           /* Verbose option */
+WHERE gaint irec;
+WHERE gaint scanflg;        /* general scan between GRIB records ASSUMED */
+WHERE gaint scaneof;        /* option to ignore failure to find data at end of file */
+WHERE gaint scanEOF;        /* option to ignore failure to find data at end of file */
+WHERE gaint scanlim;        /* the default # of max bytes between records */
+WHERE gaint notau;          /* force time to be base time */
+WHERE gaint tauflg;         /* search for a fixed tau in filling the 4-D volume */
+WHERE gaint tauoff;         /* the fixed tau in h */
+WHERE gaint tau0;           /* set the base dtg for tau search */
+WHERE gaint forceok;        /* set the base dtg for tau search */
+WHERE gaint mpiflg;         /* Artificial initial date/time same as tau0!!*/
+WHERE gaint write_map;      /* write out the map (testing only) */
+WHERE gaint update;         /* update mode for templated files for NCEP CPC */
+WHERE struct dt btimdd;     /* initial base time from dd file */
+WHERE gaint tauave;         /* use p1 rather than p2 for time offset when tri is 3 -- 
+                               eg, when product is an average, set the valid time
+                               at the start of the averaged period rather than the end */
+WHERE gaint nrec;           /* Number of records per grid */
+WHERE gaint gtype[16];      /* Grid types for this grid set */
+WHERE struct gafile *pfi;
+
+WHERE struct gaindx *pindx;
+WHERE struct gaindxb *pindxb;
+WHERE struct dt dtim, dtimi;
+WHERE gaint cnt,rc,i,flg,iarg,tcur,told;
+WHERE char cmd[256];
+WHERE unsigned char rec[512];
+WHERE char crec[512],*ch, *ifile;
+
+WHERE gaint len, skip;
+WHERE struct grhdr ghdr;
+WHERE struct gr2hdr g2hdr;
+WHERE size_t sz;
+
+
+/* ---------------- prototypes ------------------- */
+
+extern gaint gribmap (void) ;
+extern gaint gribhdr(struct grhdr *);
+extern gaint grib2hdr(struct gr2hdr *);
+extern gaint gribrec(struct grhdr *, struct gafile *, struct gaindx *, gaint, gaint, gaint);
+extern void gribfill (gaint, gaint, gaint, gaint, struct grhdr *, struct gaindx *);
+extern void gribpr (struct grhdr *);
+
+/* function prototypes */
+gaint wtgmap(void) ;
+void  putint(gaint, unsigned char *,gaint *) ;
+#if GRIB2
+void  g2fill (gaint, gaint, gaint, off_t, g2int, struct gag2indx *);
+gaint wtg2map (struct gafile *, struct gag2indx *);
+gaint g2grid_check (gribfield *, struct gafile *pfi, gaint r, gaint f);
+gaint g2time_check (gribfield *, g2int *, struct gafile *, gaint, gaint, gaint, gaint);
+gaint g2var_match (gribfield *, struct gafile *, gaint, gaint);
+gaint g2a_check (gribfield *, struct gavar *);
+gaint g2ens_match (gribfield *, struct gafile *);
+gaint g2ens_check (struct gaens *, gribfield *);
+gaint g2sp (gribfield *);
+gaint g2sp2 (gribfield *);
+void  g2prnt (gribfield *, gaint, g2int, gaint, gaint);
+#endif
diff --git a/src/gagui.c b/src/gagui.c
new file mode 100644
index 0000000..a31a005
--- /dev/null
+++ b/src/gagui.c
@@ -0,0 +1,1258 @@
+/*
+
+    Copyright (C) 1997-2011 by Arlindo da Silva <dasilva at opengrads.org>
+    All Rights Reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; using version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, please consult  
+              
+              http://www.gnu.org/licenses/licenses.html
+
+    or write to the Free Software Foundation, Inc., 59 Temple Place,
+    Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ *   Simple GrADS GUI interface based on libsx. The script interpreter
+ *   Custom_GUI() is implemented in file "gsgui.c".
+ *
+ *   REVISION HISTORY:
+ *
+ *   22May97   da Silva   First alpha version.
+ *   09Jun97   da Silva   Fixed CB_Cmd which cause the command string
+ *                        to be destroyed on the first click;
+ *                        Fixed small bug on the CB_VAR window: now
+ *                        the user can type an expression with blanks.
+ *   10Jun97   da Silva   Added CmdWin() callback.
+ *   19Sep97   da Silva   Fixed small bug in CB_Display().
+ *   10Oct97   da Silva   Revised Default_GUI().
+ *   11Mar06   da Silva   Explicitly adopted GPL.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <time.h>
+
+#include "libsx.h"		
+#if USEFREQ == 1
+#include "freq.h"	
+#endif
+#include "grads.h"
+#include "gx.h"
+
+extern struct gacmn gcmn;
+
+#include "gagui.h"
+
+static char default_var[128];         /* default variable for display */
+
+static char last_path_open[512];      /* remember last path names */
+static char last_path_sdfopen[512];
+static char last_path_exec[512];
+static char last_path_run[512];
+
+static Widget var_window;        /* window for variable selection */
+static Widget file_window;       /* window for file selection */
+static Widget expr_window;       /* window for variable selection */
+static int hold_on = 0;          /* controls 'clear' before displaying */
+
+#define MAXROWS 256             /* for temporary mem aloocation */
+#define MAXCOLS 256
+
+#define NCMD 64             /* Sixe of command buffer */
+#define LCMD 132            /* Max length of command */
+static int  CmdWinON = 0;              /* Make sure there is only one 
+                                          Command Win up */
+static char **CmdWinList;   /* Command buffer */
+static Widget Cmd_window, CmdExpr_window, CmdList_window, CmdStr_window;
+
+/*---------------------------------------------------------------------*
+
+/*
+ * This is the GaGUI entry point. Return is thru the quit button.
+ *
+ */
+
+int gagui_main(int argc, char **argv)
+{
+
+/*
+  static char *argv[] = { "GrADS", "-bg", "gray", NULL, NULL };
+  static int   argc = 3;
+*/
+
+  char *path;
+
+  if ( gcmn.batflg ) return 0;  /* batch mode */
+
+  argc = OpenDisplay(argc, argv);
+  if (argc == FALSE)
+    return argc;
+
+/*
+  printf("Athena Widgets Support, (c) 1997 by Arlindo da Silva\n");
+  printf("Data Assimilation Office, NASA/GSFC\n\n");
+*/
+
+  /* Default path for file loads */
+  strcpy(last_path_open,"./");
+  strcpy(last_path_sdfopen,"./");
+  strcpy(last_path_exec,"./");
+  strcpy(last_path_run,"./");
+  if ( path = getenv("GADATA") ) {
+       strcpy(last_path_open,path);
+       strcpy(last_path_sdfopen,path);
+  }
+  if ( path = getenv("GASCRP") ) {
+       strcpy(last_path_exec,path);
+       strcpy(last_path_run,path);
+  }
+  default_var[0] = '\0';
+
+  /* Widget request on startup */
+  if ( path = getenv( "GAGUI" ) ) {
+
+       /* Built in default GUI interface */
+       if ( !strcmp(path,"default") ) {
+          argc = Default_GUI(argc, argv, NULL);
+          if (argc == 0) exit(0);
+          printf("     <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
+          MainLoop();
+
+       /* Widget set from a script */
+       } else {
+         if(Custom_GUI(path)) return 1;
+         MainLoop();
+       }
+
+  }
+
+}
+
+
+/* List() - Allocates memory for character list */
+char **List(int rows,int cols)
+{
+  int  i;
+  char **p;
+
+  /* Allocate pointers to rows */
+  p = ( char ** ) calloc ( rows, sizeof(char *) );
+  if(!p) {
+    printf("Error: cannot allocate memory for list (rows)\n");
+    return (char **)NULL;
+  }
+
+  /* Allocate rows and set pointers to them */
+  for(i=0; i<rows; i++) {
+      p[i] = ( char * ) calloc ( cols, sizeof(char) );
+      if(!p[i]) {
+	printf("Error: cannot allocate memory for list (cols)\n");
+	return (char **)NULL;
+      }
+  }
+
+  return (char **)p;
+}
+
+/* Free_List() - De-allocates memory for character list */
+void Free_List(char **list, int rows)
+{
+   int i;
+   for(i=0;i<rows;i++) free((char *)list[i]);
+   free((char *)list);
+}
+
+/*
+ * Return the directory component of a string or NULL if it's in
+ * the current directory.
+ */
+char *dirname(char *str)
+{
+  char *ptr, *tmp;
+
+  ptr = strrchr(str, '/');
+  if (ptr == NULL)
+    return NULL;
+
+  *ptr = '\0';
+  tmp = strdup(str);
+
+  *ptr = '/';
+
+  return tmp;
+}
+
+
+
+/*
+ *  Default_GUI() - sets up default widget set.
+ */
+
+int 
+Default_GUI(int argc, char **argv, void *data)
+{
+  Widget  root, file, print, options, quit, reinit,prompt;
+  Widget  clear, hold, prev, play, next, dim, var;
+  char str[256];
+  int i, gold, blue, gray;
+
+/*
+  argc = OpenDisplay(argc, argv);
+  if (argc == FALSE)
+    return argc;
+*/
+
+  snprintf(str,255, "GrADS Version " GRADS_VERSION "\n");
+  root = MakeLabel(str);
+
+  file = MakeMenu ( "File" );
+         MakeMenuItem(file, "Open",            CB_Load,    "open");
+         MakeMenuItem(file, "SDF Open",        CB_Load,    "sdfopen");
+         MakeMenuItem(file, "XDF Open",        CB_Load,    "xdfopen");
+         MakeMenuItem(file, "File Selection ", CB_FileSel, NULL );
+         MakeMenuItem(file, "_______________", NULL,       NULL );
+         MakeMenuItem(file, "Exec",            CB_Load,    "exec");
+         MakeMenuItem(file, "Run",             CB_Load,    "run");
+         MakeMenuItem(file, "GUI",             CB_Load,    "gui");
+         MakeMenuItem(file, "_______________", NULL,       NULL );
+         MakeMenuItem(file, "Refresh",         CB_Cmd,     "  ");
+         MakeMenuItem(file, "Reinit",          CB_Cmd,     "reinit");
+         MakeMenuItem(file, "Exit",            CB_Exit,    NULL );
+
+  print = MakeMenu ( "Print" );
+          MakeMenuItem(print, "Print",         CB_Cmd,     "print");
+          MakeMenuItem(print, "Enable  Print", CB_Load,    "enable print");
+          MakeMenuItem(print, "Disable Print", CB_Cmd,     "disabled print");
+
+  options = MakeMenu ( "Options" );
+            MakeMenuItem(options, "Shaded",      CB_Cmd, "set gxout shaded" );
+            MakeMenuItem(options, "Contour",     CB_Cmd, "set gxout contour" );
+            MakeMenuItem(options, "Grid Fill",   CB_Cmd, "set gxout grfill" );
+            MakeMenuItem(options, "Grid Values", CB_Cmd, "set gxout grid" );
+            MakeMenuItem(options, "Vector",      CB_Cmd, "set gxout vector" );
+            MakeMenuItem(options, "Streamlines", CB_Cmd, "set gxout stream" );
+            MakeMenuItem(options, "Bar Chart",   CB_Cmd, "set gxout bar" );
+            MakeMenuItem(options, "Line Plot",   CB_Cmd, "set gxout line" );
+            MakeMenuItem(options, "Wind Barbs",  CB_Cmd, "set gxout  barb" );
+            MakeMenuItem(options, "_______________",  NULL, NULL );
+            MakeMenuItem(options, "Contour Interval",  CB_CmdStr, "set cint" );
+            MakeMenuItem(options, "Draw Title", CB_CmdStr, "draw title " );
+            MakeMenuItem(options, "Color Bar",  CB_Cmd, "run cbarn" );
+
+  reinit  = MakeButton("Reinit",  CB_Cmd,     "reinit" );
+  clear  = MakeButton("Clear",  CB_Cmd,     "clear" );
+  quit   = MakeButton("Quit",   CB_Cmd,     "quit"  );
+  prompt = MakeButton("ga>",  CB_CmdWin, NULL );
+
+  dim    = MakeMenu("Dim");
+           MakeMenuItem(dim, "Longitude", CB_CmdStr, "set lon " );
+           MakeMenuItem(dim, "Latitude",  CB_CmdStr, "set lat " );
+           MakeMenuItem(dim, "Level",     CB_CmdStr, "set lev " );
+           MakeMenuItem(dim, "Time",      CB_CmdStr, "set time " );
+           MakeMenuItem(dim, "_________", NULL,      NULL );
+           MakeMenuItem(dim, "x",         CB_CmdStr, "set x " );
+           MakeMenuItem(dim, "y",         CB_CmdStr, "set y " );
+           MakeMenuItem(dim, "z",         CB_CmdStr, "set z " );
+           MakeMenuItem(dim, "t",         CB_CmdStr, "set t " );
+
+  var    = MakeButton("Var",    CB_VarSel,  NULL );
+  hold   = MakeToggle("Hold",   FALSE, NULL, CB_Toggle,  "hold" );
+  prev   = MakeButton("<<",   CB_Display, "<<" );
+  play   = MakeButton("Display",   CB_Display, "DISPLAY" );
+  next   = MakeButton(">>",   CB_Display, ">>" );
+
+
+  /* First row */
+  SetWidgetPos(file,    PLACE_UNDER, root, NO_CARE, NULL);
+  SetWidgetPos(print,   PLACE_UNDER, root, PLACE_RIGHT, file );
+  SetWidgetPos(options, PLACE_UNDER, root, PLACE_RIGHT, print );
+  SetWidgetPos(dim,     PLACE_UNDER, root, PLACE_RIGHT, options );
+  SetWidgetPos(reinit,     PLACE_UNDER, root, PLACE_RIGHT, dim);
+  SetWidgetPos(prompt,  PLACE_UNDER, root, PLACE_RIGHT, reinit );
+
+  /* Second row */
+  SetWidgetPos(hold,   PLACE_UNDER, file, NO_CARE, NULL);
+  SetWidgetPos(var,   PLACE_UNDER, file, PLACE_RIGHT, hold );
+  SetWidgetPos(prev,  PLACE_UNDER, file, PLACE_RIGHT, var );
+  SetWidgetPos(play,  PLACE_UNDER, file, PLACE_RIGHT, prev );
+  SetWidgetPos(next,  PLACE_UNDER, file, PLACE_RIGHT, play );
+  SetWidgetPos(clear, PLACE_UNDER, file, PLACE_RIGHT, next );
+  SetWidgetPos(quit,  PLACE_UNDER, file, PLACE_RIGHT, clear );
+
+  ShowDisplay();
+  
+  GetStandardColors();
+  gold = GetNamedColor("gold");
+  blue = GetNamedColor("LightSkyBlue");
+  gray = GetNamedColor("gray");
+
+  /* Color of widgets */
+  SetFgColor(root,RED);
+  SetFgColor(prompt,YELLOW);
+  SetBgColor(prompt,RED);
+
+  SetBgColor(file,blue);
+  SetBgColor(print,blue);
+  SetBgColor(options,blue);
+  SetBgColor(dim,blue);
+
+  SetBgColor(reinit,gray);
+  SetBgColor(var,gray);
+  SetBgColor(hold,gray);
+  SetBgColor(clear,gray);
+  SetBgColor(quit,gray);
+  
+  SetBgColor(prev,gold);
+  SetBgColor(play,gold);
+  SetBgColor(next,gold);
+
+  return argc;
+}
+
+/*
+ * CB_Open() - Callback function for (sdf) opening a file.  The opened file
+ *             becomes the default and the user is asked to select a
+ *             variable from the file. Unlike CB_Load(), the user must
+ *             provide the file name.
+ *
+ */
+void CB_Open(Widget w, void *data)
+{
+
+  char cmd[1024];
+  int  rc;
+
+  printf("%s\n", data); 
+  gcmn.sig = 0;
+  strncpy(cmd,data,1024);
+  rc = gacmd(cmd,&gcmn,0);
+  if(rc) Beep();
+  else if (cmpwrd("open",data)||cmpwrd("sdfopen",data)) 
+    { 
+      snprintf(cmd,1023,"set dfile %d", gcmn.fnum);
+      gcmn.sig = 0;
+      gacmd(cmd,&gcmn,0);  /* new file becomes default */
+      CB_VarSel(w, data);
+    }
+  
+}
+
+#ifndef HAVE_SIMPLEGETFILE
+char *SimpleGetFile(char *path)
+{
+#ifndef GETFILE_SHORT_PROTOTYPE
+  return GetFile("Simple file requestor", path, NULL, NULL);
+#else
+  return GetFile(path);
+#endif
+}
+#endif
+
+/*
+ * CB_Load() - Callback function for the load button.  This just calls
+ *          SimpleGetFile() to get a file name. In case of "open" or "sdfopen", 
+ *          the file becomes the default and the user is asked to select a
+ *          variable from this file.
+ */
+void CB_Load(Widget w, void *data)
+{
+  char *fname, *dname, *last_path, cmd[1024];
+  int i,rc;
+
+  if(strstr(data,"open"))         last_path = last_path_open;
+  else if(strstr(data,"sdfopen")) last_path = last_path_sdfopen;
+  else if(strstr(data,"exec"))    last_path = last_path_exec;
+  else if(strstr(data,"run"))     last_path = last_path_run;
+  else                            last_path = NULL;
+  fname = SimpleGetFile(last_path);
+
+  if(fname) 
+    {
+
+    /* save retrieved directory name for next time */
+    dname = dirname(fname);
+    if(strstr(data,"open"))           strcpy(last_path_open,dname);
+    else if(strstr(data,"sdfopen"))   strcpy(last_path_sdfopen,dname);
+    else if(strstr(data,"exec"))      strcpy(last_path_exec,dname);
+    else if(strstr(data,"run"))       strcpy(last_path_run,dname);
+    if(dname) free(dname);
+
+    snprintf(cmd,1023,"%s %s", data, fname);
+    printf("%s\n", cmd); 
+    gcmn.sig = 0;
+    rc = gacmd(cmd,&gcmn,0);
+    if(rc) Beep();
+    else if (cmpwrd("open",cmd)||cmpwrd("sdfopen",cmd)) 
+      { 
+        snprintf(cmd,1023,"set dfile %d", gcmn.fnum);
+        gcmn.sig = 0;
+        gacmd(cmd,&gcmn,0);  /* new file becomes default */
+	CB_VarSel(w, data);
+      }
+
+    free(fname);
+    }
+  else {
+    printf("%s cancelled\n", data);
+    Beep();
+  }
+
+}
+
+
+/*
+ * CB_Cmd() - Callback funtion for a generic grads command  button.
+ */
+void CB_Cmd(Widget w, void *data)
+{
+
+    char cmd[1024];   /* temp space */
+    int rc;
+    if(data) {
+      gcmn.sig = 0;
+      strncpy(cmd,data,1024); /* need this or data will be overitten */
+      printf("%s\n", cmd); 
+      rc=gacmd(cmd,&gcmn,0);
+      if(rc<0) {
+        if(GetYesNo("About to exit GrADS. Really?") == TRUE ) {
+	  gxend();
+	  exit(0);  /* not sure if needed */
+	}
+      }
+      if(rc) Beep();
+    } else {
+      Beep();
+      printf("\n    ***** GUI option not implemented yet *****\n\n");
+    }
+}
+
+
+/*
+ *  CB_CmdLine() - Callback funtion for the command line button.
+ */
+void CB_CmdLine(Widget w, void *data)
+{
+
+  char cmd[1024];
+  int rc=0;
+
+  printf("\n     <<< Enter '.' to leave the command line interface >>>\n\n");
+
+  while (rc>-1) {
+#if READLINE == 1
+    nxrdln(&cmd[0],"ga->> ");
+#else
+    nxtcmd(&cmd[0],"ga>>");
+#endif
+    if ( cmd[0] == '.' ) 
+    {
+       printf("     <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
+       return;
+    }
+    gcmn.sig = 0;
+    rc = gacmd(cmd,&gcmn,0);
+    /*    if(rc<0)
+       if(GetYesNo("About to exit GrADS. Really?") == FALSE ) rc=0;
+       */   /* Command liners know what they are doing ... */
+  }
+  gxend();
+  exit(0);  /* not sure if needed */
+
+}
+
+
+/*
+ * CB_VarSel() - Callback for selecting a variable.
+ *
+ */
+void CB_VarSel(Widget W, void *data)
+{
+   Widget w[8];
+   struct gacmn *pcm;
+   struct gafile *pfi;
+   struct gavar *pvar;
+   int i;
+   char **item_list, *var, tmp[MAXROWS];
+
+   /* Make Variable List from GrADS data structures */
+   pcm = &gcmn;
+   if (pcm->pfi1==NULL) {
+      Beep();
+      printf("No Files Open\n");
+      return;
+   }
+   pfi = pcm->pfid;
+   pvar = pfi->pvar1;
+   item_list = (char **) List(pfi->vnum+1,MAXCOLS);
+   if(!item_list) return;
+   for (i=0;i<pfi->vnum;i++) {
+     /*      printf ("    %s %i %i %s\n",
+              pvar->abbrv,pvar->levels,pvar->units[0],pvar->varnm);
+	      */
+      /* item_list[i] = pvar->abbrv; */
+     snprintf(item_list[i],255,"%12.12s  %3i  %s", 
+              pvar->abbrv, pvar->levels, pvar->varnm);
+      pvar++;
+      
+    }
+   item_list[pfi->vnum]=(char *)NULL; /* terminate list */
+
+
+    /* Creates widgets, etc... */
+  var_window = MakeWindow("Select a Variable", SAME_DISPLAY, EXCLUSIVE_WINDOW);
+
+  w[0]  = MakeLabel(pfi->title);
+  w[2]  = MakeScrollList(item_list, 500, 250, (void *)CB_VarList, item_list);
+  w[3]  = MakeLabel("GrADS Expression: ");
+  w[4]  = MakeStringEntry("", 300, (void *)CB_VarStr,         &item_list);
+  expr_window = w[4];
+  w[5]  = MakeButton("OK",         (void *)CB_VarOK,           NULL);
+  w[6]  = MakeLabel("Click on a Variable from the List or Enter an Expression");
+  w[7]  = MakeButton("Cancel",     (void *)CB_VarCancel,        &item_list);
+
+  SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE,     NULL);
+  SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE,     NULL);
+  SetWidgetPos(w[4], PLACE_UNDER, w[2], PLACE_RIGHT, w[3]);
+  SetWidgetPos(w[5], PLACE_UNDER, w[3], NO_CARE,     NULL);
+  SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
+  SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
+
+  ShowDisplay();
+  SetFgColor(w[0],BLUE);
+  SetFgColor(w[6],RED);
+
+  
+  if(default_var[0]) var = default_var;
+  else {
+         strcpy(tmp,item_list[0]);
+	 var = strtok(tmp," ");
+  }
+  SetStringEntry(expr_window, var);
+
+  MainLoop();
+  
+  SetCurrentWindow(ORIGINAL_WINDOW);
+
+  Free_List(item_list,pfi->vnum+1);
+
+}
+
+
+/*
+ * CB_VarList() - Callback routine for Clicking on variable list button
+ */
+
+
+void CB_VarList(Widget w, char *str, int index, void *data)
+{
+  char *var, cmd[1024];
+  var = strtok(str," ");
+  strcpy(default_var,var);
+  SetCurrentWindow(var_window);
+  CloseWindow();
+  if(!hold_on) CB_Cmd(w,"clear");
+  snprintf(cmd,1023,"display %s", default_var);
+  CB_Cmd(w,cmd);  /* display the variable */
+}
+
+void CB_VarStr(Widget w, char *str, int index, void *data)
+{
+  char cmd[1024];
+  strcpy(default_var,str);
+  SetCurrentWindow(var_window);
+  CloseWindow();
+  SyncDisplay();
+  if(!hold_on) CB_Cmd(w,"clear");
+  snprintf(cmd,1023,"display %s", default_var);
+  CB_Cmd(w,cmd);  /* display the variable */
+}
+
+void CB_VarOK(Widget w, void *data)
+{
+   int index=1;
+   char *str, *tmp;
+   str = GetStringEntry(expr_window);
+   if(str==NULL) {
+     Beep();
+     return;
+   }
+   CB_VarStr(w, str, index, data);
+   if(str!=NULL) free(str);
+}
+
+void CB_VarCancel(Widget w, void *data)
+{
+  SetCurrentWindow(var_window);
+  CloseWindow();
+  Beep();
+  printf("Variable selection cancelled\n");
+  return;
+
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*
+ * CB_CmdWin() - Callback for a command window.
+ *
+ */
+void CB_CmdWin(Widget W, void *data)
+{
+   Widget w[8];
+   int i;
+
+   if(CmdWinON) {
+     Beep();
+     printf("Error: Command window already up!\n");
+     return;
+   }
+
+   /* Initialize Command Win buffer */
+   CmdWinList = (char **) List(NCMD+1,LCMD);
+   if(!CmdWinList) return;
+   for(i=0;i<NCMD;i++) CmdWinList[i][0] = '\0'; 
+   CmdWinList[NCMD] = (char *) NULL;
+   strncpy(CmdWinList[0], "clear",             LCMD);
+   strncpy(CmdWinList[1], "reinit",            LCMD);
+   strncpy(CmdWinList[2], "set gxout shaded",  LCMD);
+   strncpy(CmdWinList[3], "set gxout contour", LCMD);
+   strncpy(CmdWinList[4], "print",             LCMD);
+   strncpy(CmdWinList[5], "quit",              LCMD);
+   
+
+    /* Creates widgets, etc... */
+  Cmd_window = MakeWindow("GrADS Command Window", SAME_DISPLAY, 
+                           NONEXCLUSIVE_WINDOW);
+
+  w[0]  = MakeLabel("GrADS Command Window");
+  w[1]  = MakeLabel("ga> ");
+  w[2]  = MakeStringEntry("", 450, (void *)CB_CmdWinStr, NULL);
+  CmdExpr_window = w[2];
+
+  w[3]  = MakeScrollList(CmdWinList, 500, 200, (void *)CB_CmdWinList, 
+                         CmdWinList);
+  CmdList_window = w[3];
+  w[4]  = MakeButton("OK",    (void *)CB_CmdWinOK,          NULL);
+  w[5]  = MakeButton("Clear",  (void *)CB_CmdWinClear,  NULL);
+  w[6]  = MakeButton("Classic Cmd Line",   (void *)CB_CmdLine,  NULL);
+  w[7]  = MakeButton("Quit",  (void *)CB_Cmd,  "quit");
+
+  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE,     NULL);
+  SetWidgetPos(w[2], PLACE_UNDER, w[0], PLACE_RIGHT, w[1]);
+  SetWidgetPos(w[3], PLACE_UNDER, w[1], NO_CARE,     NULL);
+  SetWidgetPos(w[4], PLACE_UNDER, w[3], NO_CARE,     NULL);
+  SetWidgetPos(w[5], PLACE_UNDER, w[3], PLACE_RIGHT, w[4]); 
+  SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
+  SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
+
+  ShowDisplay();
+
+  SetFgColor(w[0],BLUE);
+  SetFgColor(w[1],YELLOW);
+  SetBgColor(w[1],RED);
+  SetFgColor(w[4],BLUE);
+  SetFgColor(w[5],BLUE);
+  SetFgColor(w[6],BLUE);
+  SetFgColor(w[7],BLUE);
+
+  CmdWinON = 1;
+
+}
+
+
+void Add_CmdList( char *cmd )
+{
+  int i;
+  char *tmp;
+  tmp = CmdWinList[NCMD-1];
+  for(i=NCMD-1;i>0;i--) CmdWinList[i] = CmdWinList[i-1];
+  CmdWinList[0] = tmp;
+  strncpy(CmdWinList[0],cmd,LCMD);
+  ChangeScrollList(CmdList_window, CmdWinList);
+}
+
+void CB_CmdWinList(Widget w, char *str, int index, void *data)
+{
+  static time_t cur_click, last_click=0, tloc=0;
+  float tdiff;
+  char cmd[1024];
+
+  
+  cur_click = time(&tloc);
+  tdiff = (float)(cur_click - last_click);
+  strncpy(cmd,str,1024);
+  if(tdiff > 1. )  /* not a double click */
+   {
+     last_click = cur_click;
+     SetStringEntry(CmdExpr_window, cmd );
+   } 
+   else {
+     CB_Cmd(w,cmd);
+     Add_CmdList(cmd);
+     SetStringEntry(CmdExpr_window, " " );
+     last_click = 0;
+   }
+
+}
+
+void CB_CmdWinStr(Widget w, char *str, int index, void *data)
+{
+  char cmd[1024];
+  strncpy(cmd,str,1024);
+  CB_Cmd(w,cmd); 
+  Add_CmdList(cmd);
+  SetStringEntry(CmdExpr_window, " " );
+}
+
+void CB_CmdWinClear(Widget w, void *data)
+{
+  char cmd[1024] = "clear";
+  Add_CmdList(cmd);
+  CB_Cmd(w,cmd); 
+  SetStringEntry(CmdExpr_window, " " );
+}
+
+void CB_CmdWinOK(Widget w, void *data)
+{
+   int index=1;
+   char *str;
+   str = GetStringEntry(CmdExpr_window);
+   if(str==NULL) {
+     Beep();
+     return;
+   }
+   CB_CmdWinStr(w, str, index, data);
+   if(str!=NULL) free(str);
+}
+
+void CB_CmdWinDone(Widget w, void *data)
+{
+  SetCurrentWindow(Cmd_window);
+  CloseWindow();
+  printf("Command Window closed\n");
+  CmdWinON = 0;
+  Free_List(CmdWinList,NCMD+1);
+  return;
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+/*
+ * CB_Display() - Callback function for displaying the default variable.
+ *
+ */
+
+void CB_Display(Widget w, void *data)
+{
+
+    struct gacmn *pcm;
+    struct gafile *pfi;
+    int  rc, t, tbeg, tend, tlast;
+    int  v1, v2;
+    char cmd[256];
+
+    /* Any file open? */
+    pcm = &gcmn;
+    if (pcm->pfi1==NULL) {
+       Beep();
+       printf("No Files Open\n");
+       return;
+    }
+    pfi = pcm->pfid;
+
+    /* Default variable? */
+    if(!default_var[0]) {
+      Beep();
+      printf("No default variable\n");
+      return;
+    }
+
+
+    /* Just Display current variable */
+    if ( strstr(data,"display") || strstr(data,"DISPLAY") ) { 
+      if(!hold_on) CB_Cmd(w,"clear");
+      snprintf(cmd,1023,"display %s", default_var );
+      CB_Cmd(w,cmd);
+      return;
+    }
+
+
+    /* Advance time or animate... */
+
+    v1 = (int) t2gr(pfi->abvals[3],&(pcm->tmin));
+    v2 = (int) t2gr(pfi->abvals[3],&(pcm->tmax));
+    tlast = pfi->dnum[3];
+
+    /* If dimenions are not varying ... */
+    if ( v1 == v2 ) {
+
+      if ( strstr(data,"<<") ) {
+        v1--;
+	tbeg = v1;
+	tend = tbeg;
+      }
+      else if ( strstr(data,">>") ) {
+        v1++;
+	tbeg = v1;
+	tend = tbeg;
+      }
+      else if ( strstr(data,"PLAY") ) {
+	tbeg = v1; 
+	tend = tlast;
+      }
+      
+      /* time dim is varying, keep it */
+    } else {
+      tbeg = v1;
+      tend = v2;
+    }
+
+    /* make sure all is within range */
+    if(tbeg<1)      tbeg  = 1;
+    if(tbeg>tlast)  tbeg  = tlast;
+    if(tend<1)      tend  = 1;
+    if(tend>tlast)  tend = tlast;
+
+    /* Set time range and display variable */
+    snprintf(cmd,1023,"set t %d %d", tbeg, tend);
+    CB_Cmd(w,cmd);
+    if(!hold_on) CB_Cmd(w,"clear");
+
+    /* Display the variable: one frame or (continuous) animation */
+    snprintf(cmd,1023,"display %s", default_var );
+    CB_Cmd(w,cmd);
+
+    /* If we setup a time range for PLAY, restore time to what it
+       was before the animation. */
+    if(v1==v2&&strstr(data,"PLAY")) {
+       snprintf(cmd,1023,"set t %d %d", v1, v1);
+       CB_Cmd(w,cmd);
+    }
+
+}
+
+
+/*
+ * CB_Toggle() - Callback funtion for a generic toggle button.
+ */
+void CB_Toggle(Widget w, void *data)
+{
+
+  if ( strstr(data,"hold") ) {
+       hold_on = 1 - hold_on;
+       if(hold_on) printf("Hold  ON: no clear screen before display\n");
+       else        printf("Hold OFF: clear screen before display\n");
+  }
+}
+
+
+/*
+ * CB_FileSel() - Callback for selecting an already open file.
+ *
+ */
+void CB_FileSel(Widget W, void *data)
+{
+   Widget w[8];
+   struct gacmn *pcm;
+   struct gafile *pfi;
+   int j;
+   char **item_list;
+
+   /* Make File List from GrADS data structures */
+   pcm = &gcmn;
+   if (pcm->pfi1==NULL) {
+      Beep();
+      printf("No Files Open\n");
+      return;
+   } else {
+      pfi = pcm->pfi1;
+      item_list = (char **) List(MAXROWS,MAXCOLS);
+      j = 0;
+      while (pfi!=NULL && j<MAXROWS-1) {
+        snprintf(item_list[j],255,"%12s  %s", pfi->name, pfi->title);
+        pfi = pfi->pforw;
+        j++;
+      }
+      item_list[j] = (char *) NULL;
+    }
+
+  /* Creates widgets, etc... */
+  file_window = MakeWindow("Select a File", SAME_DISPLAY, EXCLUSIVE_WINDOW);
+
+  w[0]  = MakeLabel("Files Open:");
+  w[2]  = MakeScrollList(item_list, 500, 250, (void *)CB_FileList, item_list);
+  w[6]  = MakeLabel("Click on a File");
+
+  SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE,     NULL);
+  SetWidgetPos(w[6], PLACE_UNDER, w[2], NO_CARE,     NULL);
+
+  ShowDisplay();
+  SetFgColor(w[0],BLUE);
+  SetFgColor(w[6],RED);
+
+  MainLoop();
+  
+  SetCurrentWindow(ORIGINAL_WINDOW);
+
+  Free_List(item_list,MAXROWS);
+
+}
+
+
+/*
+ * CB_FileList() - Callback routine for file list.
+ */
+
+
+void CB_FileList(Widget w, char *str, int index, void *data)
+{
+  char cmd[1024];
+  SetCurrentWindow(file_window);
+  CloseWindow();
+  snprintf(cmd,1023,"set dfile %d", index+1);
+  CB_Cmd(w,cmd);  /* set file as default */
+}
+
+
+/*
+ * CB_CmdStr() - Callback funtion for a generic grads command with user input.
+ *               *** GetString() not working **** 
+*/
+void CB_CmdStrOld(Widget w, void *data)
+{
+    char cmd[1024], *str;
+
+    str = (char *) GetString(data, "");;
+    printf("after GetSTrng\n");
+    if(str!=NULL) {
+      snprintf(cmd,1023,"%s %s", data, str);
+      CB_Cmd(w,cmd);
+      free(str);
+    }
+
+}
+
+
+/*-----------------------------------------------------------------------*/
+
+void CB_CmdTextStr(Widget w, char *str, void *data)
+{
+  char cmd[1024];
+  strcpy(cmd,str);
+  CB_Cmd(w,cmd); 
+  CloseWindow();
+}
+
+void CB_TextOK(Widget w, void *data)
+{
+  char *str;
+   str = GetStringEntry(CmdStr_window);
+   if(str==NULL) {
+     return;
+   }
+   CB_CmdTextStr(w,str,data);
+}
+
+void CB_TextCancel(Widget w, void *data)
+{
+  printf("Command <%s> cancelled\n",data);
+  CloseWindow();
+  return;
+
+}
+
+/*
+ * CB_CmdText() - Callback for a command string window.
+ *                Provide our own because GetString() is not
+ *                working reliably.
+ */
+void CB_CmdStr(Widget W, void *data)
+{
+  Widget w[3], window;
+
+  /* Creates widgets, etc... */
+  window = MakeWindow(data, SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
+
+  w[0]  = MakeStringEntry(data, 200, (void *)CB_CmdTextStr, NULL);
+  w[1]  = MakeButton("OK",         (void *)CB_TextOK,       NULL);
+  w[2]  = MakeButton("Cancel",     (void *)CB_TextCancel,   data);
+
+  CmdStr_window = w[0];
+
+  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
+  SetWidgetPos(w[2], PLACE_UNDER, w[0], PLACE_RIGHT, w[1]);
+
+  ShowDisplay();
+
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*
+ * CB_Exit() - Exits GUI, well... fake it.
+ *             NOTE: not working properly yet.
+ */
+
+void CB_Exit(Widget w, void *data)
+{
+
+/*  if(GetYesNo("About to exit Graphical User Interface. Really?") == FALSE) 
+     return;
+*/
+
+  /* Get rid of GUI window */
+  CloseWindow();
+  SetCurrentWindow(ORIGINAL_WINDOW);
+ 
+}
+
+/*
+ * CB_CloseWindow - what it says.
+ */
+
+void CB_CloseWindow(Widget w, void *data)
+{
+  CloseWindow();
+  return;
+
+}
+
+
+/*----------------------- Text Viewer/Edit Widget --------------------*/
+
+/* The code below is based on xmore.c by Dominic Giampolo */
+
+void Editor_Quit(Widget foo, void *arg)
+{
+  WinInfo *wi=(WinInfo *)arg;
+
+  *(wi->num_windows) = *(wi->num_windows) - 1;
+
+  SetCurrentWindow(XtParent(XtParent(foo)));
+  CloseWindow();
+  
+  /* if (*(wi->num_windows) == 0) exit(0); */
+
+}
+
+
+/*
+ * Open a new file in the same window.
+ */
+void Editor_File(Widget foo, void *arg)
+{
+  WinInfo *wi=(WinInfo *)arg;
+  char *fname;
+
+  fname = SimpleGetFile(wi->cur_path);
+  if (fname)
+   {
+     SetTextWidgetText(wi->text_widget, fname, TRUE);
+     SetLabel(wi->label_widget, fname);
+
+     if (wi->cur_path)
+       free(wi->cur_path);
+     
+     wi->cur_path = dirname(fname);
+   }
+}
+
+
+
+#define MAXLABEL  80
+
+void make_text_viewer(char *fname, WinInfo *arg)
+{
+  Widget w[10];
+  static char dummy_label[MAXLABEL];
+  int i, width;
+  XFont xf;
+
+  for(i=0; i < MAXLABEL-1; i++)
+    dummy_label[i] = ' ';
+  dummy_label[i] = '\0';
+
+  w[0] = MakeLabel(dummy_label);
+
+/*  xf = GetWidgetFont(w[0]);
+  if (xf != NULL)
+    width = TextWidth(xf, dummy_label);
+  else */
+    width = 600;
+
+  w[1] = MakeTextWidget(fname, TRUE, FALSE, width, 400);
+  w[2] = MakeButton("Open", Editor_File, arg);
+  w[3] = MakeButton("Quit", Editor_Quit, arg);
+  
+  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
+  SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
+  SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
+  
+  AttachEdge(w[0], RIGHT_EDGE,  ATTACH_LEFT);
+  AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
+  
+  AttachEdge(w[1], LEFT_EDGE,   ATTACH_LEFT);
+  AttachEdge(w[1], RIGHT_EDGE,  ATTACH_RIGHT);
+  AttachEdge(w[1], TOP_EDGE,    ATTACH_TOP);
+  AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
+  
+  AttachEdge(w[2], LEFT_EDGE,   ATTACH_LEFT);
+  AttachEdge(w[2], RIGHT_EDGE,  ATTACH_LEFT);
+  AttachEdge(w[2], TOP_EDGE,    ATTACH_BOTTOM);
+  AttachEdge(w[2], BOTTOM_EDGE, ATTACH_BOTTOM);
+
+  AttachEdge(w[3], LEFT_EDGE,   ATTACH_LEFT);
+  AttachEdge(w[3], RIGHT_EDGE,  ATTACH_LEFT);
+  AttachEdge(w[3], TOP_EDGE,    ATTACH_BOTTOM);
+  AttachEdge(w[3], BOTTOM_EDGE, ATTACH_BOTTOM);
+
+  arg->text_widget  = w[1];
+  arg->label_widget = w[0];
+
+  ShowDisplay();
+
+  SetLabel(w[0], fname);   /* set the real filename */
+}
+
+
+void make_text_editor(char *fname, WinInfo *arg)
+{
+  Widget w[10];
+  static char dummy_label[MAXLABEL];
+  int i, width;
+  XFont xf;
+
+  for(i=0; i < MAXLABEL-1; i++)
+    dummy_label[i] = ' ';
+  dummy_label[i] = '\0';
+
+  w[0] = MakeLabel(dummy_label);
+
+/*  xf = GetWidgetFont(w[0]);
+  if (xf != NULL)
+    width = TextWidth(xf, dummy_label);
+  else */
+    width = 600;
+
+  w[1] = MakeTextWidget(fname, TRUE, TRUE, width, 400);
+  w[2] = MakeButton("Open", Editor_File, arg);
+  w[3] = MakeButton("Save", NULL, arg);
+  w[4] = MakeButton("Save as", NULL, arg);
+  w[5] = MakeButton("Exec", NULL, arg);
+  w[6] = MakeButton("Run", NULL, arg);
+  w[7] = MakeButton("GUI", NULL, arg);
+  w[8] = MakeButton("Quit", Editor_Quit, arg);
+  
+  SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
+  SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
+  SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
+  SetWidgetPos(w[4], PLACE_UNDER, w[1], PLACE_RIGHT, w[3]);
+  SetWidgetPos(w[5], PLACE_UNDER, w[1], PLACE_RIGHT, w[4]);
+  SetWidgetPos(w[6], PLACE_UNDER, w[1], PLACE_RIGHT, w[5]);
+  SetWidgetPos(w[7], PLACE_UNDER, w[1], PLACE_RIGHT, w[6]);
+  SetWidgetPos(w[8], PLACE_UNDER, w[1], PLACE_RIGHT, w[7]);
+  
+  AttachEdge(w[0], RIGHT_EDGE,  ATTACH_LEFT);
+  AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
+  
+  AttachEdge(w[1], LEFT_EDGE,   ATTACH_LEFT);
+  AttachEdge(w[1], RIGHT_EDGE,  ATTACH_RIGHT);
+  AttachEdge(w[1], TOP_EDGE,    ATTACH_TOP);
+  AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
+  
+  for(i=2;i<=8;i++) {
+     AttachEdge(w[i], LEFT_EDGE,   ATTACH_LEFT);
+     AttachEdge(w[i], RIGHT_EDGE,  ATTACH_LEFT);
+     AttachEdge(w[i], TOP_EDGE,    ATTACH_BOTTOM);
+     AttachEdge(w[i], BOTTOM_EDGE, ATTACH_BOTTOM);
+  }
+
+  arg->text_widget  = w[1];
+  arg->label_widget = w[0];
+
+  ShowDisplay();
+
+  SetLabel(w[0], fname);   /* set the real filename */
+}
+
+
+/*
+ * CB_Browse() - Text viewer callback. Ideal for help files.
+ *
+ */
+
+void CB_Browse(Widget w, void *data)
+{
+
+  char *fname;
+  int  num_windows=1;
+  Widget this;
+  WinInfo *wi;
+
+
+  fname = (char *) data;
+  if ( !strcmp(fname,"NULL") ) fname = SimpleGetFile(NULL);
+  if ( !fname ) return;
+
+  this = MakeWindow("GrADS Text Viewer", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
+  if ( w == NULL ) return;
+
+  wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
+  if (wi == NULL) return;
+     
+  wi->num_windows = &num_windows;
+  wi->cur_path = dirname(fname);
+     
+  make_text_viewer(fname, wi);
+
+}
+
+void CB_Edit(Widget w, void *data)
+{
+
+  char *fname;
+  int  num_windows=1;
+  Widget this;
+  WinInfo *wi;
+
+  fname = (char *)data;
+  if ( !strcmp(fname,"NULL") ) fname = SimpleGetFile(NULL);
+  if ( !fname ) return;
+
+  this = MakeWindow("GrADS Text Editor", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
+  if ( w == NULL ) return;
+
+  wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
+  if (wi == NULL) return;
+     
+  wi->num_windows = &num_windows;
+  wi->cur_path = dirname(fname);
+     
+  make_text_editor(fname, wi);
+
+}
+
+
diff --git a/src/gagui.h b/src/gagui.h
new file mode 100644
index 0000000..eb1628e
--- /dev/null
+++ b/src/gagui.h
@@ -0,0 +1,69 @@
+/*
+
+    Copyright (C) 1997-2011 by Arlindo da Silva <dasilva at opengrads.org>
+    All Rights Reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; using version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, please consult  
+              
+              http://www.gnu.org/licenses/licenses.html
+
+    or write to the Free Software Foundation, Inc., 59 Temple Place,
+    Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include "libsx.h"
+
+int init_display(int argc, char **argv, void *data);
+int Custom_GUI( char *fname );
+int gagui_main(int argc, char **argv);
+
+/* callback protos */
+void CB_Exit       (Widget w, void *data);
+void CB_CloseWindow(Widget w, void *data); 
+void CB_Open       (Widget w, void *data);
+void CB_Load       (Widget w, void *data);
+void CB_Cmd        (Widget w, void *data);
+void CB_CmdStr     (Widget w, void *data);
+void CB_CmdLine    (Widget w, void *data);
+void CB_Display    (Widget w, void *data);
+void CB_Toggle     (Widget w, void *data);
+
+void CB_VarSel     (Widget w, void *data);
+void CB_VarOK      (Widget w, void *data);
+void CB_VarCancel  (Widget w, void *data);
+void CB_VarList    (Widget w, char *str, int index, void *data);
+void CB_VarStr     (Widget w, char *str, int index, void *data);
+
+void CB_CmdWin     (Widget w, void *data);
+void CB_CmdWinOK   (Widget w, void *data);
+void CB_CmdWinClear (Widget w, void *data);
+void CB_CmdWinDone (Widget w, void *data);
+void CB_CmdWinList (Widget w, char *str, int index, void *data);
+void CB_CmdWinStr  (Widget w, char *str, int index, void *data);
+
+void CB_FileSel    (Widget w, void *data);
+void CB_Browse     (Widget w, void *data);
+void CB_Edit       (Widget w, void *data);
+void CB_FileList   (Widget w, char *str, int index, void *data);
+
+/* kk --- 020619 added List and Free_List --- kk */
+char **List(int rows,int cols);
+void Free_List(char **list, int rows);
+/* kk --- 020619 added List and Free_List --- kk */
+typedef struct wininfo
+{
+  Widget window, text_widget, label_widget;
+  int *num_windows;
+  char *cur_path;
+}WinInfo;
diff --git a/src/gagx.c b/src/gagx.c
new file mode 100644
index 0000000..ddb64d7
--- /dev/null
+++ b/src/gagx.c
@@ -0,0 +1,7349 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "grads.h"
+#include "gx.h"
+#include "wx.h"
+
+#if GEOTIFF==1
+#include "xtiffio.h"
+#include "geotiffio.h"
+#include "geotiff.h"
+#include "geokeys.h"
+#include "geo_normalize.h"
+#endif
+
+void gatmlb (struct gacmn *);    /* time label*/
+static char pout[256];           /* Build error msgs here */
+static struct mapprj mpj;        /* Common map projection structure */
+static gadouble wxymin,wxymax;   /* wx symbol limits */
+#if USESHP==1
+gaint s2shpwrt (SHPHandle, DBFHandle, struct dbfld *);
+gaint gxshplin (SHPHandle, DBFHandle, struct dbfld *);
+gaint gxclvert(FILE *);
+static struct dbfld *dbanch=NULL;  /* Anchor for shapefile data base fields */
+static struct dbfld *dblast=NULL;  /* Last dbfld struct in chain */
+#endif
+
+/* Current I and J axis translation routines for grid to absolute
+   for use by gaconv */
+
+/* A note:  the conversion routines normally handle grid
+   coordinates relative to the file (for convenience).
+   But the graphics routines normally use grid coordinates
+   with respect to the grid being worked with (ie, values
+   1 to n).  Thus the gaconv routine handles this translation
+   with the ioffset and joffset values.  */
+
+static gadouble (*iconv) (gadouble *, gadouble);
+static gadouble (*jconv) (gadouble *, gadouble);
+static gadouble *ivars, *jvars;
+static gadouble ioffset, joffset;
+static gadouble idiv, jdiv;
+
+void gagx (struct gacmn *pcm) {
+  gxstrt (pcm->xsiz,pcm->ysiz,pcm->batflg,pcm->hbufsz);
+  pcm->pass = 0;
+  pcm->ccolor = -9;
+  pcm->cint = 0.0;
+  pcm->cstyle = -9;
+  pcm->cthick = 3;
+  pcm->shdcnt = 0;
+  pcm->cntrcnt = 0;
+  pcm->lastgx = 0;
+  pcm->xdim = -1;
+  pcm->ydim = -1;
+  pcm->xgr2ab = NULL;
+  pcm->ygr2ab = NULL;
+  pcm->xab2gr = NULL;
+  pcm->yab2gr = NULL;
+}
+
+gaint rcols[13] = {9,14,4,11,5,13,3,10,7,12,8,2,6};
+
+/* Figure out which graphics routine to call.  Use the first
+   grid hung off gacmn to determine whether we are doing
+   a 0-D, 1-D, or 2-D output.    */
+
+void gaplot (struct gacmn *pcm) {
+struct gagrid *pgr;
+struct gastn *stn;
+gaint proj;
+
+  pcm->relnum = pcm->numgrd;
+  proj = pcm->mproj;
+  if (pcm->mproj>1 && (pcm->xflip || pcm->yflip)) pcm->mproj = 1;
+
+  if (pcm->gout0==1) gastts(pcm);           /* gxout stat     */
+  else if (pcm->gout0==2) gadprnt(pcm);     /* gxout print    */
+  else if (pcm->gout0==3) gaoutgds(pcm);    /* gxout writegds */
+  else {
+    /*  If statflg, produce gxout-stat output for all displays  */
+    if (pcm->statflg) gastts(pcm);
+  
+    /* output is a grid */
+    if (pcm->type[0] == 1) {
+      pgr = pcm->result[0].pgr;
+      if (pgr->idim==-1) {                                     /* 0-D */
+	if (pcm->gout2a == 7) gafwrt (pcm);
+	else if (pcm->gout2a == 12) {
+	  gaprnt (0,"Invalid dimension environment for GeoTIFF: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else if (pcm->gout2a == 13) {
+	  gaprnt (0,"Invalid dimension environment for KML: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else if (pcm->gout2a == 15) {
+	  gaprnt (0,"Invalid dimension environment for Shapefile: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else {
+	  if (pgr->umin==1)
+	    snprintf(pout,255,"Result value = %g \n",pgr->rmin);
+	  else
+	    snprintf(pout,255,"Result value = %g \n",pcm->undef);
+	  gaprnt (2,pout);
+	}
+      }
+      else if (pgr->jdim==-1) {                                /* 1-D */
+	if (pcm->gout2a==7) gafwrt (pcm);
+	else if (pcm->gout2a == 12) {
+	  gaprnt (0,"Invalid dimension environment for GeoTIFF: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else if (pcm->gout2a == 13) {
+	  gaprnt (0,"Invalid dimension environment for KML: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else if (pcm->gout2a == 15) {
+	  gaprnt (0,"Invalid dimension environment for Shapefile: \n");
+	  gaprnt (0,"  Longitude and Latitude must be varying \n");
+	}
+	else if (pcm->gout2b==5 && pcm->numgrd>1) gascat(pcm);
+	else if (pcm->gout1==1) gagrph(pcm,0);
+	else if (pcm->gout1==2) gagrph(pcm,1);
+	else if (pcm->gout1==3) gagrph(pcm,2);
+	else galfil(pcm);
+      }
+      else {                                                  /* 2-D */
+	if (pcm->numgrd==1) {
+	  if (pcm->gout2a == 1) gacntr (pcm,0,0);         /* contour */
+	  else if (pcm->gout2a ==  2) gacntr (pcm,1,0);   /* shaded */
+	  else if (pcm->gout2a ==  3) gaplvl (pcm);       /* grid */
+	  else if (pcm->gout2a ==  6) gafgrd (pcm);       /* fgrid */
+	  else if (pcm->gout2a ==  7) gafwrt (pcm);       /* fwrite */
+	  else if (pcm->gout2a == 10) gacntr (pcm,2,0);   /* grfill */
+	  else if (pcm->gout2a == 12) gagtif (pcm,0);     /* geotiff */
+	  else if (pcm->gout2a == 13 && pcm->kmlflg==1) gagtif (pcm,1);  /* kml image output */
+	  else if (pcm->gout2a == 13 && pcm->kmlflg>1)  gakml (pcm);     /* kml contours or polygons */
+	  else if (pcm->gout2a == 14) gacntr (pcm,3,0);   /* imap */
+	  else if (pcm->gout2a == 15) gashpwrt (pcm);     /* shapefile */
+	  else if (pcm->gout2a == 16) gacntr (pcm,4,0);   /* gxshad2   */
+	  else if (pcm->gout2a == 17) gacntr (pcm,5,0);   /* gxshad2b  */
+	  else {
+	    gaprnt (0,"Internal logic error: invalid gout2a value\n");
+            return;
+          }
+	} 
+	else {
+	  if (pcm->gout2b == 3) gaplvl (pcm);
+	  else if (pcm->gout2b == 4 ) gavect (pcm,0);
+	  else if (pcm->gout2b == 5 ) gascat (pcm);
+	  else if (pcm->gout2b == 8 ) gastrm (pcm);
+	  else gavect (pcm,1);
+	}
+      }
+    }
+    else {
+    /* Output is station data */
+      stn = pcm->result[0].stn;
+      if (stn->idim==0 && stn->jdim==1) {
+	if (pcm->goutstn==1 || pcm->goutstn==2 || pcm->goutstn==6) gapstn (pcm);
+	else if (pcm->goutstn==3) gafstn(pcm);
+	else if (pcm->goutstn==4) gapmdl (pcm);
+	else if (pcm->goutstn==7) gasmrk (pcm);
+	else if (pcm->goutstn==8) gastnwrt (pcm);
+	else if (pcm->goutstn==9) gashpwrt (pcm);   /* shapefile*/
+	else gawsym (pcm);
+      }
+      else if (stn->idim==2 && stn->jdim == -1) gapprf (pcm);
+      else if (stn->idim==3 && stn->jdim == -1) gatser (pcm);
+      else gaprnt (0,"Invalid station data dimension environment\n");
+    }
+  }
+  pcm->mproj = proj;
+}
+
+void gawgdsval(FILE* outfile, gafloat *val) {
+  if (BYTEORDER != 1) {  /* always write big endian for the GDS */
+    gabswp(val, 1);
+  }
+  fwrite(val, sizeof(gafloat), 1, outfile);
+}
+
+void gawgdstime(FILE* outfile, gadouble *val) {
+  snprintf(pout,255, "pre-byteswapped time: %g", *val); gaprnt(0, pout);
+  if (BYTEORDER != 1) {  /* always write big endian for the GDS */
+    ganbswp((char*)val, sizeof(gadouble));
+  }
+  snprintf(pout,255, "byteswapped time: %g", *val); gaprnt(0, pout);
+  fwrite(val, sizeof(gadouble), 1, outfile);
+}
+
+
+/* Writes station data out to a file as a DODS sequence */
+void gaoutgds (struct gacmn *pcm) {
+
+  const char startrec[4] = {0x5a, 0x00, 0x00, 0x00};
+  const char stnidlen[4] = {0x00, 0x00, 0x00, 0x08};
+  const char endrec[4]   = {0xa5, 0x00, 0x00, 0x00};
+  
+  struct garpt **currpt;
+  struct garpt *ref, *levelref;
+  gadouble coardstime;
+  gafloat outFloat;
+  gaint i, numvars, retval, levelstart, numreps;
+  gaint *varlevels;
+  char *sendstnid, *sendlat, *sendlon, *sendlev, *sendtime, *senddep, *sendind;
+  char *sendoptions;
+  FILE *outfile;
+  size_t sz;
+
+  if (pcm->wgds->fname == NULL) {
+    gaprnt(0, "error: no file specified (use \"set writegds\").\n");
+    return;
+  }
+  outfile = fopen(pcm->wgds->fname, "ab");
+  if (outfile == NULL) {
+    gaprnt(0, "error: WRITEGDS unable to open ");
+    gaprnt(0, pcm->wgds->fname);
+    gaprnt(0, " for write\n");
+    return;
+  } 
+  gaprnt(0, "got options and opened file\n");
+
+  if (pcm->wgds->opts == NULL) {
+    gaprnt(0, "No options specified. Defaulting to full output (\"sxyztdi\").\n");
+    sendoptions = "sxyztdi";
+  } else {
+    sendoptions = pcm->wgds->opts;
+  }
+
+  if (strchr(sendoptions, 'f')) {
+    /* Write a DODS End-Of-Sequence marker to indicate to the client 
+     *  that there is no more data. This is separate from gaoutgds() so 
+     *  that time loops can be written as a single sequence.
+     */
+    gaprnt(0, "Finishing sequence:\n");
+    gaprnt(0, "EOS\n");
+    fwrite(endrec, sizeof(char), 4, outfile);
+    fclose(outfile);
+    return;
+  }
+
+  sendstnid = strchr(sendoptions, 's');
+  sendlon = strchr(sendoptions, 'x');
+  sendlat = strchr(sendoptions, 'y');
+  sendlev = strchr(sendoptions, 'z');
+  sendtime = strchr(sendoptions, 't');
+  senddep = strchr(sendoptions, 'd');
+  sendind = strchr(sendoptions, 'i');
+
+  numvars = pcm->numgrd;
+  sz = sizeof(struct garpt *) * numvars;
+  currpt = (struct garpt **)galloc(sz,"currpt");
+  sz = sizeof(gaint) * numvars;
+  varlevels = (gaint *)galloc(sz,"varlevels");
+  if (currpt == NULL || varlevels == NULL) {
+    gaprnt(0, "error: memory allocation failed\n");
+    fclose(outfile);
+    return;
+  }
+  for (i = 0; i < numvars; i++) {
+    varlevels[i] =  pcm->result[i].stn->pvar->levels;
+    currpt[i] =  pcm->result[i].stn->rpt;
+  }
+
+  /* set levelstart to index of first level-dependent variable.
+   * if none is found, levelstart = numvars (this is used below)  */
+  levelstart = 0;
+  while (varlevels[levelstart] == 0 && levelstart < numvars) {
+    levelstart++;
+  }
+
+  retval = 0;
+  numreps = 0;
+
+  /* write reports */
+  while (currpt[0]) {
+    ref = currpt[0];
+    coardstime = ref->tim; /* change to meaningful conversion */
+
+    gaprnt(0, "SOI ");
+    fwrite(startrec, sizeof(char), 4, outfile);
+
+    gaprnt(0, ">>\t");
+
+    if (sendstnid) {
+      snprintf(pout,255, "stnid: %.8s  ", ref->stid); gaprnt(0, pout);
+      fwrite(stnidlen, sizeof(char), 4, outfile);
+      fwrite(&(ref->stid), sizeof(char), 8, outfile);
+    }
+    if (sendlon) {
+      snprintf(pout,255, "lon: %f  ", ref->lon); gaprnt(0, pout);
+      outFloat = ref->lon;
+      gawgdsval(outfile, &outFloat);
+    } 
+    if (sendlat) {
+      snprintf(pout,255, "lat: %f  ", ref->lat); gaprnt(0, pout);
+      outFloat = ref->lat;
+      gawgdsval(outfile, &outFloat);
+    }
+    if (sendtime) {
+      snprintf(pout,255, "time: %f  ", coardstime); gaprnt(0, pout);
+      gawgdstime(outfile, &coardstime);
+    }
+    gaprnt(0, "\n\t");
+
+    /* level independent data */
+    /* write data value and move ptr to next report simultaneously */
+    for (i = 0; i < numvars; i++) {
+      if (varlevels[i]) continue;
+      if (currpt[i] == NULL || 
+	  currpt[i]->lat != ref->lat ||
+	  currpt[i]->lon != ref->lon ||
+	  currpt[i]->tim != ref->tim) {
+	gaprnt(0, "error: bad structure in result\n");
+	retval = 1;
+	goto cleanup;
+      }
+      if (sendind) {
+	snprintf(pout,255, "[%s: %f]  ", 
+		pcm->result[i].stn->pvar->abbrv, currpt[i]->val); 
+	gaprnt(0, pout);
+	outFloat = currpt[i]->val;
+	gawgdsval(outfile, &outFloat);
+      }
+      currpt[i] = currpt[i]->rpt;
+    }
+
+    /* level dependent data */
+    /* write data for z-levels until we hit a new lat/lon/time */
+    if (levelstart < numvars) { /* if there are level-dep vars */
+      while (currpt[levelstart]&& /* and there are still more reports */
+	     ref->lat == currpt[levelstart]->lat && /* and we haven't hit a  */
+	     ref->lon == currpt[levelstart]->lon && /* new lat/lon/time */
+	     ref->tim == currpt[levelstart]->tim) { 
+	
+	levelref = currpt[levelstart];
+	
+	gaprnt(0, "\n\tSOI ");
+	fwrite(startrec, sizeof(char), 4, outfile);
+	
+	if (sendlev) {
+	  snprintf(pout,255, "lev: %f  ", levelref->lev); gaprnt(0, pout);
+	  outFloat = levelref->lev;
+	  gawgdsval(outfile, &outFloat);
+	}
+	/* write data value and move ptr to next report simultaneously */
+	for (i = levelstart; i < numvars; i++) {
+	  if (!varlevels[i]) continue;
+	  if (currpt[i] == NULL ||
+	      currpt[i]->lat != ref->lat ||
+	      currpt[i]->lon != ref->lon ||
+	      currpt[i]->tim != ref->tim ||
+	      currpt[i]->lev != levelref->lev) {
+	    gaprnt(0, "error: bad structure in result\n");
+	    retval = 1;
+	    goto cleanup;
+	  }
+	  if (senddep) {
+	    snprintf(pout,255, "[%s: %f]  ", pcm->result[i].stn->pvar->abbrv, 
+		    currpt[i]->val); gaprnt(0, pout);
+	    outFloat = currpt[i]->val;
+	    gawgdsval(outfile, &outFloat);
+	  }
+	  currpt[i] = currpt[i]->rpt;
+	}
+      }
+      gaprnt(0, "\n\tEOS ");
+      fwrite(endrec, sizeof(char), 4, outfile);
+    } 
+    
+    gaprnt(0, "\n");
+    numreps++;
+  }
+
+  /* don't write the final EOS, so that time loops can be concatenated
+   * as a single sequence.  */
+  /*    gaprnt(0, "EOS\n"); */
+  /*    fwrite(endrec, sizeof(char), 4, outfile); */
+
+  snprintf(pout,255, "WRITEGDS: %d reports x %d vars written as %d records\n",
+	  pcm->result[0].stn->rnum, numvars, numreps); gaprnt(0, pout);
+
+cleanup:
+  fclose(outfile);
+  gree(varlevels,"f293");
+  gree(currpt,"f294");
+  return;
+}
+
+
+void gadprnt (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt;
+struct gagrid *pgr;
+gadouble *gr;
+gaint siz,i,j,k,lnum;
+char *gru;
+
+  if (pcm->type[0] == 1) {          
+    /* Data type grid */
+    pgr = pcm->result[0].pgr;
+    siz = pgr->isiz*pgr->jsiz;
+    snprintf(pout,255,"Printing Grid -- %i Values -- Undef = %g\n", siz, pcm->undef);
+    gaprnt(2,pout);
+    gr  = pgr->grid;
+    gru = pgr->umask;
+    lnum = 0;
+    for (i=0; i<siz; i++) {
+      if (pcm->prstr) {
+        if (*gru==0 && pcm->prudef) {
+          pout[0]='U'; pout[1]='n'; pout[2]='d'; pout[3]='e'; pout[4]='f'; pout[5]='\0';
+        } 
+	else if (*gru==0) {
+          snprintf(pout,255,pcm->prstr,pcm->undef);
+	}
+	else {
+          snprintf(pout,255,pcm->prstr,*gr);
+        }
+	/* pad with blanks? */
+        if (pcm->prbnum>0) {
+          j = 0;
+          while (pout[j]) j++;
+          for (k=0; k<pcm->prbnum; k++) {
+            pout[j] = ' ';
+            j++;
+          }
+          pout[j] = '\0';
+        }
+        gaprnt (2,pout);
+      } 
+      else {
+        if (*gru==0) 
+          snprintf(pout,255,"%g ",pcm->undef);
+	else 
+	  snprintf(pout,255,"%g ",*gr);
+        gaprnt (2,pout);
+      }
+      lnum++;
+      if (lnum >= pcm->prlnum)  {
+        gaprnt (2,"\n");
+        lnum = 0;
+      }
+      gr++; gru++;
+    }
+    if (lnum>0) gaprnt (2,"\n");
+  } 
+  else {                           
+    /* Data type station */
+    stn = pcm->result[0].stn;
+    snprintf(pout,255,"Printing Stations -- %i Reports -- Undef = %g\n", stn->rnum, pcm->undef);
+    gaprnt(2,pout);
+    rpt = stn->rpt;
+    while (rpt) {
+	snprintf(pout,255,"%c%c%c%c%c%c%c%c %-9.4g %-9.4g %-9.4g \n",
+	   rpt->stid[0], rpt->stid[1], rpt->stid[2], rpt->stid[3],
+           rpt->stid[4], rpt->stid[5], rpt->stid[6], rpt->stid[7],
+           rpt->lon,rpt->lat,rpt->lev);
+      gaprnt(2,pout);
+      if (pcm->prstr) {
+        if (rpt->umask==0 && pcm->prudef) {
+          pout[0]='U'; pout[1]='n'; pout[2]='d'; pout[3]='e'; pout[4]='f'; pout[5]='\0';
+        } 
+	else if (rpt->umask==0) {
+          snprintf(pout,255,pcm->prstr,pcm->undef);
+	}
+	else {
+          snprintf(pout,255,pcm->prstr,rpt->val);
+        }
+      } else {
+        if (rpt->umask==0) 
+          snprintf(pout,255,"%g ",pcm->undef);
+	else 
+	  snprintf(pout,255,"%g ",rpt->val);
+      }
+      gaprnt(2,pout);
+      gaprnt(2,"\n");
+      rpt = rpt->rpt;
+    }
+  }
+}
+
+/*  Write info and stats on data item to grads output stream */
+
+void gastts (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt;
+struct gagrid *pgr;
+struct dt dtim;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble *gr;
+gadouble cint,cmin,cmax,rmin,rmax;
+gadouble sum,sumsqr,dum,gcntm1;        
+gaint i,ucnt,gcnt,gcnto,siz;
+char *grumask;
+char lab[20];
+
+  /* Grid Data */
+  if (pcm->type[0] == 1) {          
+    pgr = pcm->result[0].pgr;
+    gaprnt(2,"Data Type = grid\n");
+    snprintf(pout,255,"Dimensions = %i %i\n", pgr->idim, pgr->jdim);
+    gaprnt(2,pout);
+    if (pgr->idim>-1) {
+      snprintf(pout,255,"I Dimension = %i to %i", pgr->dimmin[pgr->idim], pgr->dimmax[pgr->idim]);
+      gaprnt(2,pout);
+      /* Linear scaling info */
+      if (pgr->idim>-1 && pgr->ilinr==1) {     
+        gaprnt(2," Linear");
+        if (pgr->idim==3) {
+          gr2t (pgr->ivals,pgr->dimmin[3],&dtim);
+          if (dtim.mn==0) 
+	    gat2ch (&dtim,4,lab,20);
+          else 
+	    gat2ch (&dtim,5,lab,20);
+          if (*(pgr->ivals+5)!=0) {
+            snprintf(pout,255," %s %gmo\n",lab,*(pgr->ivals+5));
+          } else {
+            snprintf(pout,255," %s %gmn\n",lab,*(pgr->ivals+6));
+          }
+          gaprnt (2,pout);
+        } else {
+          conv = pgr->igrab;
+          snprintf(pout,255," %g %g\n",conv(pgr->ivals,pgr->dimmin[pgr->idim]),*(pgr->ivals));
+          gaprnt (2,pout);
+        }
+      }
+      /* Levels scaling info */
+      if (pgr->idim>-1 && pgr->ilinr!=1) {     
+        gaprnt(2," Levels");
+        conv = pgr->igrab;
+        for (i=pgr->dimmin[pgr->idim]; i<=pgr->dimmax[pgr->idim]; i++) {
+          snprintf(pout,255," %g",conv(pgr->ivals,i));
+          gaprnt (2,pout);
+        }
+        gaprnt (2,"\n");
+      }
+    } else {
+      gaprnt(2,"I Dimension = -999 to -999\n");
+    }
+    if (pgr->jdim>-1) {
+      snprintf(pout,255,"J Dimension = %i to %i",pgr->dimmin[pgr->jdim],pgr->dimmax[pgr->jdim]);
+      gaprnt(2,pout);
+      /* Linear scaling info */
+      if (pgr->jdim>-1 && pgr->jlinr==1) {     
+        gaprnt(2," Linear");
+        if (pgr->jdim==3) {
+          gr2t (pgr->jvals,pgr->dimmin[3],&dtim);
+          if (dtim.mn==0) 
+	    gat2ch (&dtim,4,lab,20);
+          else 
+	    gat2ch (&dtim,5,lab,20);
+          if (*(pgr->jvals+5)!=0) {
+            snprintf(pout,255," %s %gmo\n",lab,*(pgr->jvals+5));
+          } else {
+            snprintf(pout,255," %s %gmn\n",lab,*(pgr->jvals+6));
+          }
+          gaprnt (2,pout);
+        } else {
+          conv = pgr->jgrab;
+          snprintf(pout,255," %g %g\n",conv(pgr->jvals,pgr->dimmin[pgr->jdim]),*(pgr->jvals));
+          gaprnt (2,pout);
+        }
+      }
+      /* Levels scaling info */
+      if (pgr->jdim>-1 && pgr->jlinr!=1) {     
+        gaprnt(2," Levels");
+        conv = pgr->jgrab;
+        for (i=pgr->dimmin[pgr->jdim]; i<=pgr->dimmax[pgr->jdim]; i++) {
+          snprintf(pout,255," %g",conv(pgr->jvals,i));
+          gaprnt (2,pout);
+        }
+        gaprnt (2,"\n");
+      }
+    } else {
+      gaprnt(2,"J Dimension = -999 to -999\n");
+    }
+    siz = pgr->isiz*pgr->jsiz;
+    snprintf(pout,255,"Sizes = %i %i %i\n",pgr->isiz,pgr->jsiz,siz);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Undef value = %g\n",pcm->undef);
+    gaprnt(2,pout);
+    ucnt = 0;  gcnt = 0; sum=0; sumsqr=0; 
+    gr = pgr->grid;
+    grumask = pgr->umask;
+    for (i=0; i<siz; i++) {
+      if (*(grumask+i)==0) ucnt++;
+      else {
+	dum = *(gr+i);
+	sum += dum;
+	sumsqr += dum*dum;
+	gcnt++;
+      }
+    }
+    snprintf(pout,255,"Undef count = %i  Valid count = %i\n",ucnt,gcnt);
+    gaprnt(2,pout);
+    if (pgr->idim>-1) {
+      gamnmx (pgr);
+      snprintf(pout,255,"Min, Max = %g %g\n",pgr->rmin,pgr->rmax);
+      gaprnt(2,pout);
+      cint = 0.0;
+      gacsel (pgr->rmin,pgr->rmax,&cint,&cmin,&cmax);
+
+      if (pgr->jdim==-1) {
+        cmin = cmin - cint*2.0;
+        cmax = cmax + cint*2.0;
+      }
+      if (dequal(cint,0.0,1e-12)==0 || dequal(cint,pgr->undef,1e-12)==0) {
+        cmin = pgr->rmin-5.0;
+        cmax = pgr->rmax+5.0;
+        cint = 1.0;
+      }
+      snprintf(pout,255,"Cmin, cmax, cint = %g %g %g\n",cmin,cmax,cint);
+      gaprnt(2,pout);
+      gcntm1=gcnt-1;
+      if(gcntm1<=0) gcntm1=1;
+      gcnto=gcnt;
+      if(gcnt<=0) gcnt=1;
+      snprintf(pout,255,"Stats[sum,sumsqr,root(sumsqr),n]:     %g %g %g %d\n",
+	       sum,sumsqr,sqrt(sumsqr),gcnto);
+      gaprnt(2,pout);
+      snprintf(pout,255,"Stats[(sum,sumsqr,root(sumsqr))/n]:     %g %g %g\n",
+	       sum/gcnt,sumsqr/gcnt,sqrt(sumsqr/gcnt));
+      gaprnt(2,pout);
+      snprintf(pout,255,"Stats[(sum,sumsqr,root(sumsqr))/(n-1)]: %g %g %g\n",
+	       sum/gcntm1,sumsqr/gcntm1,sqrt(sumsqr/gcntm1));
+      gaprnt(2,pout);
+      dum=(sumsqr/gcnt)-((sum/gcnt)*(sum/gcnt));
+      if(dum>0){
+	snprintf(pout,255,"Stats[(sigma,var)(n)]:     %g %g\n",sqrt(dum),dum);
+      } else {
+	snprintf(pout,255,"Stats[(sigma,var)(n)]:     %g %g\n",0.0,0.0);
+      }
+      gaprnt(2,pout);
+      dum=dum*(gcnt/gcntm1);
+      if(dum>0) {
+	snprintf(pout,255,"Stats[(sigma,var)(n-1)]:   %g %g\n",sqrt(dum),dum);
+      } else {
+	snprintf(pout,255,"Stats[(sigma,var)(n-1)]:   %g %g\n",0.0,0.0);
+      }
+      gaprnt(2,pout);
+    } else {
+      snprintf(pout,255,"Min, Max = %g %g\n",pgr->rmin,pgr->rmin);
+      gaprnt(2,pout);
+    }
+
+  } else {                           /* Data type station */
+    gaprnt(2,"Data Type = station\n");
+    stn = pcm->result[0].stn;
+    snprintf(pout,255,"Dimensions = %i %i\n",stn->idim,stn->jdim);
+    gaprnt(2,pout);
+    if (stn->idim>-1) {
+      if (stn->idim!=3) {
+        snprintf(pout,255,"I Dimension = %g to %g\n",stn->dmin[stn->idim],stn->dmax[stn->idim]);
+        gaprnt(2,pout);
+      } else {
+        snprintf(pout,255,"I Dimension = %i to %i\n",stn->tmin, stn->tmax);
+        gaprnt(2,pout);
+      }
+    } else {
+      gaprnt(2,"I Dimension = -999 to -999\n");
+    }
+    if (stn->jdim>-1) {
+      if (stn->jdim!=3) {
+        snprintf(pout,255,"J Dimension = %g to %g\n",stn->dmin[stn->jdim],stn->dmax[stn->jdim]);
+        gaprnt(2,pout);
+      } else {
+        snprintf(pout,255,"J Dimension = %i to %i\n",stn->tmin, stn->tmax);
+        gaprnt(2,pout);
+      }
+    } else {
+      gaprnt(2,"J Dimension = -999 to -999\n");
+    }
+    snprintf(pout,255,"Stn count = %i\n",stn->rnum);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Undef value = %g\n",pcm->undef);
+    gaprnt(2,pout);
+    ucnt = 0;  gcnt = 0; sum=0; sumsqr=0;  
+    rmin = 9e33;
+    rmax = -9e33;
+    rpt = stn->rpt;
+
+    while (rpt) {
+      if (rpt->umask==0) ucnt++;
+      else {
+        gcnt++;
+	dum = rpt->val;
+        sum += dum;
+	sumsqr += dum*dum;
+        if (rpt->val<rmin) rmin = rpt->val;
+        if (rpt->val>rmax) rmax = rpt->val;
+      }
+      rpt = rpt->rpt;
+    }
+    gcntm1 = gcnt-1;
+    if (gcntm1 <= 0) gcntm1=1;
+    if (gcnt==0) {
+      rmin = pcm->undef;
+      rmax = pcm->undef;
+    }
+
+    snprintf(pout,255,"Undef count = %i  Valid count = %i \n",ucnt,gcnt);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Min, Max = %g %g\n",rmin,rmax);
+    gaprnt(2,pout);
+    cint = 0.0;
+
+    gacsel (rmin,rmax,&cint,&cmin,&cmax);
+    if (stn->jdim==-1) {
+      cmin = cmin - cint*2.0;
+      cmax = cmax + cint*2.0;
+    }
+    if (dequal(cint,0.0,1e-12)==0 || dequal(cint,stn->undef,1e-12)==0) {
+      cmin = rmin-5.0;
+      cmax = rmax+5.0;
+      cint = 1.0;
+    }
+    snprintf(pout,255,"Cmin, cmax, cint = %g %g %g\n",cmin,cmax,cint);
+    gaprnt(2,pout);
+
+    gcntm1 = gcnt-1;
+    if(gcntm1 <= 0) gcntm1=1;
+    gcnto = gcnt;
+    if(gcnt <= 0) gcnt=1;
+    snprintf(pout,255,"Stats[sum,sumsqr,root(sumsqr),n]:     %g %g %g %d\n",
+	     sum,sumsqr,sqrt(sumsqr),gcnto);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Stats[(sum,sumsqr,root(sumsqr))/n)]:     %g %g %g\n",
+	     sum/gcnt,sumsqr/gcnt,sqrt(sumsqr/gcnt));
+    gaprnt(2,pout);
+    snprintf(pout,255,"Stats[(sum,sumsqr,root(sumsqr))/(n-1))]: %g %g %g\n",
+	     sum/gcntm1,sumsqr/gcntm1,sqrt(sumsqr/gcntm1));
+    gaprnt(2,pout);
+    dum=(sumsqr/gcnt)-((sum/gcnt)*(sum/gcnt));
+    if(dum>0){
+      snprintf(pout,255,"Stats[(sigma,var)(n)]:     %g %g\n",sqrt(dum),dum);
+    } else {
+      snprintf(pout,255,"Stats[(sigma,var)(n)]:     %g %g\n",0.0,0.0);
+    }
+    gaprnt(2,pout);
+    dum=dum*(gcnt/gcntm1);
+    if(dum>0) {
+      snprintf(pout,255,"Stats[(sigma,var)(n-1)]:   %g %g\n",sqrt(dum),dum);
+    } else {
+      snprintf(pout,255,"Stats[(sigma,var)(n-1)]:   %g %g\n",0.0,0.0);
+    }
+    gaprnt(2,pout);
+
+    if(pcm->stnprintflg) {
+      snprintf(pout,255,"Printing station values:  #obs = %d\n",gcnt);
+      gaprnt(2,pout);
+      gcnt=0;
+      ucnt=0;
+      rpt = stn->rpt;
+      snprintf(pout,255,"OB    ID       LON      LAT      LEV      VAL\n");
+      gaprnt(2,pout);
+      while (rpt) {
+	if (rpt->umask==0) ucnt++;
+	else {
+	  gcnt++;
+	  snprintf(pout,255,"%-5i %.8s %-8.6g %-8.6g %-8.6g %-8.6g\n",
+		   gcnt,rpt->stid,rpt->lon,rpt->lat,rpt->lev,rpt->val);
+	  gaprnt(2,pout);
+	}
+	rpt = rpt->rpt;
+      }
+    }
+  }
+  gagsav(22,pcm,NULL);
+}
+
+/*  Special routine -- find closest station to an X,Y position. */
+
+void gafstn (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt, *srpt;
+struct gagrid *pgr;
+gadouble x,y,r,d,xpos,ypos,rlon;
+
+  if (pcm->numgrd<3 || pcm->type[0]!=0 || pcm->type[1]!=1 || pcm->type[2]!=1) {
+    gaprnt (0,"Error: Invalid data types for findstn\n");
+    return;
+  }
+
+  gamscl (pcm);       /* Do map level scaling */
+  stn = pcm->result[0].stn;
+  pgr = pcm->result[1].pgr;
+  xpos = pgr->rmin;
+  pgr = pcm->result[2].pgr;
+  ypos = pgr->rmin;
+  rpt = stn->rpt;
+  srpt = NULL;
+  r = 1.0e30;
+  while (rpt) {
+    rlon = rpt->lon;
+    if (rlon<pcm->dmin[0]) rlon+=360.0;
+    if (rlon>pcm->dmax[0]) rlon-=360.0;
+    gxconv (rlon,rpt->lat,&x,&y,2);
+    d = hypot(x-xpos,y-ypos);
+    if (d<r) {
+      r = d;
+      srpt = rpt;
+    }
+    rpt = rpt->rpt;
+  }
+  if (srpt) {
+    srpt->stid[7] = '\0';
+    snprintf(pout,255,"%s %g %g %g\n",srpt->stid,srpt->lon,srpt->lat,r);
+    gaprnt(2,pout);
+  } else gaprnt (2,"No stations found\n");
+  gagsav (21,pcm,NULL);
+}
+
+/* Plot weather symbols at station locations. */
+
+void gawsym (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt;
+gadouble rlon,x,y,scl;
+gaint i;
+
+  gamscl (pcm);       /* Do map level scaling */
+  gawmap (pcm, 1);    /* Draw map */
+  pcm->xdim = 0; pcm->ydim = 1;
+  gafram (pcm);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  stn = pcm->result[0].stn;
+  rpt = stn->rpt;
+  gxwide (pcm->cthick);
+  if (pcm->ccolor<0) gxcolr(1);
+  else gxcolr (pcm->ccolor);
+  while (rpt!=NULL) {
+    if (rpt->umask != 0) {
+      rlon = rpt->lon;
+      if (rlon<pcm->dmin[0]) rlon+=360.0;
+      if (rlon>pcm->dmax[0]) rlon-=360.0;
+      if (rlon>pcm->dmin[0] && rlon<pcm->dmax[0] &&
+             rpt->lat>pcm->dmin[1] && rpt->lat<pcm->dmax[1]) {
+        i = (gaint)(rpt->val+0.1);
+        if (i>0 && i<42) {
+          gxconv (rlon,rpt->lat,&x,&y,2);
+          scl = pcm->digsiz*1.5;
+          gxwide (pcm->cthick);
+          if (pcm->wxopt==1) {
+            wxsym (i, x, y, scl, pcm->ccolor, pcm->wxcols);
+          } else {
+            gxmark (i,x,y,scl);
+          }
+        }
+      }
+    }
+    rpt = rpt->rpt;
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr (pcm->anncol);
+  gxwide (pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gxstyl(1);
+  gaaxpl(pcm,0,1);
+  gagsav(12,pcm,NULL);
+}
+
+/* Plot colorized markers at station locations */
+
+void gasmrk (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt;
+gadouble rlon,x,y,cwid,sizstid;
+gaint i,len,icnst,cnt; 
+char lab[20];
+
+  gamscl (pcm);       /* Do map level scaling */
+  gawmap (pcm, 1);    /* Draw map */
+  pcm->xdim = 0; pcm->ydim = 1;
+  gafram (pcm);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  stn = pcm->result[0].stn;
+  gasmnmx (stn);
+
+  if (dequal(stn->smin,stn->undef,1e-12)==0 || 
+      dequal(stn->smax,stn->undef,1e-12)==0) return;
+  gaselc (pcm,stn->smin,stn->smax);
+  rpt = stn->rpt;
+  gxwide (pcm->cthick);
+
+  icnst=0;
+  if (dequal(stn->smin,stn->smax,1e-12)==0) icnst=1;
+  if (pcm->ccolor<0 && icnst) {
+    pcm->ccolor=1;
+    gxcolr(pcm->ccolor);
+  } else if (pcm->ccolor<0) {
+    gxcolr(1);
+  } else {
+    gxcolr (pcm->ccolor);
+  }
+
+  cnt = 0;
+  sizstid=pcm->digsiz*0.65;
+
+  while (rpt!=NULL) {
+    cnt++;
+    if (rpt->umask != 0) {
+      rlon = rpt->lon;
+      if (rlon<pcm->dmin[0]) rlon+=360.0;
+      if (rlon>pcm->dmax[0]) rlon-=360.0;
+      if (rlon>=pcm->dmin[0] && rlon<=pcm->dmax[0] &&
+	  rpt->lat>=pcm->dmin[1] && rpt->lat<=pcm->dmax[1]) {
+        gxconv (rlon,rpt->lat,&x,&y,2);
+        i = gashdc (pcm,rpt->val);
+
+	/* if constant grid, use user ccolor */
+	if (icnst) {
+	  gxcolr(pcm->ccolor);
+	} else {
+	  gxcolr (i);
+	}
+        gxmark (pcm->cmark,x,y,pcm->digsiz*0.5);
+
+        /* stn id plot */
+	if (pcm->stidflg) {
+	  gxmark (1,x,y,pcm->digsiz*0.5);
+	  getwrd (lab,rpt->stid,8);
+          len = strlen(lab);
+          cwid = 0.1;
+          gxchln (lab,len,sizstid,&cwid);
+          x = x-cwid*0.5;
+          y = y-(sizstid*1.7);
+          if (pcm->ccolor!=0) {
+            gxcolr (gxqbck());
+            gxrecf (x-0.01,x+cwid+0.01,y-0.01,y+sizstid+0.01);
+          }
+          if (pcm->ccolor<0) gxcolr(1);
+          else gxcolr (pcm->ccolor);
+          gxchpl (lab,len,x,y,sizstid,sizstid,0.0);
+	}
+
+      }
+    }
+    rpt = rpt->rpt;
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide(pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gxstyl(1);
+  gaaxpl(pcm,0,1);
+  gagsav(14,pcm,NULL);
+}
+
+/* Plot station values as either one number centered on the station
+   location or as two numbers above and below a crosshair, or as
+   a wind barb if specified by user */
+
+void gapstn (struct gacmn *pcm) {
+struct gastn *stn, *stn2;
+struct garpt *rpt, *rpt2;
+gadouble x,y,rlon;
+gadouble dir,spd,umax,vmax,vscal=0.0,cwid;
+gaint len,flag,hemflg;
+char lab[20];
+
+  gamscl (pcm);       /* Do map level scaling */
+  gawmap (pcm, 1);    /* Draw map */
+  pcm->xdim = 0;
+  pcm->ydim = 1;
+  gafram(pcm);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  /* Plot barb or vector at station location */
+
+  if (pcm->numgrd>1 && (pcm->goutstn==2 || pcm->goutstn==6)) {
+    stn = pcm->result[0].stn;
+    stn2 = pcm->result[1].stn;
+    if (pcm->goutstn==6) {            /* Get vector scaling */
+      if (!pcm->arrflg) {
+        rpt = stn->rpt;
+        umax = -9.99e33;
+        while (rpt) {
+          if (umax<fabs(rpt->val)) umax = fabs(rpt->val);
+          rpt = rpt->rpt;
+        }
+        rpt = stn2->rpt;
+        vmax = -9.99e33;
+        while (rpt) {
+          if (vmax<fabs(rpt->val)) vmax = fabs(rpt->val);
+          rpt = rpt->rpt;
+        }
+        vscal = hypot(umax,vmax);
+        x = floor(log10(vscal));
+        y = floor(vscal/pow(10.0,x));
+        vscal = y * pow(10.0,x);
+        pcm->arrsiz = 0.5;
+        pcm->arrmag = vscal;
+      } else {
+        vscal = pcm->arrmag;
+      }
+      pcm->arrflg = 1;
+    }
+    rpt = stn->rpt;
+    if (pcm->ccolor<0) gxcolr(1);
+    else gxcolr (pcm->ccolor);
+    gxwide (pcm->cthick);
+    while (rpt!=NULL) {
+      if (rpt->umask != 0) {
+        rpt2 = stn2->rpt;
+        while (rpt2!=NULL) {
+          if (rpt2->umask != 0 && 
+	      dequal(rpt->lat,rpt2->lat,1e-12)==0 &&
+              dequal(rpt->lon,rpt2->lon,1e-12)==0) {
+            rlon = rpt->lon;
+            if (rlon<pcm->dmin[0]) rlon+=360.0;
+            if (rlon>pcm->dmax[0]) rlon-=360.0;
+            if (rlon>pcm->dmin[0] && rlon<pcm->dmax[0] &&
+                rpt->lat>pcm->dmin[1] && rpt->lat<pcm->dmax[1]) {
+              gxconv (rlon,rpt->lat,&x,&y,2);
+              if (dequal(rpt2->val,0.0,1e-12)==0 && dequal(rpt->val,0.0,1e-12)==0) 
+		dir = 0.0;
+              else {
+		dir = gxaarw(rpt->lon,rpt->lat);
+                if (dir<-900.0) {
+                  gaprnt(0,"Error: vector/barb not compatible with the current map projection\n");
+                  return;
+                }
+		dir = dir + atan2(rpt2->val,rpt->val);
+              }
+              spd = hypot(rpt->val,rpt2->val);
+              if (pcm->goutstn==2) {
+                hemflg = 0;
+                if (pcm->hemflg == 1) hemflg = 1;
+                else if (pcm->hemflg == 0) hemflg = 0;
+                else if (rpt->lat<0.0) hemflg = 1;
+                gabarb (x, y, pcm->digsiz*3.5, pcm->digsiz*2.0,
+                     pcm->digsiz*0.25, dir, spd, hemflg);
+                gxmark (2,x,y,pcm->digsiz*0.5);
+              } else {
+                if (vscal>0.0) {
+                  gaarrw (x, y, dir, pcm->arrsiz*spd/vscal, pcm->ahdsiz);
+                } else {
+                  gaarrw (x, y, dir, pcm->arrsiz, pcm->ahdsiz);
+                }
+              }
+            }
+            break;
+          }
+          rpt2 = rpt2->rpt;
+        }
+      }
+      rpt = rpt->rpt;
+    }
+
+  /* Plot number at station location */
+
+  } else {
+    gxwide (pcm->cthick);
+    stn = pcm->result[0].stn;
+    rpt = stn->rpt;
+    flag=0;
+    if (pcm->numgrd>1 || pcm->stidflg) flag = 1;
+    while (rpt!=NULL) {
+      if (rpt->umask != 0) {
+        rlon = rpt->lon;
+        if (rlon<pcm->dmin[0]) rlon+=360.0;
+        if (rlon>pcm->dmax[0]) rlon-=360.0;
+        if (rlon>pcm->dmin[0] && rlon<pcm->dmax[0] &&
+            rpt->lat>pcm->dmin[1] && rpt->lat<pcm->dmax[1]) {
+          gxconv (rlon,rpt->lat,&x,&y,2);
+          if (flag) gxmark (1,x,y,pcm->digsiz*0.5);
+          snprintf(lab,19,"%.*f",pcm->dignum,(gafloat)rpt->val);
+          len = strlen(lab);
+          cwid = 0.1;
+          gxchln (lab,len,pcm->digsiz,&cwid);
+          x = x-cwid*0.5;
+          if (flag) {
+            y = y+(pcm->digsiz*0.7);
+          } else {
+            y = y-(pcm->digsiz*0.5);
+          }
+          if (pcm->ccolor!=0) {
+            gxcolr (gxqbck());
+            gxrecf (x-0.01,x+cwid+0.01,y-0.01,y+pcm->digsiz+0.01);
+          }
+          if (pcm->ccolor<0) gxcolr(1);
+          else gxcolr (pcm->ccolor);
+          gxchpl (lab,len,x,y,pcm->digsiz,pcm->digsiz,0.0);
+        }
+      }
+      rpt=rpt->rpt;
+    }
+    if ( (flag && pcm->type[1]==0) || pcm->stidflg) {
+      if (!pcm->stidflg) stn = pcm->result[1].stn;
+      rpt = stn->rpt;
+      while (rpt!=NULL) {
+	if (rpt->umask != 0) {
+	  rlon = rpt->lon;
+	  if (rlon<pcm->dmin[0]) rlon+=360.0;
+	  if (rlon>pcm->dmax[0]) rlon-=360.0;
+	  if (rlon>pcm->dmin[0] && rlon<pcm->dmax[0] &&
+	      rpt->lat>pcm->dmin[1] && rpt->lat<pcm->dmax[1]) {
+	    gxconv (rlon,rpt->lat,&x,&y,2);
+	    gxmark (1,x,y,pcm->digsiz*0.5);
+	    if (pcm->stidflg) {
+	      getwrd (lab,rpt->stid,8);
+	    } else {
+	      snprintf(lab,19,"%.*f",pcm->dignum,(gafloat)rpt->val); 
+	    }
+	    len = strlen(lab);
+	    cwid = 0.1;
+	    gxchln (lab,len,pcm->digsiz,&cwid);
+	    x = x-cwid*0.5;
+	    y = y-(pcm->digsiz*1.7);
+	    if (pcm->ccolor!=0) {
+	      gxcolr (gxqbck());
+	      gxrecf (x-0.01,x+cwid+0.01,y-0.01,y+pcm->digsiz+0.01);
+	    }
+	    if (pcm->ccolor<0) gxcolr(1);
+	    else gxcolr (pcm->ccolor);
+	    gxchpl (lab,len,x,y,pcm->digsiz,pcm->digsiz,0.0);
+	  }
+	}
+        rpt=rpt->rpt;
+      }
+    }
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide(pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gxstyl(1);
+  gaaxpl(pcm,0,1);
+  gagsav (10,pcm,NULL);
+}
+
+/*  Draw wind barb at location x, y, direction dir, speed
+    spd, with barb lengths of blen, pointer length of plen
+    (before barbs added), starting at rad distance from the
+    center point x,y.  If calm, a circle is drawn at rad*1.2
+    radius.  Direction is direction wind blowing towards.  */
+
+void gabarb (gadouble x, gadouble y, gadouble plen, gadouble blen, gadouble rad,
+      gadouble dir, gadouble spd, gaint hemflg) {
+gadouble bgap,padd,var,a70,cosd70,sind70;
+gadouble xp1,yp1,xp2,yp2,xp3,yp3;
+gaint flag,flg2;
+
+  dir = dir + pi;   /* Want direction wind blowing from */
+
+  /* Calculate added length due to barbs */
+
+  bgap = blen*0.3;
+  padd = 0.0;
+  var = spd;
+  if (var<0.01) {
+    rad*=2.0;
+    if (rad+blen*0.3>rad*1.4) gxmark(2,x,y,rad+blen*0.3);
+    else gxmark (2,x,y,rad*1.4);
+    return;
+  } else {
+    if (var<2.5) padd = bgap;
+    while (var>=47.5) { var-=50.0; padd+=bgap*1.6;}
+    while (var>=7.5)  { var-=10.0; padd+=bgap;}
+    if (var>=2.5) padd+=bgap;
+  }
+  plen+=padd;
+
+  /* Draw pointer */
+
+  xp1 = x + plen*cos(dir);
+  yp1 = y + plen*sin(dir);
+  xp2 = x + rad*cos(dir);
+  yp2 = y + rad*sin(dir);
+  gxplot (xp2,yp2,3);
+  gxplot (xp1,yp1,2);
+
+  /* Start out at the end of the pointer and add barbs
+     til we run out of barbs to add.  */
+
+  var = spd;
+  a70 = 70.0*pi/180.0;
+  if (hemflg) {
+    cosd70 = cos(dir+a70);
+    sind70 = sin(dir+a70);
+  } else {
+    cosd70 = cos(dir-a70);
+    sind70 = sin(dir-a70);
+  }
+  flag = 1;
+  flg2 = 0;
+  while (var>=47.5) {
+    xp1 = x + plen*cos(dir);
+    yp1 = y + plen*sin(dir);
+    xp2 = xp1 + blen*cosd70;
+    yp2 = yp1 + blen*sind70;
+    xp3 = x + (plen-bgap*1.45)*cos(dir);
+    yp3 = y + (plen-bgap*1.45)*sin(dir);
+    gxplot (xp1,yp1,3);
+    gxplot (xp2,yp2,2);
+    gxplot (xp3,yp3,2);
+    plen = plen - bgap*1.6;
+    var-=50.0;
+    flg2 = 1;
+  }
+  while (var>=7.5) {
+    if (flg2) {plen-=bgap*0.7; flg2 = 0;}
+    xp1 = x + plen*cos(dir);
+    yp1 = y + plen*sin(dir);
+    xp2 = xp1 + blen*cosd70;
+    yp2 = yp1 + blen*sind70;
+    gxplot (xp1,yp1,3);
+    gxplot (xp2,yp2,2);
+    plen-=bgap;
+    var-=10.0;
+    flag = 0;
+  }
+  if (var>=2.5) {
+    if (flag) plen-=bgap;
+    xp1 = x + plen*cos(dir);
+    yp1 = y + plen*sin(dir);
+    xp2 = xp1 + 0.5*blen*cosd70;
+    yp2 = yp1 + 0.5*blen*sind70;
+    gxplot (xp1,yp1,3);
+    gxplot (xp2,yp2,2);
+  }
+  return;
+}
+
+/* Plot station model using station data.  Complexity of model
+   depends on the number of result objects available.
+   First two are assumed to be u and v winds, which are required
+   for the station model to be plotted. */
+
+void gapmdl (struct gacmn *pcm) {
+struct gastn *stn, *stn1;
+struct garpt *rpt, *rpt1;
+struct gagrid *pgr;
+gadouble vals[10];
+char udefs[10];
+gaint i,num,rc;
+
+  gamscl (pcm);       /* Do map level scaling */
+  gawmap (pcm, 1);    /* Draw map */
+  pcm->xdim = 0;
+  pcm->ydim = 1;
+  gafram (pcm);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  num = pcm->numgrd;
+  if (num>10) num=10;
+
+  /* Check validity of data -- single value (shows up as a grid) indicates
+     not to plot that variable */
+
+  for (i=0; i<pcm->numgrd; i++) {
+    if (pcm->type[i]==1) {
+      pgr = pcm->result[i].pgr;
+      if (i==0 || pgr->idim!=-1) {
+        gaprnt (0,"Invalid data:  Station data required\n");
+        return;
+      }
+    }
+  }
+
+  if (pcm->ccolor<0) gxcolr(1);
+  else gxcolr (pcm->ccolor);
+  gxwide (pcm->cthick);
+
+  /* Get info for each station  -- match station ids accross all the 
+     variables which show up as separate result items.*/
+
+  stn1 = pcm->result[0].stn;
+  rpt1 = stn1->rpt;
+  while (rpt1) {
+    if (rpt1->umask == 0) {
+      udefs[0] = 0;
+    } else {
+      vals[0] = rpt1->val;
+      udefs[0] = 1;
+      for (i=1; i<pcm->numgrd; i++) {
+        if (pcm->type[i]!=1) {
+          stn = pcm->result[i].stn;
+          rpt = stn->rpt;
+          while (rpt) {
+            if (dequal(rpt->lon,rpt1->lon,1e-12)==0 && 
+                dequal(rpt->lat,rpt1->lat,1e-12)==0 &&
+                cmpch(rpt->stid,rpt1->stid,8)==0) break;
+            rpt = rpt->rpt;
+          }
+          if (rpt && rpt->umask==1) {
+            vals[i] = rpt->val;
+            udefs[i] = 1;
+          }
+          else udefs[i] = 0;
+        }
+        else udefs[i] = 0;
+      }
+    }
+    rc = gasmdl (pcm,rpt1,vals,udefs);
+    if (rc) return;
+    rpt1 = rpt1->rpt;
+  }
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide(pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gxstyl(1);
+  gaaxpl(pcm,0,1);
+  gagsav (11,pcm,NULL);
+}
+
+/* Plot an individual station model */
+
+gaint gasmdl (struct gacmn *pcm, struct garpt *rpt, gadouble *vals, char *udefs) {
+gaint num,icld,i,col,ivis,itop,ibot,ii,hemflg;
+gadouble x,y;
+gadouble spd,dir,roff,scl,rad,t,digsiz,msize,plen,wrad;
+gadouble xlo[7],xhi[7],ylo[7],yhi[7],orad,xv,yv;
+char ch[20],len;
+
+  col = pcm->ccolor;
+  if (pcm->ccolor<0) col = 1;
+  gxcolr(col);
+  num = pcm->numgrd;
+
+  /* If no winds, just return */
+  if ( *udefs==0 || *(udefs+1)==0) return(0);
+
+  /* Plot */
+  gxconv (rpt->lon,rpt->lat,&x,&y,2);
+  hemflg = 0;
+  if (pcm->hemflg == 1) hemflg = 1;
+  else if (pcm->hemflg == 0) hemflg = 0;
+  else if (rpt->lat<0.0) hemflg = 1;
+
+  icld = (gaint)(floor(*(vals+6)+0.1));
+  digsiz = pcm->digsiz;
+  if (icld>19 && icld<26) msize = digsiz*1.4;
+  else msize = digsiz;
+  wrad = msize*0.5;
+  if (dequal(*vals,0.0,1e-12)==0 && dequal(*(vals+1),0.0,1e-12)==0) 
+    rad = msize*0.8;
+  else 
+    rad = msize*0.65;
+
+  /* Plot clouds: 20 = clr, 21 = sct, 22 = bkn, 23 = ovc, 24 = obsc, 25 = missng */
+  icld = (gaint)(floor(*(vals+6)+0.1));
+  if (col==0 && icld>19) {
+    if (icld!=23) gxmark(3,x,y,msize);
+  } else {
+    if (icld==20) gxmark(2,x,y,msize);
+    else if (icld==21) gxmark(10,x,y,msize);
+    else if (icld==22) gxmark(11,x,y,msize);
+    else if (icld==23) gxmark(3,x,y,msize);
+    else if (icld==24) {
+      gxmark(2,x,y,msize);
+      roff = msize/2.8284;
+      gxplot (x-roff,y+roff,3);
+      gxplot (x+roff,y-roff,2);
+      gxplot (x+roff,y+roff,3);
+      gxplot (x-roff,y-roff,2);
+    }
+    else if (icld==25) {
+      gxmark(2,x,y,msize);
+      roff = msize*0.3;
+      gxchpl ("`0M",3,x-roff*1.2,y-roff*0.9,roff*2.0,roff*2.0,0.0);
+    }
+    else {
+      if (icld>0 && icld<9) gxmark(icld,x,y,msize);
+      else gxmark(2,x,y,msize);
+    }
+  }
+
+  /* Plot wxsym */
+  gxwide (pcm->cthick+1);
+  xlo[0] = -999.9;
+  if (*(udefs+7)) {
+    i = (gaint)(*(vals+7)+0.1);
+    if (i>0&&i<40) {
+      scl = digsiz*3.0;
+      xhi[0] = x - rad*1.1;
+      xlo[0] = xhi[0] - (sxwid[i-1]*scl);
+      ylo[0] = y + symin[i-1]*scl;
+      yhi[0] = y + symax[i-1]*scl;
+      wxsym (i,xlo[0]+(sxwid[i-1]*scl*0.5),y,scl,pcm->ccolor,pcm->wxcols);
+      gxcolr(col);
+    }
+  }
+
+  /* Plot visibility */
+  gxwide(pcm->cthick);
+  xlo[5] = -999.9;
+  if (*(udefs+8)) {
+    i = (gaint)((*(vals+8)*32.0)+0.5);
+    ivis = i/32;
+    itop = i - ivis*32;
+    ibot = 32;
+    while (itop!=0) {
+      i = itop/2;
+      if (i*2!=itop) break;
+      itop = i;
+      ibot = ibot/2;
+    }
+    yv = y-digsiz*0.5;
+    if (xlo[0]<-990.0) xv = x - rad*1.6;
+    else  xv = xlo[0] - digsiz*0.2;
+    xhi[5] = xv;
+    ylo[5] = yv;
+    yhi[5] = yv+digsiz;
+    if (itop>0) {
+      snprintf(ch,19,"%i",ibot);
+      len = 0;
+      while (*(ch+len)) len++;
+      xv = xv - ((gadouble)len)*digsiz*0.65;
+      gxchpl (ch,len,xv,yv,digsiz*0.65,digsiz*0.65,0.0);
+      snprintf(ch,19,"%i",itop);
+      len = 0;
+      while (*(ch+len)) len++;
+      gxplot (xv-digsiz*0.4,yv,3);
+      gxplot (xv+digsiz*0.1,yv+digsiz,2);
+      xv = xv - ((gadouble)len+0.4)*digsiz*0.65;
+      gxchpl (ch,len,xv,yv+digsiz*0.35,digsiz*0.65,digsiz*0.65,0.0);
+    }
+    if (ivis>0 || (ivis==0 && itop==0)) {
+      snprintf(ch,19,"%i",ivis);
+      len = 0;
+      while (*(ch+len)) len++;
+      xv = xv - ((gadouble)len)*digsiz;
+      gxchpl (ch,len,xv,yv,digsiz,digsiz,0.0);
+    }
+    xlo[5] = xv;
+  }
+
+  /* Plot temperature */
+  xlo[1] = -999.9;
+  if (*(udefs+2)) {
+    snprintf(ch,19,"%.*f",pcm->dignum,(gafloat)(*(vals+2)));
+    len = 0;
+    while (*(ch+len)) len++;
+    if (xlo[0]>-999.0) ylo[1] = yhi[0]+digsiz*0.4;
+    else if (xlo[5]>-999.0) ylo[1] = yhi[5]+digsiz*0.4;
+    else ylo[1] = y + digsiz*0.3;
+    t = ylo[1]-y;
+    t = rad*rad - t*t;
+    if (t<=0.0) xhi[1] = x-digsiz*0.3;
+    else {
+      t = sqrt(t);
+      if (t<digsiz*0.3) t = digsiz*0.3;
+      xhi[1] = x-t;
+    }
+    xlo[1] = xhi[1] - (gadouble)len * digsiz;
+    yhi[1] = ylo[1] + digsiz;
+    gxchpl (ch,len,xlo[1],ylo[1],digsiz,digsiz,0.0);
+  }
+
+  /* Plot dewpoint */
+  xlo[2] = -999.9;
+  if (*(udefs+3)) {
+    snprintf(ch,19,"%.*f",pcm->dignum,(gafloat)*(vals+3));
+    len = 0;
+    while (*(ch+len)) len++;
+    if (xlo[0]>-999.0) yhi[2] = ylo[0]-digsiz*0.4;
+    else if (xlo[5]>-999.0) yhi[2] = ylo[5]-digsiz*0.4;
+    else yhi[2] = y - digsiz*0.3;
+    t = y - yhi[2];
+    t = rad*rad - t*t;
+    if (t<=0.0) xhi[2] = x-digsiz*0.3;
+    else {
+      t = sqrt(t);
+      if (t<digsiz*0.3) t = digsiz*0.3;
+      xhi[2] = x-t;
+    }
+    xlo[2] = xhi[2] - (gadouble)len * digsiz;
+    ylo[2] = yhi[2] - digsiz;
+    gxchpl (ch,len,xlo[2],ylo[2],digsiz,digsiz,0.0);
+  }
+
+  /* Plot Pressure */
+  xlo[3] = -999.9;
+  if (*(udefs+4)) {
+    i = (gaint)(*(vals+4)+0.5);
+    ii = 0;
+    if (pcm->mdldig3) {
+      snprintf(ch,19,"%i",i+10000);
+      len = 0;
+      while (*(ch+len)) len++;
+      ii = len-3;
+      len = 3;
+    } else {
+      snprintf(ch,19,"%.*f",pcm->dignum,(gafloat)*(vals+4));
+      len = 0;
+      while (*(ch+len)) len++;
+    }
+    xlo[3] = x + rad*0.87;
+    ylo[3] = y + rad*0.5;
+    xhi[3] = xlo[3] + digsiz*(gadouble)len;
+    yhi[3] = ylo[3] + digsiz;
+    gxchpl (ch+ii,len,xlo[3],ylo[3],digsiz,digsiz,0.0);
+  }
+
+  /* Plot pressure tendency */
+  xlo[4] = -999.9;
+  if (*(udefs+5)) {
+    if (*(vals+5)>0.0) snprintf(ch,19,"+%.*f",pcm->dignum,(gafloat)*(vals+5));
+    else snprintf(ch,19,"%.*f",pcm->dignum,(gafloat)*(vals+5));
+    len = 0;
+    while (*(ch+len)) len++;
+    xlo[4] = x + rad;
+    if (xlo[3]>-990.0) yhi[4] = ylo[3]-digsiz*0.4;
+    else yhi[4] = y + digsiz*0.5;
+    xhi[4] = xlo[4] + digsiz*(gadouble)len;
+    ylo[4] = yhi[4] - digsiz;
+    gxchpl (ch,len,xlo[4],ylo[4],digsiz,digsiz,0.0);
+  }
+
+  /* plot stid lower right */
+  xlo[6] = -999.9;
+  if (pcm->stidflg) {
+    len = 4;
+    if (xlo[4]>-990.0) yhi[6] = ylo[4]-digsiz*0.4;
+    else yhi[6] = y - rad;
+    if (xlo[2]>-990.0) xlo[6] = xhi[2]+0.6*digsiz;
+    else xlo[6] = x - 1.2*digsiz;
+    xhi[6] = xlo[6] + 0.6*digsiz*(gadouble)len;
+    ylo[6] = yhi[6] - 0.6*digsiz;
+    gxchpl (rpt->stid,len,xlo[6],ylo[6],0.6*digsiz,0.6*digsiz,0.0);
+  }
+
+  /* Plot wind barb */
+  if (dequal(*vals,0.0,1e-12)==0 && dequal(*(vals+1),0.0,1e-12)==0) {
+    dir = 0.0;
+  } else {
+    dir = gxaarw(rpt->lon,rpt->lat);
+    if (dir<-900.0) {
+      gaprnt(0,"Error: vector/barb not compatible with current map projection\n");
+      return (1);
+    }
+    dir = dir + atan2(*(vals+1),*vals);
+  }
+  spd = hypot(*vals,*(vals+1));
+  orad = wndexit (spd*cos(dir), spd*sin(dir), x, y, rad, xlo, xhi, ylo, yhi);
+  if (orad<-990.0) {
+    plen = pcm->digsiz*3.5;
+  } else {
+    plen = pcm->digsiz*0.5+orad;
+    if (plen<pcm->digsiz*3.5) plen = pcm->digsiz*3.5;
+    if (plen>pcm->digsiz*6.0) plen = orad;
+    wrad = orad;
+  }
+  gabarb (x, y, plen, pcm->digsiz*2.5, wrad, dir, spd, hemflg);
+  return(0);
+}
+
+/* Find exit radius for the wind barb */
+
+gadouble wndexit (gadouble uu, gadouble vv, gadouble x, gadouble y, gadouble rad,
+                     gadouble *xlo, gadouble *xhi, gadouble *ylo, gadouble *yhi) {
+gadouble u,v,xn,yn,orad,fuzz,fuzz2;
+
+  u = -1.0*uu;
+  v = -1.0*vv;
+  orad = -999.9;
+  fuzz = rad*0.25;
+  fuzz2 = fuzz*0.5;
+
+  if (dequal(u,0.0,1e-12)==0 && dequal(v,0.0,1e-12)==0) return(orad);
+  if (u<0.0) {
+    if (v>0.0 && xlo[1]>-990.0) {
+      yhi[1] = yhi[1]+fuzz;
+      xn = x + (yhi[1]-y)*u/v;
+      if (xn>xlo[1]-fuzz && xn<xhi[1]+fuzz2) {
+        orad = hypot(xn-x, yhi[1]-y);
+        return (orad);
+      }
+      xlo[1] = xlo[1] - fuzz2;
+      yn = y + (xlo[1]-x)*v/u;
+      if (yn>ylo[1]-fuzz && yn<yhi[1]+fuzz) {
+        orad = hypot(xlo[1]-x,yn-y);
+        return (orad);
+      }
+    }
+    if (v<0.0 && xlo[2]>-990.0) {
+      ylo[2] = ylo[2]-fuzz;
+      xn = x + (ylo[2]-y)*u/v;
+      if (xn>xlo[2]-fuzz && xn<xhi[2]+fuzz2) {
+        orad = hypot(xn-x, ylo[2]-y);
+        return (orad);
+      }
+      xlo[2] = xlo[2] - fuzz2;
+      yn = y + (xlo[2]-x)*v/u;
+      if (yn>ylo[2]-fuzz && yn<yhi[2]+fuzz) {
+        orad = hypot(xlo[2]-x,yn-y);
+        return (orad);
+      }
+    }
+    if (xlo[5]>-990.0) {
+      xlo[5] = xlo[5] - fuzz2;
+      yn = y + (xlo[5]-x)*v/u;
+      if (yn>ylo[5]-fuzz && yn<yhi[5]+fuzz) {
+        orad = hypot(xlo[5]-x,yn-y);
+        return (orad);
+      }
+      if (v>0.0) {
+        yhi[5] = yhi[5]+fuzz;
+        xn = x + (yhi[5]-y)*u/v;
+        if (xn>xlo[5]-fuzz && xn<xhi[5]+fuzz2) {
+          orad = hypot(xn-x, yhi[5]-y);
+          return (orad);
+        }
+      }
+      if (v<0.0) {
+        ylo[5] = ylo[5]-fuzz;
+        xn = x + (ylo[5]-y)*u/v;
+        if (xn>xlo[5]-fuzz && xn<xhi[5]+fuzz2) {
+          orad = hypot(xn-x, ylo[5]-y);
+          return (orad);
+        }
+      }
+    }
+    if (xlo[0]>-990.0) {
+      xlo[0] = xlo[0] - fuzz2;
+      yn = y + (xlo[0]-x)*v/u;
+      if (yn>ylo[0]-fuzz && yn<yhi[0]+fuzz) {
+        orad = hypot(xlo[0]-x,yn-y);
+        return (orad);
+      }
+      if (v>0.0) {
+        yhi[0] = yhi[0]+fuzz;
+        xn = x + (yhi[0]-y)*u/v;
+        if (xn>xlo[0]-fuzz && xn<xhi[0]+fuzz2) {
+          orad = hypot(xn-x, yhi[0]-y);
+          return (orad);
+        }
+      }
+      if (v<0.0) {
+        ylo[0] = ylo[0]-fuzz;
+        xn = x + (ylo[0]-y)*u/v;
+        if (xn>xlo[0]-fuzz && xn<xhi[0]+fuzz2) {
+          orad = hypot(xn-x, ylo[0]-y);
+          return (orad);
+        }
+      }
+    }
+    return (orad);
+  }
+  if (u>0.0) {
+    if (xlo[4]>-990.0) {
+      xhi[4] = xhi[4] + fuzz2;
+      yn = y + (xhi[4]-x)*v/u;
+      if (yn>ylo[4]-fuzz && yn<=yhi[4]+fuzz) {
+        orad = hypot(xhi[4]-x,yn-y);
+        return (orad);
+      }
+    }
+    if (v>0.0 && xlo[3]>-990.0) {
+      yhi[3] = yhi[3] + fuzz;
+      xn = x + (yhi[3]-y)*u/v;
+      if (xn>xlo[3]-fuzz2 && xn<xhi[3]+fuzz) {
+        orad = hypot(xn-x, yhi[3]-y);
+        return (orad);
+      }
+      xhi[3] = xhi[3] + fuzz2;
+      yn = y + (xhi[3]-x)*v/u;
+      if (yn>ylo[3]-fuzz && yn<yhi[3]+fuzz) {
+        orad = hypot(xhi[3]-x,yn-y);
+        return (orad);
+      }
+    }
+    if (v<0.0 && xlo[6]>-990.0) {
+      ylo[6] = ylo[6] - fuzz;
+      xn = x + (ylo[6]-y)*u/v;
+      if (xn>xlo[6]-fuzz2 && xn<xhi[6]+fuzz) {
+        orad = hypot(xn-x, ylo[6]-y);
+        return (orad);
+      }
+      xhi[6] = xhi[6] + fuzz2;
+      yn = y + (xhi[6]-x)*v/u;
+      if (yn>ylo[6]-fuzz && yn<yhi[6]+fuzz) {
+        orad = hypot(xhi[6]-x,yn-y);
+        return (orad);
+      }
+    }
+  }
+  return (orad);
+
+}
+
+/* Plot a time series of one station (for now).  Just plot
+   the first station encountered.  */
+
+void gatser (struct gacmn *pcm) {
+struct gastn *stn, *stn2;
+struct garpt *rpt, *rpt2, *frpt;
+gadouble rmin,rmax,x,y;
+gadouble tsav,dir;
+gaint ipen,im,i,hemflg;
+
+  stn = pcm->result[0].stn;
+  rpt = stn->rpt;
+  frpt = rpt;            /* Plot stnid = 1st report */
+  if (rpt == NULL) {
+    gaprnt (0,"No stations to plot\n");
+    return;
+  }
+
+  /* First pass just get max and min values for this station */
+
+  rmin = 9.99e33;
+  rmax = -9.99e33;
+  while (rpt!=NULL) {
+    if (!cmpch(frpt->stid,rpt->stid,8)) {
+      if (rpt->umask != 0) {
+        if (rpt->val < rmin) rmin = rpt->val;
+        if (rpt->val > rmax) rmax = rpt->val;
+      }
+    }
+    rpt = rpt->rpt;
+  }
+  if (rmin>rmax) {
+    gaprnt (0,"All stations undefined for this variable\n");
+    return;
+  }
+
+  /* Do scaling */
+
+  i = pcm->frame;
+  if (pcm->tser) pcm->frame = 0;
+  gas1d (pcm, rmin, rmax, 3, pcm->rotate, NULL, stn);
+  pcm->frame = i;
+
+  /* Set up graphics */
+
+  if (pcm->ccolor<0) pcm->ccolor=1;
+  gxcolr (pcm->ccolor);
+  if (pcm->cstyle>0) gxstyl(pcm->cstyle);
+  else gxstyl(1);
+  gxwide (pcm->cthick);
+
+  /* Next pass plot lines. */
+
+  if (pcm->tser == 1) {
+    rpt = stn->rpt;
+    while (rpt!=NULL) {
+      gxconv (rpt->tim,0,&x,&y,3);
+      if (rpt->umask != 0) {
+        i = (gaint)(rpt->val+0.5);
+        wxsym (i, x, pcm->ysiz1, pcm->digsiz*1.5, -1, pcm->wxcols);
+      } else {
+        gxchpl ("M",1,x,pcm->ysiz1,pcm->digsiz,pcm->digsiz,0.0);
+      }
+      rpt = rpt->rpt;
+    }
+  } else if (pcm->tser==2) {
+    stn2 = pcm->result[1].stn;
+    rpt = stn->rpt;
+    rpt2 = stn2->rpt;
+    while (rpt!=NULL) {
+      if (rpt->umask != 0 && rpt2->umask != 0) {
+        gxconv (rpt->tim,rpt->val,&x,&y,3);
+        if (dequal(rpt->val,0.0,1e-12)==0 && dequal(rpt2->val,0.0,1e-12)==0) 
+	  dir = 0.0;
+        else 
+	  dir = atan2(rpt2->val,rpt->val);
+        hemflg = 0;
+        if (pcm->hemflg == 1) hemflg = 1;
+        else if (pcm->hemflg == 0) hemflg = 0;
+        else if (rpt->lat<0.0) hemflg = 1;
+        gabarb (x, pcm->ysiz1, pcm->digsiz*3.5, pcm->digsiz*2.0,
+                  pcm->digsiz*0.25, dir, hypot(rpt->val,rpt2->val), hemflg);
+      }
+      rpt = rpt->rpt;
+      rpt2 = rpt2->rpt;
+    }
+  } else {
+  gxclip (pcm->xsiz1-0.01, pcm->xsiz2+0.01, pcm->ysiz1, pcm->ysiz2);
+  if (pcm->cstyle!=0) {
+    rpt = stn->rpt;
+    tsav = rpt->tim;
+    ipen = 3;
+    while (rpt!=NULL) {
+      if (!cmpch(frpt->stid,rpt->stid,8)) {
+        if (rpt->umask != 0) {
+          if (rpt->tim - tsav > 1.0 && !pcm->miconn) ipen = 3;
+          if (pcm->rotate) gxconv (rpt->val,rpt->tim,&x,&y,3);
+          else gxconv (rpt->tim,rpt->val,&x,&y,3);
+          gxplot (x,y,ipen);
+          ipen = 2;
+        } else if (!pcm->miconn) ipen=3;
+        tsav = rpt->tim;
+      }
+      rpt = rpt->rpt;
+    }
+  }
+
+  rpt = stn->rpt;
+  im = pcm->cmark;
+  if (im>0) {
+    while (rpt!=NULL) {
+      if (!cmpch(frpt->stid,rpt->stid,8)) {
+        if (rpt->umask != 0) {
+          if (pcm->rotate) gxconv (rpt->val,rpt->tim,&x,&y,3);
+          else gxconv (rpt->tim,rpt->val,&x,&y,3);
+          if (im==1 || im==2 || im==4) {
+            gxcolr (gxqbck());
+            if (im==1) gxmark (4,x,y,pcm->digsiz+0.01);
+            else gxmark (im+1,x,y,pcm->digsiz+0.01);
+            gxcolr(pcm->ccolor);
+          }
+          gxmark (im,x,y,pcm->digsiz+0.01);
+        }
+      }
+      rpt = rpt->rpt;
+    }
+  }
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  if (pcm->rotate) 
+    gaaxpl(pcm,5,3);   /* hard-coded 4's changed to 5's */
+  else 
+    gaaxpl(pcm,3,5);   /* hard-coded 4's changed to 5's */
+  }
+  gxwide (pcm->annthk-3);
+  gxcolr (pcm->anncol);
+  if (pcm->pass==0 && pcm->grdsflg)
+           gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gagsav (13,pcm,NULL);
+}
+
+/* Plot a vertical profile given one or more stations and
+   a dimension environment where only z varies */
+
+void gapprf (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *anch, **prev, *next, *rpt, *srpt;
+gadouble x,y,rmin,rmax;
+gaint flag,i,ipen;
+char stid[10];
+
+  /* Reorder the linked list of reports so they are sorted */
+
+  stn = pcm->result[0].stn;
+  rpt = stn->rpt;
+  anch = NULL;
+  while (rpt!=NULL) {
+    prev = &anch;
+    srpt = anch;
+    flag = 0;
+    while (srpt!=NULL) {
+      if (!cmpch(srpt->stid,rpt->stid,8)) {
+        flag = 1;
+        if (srpt->lev < rpt->lev) break;
+      } else if (flag) break;
+      prev = &(srpt->rpt);
+      srpt = srpt->rpt;
+    }
+    next = rpt->rpt;
+    rpt->rpt = srpt;
+    *prev = rpt;
+    rpt = next;
+  }
+  stn->rpt = anch;
+
+  if (stn->rpt==NULL) {
+    gaprnt (0,"No station values to plot\n");
+    return;
+  }
+
+  /* Get max and min */
+
+  rmin = 9.99e33;
+  rmax = -9.99e33;
+  rpt = stn->rpt;
+  while (rpt!=NULL) {
+    if (rpt->umask != 0) {
+      if (rmin>rpt->val) rmin = rpt->val;
+      if (rmax<rpt->val) rmax = rpt->val;
+    }
+    rpt=rpt->rpt;
+  }
+  if (rmin>rmax) {
+    gaprnt (0,"All stations values are undefined\n");
+    return;
+  }
+
+  /* Scaling */
+
+  gas1d (pcm, rmin, rmax, 2, !(pcm->rotate), NULL, stn);
+
+  /* Do plot */
+
+  rpt = stn->rpt;
+  for (i=0; i<8; i++) stid[i]=' ';
+  gxstyl(pcm->cstyle);
+  if (pcm->ccolor<1) gxcolr(1);
+  else gxcolr(pcm->ccolor);
+  gxwide (pcm->cthick);
+  ipen = 3;
+  while (rpt!=NULL) {
+    if (rpt->umask == 0) {
+      if (!pcm->miconn) ipen = 3;
+    } else {
+      if (pcm->rotate) gxconv (rpt->lev,rpt->val,&x,&y,2);
+      else gxconv (rpt->val,rpt->lev,&x,&y,2);
+      if (cmpch(stid,rpt->stid,8)) ipen = 3;
+      gxplot (x,y,ipen);
+      ipen=2;
+    }
+    for (i=0; i<8; i++) stid[i]=rpt->stid[i];
+    rpt=rpt->rpt;
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  if (pcm->rotate) 
+    gaaxpl(pcm,2,5);   /* hard-coded 4's changed to 5's */
+  else 
+    gaaxpl(pcm,5,2);
+  gxcolr(pcm->anncol);
+  gxwide (pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gagsav (13,pcm,NULL);
+}
+
+/*  Routine to set up scaling for a 1-D plot.  */
+
+void gas1d (struct gacmn *pcm, gadouble cmin, gadouble cmax, gaint dim, gaint rotflg, 
+	    struct gagrid *pgr, struct gastn *stn) {
+gadouble x1,x2,y1,y2,xt1,xt2,yt1,yt2,d2r;
+gadouble cint,cmn,cmx;
+gaint axmov;
+
+  d2r = M_PI/180;
+  idiv = 1; jdiv = 1;   /* No grid expansion factor */
+  gxrset(3);            /* Reset all scaling        */
+  gxrsmapt();           /* Reset map type */
+
+  /* Set plot area limits */
+
+  if (pcm->paflg) {
+    pcm->xsiz1 = pcm->pxmin;
+    pcm->xsiz2 = pcm->pxmax;
+    pcm->ysiz1 = pcm->pymin;
+    pcm->ysiz2 = pcm->pymax;
+  } else {
+    if (rotflg) {
+      pcm->xsiz1 = pcm->xsiz/2.0 - pcm->ysiz/3.0;
+      pcm->xsiz2 = pcm->xsiz/2.0 + pcm->ysiz/3.0;
+      if (pcm->xsiz1<1.0) pcm->xsiz1 = 1.0;
+      if (pcm->xsiz2>pcm->xsiz-0.5) pcm->xsiz2 = pcm->xsiz-0.5;
+      pcm->ysiz1 = 0.75;
+      pcm->ysiz2 = pcm->ysiz-0.75;
+    } else {
+      pcm->xsiz1 = 2.0;
+      pcm->xsiz2 = pcm->xsiz - 0.5;
+      pcm->ysiz1 = 0.75;
+      pcm->ysiz2 = pcm->ysiz - 0.75;
+    }
+  }
+
+  /* Determine axis limits and label interval.  Use user
+     supplied AXLIM if available.  Also try to use most recent
+     limits if frame hasn't been cleared -- if rotated, force
+     use of most recent limits, since we don't plot new axis.  */
+
+  cint = 0.0;
+  gacsel (cmin,cmax,&cint,&cmn,&cmx);
+  if (cint==0.0) {
+    cmn = cmin-5.0;
+    cmx = cmin+5.0;
+    cint = 2.0;
+  } else {
+    cmn = cmn - 2.0*cint;
+    cmx = cmx + 2.0*cint;
+  }
+  axmov = 1;
+
+  if (pcm->aflag == -1 || (rotflg && pcm->pass>0)) {
+    /* put check for 0 value if doing a second + plot on the same page
+       this means that the scaling from the first plot is not appropriate  */
+    if(!(pcm->rmin == 0 && pcm->rmax == 0)) {
+      cmn = pcm->rmin;
+      cmx = pcm->rmax;
+      cint = pcm->rint;
+    }
+    axmov = 0;
+    
+  } else if (pcm->aflag == 1) {
+    if ( (cmin > (pcm->rmin-pcm->rint*2.0)) &&
+         (cmax < (pcm->rmax+pcm->rint*2.0)) ) {
+      cmn = pcm->rmin;
+      cmx = pcm->rmax;
+      cint = pcm->rint;
+      axmov = 0;
+    }
+  }
+
+  if (!pcm->ylpflg && axmov && pcm->yllow>0.0) {
+    pcm->ylpos = pcm->ylpos - pcm->yllow - 0.1;
+  }
+  pcm->yllow = 0.0;
+
+  /* Set absolute coordinate scaling for this grid.
+     Note that this code assumes knowledge of the time
+     coordinate scaling setup -- namely, that the same
+     vals are used for t2gr as gr2t.                 */
+
+  if (pgr!=NULL) {
+    y1 = cmn; y2 = cmx;
+    if (dim==3) {
+      x1 = t2gr(pgr->ivals,&(pcm->tmin));
+      x2 = t2gr(pgr->ivals,&(pcm->tmax));
+      if (pcm->log1d > 1) {
+        if (cmn<=0.0 || cmx<=0.0) {
+          gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          if (rotflg) { gxproj(galogx); gxback(gaalogx); }
+          else { gxproj(galogy); gxback(gaalogy); }
+          y1 = log10(cmn); y2 = log10(cmx);
+        }
+      }
+    } else {
+      x1 = pcm->dmin[dim];
+      x2 = pcm->dmax[dim];
+      if (pcm->log1d) {  /* Only one kind of 1D scaling at a time */
+        if (pcm->log1d == 1) {
+          if (x1<=0.0 || x2<=0.0) {
+            gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+            gaprnt (1,"Linear scaling used\n");
+          } else {
+            if (rotflg) { gxproj(galogy); gxback(gaalogy); }
+            else { gxproj(galogx); gxback(gaalogx); }
+            x1 = log10(x1); x2 = log10(x2);
+          }
+        }
+        if (pcm->log1d == 2) {
+          if (cmn<=0.0 || cmx<=0.0) {
+            gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+            gaprnt (1,"Linear scaling used\n");
+          } else {
+            if (rotflg) { gxproj(galogx); gxback(gaalogx); }
+            else { gxproj(galogy); gxback(gaalogy); }
+            y1 = log10(cmn); y2 = log10(cmx);
+          }
+        }
+        if (pcm->log1d == 3) {
+          if (cmn<=0.0 || cmx<=0.0 || x1<=0.0 || x2<=0.0) {
+            gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+            gaprnt (1,"Linear scaling used\n");
+          } else {
+            gxproj(galog2); gxback(gaalog2); 
+            y1 = log10(cmn); y2 = log10(cmx);
+            x1 = log10(x1); x2 = log10(x2);
+          }
+        }
+      } 
+      else if (dim==2 && pcm->zlog) {
+        if (x1<=0.0 || x2<=0.0) {
+          gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          if (rotflg) {
+            gxproj(galny);
+            gxback(gaalny);
+          } else {
+            gxproj(galnx);
+            gxback(gaalnx);
+          }
+          x1 = log(x1);
+          x2 = log(x2);
+        }
+      }
+      else if (dim==1 && pcm->coslat) {
+        if (x1 < -90.0 || x2 > 90.0) {
+          gaprnt (1,"Cannot use cos lat scaling when coordinates exceed -90 to 90\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          if (rotflg) {
+            gxproj(gacly);
+            gxback(gaacly);
+          } else {
+            gxproj(gaclx);
+            gxback(gaaclx);
+          }
+          x1 = sin(x1*d2r);
+          x2 = sin(x2*d2r);
+        }
+      }
+    }
+    if (rotflg) {
+      pcm->xdim = 5;  /* hard-coded 4 changed to 5 */
+      pcm->ydim = dim;
+      pcm->ygr2ab = pgr->igrab;
+      pcm->yab2gr = pgr->iabgr;
+      pcm->ygrval = pgr->ivals;
+      pcm->yabval = pgr->iavals;
+      xt1 = y1; xt2 = y2; yt1 = x1; yt2 = x2;
+      if (pcm->xflip) {xt1 = y2; xt2 = y1;}
+      if (pcm->yflip) {yt1 = x2; yt2 = x1;}
+    } else {
+      pcm->xdim = dim;
+      pcm->ydim = 5;  /* hard-coded 4 changed to 5*/
+      pcm->xgr2ab = pgr->igrab;
+      pcm->xab2gr = pgr->iabgr;
+      pcm->xgrval = pgr->ivals;
+      pcm->xabval = pgr->iavals;
+      xt1 = x1; xt2 = x2; yt1 = y1; yt2 = y2;
+      if (pcm->xflip) {xt1 = x2; xt2 = x1;}
+      if (pcm->yflip) {yt1 = y2; yt2 = y1;}
+    }
+    gxscal (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2,xt1,xt2,yt1,yt2);
+    if (rotflg) {
+      if (dim==3) {
+	jconv = NULL;
+      }
+      else {
+        jconv = pgr->igrab;
+        jvars = pgr->ivals;
+      }
+      joffset = pgr->dimmin[dim]-1;
+      iconv = NULL;
+      ioffset = 0;
+    } else {
+      if (dim==3) {
+	iconv = NULL;
+      }
+      else {
+        iconv = pgr->igrab;
+        ivars = pgr->ivals;
+      }
+      ioffset = pgr->dimmin[dim]-1;
+      jconv = NULL;
+      joffset = 0;
+    }
+    gxgrid (gaconv);
+  }   
+  else {
+    if (dim==3) {
+      x1 = t2gr(stn->tvals, &(pcm->tmin));
+      x2 = t2gr(stn->tvals, &(pcm->tmax));
+    } else {
+      x1 = pcm->dmin[dim];
+      x2 = pcm->dmax[dim];
+      if (dim==2 && pcm->zlog) {
+        if (x1<=0.0 || x2<=0.0) {
+          gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          if (rotflg) {
+            gxproj(galny);
+            gxback(gaalny);
+          } else {
+            gxproj(galnx);
+            gxback(gaalnx);
+          }
+          x1 = log(x1);
+          x2 = log(x2);
+        }
+      }
+      if (dim==1 && pcm->coslat) {
+        if (x1 < -90.0 || x2 > 90.0) {
+          gaprnt (1,"Cannot use cos lat scaling when coordinates exceed -90 to 90\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          if (rotflg) {
+            gxproj(gacly);
+            gxback(gaacly);
+          } else {
+            gxproj(gaclx);
+            gxback(gaaclx);
+          }
+          x1 = sin(x1*d2r);
+          x2 = sin(x2*d2r);
+        }
+      }
+    }
+    if (rotflg) {
+      pcm->xdim = 5;
+      pcm->ydim = dim;
+      if (dim==3) pcm->ygrval = stn->tvals;
+      xt1 = cmn; xt2 = cmx; yt1 = x1; yt2 = x2;
+      if (pcm->xflip) {xt1 = cmx; xt2 = cmn;}
+      if (pcm->yflip) {yt1 = x2; yt2 = x1;}
+      gxscal (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2,xt1,xt2,yt1,yt2);
+    } else {
+      pcm->xdim = dim;
+      pcm->ydim = 5;
+      if (dim==3) pcm->xgrval = stn->tvals;
+      xt1 = x1; xt2 = x2; yt1 = cmn; yt2 = cmx;
+      if (pcm->xflip) {xt1 = x1; xt2 = x2;}
+      if (pcm->yflip) {yt1 = cmn; yt2 = cmx;}
+      gxscal (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2,x1,x2,cmn,cmx);
+    }
+  }
+  pcm->rmin = cmn;
+  pcm->rmax = cmx;
+  pcm->rint = cint;
+  if (pcm->aflag == 0) pcm->aflag = 1;
+  gafram (pcm);
+}
+
+/* Set up grid level scaling for a 2-D plot */
+
+void gas2d (struct gacmn *pcm, struct gagrid *pgr, gaint imap) {
+gadouble x1,x2,y1,y2,xt1,xt2,yt1,yt2,d2r;
+gaint idim,jdim;
+
+  d2r = M_PI/180;
+  gxrset (3);       /* Reset all scaling */
+  gxrsmapt();       /* Reset map type */
+
+  /* Set up linear level scaling (level 1) and map level scaling
+     (level 2).  If no map drawn, just do linear level scaling.  */
+
+  idim = pgr->idim;
+  jdim = pgr->jdim;
+  pcm->xdim = idim;
+  pcm->ydim = jdim;
+  pcm->xgrval = pgr->ivals;  pcm->ygrval = pgr->jvals;
+  pcm->xabval = pgr->iavals; pcm->yabval = pgr->javals;
+  pcm->xgr2ab = pgr->igrab;  pcm->ygr2ab = pgr->jgrab;
+  pcm->xab2gr = pgr->iabgr;  pcm->yab2gr = pgr->jabgr;
+  if (idim==0 && jdim==1) {
+    gamscl (pcm);               /* Do map level scaling */
+    if (imap) gawmap(pcm, 1);   /* Draw map if requested */
+  }
+  else {
+    if (pcm->paflg) {
+      pcm->xsiz1 = pcm->pxmin;
+      pcm->xsiz2 = pcm->pxmax;
+      pcm->ysiz1 = pcm->pymin;
+      pcm->ysiz2 = pcm->pymax;
+    } else {
+      pcm->xsiz1 = 1.5; 
+      pcm->xsiz2 = pcm->xsiz-0.5;
+      pcm->ysiz1 = 1.0;
+      pcm->ysiz2 = pcm->ysiz-0.5;
+    }
+    if (idim==3) {
+      x1 = t2gr(pgr->ivals,&(pcm->tmin));
+      x2 = t2gr(pgr->ivals,&(pcm->tmax));
+    } else if (idim==5) {
+      x1 = 1; 
+      x2 = pgr->isiz;  /* COLL */
+    } else {
+      x1 = pcm->dmin[idim];
+      x2 = pcm->dmax[idim];
+      if (idim==2 && pcm->zlog) {
+        if (x1<=0.0 || x2<=0.0) {
+          gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          gxproj(galnx);
+          gxback(gaalnx);
+          x1 = log(x1);
+          x2 = log(x2);
+        }
+      }
+      else if (idim==1 && pcm->coslat) {  /* can't have zlog and coslat both */
+        if (x1 < -90.0 || x2 > 90.0) {
+          gaprnt (1,"Cannot use cos lat scaling when coordinates exceed -90 to 90\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          gxproj(gaclx);
+          gxback(gaaclx);
+          x1 = sin(x1*d2r);
+          x2 = sin(x2*d2r);
+        }
+      }
+    }
+    if (jdim==3) {
+      y1 = t2gr(pgr->jvals,&(pcm->tmin));
+      y2 = t2gr(pgr->jvals,&(pcm->tmax));
+    } else {
+      y1 = pcm->dmin[jdim];
+      y2 = pcm->dmax[jdim];
+      if (jdim==2 && pcm->zlog) {
+        if (y1<=0.0 || y2<=0.0) {
+          gaprnt (1,"Cannot use log scaling when coordinates <= 0\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          gxproj(galny);
+          gxback(gaalny);
+          y1 = log(y1);
+          y2 = log(y2);
+        }
+      }
+      else if (jdim==1 && pcm->coslat) {  /* can't have zlog and coslat both */
+        if (y1 < -90.0 || y2 > 90.0) {
+          gaprnt (1,"Cannot use cos lat scaling when coordinates exceed -90 to 90\n");
+          gaprnt (1,"Linear scaling used\n");
+        } else {
+          gxproj(gacly);
+          gxback(gaacly);
+          y1 = sin(y1*d2r);
+          y2 = sin(y2*d2r);
+        }
+      }
+    }
+    xt1 = x1; xt2 = x2; yt1 = y1; yt2 = y2;
+    if (pcm->xflip) { xt1 = x2; xt2 = x1; }
+    if (pcm->yflip) { yt1 = y2; yt2 = y1; }
+    gxscal (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2,xt1,xt2,yt1,yt2);
+  }
+
+  /* Now set up level 2 grid scaling done through gaconv */
+
+  if (idim==5) ioffset = 0;  /* COLL */
+  else ioffset = pgr->dimmin[idim]-1;
+  if (idim==3) iconv = NULL;
+  else {
+    iconv = pgr->igrab;
+    ivars = pgr->ivals;
+  }
+  if (jdim==5) joffset = 1;  /* COLL */
+  else joffset = pgr->dimmin[jdim]-1;
+  if (jdim==3) jconv = NULL;
+  else {
+    jconv = pgr->jgrab;
+    jvars = pgr->jvals;
+  }
+  gxgrid (gaconv);
+
+  if (idim==5) {   /* COLL -- predefine axis */
+    pcm->rmin = 1;
+    pcm->rmax = (gadouble)(pgr->isiz);
+    pcm->axmin = 1.0;
+    pcm->axmax = pcm->rmax;
+    pcm->axflg = 1;
+    pcm->axint = 1.0;
+  }
+}
+
+/* Line plot fill.  Fill above and below a line plot */
+
+void galfil (struct gacmn *pcm) {
+struct gagrid *pgr1, *pgr2;
+gadouble *gr1,*gr2,rmin,rmax,*v1,*v2,*u,*xy,uu,vv;
+gaint rotflg,sflag,cnt,abflg,i,colr=0;
+char *gr1u,*gr2u;
+size_t sz;
+
+  /* Check args */
+
+  if (pcm->numgrd<2) {
+    gaprnt (0,"Error plotting linefill:  Only one grid provided\n");
+    return;
+  }
+  pgr1 = pcm->result[0].pgr;
+  pgr2 = pcm->result[1].pgr;
+  if (pgr1->idim!=pgr2->idim || pgr1->jdim!=-1 ||
+      pgr2->jdim!=-1 || gagchk(pgr1,pgr2,pgr1->idim)) {
+    gaprnt (0,"Error plotting linefill:  Invalid grids --");
+    gaprnt (0," different scaling\n");
+    return;
+  }
+
+  gamnmx(pgr1);
+  gamnmx(pgr2);
+  if (pgr1->umin==0 || pgr2->umin==0) {
+    gaprnt (1,"Cannot plot data - all undefined values \n");
+    return;
+  }
+  rmin = pgr1->rmin;
+  if (rmin>pgr2->rmin) rmin = pgr2->rmin;
+  rmax = pgr1->rmax;
+  if (rmax<pgr2->rmax) rmax = pgr2->rmax;
+
+  /* Do scaling */
+
+  rotflg = 0;
+  if (pgr1->idim==2) rotflg = 1;
+  if (pcm->rotate) rotflg = !rotflg;
+  gas1d (pcm, rmin, rmax, pgr1->idim, rotflg, pgr1, NULL);
+
+  gxclip (pcm->xsiz1-0.01, pcm->xsiz2+0.01, pcm->ysiz1, pcm->ysiz2);
+
+ /* Allocate some buffer areas */
+
+  sz = sizeof(gadouble)*pgr1->isiz;
+  u  = (gadouble *)galloc(sz,"gridu");
+  v1 = (gadouble *)galloc(sz,"gridv1");
+  v2 = (gadouble *)galloc(sz,"gridv2");
+  sz = sizeof(gadouble)*(pgr1->isiz*4+8);
+  xy = (gadouble *)galloc(sz,"gridxy");
+  if (u==NULL || v1==NULL || v2==NULL || xy==NULL) {
+    gaprnt(0,"Memory allocation error in linefill\n");
+    return;
+  }
+
+  /* Find a start point.  It is the first point where
+     two points in a row are not missing (in both lines)
+     and are not equal.  */
+
+  gr1 = pgr1->grid;
+  gr2 = pgr2->grid;
+  gr1u = pgr1->umask;
+  gr2u = pgr2->umask;
+
+  i = 1;
+  while (1) {
+    if (i>=pgr1->isiz) break;
+    if (*gr1u!=0 && *gr2u!=0 &&
+        *(gr1u+1)!=0 && *(gr2u+1)!=0 &&
+        (*gr1!=*gr2 || *(gr1+1)!=*(gr2+1))) break;
+    i++; gr1++; gr2++; gr1u++; gr2u++;
+  }
+  if (i>=pgr1->isiz) {
+    gree(u,"f280");
+    gree(v1,"f281");
+    gree(v2,"f282");
+    gree(xy,"f283");
+    gaprnt (1,"Cannot plot data - too many undefined values \n");
+    return;
+  }
+
+  /* Set up for loop */
+
+  cnt = 1;
+  *u = i;
+  *v1 = *gr1;
+  *v2 = *gr2;
+  abflg = 0;
+  if (*gr1>*gr2) abflg = 1;
+  if (*gr1<*gr2) abflg = 2;
+  i++; gr1++; gr2++; gr1u++; gr2u++;
+  if (abflg==0) {      /* if 1st point is same for both lines */
+    if (*gr1>*gr2) abflg = 1;
+    if (*gr1<*gr2) abflg = 2;
+  }
+
+  /* Go through rest of data */
+
+  while (i<=pgr1->isiz) {
+    sflag = 0;
+
+    /* If we hit missing data, terminate the current poly fill */
+   
+    if (*gr1u==0 || *gr2u==0) {
+      if (abflg==1) colr=pcm->lfc1;
+      if (abflg==2) colr=pcm->lfc2;
+      if (colr>-1) {
+        gxcolr(colr);
+        lfout (u, v1, v2, xy, cnt, rotflg);
+      }
+      sflag = 1;
+
+    /* No missing data.  Polygon continues until the curves cross.  */  
+
+    } else {
+      if (abflg==0) {   /* this shouldn't really happen? */
+        if (*gr1>*gr2) abflg = 1;
+        else if (*gr1<*gr2) abflg = 2;
+        else sflag = 1;
+      } else if (abflg==1) {
+        if (*gr1<*gr2) {  /* Curves crossed */
+          lfint (*(v1+cnt-1),*gr1,*(v2+cnt-1),*gr2,&uu,&vv);
+          uu = uu + (gadouble)(i-1);
+          *(u+cnt) = uu;
+          *(v1+cnt) = vv;
+          *(v2+cnt) = vv;
+          cnt++;
+          if (abflg==1) colr=pcm->lfc1;
+          if (abflg==2) colr=pcm->lfc2;
+          if (colr>-1) {
+            gxcolr(colr);
+            lfout (u, v1, v2, xy, cnt, rotflg);
+          }
+          *u = uu; *v1 = vv; *v2 = vv;
+          *(u+1) = i; *(v1+1) = *gr1; *(v2+1) = *gr2;
+          cnt = 2;
+          abflg = 2;
+        } else if (*gr1==*gr2) {  /* Curves touching */
+          *(v1+cnt) = *gr1;
+          *(v2+cnt) = *gr2;
+          *(u+cnt) = i;
+          cnt++;
+          if (abflg==1) colr=pcm->lfc1;
+          if (abflg==2) colr=pcm->lfc2;
+          if (colr>-1) {
+            gxcolr(colr);
+            lfout (u, v1, v2, xy, cnt, rotflg);
+          }
+          sflag = 1;
+        } else {    /* curves not crossing; add to poygon */
+          *(u+cnt) = i;
+          *(v1+cnt) = *gr1;
+          *(v2+cnt) = *gr2;
+          cnt++;
+        }
+      } else if (abflg==2) {
+        if (*gr1>*gr2) {
+          lfint (*(v1+cnt-1),*gr1,*(v2+cnt-1),*gr2,&uu,&vv);
+          uu = uu + (gadouble)(i-1);
+          *(u+cnt) = uu;
+          *(v1+cnt) = vv;
+          *(v2+cnt) = vv;
+          cnt++;
+          if (abflg==1) colr=pcm->lfc1;
+          if (abflg==2) colr=pcm->lfc2;
+          if (colr>-1) {
+            gxcolr(colr);
+            lfout (u, v1, v2, xy, cnt, rotflg);
+          }
+          *u = uu; *v1 = vv; *v2 = vv;
+          *(u+1) = i; *(v1+1) = *gr1; *(v2+1) = *gr2;
+          cnt = 2;
+          abflg = 1;
+        } else if (*gr1==*gr2) {
+          *(v1+cnt) = *gr1;
+          *(v2+cnt) = *gr2;
+          *(u+cnt) = i;
+          cnt++;
+          if (abflg==1) colr=pcm->lfc1;
+          if (abflg==2) colr=pcm->lfc2;
+          if (colr>-1) {
+            gxcolr(colr);
+            lfout (u, v1, v2, xy, cnt, rotflg);
+          }
+          sflag = 1;
+        } else {
+          *(u+cnt) = i;
+          *(v1+cnt) = *gr1;
+          *(v2+cnt) = *gr2;
+          cnt++;
+        }
+      }
+    }
+
+    /* If necessary, search for new start point */
+
+    if (sflag) {
+      while (1) {
+        if (i>=pgr1->isiz) break;
+        if (*gr1u!=0 && *gr2u!=0 &&
+            *(gr1u+1)!=0 && *(gr2u+1)!=0 &&
+            (*gr1!=*gr2 || *(gr1+1)!=*(gr2+1))) break;
+        i++; gr1++; gr2++; gr1u++; gr2u++;
+      }
+      if (i<pgr1->isiz) {
+        cnt = 1;
+        *u = i;
+        *v1 = *gr1;
+        *v2 = *gr2;
+        abflg = 0;
+        if (*gr1>*gr2) abflg = 1;
+        if (*gr1<*gr2) abflg = 2;
+        i++; gr1++; gr2++; gr1u++; gr2u++;
+        if (abflg==0) { 
+          if (*gr1>*gr2) abflg = 1;
+          if (*gr1<*gr2) abflg = 2;
+        }
+      } else {
+        cnt = 0;
+        i = pgr1->isiz+1;
+      }
+    } else {
+      i++; gr1++; gr2++; gr1u++; gr2u++;
+    }
+  }
+
+  /* Finish up and plot last poly */
+
+  if (cnt>1) {
+    if (abflg==1) colr=pcm->lfc1;
+    if (abflg==2) colr=pcm->lfc2;
+    if (colr>-1) {
+      gxcolr(colr);
+      lfout (u, v1, v2, xy, cnt, rotflg);
+    }
+  }
+  gree(u,"f284");
+  gree(v1,"f285");
+  gree(v2,"f286");
+  gree(xy,"f287");
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  if (rotflg) 
+    gaaxpl(pcm,5,pgr1->idim);      /* hard coded 4's changed to 5's */
+  else 
+    gaaxpl(pcm,pgr1->idim,5);      /* hard coded 4's changed to 5's */
+  gxwide (pcm->annthk-3);
+  gxcolr (pcm->anncol);
+  if (pcm->pass==0 && pcm->grdsflg)
+           gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gagsav (17,pcm,pgr1);
+}
+
+void lfint (gadouble v11, gadouble v12, gadouble v21, gadouble v22, gadouble *u, gadouble *v) {
+  *u = (v21-v11)/(v12-v11-v22+v21);
+  *v = v11 + *u*(v12-v11);
+}
+
+void lfout (gadouble *u, gadouble *v1, gadouble *v2, gadouble *xyb, gaint cnt, gaint rotflg) {
+gaint i,j,ii;
+gadouble *xy;
+
+  xy = xyb;
+  if (cnt<2) {
+    gaprnt (0,"Internal Logic check 4 in linefill\n");
+    return;
+  }
+  j = 0;
+  for (i=0; i<cnt; i++) {
+    if (rotflg) gxconv (*(v1+i),*(u+i),xy,xy+1,3);
+    else gxconv (*(u+i),*(v1+i),xy,xy+1,3);
+    j++; xy+=2;
+  }
+  i = cnt-1;
+  if (*(v1+i) != *(v2+i) ) {
+    if (rotflg) gxconv (*(v2+i),*(u+i),xy,xy+1,3);
+    else gxconv (*(u+i),*(v2+i),xy,xy+1,3);
+    j++; xy+=2;
+  }
+  for (i=2; i<cnt; i++) {
+    ii = cnt-i;
+    if (rotflg) gxconv (*(v2+ii),*(u+ii),xy,xy+1,3);
+    else gxconv (*(u+ii),*(v2+ii),xy,xy+1,3);
+    j++; xy+=2;
+  }
+  if (*v1 != *v2) {
+    if (rotflg) gxconv (*v2,*u,xy,xy+1,3);
+    else gxconv (*u,*v2,xy,xy+1,3);
+    j++; xy+=2;
+  }
+  gxfill (xyb,j);
+}
+
+/* Do line graph (barflg=0) or bar graph (barflg=1) or
+   1-D wind vector/barb plot (barflg=2) */
+
+void gagrph (struct gacmn *pcm, gaint barflg) {
+struct gagrid *pgr,*pgr2=NULL,*pgr3=NULL;
+gadouble x1,x2,y1,y2,x,y,xz,yz,rmin,rmax,xx,yy;
+gadouble *gr,*gr2=0,*gr3=0;
+gadouble gap,umax,vmax,vscal=0,dir;
+gaint ip,i,im,bflg,rotflg,flag,pflg,hflg=0,hemflg;
+char *gru,*gr2u=NULL,*gr3u=NULL;
+
+  /* Determine min and max */
+
+  pgr = pcm->result[0].pgr;
+  gamnmx(pgr);
+  if (pgr->umin==0) {
+    gaprnt (1,"Cannot plot data - all undefined values \n");
+    gxcolr(1);
+    if (pcm->dwrnflg) gxchpl ("Entire Grid Undefined",21,3.0,4.5,0.3,0.25,0.0);
+    return;
+  }
+  rmin = pgr->rmin; 
+  rmax = pgr->rmax;
+
+  flag = 0;
+  if (pcm->numgrd>1) {
+    flag = 1;
+    pgr2 = pcm->result[1].pgr;
+    if (pgr2->idim!=pgr->idim || pgr2->jdim!=pgr->jdim ||
+        gagchk(pgr2,pgr,pgr->idim) || gagchk(pgr2,pgr,pgr->jdim)) {
+      flag = 0;
+      gaprnt (0,"Error in line/bar graph:  Invalid 2nd field");
+      gaprnt (0,"   2nd grid ignored -- has different scaling");
+    } else {
+      if (barflg==1) {
+        gamnmx(pgr2);
+        if (pgr2->umin==0) {
+          gaprnt (1,"Cannot plot data - 2nd arg all undefined values \n");
+          return;
+        }
+        if (rmin>pgr2->rmin) rmin = pgr2->rmin;
+        if (rmax<pgr2->rmax) rmax = pgr2->rmax;
+      }
+    }
+    if (pcm->numgrd>2 && flag==1) {
+      flag = 2;
+      pgr3 = pcm->result[2].pgr;
+      if (pgr3->idim!=pgr->idim || pgr3->jdim!=pgr->jdim ||
+          gagchk(pgr3,pgr,pgr->idim) || gagchk(pgr3,pgr,pgr->jdim)) {
+        flag = 1;
+        gaprnt (0,"Error in line/bar graph:  Invalid 3rd field");
+        gaprnt (0,"   3rd grid ignored -- has different scaling");
+      }
+    }
+  }
+
+  /* Do scaling */
+
+  rotflg = 0;
+  if (pgr->idim==2) rotflg = 1;
+  if (pcm->rotate) rotflg = !rotflg;
+  gas1d (pcm, rmin, rmax, pgr->idim, rotflg, pgr, NULL);
+
+  /* Set up graphics */
+
+  if (pcm->ccolor<0) pcm->ccolor=1;
+  gxcolr (pcm->ccolor);
+  gxstyl(pcm->cstyle);
+  gxwide (pcm->cthick);
+  gr  = pgr->grid;
+  gru = pgr->umask;
+  if (flag) {
+    gr2  = pgr2->grid;
+    gr2u = pgr2->umask;
+  }
+  gxclip (pcm->xsiz1-0.01, pcm->xsiz2+0.01, pcm->ysiz1, pcm->ysiz2);
+
+  /* Do bar graph */
+
+  if (barflg) {
+    bflg = pcm->barflg;
+    gap = ((gadouble)pcm->bargap)*0.5/100.0;
+    gap = 0.5-gap;
+    if (rotflg) {
+      if (bflg==1) gxconv (pcm->barbase,1.0,&xz,&y,3);
+      else if (bflg==0) xz = pcm->xsiz1;
+      else xz = pcm->xsiz2;
+      if (bflg==1 && (xz<pcm->xsiz1||xz>pcm->xsiz2)) {
+        gaprnt(0,"Error drawing bargraph: base value out of range\n");
+        gaprnt(0,"    Drawing graph from bottom\n");
+        bflg = 0;
+        xz = pcm->xsiz1;
+      }
+      for (i=1;i<=pgr->isiz;i++) {
+        pflg = 1;
+        if (flag) {
+          if (*gru == 0 || *gr2u == 0) {
+            pflg=0;
+          } else {
+            gxconv (*gr,(gadouble)(i)-gap,&x2,&y1,3);
+            gxconv (*gr,(gadouble)(i)+gap,&x2,&y2,3);
+            gxconv (*gr,(gadouble)(i),&x2,&yz,3);
+            gxconv (*gr2,(gadouble)(i),&x1,&yz,3);
+          }
+        } else {
+          if (*gru == 0) {
+            pflg = 0;
+          } else {
+            gxconv (*gr,(gadouble)(i)-gap,&x2,&y1,3);
+            gxconv (*gr,(gadouble)(i)+gap,&x2,&y2,3);
+            gxconv (*gr,(gadouble)(i),&x2,&yz,3);
+            x1 = xz;
+          }
+        }
+        if (pflg) {
+          if (barflg==2) {
+            gxplot(x1,yz,3);
+            gxplot(x2,yz,2);
+            gxplot(x1,y1,3);
+            gxplot(x1,y2,2);
+            gxplot(x2,y1,3);
+            gxplot(x2,y2,2);
+          } else if (pcm->barolin) {
+            gxplot(x1,y1,3);
+            gxplot(x1,y2,2);
+            gxplot(x2,y2,2);
+            gxplot(x2,y1,2);
+            gxplot(x1,y1,2);
+          } else gxrecf (xz, x, y1, y2);
+        }
+        gr++; gru++;
+        if (flag) {
+	  gr2++; gr2u++;
+	}
+      }
+    } else {
+      if (bflg==1) gxconv (1.0,pcm->barbase,&x,&yz,3);
+      else if (bflg==0) yz = pcm->ysiz1;
+      else yz = pcm->ysiz2;
+      if (bflg==1 && (yz<pcm->ysiz1||yz>pcm->ysiz2)) {
+        gaprnt(0,"Error drawing bargraph: base value out of range\n");
+        gaprnt(0,"    Drawing graph from bottom\n");
+        bflg = 0;
+        yz = pcm->ysiz1;
+      }
+      for (i=1;i<=pgr->isiz;i++) {
+        pflg = 1;
+        if (flag) {
+          if (*gru == 0 || *gr2u == 0) {
+            pflg=0;
+          } else {
+            gxconv ((gadouble)(i)-gap,*gr,&x1,&y1,3);
+            gxconv ((gadouble)(i)+gap,*gr,&x2,&y1,3);
+            gxconv ((gadouble)(i),*gr,&xz,&y1,3);
+            gxconv ((gadouble)(i),*gr2,&xz,&y2,3);
+          }
+        } else {
+          if (*gru == 0) {
+            pflg = 0;
+          } else {
+            gxconv ((gadouble)(i)-gap,*gr,&x1,&y1,3);
+            gxconv ((gadouble)(i)+gap,*gr,&x2,&y1,3);
+            gxconv ((gadouble)(i),*gr,&xz,&y1,3);
+            y2 = yz;
+          }
+        }
+        if (pflg) {
+          if (barflg==2) {
+            gxplot(xz,y1,3);
+            gxplot(xz,y2,2);
+            gxplot(x1,y1,3);
+            gxplot(x2,y1,2);
+            gxplot(x1,y2,3);
+            gxplot(x2,y2,2);
+          } else if (pcm->barolin) {
+            gxplot(x1,y1,3);
+            gxplot(x1,y2,2);
+            gxplot(x2,y2,2);
+            gxplot(x2,y1,2);
+            gxplot(x1,y1,2);
+          } else gxrecf (x1, x2, y1, y2);
+        }
+        gr++; gru++;
+        if (flag) {
+	  gr2++; gr2u++;
+	}
+      }
+    }
+
+  /* Do line graph, or wind vectors/barbs when 3 grids */
+
+  } else {
+
+    /*  Draw the line first */
+
+    if (pcm->cstyle!=0 && flag<2) {
+      ip=3;
+      for (i=1;i<=pgr->isiz;i++) {
+        if (*gru == 0) {
+          if (!pcm->miconn) ip = 3;
+        } else {
+          if (rotflg) gxconv (*gr,(gadouble)i,&x,&y,3);
+          else gxconv ((gadouble)i,*gr,&x,&y,3);
+          gxplot (x,y,ip);
+          ip=2;
+        }
+        gr++; gru++;
+      }
+    }
+
+    /* Now draw the markers, or wind vectors/barbs */
+
+    im = pcm->cmark;
+    if (im>0 || flag==2) {
+      gxstyl (1);
+      gr=pgr->grid;
+      gru=pgr->umask;
+      if (flag==2) {   /* if vectors/barbs, get ready */
+        gr2 = pgr2->grid;
+        gr3 = pgr3->grid;
+        gr2u = pgr2->umask;
+        gr3u = pgr3->umask;
+
+        /* hflg=0 idim is lat
+           hflg=2 plot nhem
+           hflg=3 plot shem */
+
+        if (pcm->hemflg==0) hflg = 2;
+        else if (pcm->hemflg==1) hflg = 3;
+        else {
+          if (pgr2->idim==1) hflg = 0;
+          else {
+            if (pcm->dmin[1] < 0.0) hflg = 3; 
+            else hflg = 2;
+          }
+        }
+        if (!pcm->arrflg) {
+          gamnmx (pgr2);
+          gamnmx (pgr3);
+          umax = pgr2->rmax;
+          if (umax<fabs(pgr2->rmin)) umax = fabs(pgr2->rmin);
+          vmax = pgr3->rmax;
+          if (vmax<fabs(pgr3->rmin)) vmax = fabs(pgr3->rmin);
+          vscal = hypot(umax,vmax);
+          if (vscal>0.0) {
+            x = floor(log10(vscal));
+            y = floor(vscal/pow(10.0,x));
+            vscal = y * pow(10.0,x);
+            pcm->arrsiz = 0.5;
+          } else vscal=1.0;
+          pcm->arrmag = vscal;
+        } else {
+          vscal = pcm->arrmag;
+        }
+        pcm->arrflg = 1;
+      }
+      for (i=1;i<=pgr->isiz;i++) {
+        if (*gru != 0) {
+          if (rotflg) gxconv (*gr,(gadouble)i,&x,&y,3);
+          else gxconv ((gadouble)i,*gr,&x,&y,3);
+          if (flag==2) {   /* handle vectors/barbs */
+             /*  xcv */
+            if (*gr2u != 0 && *gr3u != 0) {
+              if (rotflg) gxgrmp (*gr,(gadouble)i,&xx,&yy);
+              else gxgrmp ((gadouble)i,*gr,&yy,&xx);
+              hemflg = 0;
+              if (hflg==0 && yy<0.0) hemflg = 1;
+              if (hflg==3) hemflg = 1;
+              if (*gr2==0.0 && *gr3==0.0) dir = 0.0;
+              else dir = atan2(*gr3,*gr2);
+              if (pcm->gout1a==2) {
+                gabarb (x, y, pcm->digsiz*3.5, pcm->digsiz*2.0,
+                   pcm->digsiz*0.25, dir, hypot(*gr2,*gr3), hemflg);
+              } else {
+                if (vscal>0.0) {
+                  gaarrw (x, y, dir, pcm->arrsiz*hypot(*gr2,*gr3)/vscal, pcm->ahdsiz);
+                } else {
+                  gaarrw (x, y, dir, pcm->arrsiz, pcm->ahdsiz);
+                }
+              }
+            }
+          } else {
+            if (im==1 || im==2 || im==4 || im==8) {
+              gxcolr (gxqbck());
+              if (im==1) gxmark (4,x,y,pcm->digsiz+0.01);
+              else gxmark (im+1,x,y,pcm->digsiz+0.01);
+              gxcolr(pcm->ccolor);
+            }
+            gxmark (im,x,y,pcm->digsiz+0.01);
+          }
+        }
+        gr++; gru++;
+        if (flag==2) { 
+	  gr2++; gr3++; 
+	  gr2u++; gr3u++;
+	}
+      }
+    }
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  if (rotflg) 
+    gaaxpl(pcm,5,pgr->idim);   /* hard coded 4 changed to 5 */
+  else 
+    gaaxpl(pcm,pgr->idim,5);   /* hard coded 4 changed to 5 */
+  gxwide (pcm->annthk-3);
+  gxcolr (pcm->anncol);
+  if (pcm->pass==0 && pcm->grdsflg)
+           gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  if (barflg) gagsav (8,pcm,pgr);
+  else  gagsav (6,pcm,pgr);
+}
+
+/* Do 2-D streamlines */
+
+void gastrm (struct gacmn *pcm) {
+struct gagrid *pgru, *pgrv, *pgrc=NULL;
+gadouble *u, *v, *c=0;
+gaint flag,lcol;
+char *umask, *vmask, *cmask=NULL;
+
+  if (pcm->numgrd<2) {
+    gaprnt (0,"Error plotting streamlines:  Only one grid provided\n");
+    return;
+  }
+  pgru = pcm->result[0].pgr;
+  pgrv = pcm->result[1].pgr;
+  if (pgru->idim!=pgrv->idim || pgru->jdim!=pgrv->jdim ||
+      gagchk(pgru,pgrv,pgru->idim) || gagchk(pgru,pgrv,pgru->jdim)) {
+    gaprnt (0,"Error plotting streamlines:  Invalid grids\n");
+    gaprnt (0,"   Vector component grids have difference scaling\n");
+    return;
+  }
+  flag = 0;
+  if (pcm->numgrd>2) {
+    flag = 1;
+    pgrc = pcm->result[2].pgr;
+    if (pgrc->idim!=pgru->idim || pgrc->jdim!=pgru->jdim ||
+        gagchk(pgrc,pgru,pgru->idim) || gagchk(pgrc,pgru,pgru->jdim)) {
+      flag = 0;
+      gaprnt (0,"Error plotting streamlines:  Invalid color grid");
+      gaprnt (0,"   Color grid ignored -- has different scaling");
+    }
+  }
+
+  if ( (pcm->rotate && (pgru->idim!=2 || pgru->jdim!=3)) ||
+      (!pcm->rotate && pgru->idim==2 && pgru->jdim==3)) {
+    pgru = gaflip(pgru,pcm);
+    pgrv = gaflip(pgrv,pcm);
+    if (flag) pgrc = gaflip(pgrc,pcm);
+  }
+
+  gxstyl (1);
+  gxwide (1);
+  gas2d (pcm, pgru, 1);     /* Set up scaling, draw map if apprprt */
+
+  gafram (pcm);
+  idiv = 1.0; jdiv = 1.0;
+
+  if (flag) {
+    gamnmx (pgrc);
+    if (pgrc->umin==0) {
+      gaprnt (0,"Connot color vectors -- Color grid all undefined\n");
+      flag = 0;
+    } else gaselc(pcm,pgrc->rmin,pgrc->rmax);
+  }
+
+  u = pgru->grid;
+  v = pgrv->grid;
+  umask = pgru->umask;
+  vmask = pgrv->umask;
+  if (flag) {
+    c = pgrc->grid;
+    cmask = pgrc->umask;
+  }
+
+  if (pcm->ccolor>=0) lcol = pcm->ccolor;
+  else lcol=1;
+  gxcolr (lcol);
+  gxstyl(pcm->cstyle);
+  gxwide(pcm->cthick);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  if (flag) {
+    gxstrm (u,v,c,pgru->isiz,pgru->jsiz,umask,vmask,cmask,flag,
+      pcm->shdlvs,pcm->shdcls,pcm->shdcnt,pcm->strmden,
+      pcm->strmarrd,pcm->strmarrsz, pcm->strmarrt);
+  } else {
+    gxstrm (u,v,NULL,pgru->isiz,pgru->jsiz,umask,vmask,0,flag,
+      pcm->shdlvs,pcm->shdcls,pcm->shdcnt,pcm->strmden,
+      pcm->strmarrd,pcm->strmarrsz, pcm->strmarrt);
+  }
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxwide (pcm->annthk-3);
+  gxcolr (pcm->anncol);
+  if (pcm->pass==0 && pcm->grdsflg)
+       gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gaaxpl(pcm,pgru->idim,pgru->jdim);
+  gagsav (9,pcm,pgru);
+}
+
+/* Do 2-D vector plot */
+
+void gavect (struct gacmn *pcm, gaint brbflg) {
+struct gagrid *pgru, *pgrv, *pgrc=NULL;
+gadouble *u, *v, *c=0, x, y, lon, lat, umax, vmax;
+gadouble vscal, adj, dir;
+gaint i, j, flag, lcol, len, hemflg, hflg;
+char *umask,*vmask,*cmask=NULL;
+
+  if (pcm->numgrd<2) {
+    gaprnt (0,"Error plotting vector field:  Only one grid provided\n");
+    return;
+  }
+  pgru = pcm->result[0].pgr;
+  pgrv = pcm->result[1].pgr;
+  if (pgru->idim!=pgrv->idim || pgru->jdim!=pgrv->jdim ||
+      gagchk(pgru,pgrv,pgru->idim) || gagchk(pgru,pgrv,pgru->jdim)) {
+    gaprnt (0,"Error plotting vector/barb field:  Invalid grids\n");
+    gaprnt (0,"   Vector component grids have difference scaling\n");
+    return;
+  }
+  flag = 0;
+  if (pcm->numgrd>2) {
+    flag = 1;
+    pgrc = pcm->result[2].pgr;
+    if (pgrc->idim!=pgru->idim || pgrc->jdim!=pgru->jdim ||
+        gagchk(pgrc,pgru,pgru->idim) || gagchk(pgrc,pgru,pgru->jdim)) {
+      flag = 0;
+      gaprnt (0,"Error plotting vector/barb field:  Invalid color grid");
+      gaprnt (0,"   Color grid ignored -- has different scaling");
+    }
+  }
+
+  if ( (pcm->rotate && (pgru->idim!=2 || pgru->jdim!=3)) ||
+      (!pcm->rotate && pgru->idim==2 && pgru->jdim==3)) {
+    pgru = gaflip(pgru,pcm);
+    pgrv = gaflip(pgrv,pcm);
+    if (flag) pgrc = gaflip(pgrc,pcm);
+  }
+
+  gxstyl (1);
+  gxwide (1);
+  gas2d (pcm, pgru, 1);     /* Set up scaling, draw map if apprprt */
+
+  gafram (pcm);
+  idiv = 1.0; jdiv = 1.0;
+
+  if (flag) {
+    gamnmx (pgrc);
+    if (pgrc->umin==0) {
+      gaprnt (0,"Cannot color vectors/barbs -- Color grid all undefined\n");
+      flag = 0;
+    } else gaselc(pcm,pgrc->rmin,pgrc->rmax);
+  }
+
+  gamnmx (pgru);
+  gamnmx (pgrv);
+  if (pgru->umin==0) {
+    gaprnt (0,"Cannot draw vectors/barbs -- U field all undefined\n");
+    return;
+  }
+  if (pgrv->umin==0) {
+    gaprnt (0,"Cannot draw vectors/barbs -- V field all undefined\n");
+    return;
+  }
+
+  if (pcm->ccolor>=0) lcol = pcm->ccolor;
+  else lcol=1;
+  gxcolr (lcol);
+  gxstyl(1);
+  gxwide(pcm->cthick);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+  if (!pcm->arrflg) {
+    umax = pgru->rmax;
+    if (umax<fabs(pgru->rmin)) umax = fabs(pgru->rmin);
+    vmax = pgrv->rmax;
+    if (vmax<fabs(pgrv->rmin)) vmax = fabs(pgrv->rmin);
+    vscal = hypot(umax,vmax);
+    if (vscal>0.0) {
+      x = floor(log10(vscal));
+      y = floor(vscal/pow(10.0,x));
+      vscal = y * pow(10.0,x);
+      pcm->arrsiz = 0.5;
+    } else vscal=1.0;
+    pcm->arrmag = vscal;
+  } else {
+    vscal = pcm->arrmag;
+  }
+  pcm->arrflg = 1;
+
+  u = pgru->grid;
+  v = pgrv->grid;
+  umask = pgru->umask;
+  vmask = pgrv->umask;
+  if (flag) {
+    c = pgrc->grid;
+    cmask = pgrc->umask;
+  }
+
+  /* hflg=0 idim is lat
+     hflg=1 jdim is lat
+     hflg=2 plot nhem
+     hflg=3 plot shem */
+
+  if (pcm->hemflg==0) hflg = 2;
+  else if (pcm->hemflg==1) hflg = 3;
+  else {
+    if (pgru->idim==1) hflg = 0;
+    else if (pgru->jdim==1) hflg = 1;
+    else {
+      if (pcm->dmin[1] < 0.0) hflg = 3; 
+      else hflg = 2;
+    }
+  }
+  for (j=1; j<=pgru->jsiz; j++) {
+  for (i=1; i<=pgru->isiz; i++) {
+    if (*umask!=0 && *vmask!=0) {
+      gxconv ((gadouble)i,(gadouble)j,&x,&y,3);
+      gxgrmp ((gadouble)i,(gadouble)j,&lon,&lat);
+      adj = gxaarw (lon, lat);
+      if (adj < -900.0) {
+        gaprnt(0,"Error: vector/barb not compatible with current map projection\n");
+        return;
+      }
+      hemflg = 0;
+      if (hflg==0 && lon<0.0) hemflg = 1;
+      if (hflg==1 && lat<0.0) hemflg = 1;
+      if (hflg==3) hemflg = 1;
+      if (flag) {
+        if (*cmask==0) gxcolr(15);
+        else {
+          lcol = gashdc(pcm,*c);
+          if (lcol>-1) gxcolr(lcol);
+        }
+      }
+      if (lcol>-1) {
+        if (*v==0.0 && *u==0.0) dir = 0.0;
+        else dir = atan2(*v,*u);
+        if (brbflg) {
+          gabarb (x, y, pcm->digsiz*3.5, pcm->digsiz*2.0,
+                  pcm->digsiz*0.25, dir+adj, hypot(*u,*v), hemflg);
+        } else {
+          if (vscal>0.0) {
+            gaarrw (x, y, dir+adj, pcm->arrsiz*hypot(*u,*v)/vscal, pcm->ahdsiz);
+          } else {
+            gaarrw (x, y, dir+adj, pcm->arrsiz, pcm->ahdsiz);
+          }
+        }
+      }
+    }
+    u++; v++; umask++; vmask++;
+    if (flag) { c++; cmask++; }
+  }}
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+
+  if (pcm->arlflg && vscal>0.0 && !brbflg) {
+    gxcolr (pcm->anncol);
+    gxwide (pcm->annthk-2);
+    gaarrw (pcm->xsiz2-2.0,pcm->ysiz1-0.5,0.0,pcm->arrsiz, pcm->ahdsiz);
+    snprintf(pout,255,"%g",vscal);
+    len = strlen(pout);
+    x = pcm->xsiz2 - 2.0 + (pcm->arrsiz/2.0) - 0.5*0.13*(gadouble)len;
+    gxchpl (pout,len,x,pcm->ysiz1-0.7,0.13,0.13,0.0);
+  }
+  gxwide (pcm->annthk-3);
+  gxcolr (pcm->anncol);
+  if (pcm->pass==0 && pcm->grdsflg)
+       gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gaaxpl(pcm,pgru->idim,pgru->jdim);
+  if (brbflg) gagsav (15,pcm,pgru);
+  else gagsav (3,pcm,pgru);
+}
+
+/* Do (for now 2-D) scatter plot */
+
+gaint scatcol[6] = {1,3,2,4,7,8};
+gaint scattyp[6] = {1,6,4,8,7,2};
+
+void gascat (struct gacmn *pcm) {
+struct gagrid *pgr1, *pgr2, *pgrc;
+gadouble *r1, *r2, *c, x, y;
+gadouble cmin1,cmax1,cmin2,cmax2,cint1,cint2;
+gaint siz,i,pass,im,flag,lcol,drawthismark;
+char *r1mask, *r2mask, *cmask;
+
+  if (pcm->numgrd<2) {
+    gaprnt (0,"Error plotting scatter field:  Only one grid provided\n");
+    return;
+  }
+  if (pcm->type[0]==0 || pcm->type[1]==0) {
+    gaprnt (0,"Error plotting scatter field:  stn argument(s) used\n");
+    return;
+  }
+  pgr1 = pcm->result[0].pgr;
+  pgr2 = pcm->result[1].pgr;
+  if (pgr1->idim!=pgr2->idim || pgr1->jdim!=pgr2->jdim ||
+      gagchk(pgr1,pgr2,pgr1->idim) ||
+      (pgr1->jdim>-1 && gagchk(pgr1,pgr2,pgr1->jdim))) {
+    gaprnt (0,"Error plotting scatter plot:  Invalid grids\n");
+    gaprnt (0,"   The two grids have difference scaling\n");
+    return;
+  }
+  flag = 0;
+  if (pcm->numgrd>2) {
+    flag = 1;
+    pgrc = pcm->result[2].pgr;
+    if (pgrc->idim!=pgr1->idim || pgrc->jdim!=pgr2->jdim ||
+        gagchk(pgrc,pgr1,pgr1->idim) || gagchk(pgrc,pgr2,pgr2->jdim)) {
+      flag = 0;
+      gaprnt (0,"Error plotting scatter plot:  Invalid color grid");
+      gaprnt (0,"   Color grid ignored -- has different scaling");
+    }
+  }
+
+  pcm->xdim = 5;  /* hard coded 4's changed to 5's */
+  pcm->ydim = 5;  /* hard coded 4's changed to 5's */
+
+  gamnmx (pgr1);
+  gamnmx (pgr2);
+  if (pgr1->umin==0) {
+    gaprnt (0,"Cannot draw scatter plot -- 1st field all undefined\n");
+    return;
+  }
+  if (pgr2->umin==0) {
+    gaprnt (0,"Cannot draw scatter plot -- 2nd field all undefined\n");
+    return;
+  }
+
+  if (pcm->paflg) {
+    pcm->xsiz1 = pcm->pxmin;
+    pcm->xsiz2 = pcm->pxmax;
+    pcm->ysiz1 = pcm->pymin;
+    pcm->ysiz2 = pcm->pymax;
+  } else {
+    pcm->xsiz1 = 2.0;
+    pcm->xsiz2 = pcm->xsiz - 1.5;
+    pcm->ysiz1 = 1.00;
+    pcm->ysiz2 = pcm->ysiz - 1.00;
+  }
+  gafram (pcm);
+  gxwide (pcm->cthick);
+  idiv = 1.0; jdiv = 1.0;
+
+  if (flag) {
+    gamnmx (pgrc);
+    if (pgrc->umin==0) {
+      gaprnt (0,"Cannot colorize scatterplot -- Color grid all undefined\n");
+      flag = 0;
+    } else gaselc(pcm,pgrc->rmin,pgrc->rmax);
+  }
+
+  if (pcm->aflag != 0) {
+    cmin1 = pcm->rmin;
+    cmax1 = pcm->rmax;
+  } else {
+    cint1 = 0.0;
+    gacsel (pgr1->rmin,pgr1->rmax,&cint1,&cmin1,&cmax1);
+    if (cint1==0.0) {
+      cmin1 = pgr1->rmin-5.0;
+      cmax1 = cmin1+10.0;
+      cint1 = 2.0;
+    } else {
+      cmin1 = cmin1 - 2.0*cint1;
+      cmax1 = cmax1 + 2.0*cint1;
+    }
+  }
+  if (pcm->aflag2 != 0) {
+    cmin2 = pcm->rmin2;
+    cmax2 = pcm->rmax2;
+  } else {
+    cint2 = 0.0;
+    gacsel (pgr2->rmin,pgr2->rmax,&cint2,&cmin2,&cmax2);
+    if (cint2==0.0) {
+      cmin2 = pgr2->rmin-5.0;
+      cmax2 = cmin2+10.0;
+      cint2 = 2.0;
+    } else {
+      cmin2 = cmin2 - 2.0*cint2;
+      cmax2 = cmax2 + 2.0*cint2;
+    }
+  }
+  snprintf(pout,255,"%g %g %g %g \n",cmin1,cmax1,cmin2,cmax2);
+  gaprnt(2,pout);
+  gxscal (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2,
+          cmin1,cmax1,cmin2,cmax2);
+  pass = pcm->gpass[3];
+  if (pass>5) pass=5;
+  gxwide (pcm->cthick);
+  siz = pgr1->isiz*pgr1->jsiz;
+  r1 = pgr1->grid;
+  r2 = pgr2->grid;
+  r1mask = pgr1->umask;
+  r2mask = pgr2->umask;
+  if (flag) {
+    c = pgrc->grid;
+    cmask = pgrc->umask;
+  }
+  for (i=0; i<siz; i++) {
+    if (*r1mask!=0 && *r2mask!=0) {
+      drawthismark=1;
+      /* add color */
+      if (flag) {
+        if (*cmask==0) {
+	  /* if color grid has missing data, use color 15 */
+	  gxcolr(15);
+	}
+        else {
+          lcol = gashdc(pcm,*c);
+          if (lcol>-1) {
+	    gxcolr(lcol);
+	  }
+	  else {
+            drawthismark=0;
+	  }
+        }
+      }
+      else {
+	/* if no color grid is given, draw it the old way */
+	if (pcm->ccolor<0) gxcolr(1);   
+	else gxcolr(pcm->ccolor);
+      }
+      if (drawthismark) {
+	gxconv (*r1,*r2,&x,&y,1);
+	im = pcm->cmark;
+	gxmark (im,x,y,pcm->digsiz*0.5);
+      }
+    }
+    r1++; r2++; r1mask++; r2mask++;
+    if (flag) { c++; cmask++; }
+  }
+
+  pcm->rmin = cmin1;
+  pcm->rmax = cmax1;
+  pcm->rint = cint1;
+  gaaxis(1,pcm,5);   /* hard coded 4's changed to 5's */
+  pcm->rmin = cmin2;
+  pcm->rmax = cmax2;
+  pcm->rint = cint2;
+  gaaxis(0,pcm,5);   /* hard coded 4's changed to 5's */
+
+  pcm->rmin = cmin1;
+  pcm->rmax = cmax1;
+  pcm->aflag = 1;
+  pcm->rmin2 = cmin2;
+  pcm->rmax2 = cmax2;
+  pcm->aflag2 = 1;
+
+  if (cmin1<0.0 && cmax1>0.0) {
+    gxstyl(1);
+    gxwide(3);
+    gxconv (0.0, cmin2, &x, &y, 1);
+    gxplot (x,y,3);
+    gxconv (0.0, cmax2, &x, &y, 1);
+    gxplot (x,y,2);
+  }
+  if (cmin2<0.0 && cmax2>0.0) {
+    gxstyl(1);
+    gxwide(3);
+    gxconv (cmin1, 0.0, &x, &y, 1);
+    gxplot (x,y,3);
+    gxconv (cmax1, 0.0, &x, &y, 1);
+    gxplot (x,y,2);
+  }
+  if (pcm->pass==0 && pcm->grdsflg)
+          gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gagsav (7,pcm,pgr1);
+  pcm->gpass[3]++;
+}
+
+static gadouble a150 = 150.0*M_PI/180.0;
+
+void gaarrw (gadouble x, gadouble y, gadouble ang, gadouble siz, gadouble asiz) {
+gadouble xx,yy;
+
+  if (siz<0.0001) {
+    gxmark (2, x, y, 0.01);
+    return;
+  }
+  gxplot (x,y,3);
+  xx = x+siz*cos(ang);
+  yy = y+siz*sin(ang);
+  gxplot (xx,yy,2);
+  if (asiz==0.0) return;
+  if (asiz<0.0) asiz = -1.0*asiz*siz;
+  gxplot (xx+asiz*cos(ang+a150),yy+asiz*sin(ang+a150),2);
+  gxplot (xx,yy,3);
+  gxplot (xx+asiz*cos(ang-a150),yy+asiz*sin(ang-a150),2);
+}
+
+/* Do 2-D grid value plot */
+
+void gaplvl (struct gacmn *pcm) {
+struct gagrid *pgr,*pgrm=NULL;
+gadouble xlo,ylo,xhi,yhi,*r,*m=0,cwid;
+gaint i,j,len,lcol,flag;
+char *rmask,*mmask=NULL,lab[20];
+
+  pgr = pcm->result[0].pgr;
+  flag = 0;
+  if (pcm->numgrd>1) {
+    flag = 1;
+    pgrm = pcm->result[1].pgr;
+    if (pgrm->idim!=pgr->idim || pgrm->jdim!=pgr->jdim ||
+        gagchk(pgrm,pgr,pgr->idim) || gagchk(pgrm,pgr,pgr->jdim)) {
+      flag = 0;
+      gaprnt (0,"Error plotting grid values:  Invalid Mask grid");
+      gaprnt (0,"   Mask grid ignored -- has different scaling");
+    }
+  }
+
+  if ( (pcm->rotate && (pgr->idim!=2 || pgr->jdim!=3)) ||
+      (!pcm->rotate && pgr->idim==2 && pgr->jdim==3)) {
+    pgr = gaflip(pgr,pcm);
+    if (flag) pgrm = gaflip(pgrm,pcm);
+  }
+
+  gxstyl (1);
+  gxwide (1);
+  gas2d (pcm, pgr, 1);     /* Draw map and set up scaling */
+
+  gafram (pcm);
+  gxwide (pcm->cthick);
+  idiv = 1.0; jdiv = 1.0;
+  if (pcm->ccolor>=0) lcol = pcm->ccolor;
+  else lcol=1;
+  gxcolr(lcol);
+  gxstyl(1);
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  /* Draw grid lines  */
+
+  if (pcm->gridln != -1) {
+    if (pcm->gridln > -1) gxcolr(pcm->gridln);
+    for (i=1; i<=pgr->isiz; i++) {
+      for (j=1; j<=pgr->jsiz; j++) {
+        gxconv ((gadouble)(i)+0.5,(gadouble)(j)-0.5,&xlo,&ylo,3);
+        gxconv ((gadouble)(i)+0.5,(gadouble)(j)+0.5,&xhi,&yhi,3);
+        gxplot (xlo,ylo,3);
+        gxplot (xhi,yhi,2);
+      }
+    }
+
+    for (j=1; j<=pgr->jsiz; j++) {
+      for (i=1; i<=pgr->isiz; i++) {
+        gxconv ((gadouble)(i)-0.5,(gadouble)(j)+0.5,&xlo,&ylo,3);
+        gxconv ((gadouble)(i)+0.5,(gadouble)(j)+0.5,&xhi,&yhi,3);
+        gxplot (xlo,ylo,3);
+        gxplot (xhi,yhi,2);
+      }
+    }
+  }
+
+  r = pgr->grid;
+  rmask = pgr->umask;
+  if (flag) {
+    m = pgrm->grid;
+    mmask = pgrm->umask;
+  }
+  for (j=1; j<=pgr->jsiz; j++) {
+  for (i=1; i<=pgr->isiz; i++) {
+    if (*rmask!=0) {
+      if (flag && *mmask!=0 && *m<=0.0) {
+        gxwide (1);
+        gxcolr (15);
+      } else {
+        gxwide (pcm->cthick);
+        gxcolr (lcol);
+      }
+      gxconv ((gadouble)i,(gadouble)j,&xlo,&ylo,3);
+      snprintf(lab,19,"%.*f",pcm->dignum,(gafloat)*r);
+      len = strlen(lab);
+      cwid = pcm->digsiz*(gadouble)len;
+      gxchln (lab,len,pcm->digsiz,&cwid);
+      gxchpl (lab,len,xlo-cwid*0.5,ylo-pcm->digsiz*0.5,
+              pcm->digsiz,pcm->digsiz,0.0);
+    }
+    r++; rmask++;
+    if (flag) { m++; mmask++; }
+  }}
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide(pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+        gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gaaxpl(pcm,pgr->idim,pgr->jdim);
+  gagsav (4,pcm,pgr);
+
+}
+
+/* Writes out a shapefile */
+
+void gashpwrt (struct gacmn *pcm) {
+#if USESHP==1
+FILE *fp=NULL;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble lon,lat;  
+struct gagrid *pgr=NULL;
+struct gastn *stn=NULL;
+struct garpt *rpt;
+SHPObject *shp;
+gaint *pstart=NULL,nParts,shpid,i,j,gx,grid,len;
+gadouble *gr=NULL,val,dval;
+char *gru=NULL, *prjname=NULL, *fnroot=NULL;
+gaint rc,width,prec,fldindx,ival,error=0;
+char fldname[12];
+SHPHandle sfid=NULL;
+DBFHandle dbfid=NULL;
+struct dbfld *fld=NULL,*newfld=NULL,*nextfld;
+
+
+  /* Make sure projection is latlon */
+  if (pcm->mproj !=2) {
+    gaprnt (0,"Error in gashpwrt: mproj latlon required for gxout shapefile\n");
+    error = 1;
+    goto cleanup;
+  }
+
+  /* Determine if output is a grid or a station result */
+  grid = 1;
+  if (pcm->type[0] == 1) {
+    /* gridded data */
+    pgr = pcm->result[0].pgr;
+    gr  = pgr->grid;
+    gru = pgr->umask;
+
+    /* Make sure grid varies in X and Y */
+    if (pgr->idim!=0 || pgr->jdim!=1) {
+      gaprnt(0,"Error in gashpwrt: grid is not varying in X and Y \n");
+      error = 1;
+      goto cleanup;
+    }
+    /* set up scaling without the map (this is not done in gacntr when shpflg=1) */
+    gas2d (pcm, pgr, 0);    
+  }
+  else {
+    /* station data */
+    grid = 0;
+    stn = pcm->result[0].stn;
+    /* shapefile type is always point for station data */
+    if (pcm->shptype!=1) {
+      gaprnt(0,"Error in gashpwrt: Incorrect shapefile output type for station data \n");
+      gaprnt(0,"   You must use the -pt option with the 'set shp' command \n");
+      error = 1;
+      goto cleanup;
+    }
+    /* Make sure reports are not all undefined */
+    gasmnmx (stn);
+    if (dequal(stn->smin,stn->undef,1e-12)==0 || 
+	dequal(stn->smax,stn->undef,1e-12)==0) {
+      gaprnt (0,"Error in gashpwrt: all reports are undefined \n");
+      error = 1;
+      goto cleanup;
+    }
+    if (dequal(stn->smin,stn->smax,1e-12)==0) {
+      snprintf(pout,255,"Warning from gashpwrt: all reports have the same value = %g\n",stn->smin);
+      gaprnt(2,pout);
+    }
+    /* Do map level scaling (copied from gasmrk) */
+    gamscl (pcm);
+  }
+
+  /* Create the output files */
+  if (pcm->shpfname == NULL) {
+    fnroot = (char *)galloc(6,"shpfn");
+    snprintf(fnroot,6,"grads");
+  }
+  else {
+    len = strlen(pcm->shpfname);
+    fnroot = (char *)galloc(len+1,"shpfn");
+    snprintf(fnroot,len+1,pcm->shpfname);
+  }
+  if ((dbfid = DBFCreate(fnroot))==NULL) {
+    gaprnt(0,"Error in gashpwrt: Unable to create data base file\n");
+    error = 1; goto cleanup;
+  }
+  if (pcm->shptype==1) {
+    if ((sfid = SHPCreate(fnroot,SHPT_POINTM))==NULL) {
+      gaprnt(0,"Error in gashpwrt: Unable to create shapefile for point data\n");
+      error = 1; goto cleanup;
+    }
+  } 
+  else if (pcm->shptype==2) {
+    if ((sfid = SHPCreate(fnroot,SHPT_ARCM))==NULL) {
+      gaprnt(0,"Error in gashpwrt: Unable to create shapefile for contour lines\n");
+      error = 1; goto cleanup;
+    }
+  } 
+  else {
+    if ((sfid = SHPCreate(fnroot,SHPT_POLYGONM))==NULL) {
+      gaprnt(0,"Error in gashpwrt: Unable to create shapefile for polygons\n");
+      error = 1; goto cleanup;
+    }
+  }
+  /* Set up the list of data base fields. */
+
+  /* Allocate a new field, the GrADS version, set it as the anchor in the local chain */
+  snprintf(pout,255,"GrADS-"GRADS_VERSION"");
+  len = strlen(pout);
+  fld = newdbfld("CREATED_BY", FTString, len, 0, 0, pout);
+  if (fld==NULL) {
+    error = 1; goto cleanup;
+  }
+  if (dbanch==NULL) 
+    dbanch = fld;                      /* this is the first field */
+  else 
+    dblast->next = fld;                /* hang it off the end of the chain */
+  dblast = fld;                        /* reset the last pointer */
+  dblast->next = NULL;                 /* make sure the chain is terminated */
+
+  /* Copy the user-provided fields that are linked off of gacmn onto the local chain */
+  if (pcm->dbfld) { 
+    fld = pcm->dbfld;  
+    while (fld) {
+      if ((newfld = (struct dbfld*) galloc (sizeof(struct dbfld),"udbfld"))==NULL) {
+	error = 1; goto cleanup;
+      }
+      strcpy(newfld->name,fld->name); 
+      newfld->type  = fld->type;
+      newfld->len   = fld->len;
+      newfld->prec  = fld->prec;
+      newfld->index = fld->index;
+      newfld->flag  = fld->flag;
+      if ((newfld->value = (void*)galloc(fld->len,"newdbval"))==NULL) {
+	gree(newfld,"g292");
+	error = 1; goto cleanup;
+      }
+      strcpy(newfld->value,fld->value);
+      dblast->next = newfld;
+      dblast = newfld;
+      dblast->next = NULL;  
+      fld = fld->next;
+    } 
+  }
+
+  /* Now add more GrADS-provided fields that vary depending on shape file type.
+     These are 'dynamic' dbase fields, where values are different for each shape:
+     grid points: longitude, latitude, and grid value 
+     station points: longitude, latitude, stid, and station value 
+     contours: contour value 
+     polygons: 
+  */
+
+  width = pcm->dblen;
+  prec  = pcm->dbprec;
+  if (pcm->shptype==1) {
+    /* all point types get lon and lat */
+    snprintf(fldname,11,"LONGITUDE");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) {
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    } 
+    snprintf(fldname,11,"LATITUDE");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) {
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    }
+    if (grid) {
+      /* add grid point value */
+      snprintf(fldname,11,"GRID_VALUE");
+      if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+	dblast->next = fld; 
+	dblast = fld;
+	fld->next = NULL;
+      }
+    } else {
+      /* add stid and station data value */
+      snprintf(fldname,11,"STN_ID");
+      if ((fld = newdbfld (fldname, FTString, 9, 0, 1, NULL)) != NULL) {
+	dblast->next = fld; 
+	dblast = fld;
+	fld->next = NULL;
+      }
+      snprintf(fldname,11,"STN_VALUE");
+      if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+	dblast->next = fld; 
+	dblast = fld;
+	fld->next = NULL;
+      }
+    }
+  } else if  (pcm->shptype==2) {
+    /* add contour value */
+    snprintf(fldname,11,"CNTR_VALUE");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    }
+  } else {
+    /* add polygon index number and range values */
+    snprintf(fldname,11,"INDEX");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    }
+    snprintf(fldname,11,"MIN_VALUE");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    }
+    snprintf(fldname,11,"MAX_VALUE");
+    if ((fld = newdbfld (fldname, FTDouble, width, prec, 1, NULL)) != NULL) { 
+      dblast->next = fld; 
+      dblast = fld;
+      fld->next = NULL;
+    }
+  }
+
+  /* Add list of data base fields to the output file */
+  fld = dbanch;  
+  while (fld != NULL) {
+    if (fld->type==FTString) {
+      if ((fldindx = DBFAddField(dbfid,fld->name,FTString,fld->len,0))==-1) {
+	gaprnt(0,"Error in gashpwrt: Unable to add string field to data base file\n");
+	error = 1; goto cleanup;
+      }
+      fld->index = fldindx; 
+    }
+    else if (fld->type==FTInteger) {
+      if ((fldindx = DBFAddField(dbfid,fld->name,FTInteger,fld->len,0))==-1) {
+	gaprnt(0,"Error in gashpwrt: Unable to add integer field to data base file\n");
+	error = 1; goto cleanup;
+      }
+      fld->index = fldindx; 
+    }
+    else if (fld->type==FTDouble) {
+      if (fld->len > pcm->dblen) fld->len = pcm->dblen;
+      if ((fldindx = DBFAddField(dbfid,fld->name,FTDouble,fld->len,pcm->dbprec))==-1) {
+	gaprnt(0,"Error in gashpwrt: Unable to add integer field to data base file\n");
+	error = 1; goto cleanup;
+      }
+      fld->index = fldindx; 
+    }
+    fld = fld->next;
+  }
+  
+  /* Write out point values */
+  if (pcm->shptype==1) {
+
+    /* when you only have one point, pstart will always be zero */
+    nParts = 1;  
+    if ((pstart = (gaint*)galloc(nParts*sizeof(gaint),"pstart"))==NULL) {
+      gaprnt(2,"Memory allocation error in gashpwrt\n");
+      error = 1; goto cleanup;
+    }
+    *pstart = 0;
+
+    /* For grid expressions, loop over all grid points */
+    if (grid) {
+      shpid = 0;   /* shape index/count */
+      gx = 0;      /* grid index */
+      for (j=pgr->dimmin[1]; j<=pgr->dimmax[1]; j++) {
+	for (i=pgr->dimmin[0]; i<=pgr->dimmax[0]; i++) {
+	  if (*(gru+gx) != 0) {
+	    /* get the data value and the lat/lon for each grid point that is not undefined */
+	    val = *(gr+gx);
+	    conv = pcm->xgr2ab;
+	    lon = conv(pcm->xgrval, i);
+	    conv = pcm->ygr2ab;
+	    lat = conv(pcm->ygrval, j);
+	    
+	    /* create the shape, write it to the file, then release it */
+	    shp = SHPCreateObject (SHPT_POINTM,shpid,nParts,pstart,NULL,1,&lon,&lat,NULL,&val);
+	    rc = SHPWriteObject (sfid,-1,shp);
+	    SHPDestroyObject (shp);
+	    if (rc!=shpid) {
+	      snprintf(pout,255,"Error in gashpwrt: SHPWriteObject returned %d, shpid=%d\n",rc,shpid);
+	      gaprnt (0,pout);
+	      error = 1; goto cleanup;
+	    }
+	    /* write out the attribute fields for this shape */
+	    fld = dbanch;           /* point to the first one */
+	    while (fld != NULL) {
+	      if (fld->flag==0) {   /* static fields */
+		if (fld->type==FTString) {
+		  DBFWriteStringAttribute (dbfid,shpid,fld->index,(const char *)fld->value);
+		} else if (fld->type==FTInteger) {
+		  intprs(fld->value,&ival);
+		  DBFWriteIntegerAttribute (dbfid,shpid,fld->index,ival);
+		} else if (fld->type==FTDouble) {
+		  getdbl(fld->value,&dval);
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,dval);
+		}
+	      }
+	      else {                /* dynamic fields */
+		if (strcmp(fld->name,"LONGITUDE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,lon);
+		} else if (strcmp(fld->name,"LATITUDE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,lat);
+		} else if (strcmp(fld->name,"GRID_VALUE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+		}
+	      }
+	      fld = fld->next;      /* advance to next field */
+	    }
+	    shpid++;
+	  }
+	  gx++;
+	}
+      }
+      snprintf(pout,255,"%d grid point values written to shapefile %s\n",shpid,fnroot);
+      gaprnt(2,pout);
+    }
+    else {
+      /* Loop over all reports */
+      shpid = 0;   /* shape index/count */
+      rpt = stn->rpt;
+      while (rpt!=NULL) {
+	if (rpt->umask != 0) {
+	  lon = rpt->lon;
+	  lat = rpt->lat;
+	  /* normalize the longitude */
+	  if (lon<pcm->dmin[0]) lon+=360.0;
+	  if (lon>pcm->dmax[0]) lon-=360.0;
+	  /* check if report is within specified domain */
+	  if (lon>pcm->dmin[0] && 
+	      lon<pcm->dmax[0] &&
+	      lat>pcm->dmin[1] && 
+	      lat<pcm->dmax[1]) {
+	    /* get the data value */
+	    val = rpt->val;
+	    /* create the shape, write it to the file, then release it */
+	    shp = SHPCreateObject (SHPT_POINTM,shpid,nParts,pstart,NULL,1,&lon,&lat,NULL,&val);
+	    rc = SHPWriteObject (sfid,-1,shp);
+	    SHPDestroyObject (shp);
+	    if (rc!=shpid) {
+	      snprintf(pout,255,"Error in gashpwrt: SHPWriteObject returned %d, shpid=%d\n",rc,shpid);
+	      gaprnt (0,pout);
+	      error = 1; goto cleanup;
+	    }
+	    /* write out the attribute fields for this shape */
+	    fld = dbanch;           /* point to the first one */
+	    while (fld != NULL) {
+	      if (fld->flag==0) {   /* static fields */
+		if (fld->type==FTString) {
+		  DBFWriteStringAttribute (dbfid,shpid,fld->index,(const char *)fld->value);
+		} else if (fld->type==FTInteger) {
+		  intprs(fld->value,&ival);
+		  DBFWriteIntegerAttribute (dbfid,shpid,fld->index,ival);
+		} else if (fld->type==FTDouble) {
+		  getdbl(fld->value,&dval);
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,dval);
+		}
+	      }
+	      else {                /* dynamic fields */
+		if (strcmp(fld->name,"LONGITUDE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,lon);
+		} else if (strcmp(fld->name,"LATITUDE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,lat);
+		} else if (strcmp(fld->name,"STN_ID")==0) {
+		  DBFWriteStringAttribute (dbfid,shpid,fld->index,rpt->stid);
+		} else if (strcmp(fld->name,"STN_VALUE")==0) {
+		  DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+		}
+	      }
+	      fld = fld->next;      /* advance to next field */
+	    }
+	    shpid++;
+	  }
+	}
+	rpt = rpt->rpt;
+      }
+      snprintf(pout,255,"%d station reports written to shapefile %s\n",shpid,fnroot);
+      gaprnt(2,pout);
+    }
+
+  }
+  /* Write out contour lines */
+  else if (pcm->shptype==2) {
+    /* Call gacntr() to create buffered contour lines */
+    rc = gacntr (pcm, 0, 1); 
+    if (rc) {
+      error = 1; goto cleanup;
+    }
+
+    /* call routine in gxcntr.c to write out contour line vertices and values */
+    rc = gxshplin(sfid,dbfid,dbanch);
+    if (rc>0) {
+      snprintf(pout,255,"%d contours written to shapefile %s\n",rc,fnroot);
+      gaprnt(2,pout);
+    }
+    else if (rc==-1) {
+      error = 1;
+    }
+
+    /* release the contour buffer from memory */
+    gxcrel();
+  
+  } 
+  /* Write out polygons */
+  else {
+    s2setbuf(1);    /* turn on polygon buffering */
+    s2setdraw(1);   /* disable drawing of polygons to display */
+
+    /* call gacntr() to create shaded polygons with gxshad2 */
+    rc = gacntr (pcm,4,1);
+    if (rc) {
+      error = 1; goto cleanup;
+    }
+
+    /* call routine in gxshad2.c to write out polygon vertices and values */
+    rc = s2shpwrt(sfid,dbfid,dbanch);
+    if (rc>0) {
+      snprintf(pout,255,"%d polygons written to shapefile %s\n",rc,fnroot);
+      gaprnt(2,pout);
+    }
+    else if (rc==-1) {
+      error = 1;
+    }
+    s2frepbuf();    /* release the polygon buffer from memory */
+    s2setbuf(0);    /* turn off polygon buffering */
+    s2setdraw(0);   /* restore drawing of polygons */
+
+  }
+
+  /* write the projection file */
+  if ((prjname = (char *)galloc(5+strlen(fnroot),"prjname"))==NULL) {
+    gaprnt(0,"Error in gashpwrt: memory allocation error for prjname\n");
+    error = 1; goto cleanup;
+  }
+  sprintf(prjname,"%s.prj",fnroot);
+  fp = fopen(prjname,"w");
+  snprintf(pout,255,"GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]]\n");
+  if ((fwrite(pout,1,strlen(pout),fp))!=strlen(pout)) {
+    gaprnt(0,"Error in gashpwrt when writing to .prj file \n");
+    error = 1; goto cleanup; 
+  }
+  gree(prjname,"f293d");
+  prjname = NULL;
+
+  gagsav(25,pcm,pgr);
+  
+cleanup:
+  if (pstart  != NULL) gree(pstart,"f293c");
+  if (prjname != NULL) gree(prjname,"f293d");
+  if (fnroot  != NULL) gree(fnroot,"f293e");
+  /* release local copy of data base attributes */
+  if (dbanch != NULL) {
+    while (dbanch != NULL) {
+      /* point to first block in chain */
+      fld = dbanch;  
+      if (fld->next == NULL) {
+	/* first block is only block */
+	dbanch = NULL; 
+      } 
+      else { 
+	/* move start of chain from 1st to 2nd block */
+	nextfld = fld->next;
+	dbanch = nextfld;
+      }
+      /* release memory from 1st block */
+      if (fld->value != NULL) gree(fld->value,"f292b");
+      gree(fld,"f293b");
+    }
+  }
+  if (dblast != NULL) dblast = NULL;
+  /* if an error occurred, no shapefile is written */
+  if (error) {
+    gaprnt(0,"Shapefile not created\n");
+  }
+  /* close files */
+  if (sfid  != NULL) SHPClose(sfid);
+  if (dbfid != NULL) DBFClose(dbfid);
+  fclose(fp);
+
+
+  return;
+#else 
+  gaprnt(0,"Creating shapefiles is not supported in this build\n");
+#endif
+}
+
+/* allocates and populates a data base field 
+   flag = 0 for static fields (the same values for all shapes)
+   flag = 1 for dynamic fields (values vary with shape)
+   
+*/
+#if USESHP==1
+struct dbfld* newdbfld (char *fldname, DBFFieldType dbtype, gaint len, gaint prec, 
+			gaint flag, char *val) {
+  gaint sz;
+  struct dbfld *newfld;
+  char *value;
+  
+  /* create the new field */
+  newfld = (struct dbfld *) galloc (sizeof(struct dbfld),"dbfld"); 
+  if (newfld != NULL) {
+    strcpy(newfld->name,fldname);
+    newfld->type = dbtype;
+    newfld->len = len;
+    newfld->prec = prec;
+    newfld->flag = flag;        
+    if (flag==0) {
+      /* allocate space for the field value */
+      sz = (len+1) * sizeof(char);
+      if ((value = (void *)galloc(sz,"valuec")) == NULL) {
+	gaprnt (0,"Error in newdbfld: memory allocation failed for data base field value \n");
+	gree (newfld,"g1");
+	return NULL;
+      }
+      strcpy(value,val);
+      newfld->value = value;
+    }
+    else {
+      newfld->value = NULL;
+    }
+    newfld->next = NULL;
+    return newfld;  
+  } else {
+    gaprnt (0,"Error in newdbfld: memory allocation failed for new data base field \n");
+    return NULL;
+  }
+}
+#endif
+
+/* Writes out a KML file containing output from contour/shade2 routine */
+
+void gakml (struct gacmn *pcm) {
+  FILE *kmlfp=NULL;
+  struct gagrid *pgr;
+  gaint r,g,b,err=0,i,rc;
+  
+  /* Determine if output is a grid or a station result */
+  if (pcm->type[0] != 1) {
+    gaprnt (0,"Error in gakml: expression is not a grid \n");
+    goto cleanup;
+  }
+
+  /* Make sure projection is latlon */
+  if (pcm->mproj !=2) {
+    gaprnt (0,"Error in gakml: mproj latlon required for gxout kml\n");
+    goto cleanup;
+  }
+
+  /* Make sure we have an X-Y plot */
+  pgr = pcm->result[0].pgr;
+  if (pgr->idim!=0 || pgr->jdim!=1) {
+    gaprnt(0,"Error in gakml: Grid is not varying in X and Y \n");
+    goto cleanup;
+  }
+  
+  /* set up scaling without the map */
+  gas2d (pcm, pgr, 0);    
+
+  /* Determine data min/max, make sure grid is not undefined */
+  gamnmx (pgr);
+  if (pgr->umin==0) {
+    gaprnt (0,"Error in gakml: Entire grid is undefined \n");
+    goto cleanup;
+  }
+  
+  /* open the output file */
+  if (pcm->kmlname)
+    kmlfp = fopen (pcm->kmlname,"wb");
+  else
+    kmlfp = fopen ("grads.kml","wb");
+  if (kmlfp==NULL) {
+    if (pcm->kmlname)
+      snprintf(pout,255,"Error: fopen failed for KML text output file %s\n",pcm->kmlname);
+    else
+      snprintf(pout,255,"Error: fopen failed for KML text output file grads.kml\n");
+    gaprnt(0,pout);
+    goto cleanup;
+  }
+
+  if (pcm->kmlflg==2) {
+    rc = gacntr (pcm, 0, 1);     /* Call gacntr() to create buffered contour lines for KML file */
+    if (rc) goto cleanup;
+  } 
+  else if (pcm->kmlflg==3) {
+    s2setbuf(1);                 /* turn on polygon buffering */
+    s2setdraw(1);                /* disable drawing polygons to display */
+    rc = gacntr (pcm, 4, 1);     /* Call gacntr() to create buffered polygons for KML file */
+    if (rc) goto cleanup;
+
+  } else {
+    gaprnt(9,"logic errror in subroutine gakml\n");
+    goto cleanup;
+  }
+
+
+
+  /* write out KML headers */
+  snprintf(pout,255,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+  snprintf(pout,255,"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
+  if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+  snprintf(pout,255,"  <Document id=\"Created by GrADS-"GRADS_VERSION"\">\n");
+  if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+
+  /* Contours */
+  if (pcm->kmlflg==2) {
+    /* write out the contour colors as a set of Style tags with LineStyle */
+    for (i=0; i<pcm->cntrcnt; i++) {
+      snprintf(pout,255,"    <Style id=\"%d\">\n      <LineStyle>\n",pcm->cntrcols[i]);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      /* get rgb values for this color */
+      if (pcm->cntrcols[i]<16) {
+	gxqdrgb(pcm->cntrcols[i],&r,&g,&b);         /* default color */
+      }
+      else {
+	gxqrgb(pcm->cntrcols[i],&r,&g,&b);          /* user-defined color */
+	if (r==-999) r = g = b = 0;
+      } 
+      snprintf(pout,255,"        <color>ff%02x%02x%02x</color>\n",b,g,r);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"        <width>%d</width>\n",pcm->cthick);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"      </LineStyle>\n    </Style>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+    }
+    /* write out the locations of the contour vertices */
+    rc = gxclvert(kmlfp);
+    if (rc>0) {
+      if (pcm->kmlname)
+	snprintf(pout,255,"%d contours written to KML file %s\n",rc,pcm->kmlname);
+      else
+	snprintf(pout,255,"%d contours written to KML file grads.kml\n",rc);
+      gaprnt(2,pout);
+    }
+    else err=1;
+  }
+  /* Polygons */
+  else {
+    /* write out the polygon colors as a set of Style tags with LineStyle and PolyStyle */
+    for (i=0; i<pcm->shdcnt; i++) {
+      snprintf(pout,255,"    <Style id=\"%d\">\n",pcm->shdcls[i]);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"      <LineStyle>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      /* get rgb values for this color */
+      if (pcm->shdcls[i]>=0 && pcm->shdcls[i]<16) {
+	gxqdrgb(pcm->shdcls[i],&r,&g,&b);         /* default color */
+      }
+      else {
+	gxqrgb(pcm->shdcls[i],&r,&g,&b);          /* user-defined color */
+	if (r==-999) r = g = b = 0;
+      }
+      snprintf(pout,255,"        <color>ff%02x%02x%02x</color>\n",b,g,r);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"        <width>0</width>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"      </LineStyle>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"      <PolyStyle>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"        <color>ff%02x%02x%02x</color>\n",b,g,r);
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"        <fill>1</fill>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"      </PolyStyle>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+      snprintf(pout,255,"    </Style>\n");
+      if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+    }
+
+    /* write out the locations of the polygon vertices */
+    /* call routine in gxshad2.c to write out polygon vertices and values */
+    rc = s2polyvert(kmlfp);
+    if (rc>0) {
+      if (pcm->kmlname)
+	snprintf(pout,255,"%d polygons written to KML file %s\n",rc,pcm->kmlname);
+      else
+	snprintf(pout,255,"%d polygons written to KML file grads.kml\n",rc);
+      gaprnt(2,pout);
+    }
+    else err=1;
+
+  }
+
+  /* write out footers */
+  snprintf(pout,255,"  </Document>\n</kml>\n");
+  if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+  /* set the last graphic code */
+  gagsav (24,pcm,NULL);
+    
+ cleanup:
+  if (pcm->kmlflg==2) {
+    gxcrel();       /* release storage used by the contouring package */
+  } else {
+    s2frepbuf();    /* release the polygon buffer from memory */
+    s2setbuf(0);    /* turn off polygon buffering */
+    s2setdraw(0);   /* restore drawing of polygons */
+  }
+  if (kmlfp) fclose(kmlfp);    /* close the file */
+  if (err) gaprnt(0,"Error from fwrite when writing KML file\n");
+  return;
+}
+
+
+/* Writes out the grid in GeoTIFF format.
+
+   If kmlflag is 0, one output file is created:
+   a GeoTIFF containing a grid of floating-point or 
+   double precision data values and the geolocation metadata. 
+
+   If kmlflag is 1, two output files are created.
+   The first is a GeoTIFF containing a grid of color index values 
+   (based on default or user-specified contour levels), a color map 
+   with RGB values for each color index, and the geolocation metadata. 
+   The second is a KML file, which points to the GeoTIFF image 
+   and contains the geolocation metadata in text form. 
+   The KML file is intended for use with Google Earth.
+
+ */
+
+void gagtif (struct gacmn *pcm, gaint kmlflg) {
+#if GEOTIFF==1 
+ struct gagrid *pgr;
+ gadouble *gr,cmin,cmax,cint,pmin,pmax,dval;
+ gadouble pixelscale[3],tiepoints[24];
+ gafloat fval;
+ gaint i,j,rc,grsize,isize,jsize,color,r,g,b;
+ char *gru;
+ TIFF *tif=NULL;
+ GTIF *gtif=NULL;
+ gadouble xresolution,yresolution,smin,smax;
+ uint32 imagewidth,imagelength,rowsperstrip;
+ uint16 *colormap=NULL,*cm;
+ uint16 bitspersample,samplesperpixel,compression;
+ uint16 photometric,resolutionunit,sampleformat;
+ short depth;
+ unsigned char *cbuf=NULL,*cbuf0=NULL;
+ gafloat *fbuf=NULL,*fbuf0=NULL;
+ gadouble *dbuf=NULL,*dbuf0=NULL;
+
+
+ /* set up scaling without the map */
+ pgr = pcm->result[0].pgr;
+ gas2d (pcm, pgr, 0);    
+ isize = pgr->isiz;
+ jsize = pgr->jsiz;
+ grsize = isize * jsize;
+ gr  = pgr->grid;
+ gru = pgr->umask;
+
+ /* Make sure we have an X-Y plot */
+ if (pgr->idim!=0 || pgr->jdim!=1) {
+   gaprnt(0,"Error: Grid is not varying in X and Y \n");
+   goto cleanup;
+ }
+
+ /* Make sure projection is latlon */
+ if (pcm->mproj !=2) {
+   gaprnt (0,"Error: mproj latlon required for gxout kml\n");
+   goto cleanup;
+ }
+ 
+ /* Determine data min/max, make sure grid is not undefined */
+ gamnmx (pgr);
+ if (pgr->umin==0) {
+   gaprnt (0,"Error: Entire grid is undefined \n");
+   goto cleanup;
+ }
+
+ /* Open output files */
+ if (kmlflg) {
+   /* open the file for the image output, we'll open the KML file later */
+   if (pcm->tifname)
+     tif = XTIFFOpen(pcm->tifname, "w");
+   else
+     tif = XTIFFOpen("grads.tif", "w");
+   if (tif==NULL) {
+     if (pcm->tifname)
+       snprintf(pout,255,"Error: XTiffOpen failed for KML image output file %s\n",pcm->tifname);
+     else
+       snprintf(pout,255,"Error: XTiffOpen failed for KML image output file grads.tif\n");
+     gaprnt (0,pout);
+     goto cleanup;
+   }
+   gtif = GTIFNew(tif);
+   if (gtif==NULL) {
+     if (pcm->tifname)
+       snprintf(pout,255,"Error: GTIFNew failed for KML image output file %s\n",pcm->tifname);
+     else
+       snprintf(pout,255,"Error: GTIFNew failed for KML image output file grads.tif\n");
+     gaprnt (0,pout);
+     goto cleanup;
+   }
+ }
+ else { 
+   /* For gxout GeoTIFF, we open only one output file */
+   if (pcm->gtifname)
+     tif = XTIFFOpen(pcm->gtifname, "w");
+   else
+     tif = XTIFFOpen("gradsgeo.tif", "w");
+   if (tif==NULL) {
+     if (pcm->gtifname)
+       snprintf(pout,255,"Error: XTiffOpen failed for GeoTIFF output file %s\n",pcm->gtifname);
+     else
+       snprintf(pout,255,"Error: XTiffOpen failed for GeoTIFF output file gradsgeo.tif\n");
+     gaprnt (0,pout);
+     goto cleanup;
+   }
+   gtif = GTIFNew(tif);
+   if (gtif==NULL) {
+     if (pcm->gtifname)
+       snprintf(pout,255,"Error: GTIFNew failed for GeoTIFF output file %s\n",pcm->gtifname);
+     else
+       snprintf(pout,255,"Error: GTIFNew failed for GeoTIFF output file gradsgeo.tif\n");
+     gaprnt (0,pout);
+     goto cleanup;
+   }
+ }
+
+ /* Determine the data type of the output */
+ if (kmlflg) { 
+   depth = TIFFDataWidth(TIFF_BYTE);
+ }
+ else {
+   if (pcm->gtifflg==2) 
+     depth = TIFFDataWidth(TIFF_DOUBLE);
+   else 
+     depth = TIFFDataWidth(TIFF_FLOAT);
+ }
+
+ /* Set values for required TIFF fields, converted to proper data types */
+ imagewidth  = (uint32)isize;                /* #cols, #longitudes */
+ imagelength = (uint32)jsize;                /* #rows, #latitudes */
+ bitspersample = depth * 8;                  /* number of bits per component */
+ samplesperpixel = 1;                        /* number of components per pixel */
+ compression = 1;                            /* no compression used */
+ if (kmlflg) 
+   photometric = 3;                          /* palette color image */
+ else
+   photometric = 1;                          /* grayscale image */
+ rowsperstrip = 1;                           /* one row per strip */
+ resolutionunit = 2;                         /* inches */
+ xresolution = (gadouble)(pcm->xsiz/isize);  /* gridpoints per inch */
+ yresolution = (gadouble)(pcm->ysiz/jsize);  /* gridpoints per inch */
+ if (!kmlflg) {
+   sampleformat = 3;                         /* IEEE floating point data */
+   smin = pgr->rmin;                         /* minimum value of grid */
+   smax = pgr->rmax;                         /* maximum value of grid */
+ }
+ else {
+   sampleformat = 1;                         /* unsigned integer */
+   smin = 0;
+   smax = 255;
+ }
+ /* write out the required TIFF metadata */
+ if (TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, imagewidth)!=1)  { 
+   gaprnt(0,"Error: TIFFSetField failed for imagewidth\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_IMAGELENGTH, imagelength)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for imagelength\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for bitspersample\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for samplesperpixel\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_COMPRESSION, compression)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for compression\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for photometric\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for rowsperstrip\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, resolutionunit)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for resolutionunit\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_XRESOLUTION, xresolution)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for xresolution\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_YRESOLUTION, yresolution)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for yresolution\n"); goto cleanup; 
+ }
+ if (TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sampleformat)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for sampleformat\n"); goto cleanup; 
+ }
+ if (!kmlflg) {
+   if (TIFFSetField(tif, TIFFTAG_SMINSAMPLEVALUE, smin)!=1) {
+     gaprnt(0,"Error: TIFFSetField failed for sminsamplevalue\n"); goto cleanup;
+   }
+   if (TIFFSetField(tif, TIFFTAG_SMAXSAMPLEVALUE, smax)!=1) {
+     gaprnt(0,"Error: TIFFSetField failed for smaxsamplevalue\n"); goto cleanup;
+   }
+ }
+ snprintf(pout,255,"GrADS version "GRADS_VERSION" ");
+ if (TIFFSetField(tif, TIFFTAG_SOFTWARE, pout)!=1) { 
+   gaprnt(0,"Error: TIFFSetField failed for software\n"); goto cleanup; 
+ }
+
+ /* Get georeferencing info */
+ getcorners (pcm, pgr, tiepoints);
+
+ /* Write georeferencing info to output file */
+ if (!kmlflg) {
+   if (pgr->ilinr && pgr->jlinr) {
+     /* If the grid is linear in both dimensions, write out the ModelPixelScale and 1 tiepoint */
+     pixelscale[0] = *(pgr->ivals+0);
+     pixelscale[1] = *(pgr->jvals+0);
+     pixelscale[2] = 0.0;
+     if (TIFFSetField(tif, TIFFTAG_GEOPIXELSCALE, 3, pixelscale)!=1) { 
+       gaprnt(0,"Error: TIFFSetField failed for geopixelscale\n"); goto cleanup; 
+     }
+     /* write out one tie point */
+     if (TIFFSetField(tif, TIFFTAG_GEOTIEPOINTS, 6, tiepoints)!=1) { 
+       gaprnt(0,"Error: TIFFSetField failed for geotiepoint\n"); goto cleanup; 
+     }
+   }
+   else {
+     /* write out four tie points */
+     if (TIFFSetField(tif, TIFFTAG_GEOTIEPOINTS, 24, tiepoints)!=1) { 
+       gaprnt(0,"Error: TIFFSetField failed for tiepoints\n"); goto cleanup; 
+     }
+   }
+   
+   /* set and write the GeoKeys */
+   GTIFKeySet(gtif, GTModelTypeGeoKey,    TYPE_SHORT, 1, ModelGeographic);
+   GTIFKeySet(gtif, GTRasterTypeGeoKey,   TYPE_SHORT, 1, RasterPixelIsArea);
+   GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
+   GTIFWriteKeys(gtif);
+ }
+
+ /* For KML image output: 
+    get contour info, write the color map, and create the KML text file */
+ if (kmlflg) {   
+   if (!pcm->cflag) {
+     /* Determine contour interval */
+     gacsel (pgr->rmin,pgr->rmax,&(pcm->cint),&cmin,&cmax);
+     cint = pcm->cint;
+     /* reject constant fields for now */
+     if (cint==0.0) {
+       gaprnt (0,"Error: Grid is a constant \n");
+       goto cleanup;
+     }
+     /* make sure there aren't too many levels */
+     pmin = cmin;
+     if (pmin<pcm->cmin) pmin = pcm->cmin;
+     pmax = cmax;
+     if (pmax>pcm->cmax) pmax = pcm->cmax;
+     if ((pmax-pmin)/cint>100.0) {
+       while ((pmax-pmin)/cint>100.0) cint*=10.0;
+       pcm->cint = cint;
+       gacsel (pgr->rmin,pgr->rmax,&cint,&cmin,&cmax);
+     }
+   }
+   if (pcm->ccolor>=0) gxcolr(pcm->ccolor);
+   if (pcm->ccolor<0 && pcm->rainmn==0.0 && pcm->rainmx==0.0 && !pcm->cflag) {
+     pcm->rainmn = cmin;
+     pcm->rainmx = cmax;
+   }
+   gaselc (pcm,pgr->rmin,pgr->rmax);
+   
+   /* create and write out the color map */
+   colormap = (uint16*)_TIFFmalloc(3 * 256 * sizeof (uint16));
+   if (colormap==NULL) {
+     gaprnt(0,"Error: TIFFmalloc failed for colormap\n"); goto cleanup;
+   }
+   cm=colormap;
+   for (j=0;j<256;j++){
+     if (j<16) {
+       gxqdrgb(j,&r,&g,&b);         /* get default color rgb values */
+     }
+     else {
+       gxqrgb(j,&r,&g,&b);          /* get user-defined color rgb values */
+       if (r==-999) r = g = b = 0;
+     } 
+     *(cm+0*256+j) = (uint16)r;
+     *(cm+1*256+j) = (uint16)g;
+     *(cm+2*256+j) = (uint16)b;
+   }
+   if (TIFFSetField(tif, TIFFTAG_COLORMAP, colormap, colormap+256, colormap+512)!=1) { 
+     gaprnt(0,"Error: TIFFSetField failed for colormap\n"); goto cleanup; 
+   }
+
+   /* Create the KML text file */
+   if ((write_kml(pcm,tiepoints))!=0) goto cleanup;
+ }
+
+ /* convert the data to appropriate format */
+ if (kmlflg) {
+   /* color index geotiff (for KML output) */
+   cbuf = (unsigned char *)_TIFFmalloc(grsize * depth);
+   if (cbuf==NULL) {
+     gaprnt(0,"Error: TIFFmalloc failed for color index data buffer\n"); goto cleanup;
+   }
+   cbuf0 = cbuf;
+   for (i=0; i<grsize; i++) {
+     if (gru[i]!=0) {
+       color = gashdc (pcm, gr[i]);     /* get the relevent color for grid data value */
+     }
+     else {                             /* use the device background for undefined values */
+       if (pcm->devbck) color = 1;
+       else color = 0;
+     }
+     cbuf[i] = (unsigned char)color;
+   }
+ }
+ else {
+   if (pcm->gtifflg==1) { 
+     /* floating point geotiff */
+     fbuf = (gafloat*)_TIFFmalloc(grsize * depth);
+     if (fbuf==NULL) {
+       gaprnt(0,"Error: TIFFmalloc failed for floating point data buffer\n"); goto cleanup;
+     }
+     fbuf0 = fbuf;
+     for (i=0; i<grsize; i++) {
+       if (gru[i] != 0) 
+	 fval = (gafloat)gr[i];	         /* convert data value to float */
+       else 
+	 fval = (gafloat)pcm->undef;	 /* convert output undef value to float */
+       fbuf[i] = fval;
+     }
+
+   } else {               
+     /* double precision geotiff */
+     dbuf = (gadouble*)_TIFFmalloc(grsize * depth);
+     if (dbuf==NULL) {
+       gaprnt(0,"Error: TIFFmalloc failed for double precision data buffer\n"); goto cleanup;
+     }
+     dbuf0 = dbuf;
+     for (i=0; i<grsize; i++) {
+       if (gru[i] != 0) 
+	 dval = gr[i];	         /* use data value as is */
+       else 
+	 dval = pcm->undef;	 /* use output undef value */
+       dbuf[i] = dval;
+     }
+   }
+ }
+
+ /* write the data buffer in strips (one row per strip) */
+ for (j=0; j<pgr->jsiz; j++) {
+   /* i points to the beginning of the correct row in the grid */
+   i = (grsize - (j+1)*pgr->isiz); 
+   if (kmlflg) {
+     rc = TIFFWriteScanline(tif, cbuf0+i, j, 0);
+   } else {
+     if (pcm->gtifflg==1) 
+       rc = TIFFWriteScanline(tif, fbuf0+i, j, 0);
+     else 
+       rc = TIFFWriteScanline(tif, dbuf0+i, j, 0);
+   }
+   if (rc!=1) {
+     snprintf(pout,255,"Error: TIFFWriteScanline failed at row %d\n",j);
+     gaprnt(0,pout); goto cleanup; 
+   }
+ }
+
+ if (kmlflg) {
+   gagsav (24,pcm,NULL);
+   if (pcm->tifname)
+     snprintf(pout,255,"Created TIFF image file %s\n",pcm->tifname);
+   else
+     snprintf(pout,255,"Created TIFF image file grads.tif\n");
+   gaprnt (2,pout);
+   if (pcm->kmlname)
+     snprintf(pout,255,"  and complementary KML file %s\n",pcm->kmlname);
+   else
+     snprintf(pout,255,"  and complementary KML file grads.kml\n");
+   gaprnt (2,pout);
+ }
+ else {
+   gagsav (23,pcm,NULL);
+   if (pcm->gtifname)
+     snprintf(pout,255,"Created GeoTIFF file %s\n",pcm->gtifname);
+   else
+     snprintf(pout,255,"Created GeoTIFF file gradsgeo.tif\n");
+   gaprnt (2,pout);
+ }
+ cleanup:
+ if (colormap) _TIFFfree(colormap);
+ if (cbuf) { cbuf = cbuf0; _TIFFfree(cbuf); }
+ if (fbuf) { fbuf = fbuf0; _TIFFfree(fbuf); }
+ if (dbuf) { dbuf = dbuf0; _TIFFfree(dbuf); }
+ if (gtif) GTIFFree(gtif);
+ if (tif) TIFFClose(tif);
+ return;
+ 
+#else 
+ if (kmlflg) {
+   gaprnt(0,"Error: Creating TIFF images for KML output is not supported in this build. \n");
+   gaprnt(0,"  Try the \'-line\' option with \'set kml\' to output contour lines in KML format instead.\n");
+ }
+ else
+   gaprnt(0,"Error: Creating GeoTIFF files is not supported in this build\n");
+#endif
+ 
+}
+
+/* This routine gets the georeferencing information for the four corners of the grid */
+void getcorners(struct gacmn *pcm, struct gagrid *pgr, gadouble *tiepoints) {
+
+  /* For GeoTIFF, the raster space is treated as PixelIsArea. 
+     
+  (0,0)
+  +-----+-----+-> I
+  |     |     |        * denotes the center of the grid cell (GrADS uses this)
+  |  *  |  *  |        + denotes i,j points in standard TIFF PixelIsArea raster space
+  |   (1,1)   |
+  +-----+-----+   
+  |     |     |
+  |  *  |  *  |
+  |     |   (2,2) 
+  |-----+-----+
+  V
+  J        
+  
+  i,j raster values correspond to the corners of the grid cells instead of the centers  */
+  
+  /* geotiff raster value (0,0) gets upper left corner lat,lon
+     this is the max j index, since in GrADS j goes south->north  */
+  ij2ll (pcm, 0, 0, pgr->dimmin[0]-0.5, pgr->dimmax[1]+0.5, tiepoints, 0);
+  
+  /* geotiff raster value (0,jsize) gets lower left corner lat,lon 
+     this is the min j index, since in GrADS j goes south->north */
+  ij2ll (pcm, 0, (gadouble)pgr->jsiz, pgr->dimmin[0]-0.5, pgr->dimmin[1]-0.5, tiepoints, 6);
+  
+  /* geotiff raster value (isize,0) gets upper right corner lat,lon */
+  ij2ll (pcm, (gadouble)pgr->isiz, 0, pgr->dimmax[0]+0.5, pgr->dimmax[1]+0.5, tiepoints, 12);
+  
+  /* geotiff raster value (isize,jsize) gets lower right corner lat,lon */
+  ij2ll (pcm, (gadouble)pgr->isiz, (gadouble)pgr->jsiz, pgr->dimmax[0]+0.5, pgr->dimmin[1]-0.5, tiepoints, 18);
+}
+
+/* given a grid i,j, calculate the corresponding lat/lon, populate the tiepoints array */
+void ij2ll (struct gacmn *pcm, gadouble i, gadouble j, gadouble gx, gadouble gy, 
+            gadouble *tiepoints, gaint index) {
+gadouble (*conv) (gadouble *, gadouble);
+gadouble lon,lat;  
+
+  conv = pcm->xgr2ab;
+  lon = conv(pcm->xgrval, gx);
+  conv = pcm->ygr2ab;
+  lat = conv(pcm->ygrval, gy);
+  tiepoints[index+0] = i;
+  tiepoints[index+1] = j;
+  tiepoints[index+2] = 0.0;
+  tiepoints[index+3] = lon;
+  tiepoints[index+4] = lat;
+  tiepoints[index+5] = 0.0;
+}
+
+gaint write_kml(struct gacmn *pcm, gadouble *tpts) {
+ FILE *kmlfp=NULL;
+ struct gagrid *pgr;
+ gaint err;
+
+ /* open the file */
+ if (pcm->kmlname)
+   kmlfp = fopen (pcm->kmlname,"wb");
+ else
+   kmlfp = fopen ("grads.kml","wb");
+ if (kmlfp==NULL) {
+   if (pcm->kmlname)
+     snprintf(pout,255,"Error: fopen failed for KML text output file %s\n",pcm->kmlname);
+   else
+     snprintf(pout,255,"Error: fopen failed for KML text output file grads.kml\n");
+   gaprnt(0,pout);
+   return(1);
+ }
+ pgr = pcm->result[0].pgr;
+
+ /* write out the KML text */
+ err=0;
+ snprintf(pout,255,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"  <GroundOverlay>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"    <name>%s</name>\n",pgr->pvar->varnm);
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"    <Icon>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ if (pcm->tifname)
+   snprintf(pout,255,"      <href>%s</href>\n",pcm->tifname);
+ else
+   snprintf(pout,255,"      <href>grads.tif</href>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"    </Icon>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"    <LatLonBox>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ if ((tpts[0+3]==tpts[6+3]) && (tpts[12+3]==tpts[18+3])) {
+   if (tpts[0+3]<tpts[12+3])
+     snprintf(pout,255,"      <west>%10.5g</west>\n      <east>%10.5g</east>\n",tpts[0+3],tpts[12+3]);
+   else
+     snprintf(pout,255,"      <west>%10.5g</west>\n      <east>%10.5g</east>\n",tpts[12+3],tpts[0+3]);
+   if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ }
+ if ((tpts[0+4]==tpts[12+4]) && (tpts[6+4]==tpts[18+4])) {
+   if (tpts[0+4]<tpts[12+4])
+     snprintf(pout,255,"      <south>%10.5g</south>\n      <north>%10.5g</north>\n",tpts[0+4],tpts[6+4]);
+   else
+     snprintf(pout,255,"      <south>%10.5g</south>\n      <north>%10.5g</north>\n",tpts[6+4],tpts[0+4]);
+   if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ }
+ snprintf(pout,255,"      <rotation>0.0</rotation>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"    </LatLonBox>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"  </GroundOverlay>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+ snprintf(pout,255,"</kml>\n");
+ if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+
+ cleanup:
+ /* close the file */
+ fclose(kmlfp); 
+ if (err) gaprnt(0,"Error from fwrite when writing KML file\n");
+ return(err);
+}
+
+
+/* Write grid to a file.  */
+
+void gafwrt (struct gacmn *pcm) {
+struct gagrid *pgr;
+struct stat s;
+gaint size, exsz, rdw, ret, diff, fexists;
+gaint i, row, goff, xoff, yoff, xsiz, ysiz, incr;
+size_t write,written,sz;
+char fmode[3],*gru; 
+gafloat *fval,*fval0;
+gadouble *gr;
+
+  xoff = yoff = xsiz = ysiz = 0;
+  pgr = pcm->result[0].pgr;
+  size = pgr->isiz * pgr->jsiz;
+
+  /* Special case: output to stdout */
+  if (pcm->fwname) {
+    if ((strcmp(pcm->fwname,"-")==0) && (pcm->ffile==NULL)) {
+      pcm->ffile = stdout;
+      printf("\n<FWRITE>\n");
+    }
+  }
+
+  if (pcm->ffile == NULL) {
+    /* use the stat command to check if the file exists */
+    if (pcm->fwname) {
+      if (stat (pcm->fwname,   &s) == 0) fexists=1; 
+      else                               fexists=0; 
+    } else {
+      if (stat ("grads.fwrite",&s) == 0) fexists=1; 
+      else                               fexists=0; 
+    }
+
+    /* set the write mode */
+    if (pcm->fwappend) {
+      strcpy(fmode,"ab");
+      if (fexists) {
+	snprintf(pout,255,"Appending data to file %s.\n",pcm->fwname);
+	gaprnt (2,pout);
+      }
+    } else {
+      strcpy(fmode,"wb");
+      if (fexists) {
+	snprintf(pout,255,"Replacing file %s.\n",pcm->fwname);
+	gaprnt (2,pout);
+      }
+    }
+
+    if (pcm->fwname) pcm->ffile = fopen(pcm->fwname,fmode);
+    else pcm->ffile = fopen ("grads.fwrite",fmode);
+    if (pcm->ffile==NULL) {
+      gaprnt (0,"Error opening output file for fwrite\n");
+      if (pcm->fwname) {
+        gaprnt (0,"  File name is: ");
+        gaprnt (0,pcm->fwname);
+        gaprnt (0,"\n");
+      } else {
+        gaprnt (0,"  File name is: grads.fwrite\n");
+      }
+      return;
+    }
+  }
+
+  /* convert the grid values to floats/undefs */
+  gr=pgr->grid;
+  gru=pgr->umask;
+  fval = NULL;
+  sz = sizeof(gafloat)*size;
+  fval = (gafloat *)galloc(sz,"fwrite1");
+  fval0 = fval;
+  if (fval==NULL) {
+    gaprnt(0,"Error allocating memory for fwrite\n");
+    return;
+  }
+  for (i=0; i<size; i++) {
+    if (*gru!=0) {
+      *fval=(gafloat)*gr;
+    }
+    else {
+      *fval=(gafloat)pcm->undef;
+    }
+    gr++; gru++; fval++;
+  }
+  fval = fval0;
+
+
+  /* swap if needed.  assumes 4 byte values */  
+  rdw = size*4; 
+  if (BYTEORDER != pcm->fwenflg) { 
+    gabswp(fval,size);
+    gabswp(&rdw,1);
+  }
+
+  /* Handle -ex flag -- try to use exact grid coords */
+  written = 0;
+  exsz = size;
+  diff = 0;
+ /* only X or Y can vary  for new fwrite code */
+  if (pcm->fwexflg && pgr->idim<2 && pgr->jdim<2) {  
+    if (pcm->xexflg) {
+      if (pcm->x1ex != pgr->dimmin[0]) diff=1;
+      if (pcm->x2ex != pgr->dimmax[0]) diff=1;
+    }
+    if (pcm->yexflg) {
+      if (pcm->y1ex != pgr->dimmin[1]) diff=1;
+      if (pcm->y2ex != pgr->dimmax[1]) diff=1;
+    }
+  }
+
+  if (diff) {
+    if (pgr->idim==0) {     /* x is varying */
+      if (pcm->xexflg) {
+        xoff = pcm->x1ex - pgr->dimmin[0];  
+        xsiz = 1 + pcm->x2ex - pcm->x1ex;
+      } else {
+        xoff = 0;
+        xsiz = pgr->isiz; 
+      }
+      if (pgr->jdim==1 && pcm->yexflg) {  /* both x and y vary */
+        yoff = pcm->y1ex - pgr->dimmin[1];  
+        ysiz = 1 + pcm->y2ex - pcm->y1ex;
+      } else {
+        yoff = 0;
+        ysiz = pgr->jsiz; 
+      }
+    }
+    incr = pgr->isiz;
+    if (pgr->idim==1) {   /* x is fixed; y is varying */
+      if (pcm->yexflg) {
+        yoff = pcm->y1ex - pgr->dimmin[1];  
+        ysiz = 1 + pcm->y2ex - pcm->y1ex;
+      } else {
+        yoff = 0;
+        ysiz = pgr->isiz; 
+      }
+      xoff = 0; xsiz = 1;
+      incr = 1;
+    }
+    exsz = xsiz * ysiz;
+    rdw = exsz*4; 
+    /* Swap the record header if necessary. fix by LIS @ NASA, 3/8/2004 ***/
+    if (BYTEORDER != pcm->fwenflg) gabswp(&rdw,1);
+    if (pcm->fwsqflg) fwrite(&rdw,sizeof(gaint),1,pcm->ffile);
+    if (pgr->idim==1) {
+      goff = yoff;
+    } else {
+      goff = xoff + yoff*pgr->isiz;
+    }
+    for (row=0; row<ysiz; row++) {
+      write = fwrite (fval+goff, sizeof(gafloat), xsiz, pcm->ffile);
+      ret = ferror(pcm->ffile);
+      if (ret || (write != xsiz)) {
+        snprintf(pout,255,"Error writing data for fwrite: %s\n", strerror(errno) ); 
+        gaprnt(0, pout);
+      }
+      written = written + write;
+      goff = goff + incr;
+    }
+    if (pcm->fwsqflg) fwrite(&rdw,sizeof(gaint),1,pcm->ffile);
+  } 
+  else {
+    if (pcm->fwsqflg) fwrite(&rdw,sizeof(gaint),1,pcm->ffile);
+    written = fwrite (fval, sizeof(gafloat), size, pcm->ffile);
+    ret = ferror(pcm->ffile);
+    if (ret || (written != size)) {
+      snprintf(pout,255,"Error writing data for fwrite: %s\n", strerror(errno) ); 
+      gaprnt(0, pout);
+    }
+    if (pcm->fwsqflg) fwrite(&rdw,sizeof(gaint),1,pcm->ffile);
+  }
+
+  if (pcm->ffile != stdout) {
+    if (pcm->fwname) {
+      snprintf(pout,255,"Wrote %ld of %i elements to ", written, exsz);
+      gaprnt (2,pout);
+      gaprnt (2,pcm->fwname);
+    } else {
+      snprintf(pout,255,"Wrote %ld of %i elements to grads.fwrite", written, exsz);
+      gaprnt (2,pout);
+    }
+  
+    if (pcm->fwsqflg) gaprnt(2," as Sequential");
+    else gaprnt(2," as Stream");
+    if (pcm->fwenflg) gaprnt(2," Big_Endian\n");
+    else gaprnt(2," Little_Endian\n");
+  }
+
+  gagsav (20,pcm,NULL);
+  /* free the array of copied floats/undefs */
+  if (fval!=NULL) {
+    fval = fval0;
+    gree(fval,"f333");
+    fval0=NULL;
+  }
+}
+
+/* Write stations to file.  This is a hack.  Assumes x/y varying.  Does not 
+   handle levels.  Does not write sequential.  Writes only to grads.stnwrt.  
+   Writes one variable only.  Writes that variable as level-independent. 
+   Does no error checking.  For each time called, writes out a time delimeter
+   header.  There are probably more limitations I am not thinking of.
+   Close the file with disable stnwrt */
+
+void gastnwrt (struct gacmn *pcm) {
+struct gastn *stn;
+struct garpt *rpt;
+struct rpthdr hdr;
+gafloat val;
+int i;
+
+  if (pcm->sfile==NULL) {
+    pcm->sfile = fopen ("grads.stnwrt","wb");
+    if (pcm->sfile==NULL) {
+      gaprnt (0,"Error opening output file for stnwrt\n");
+      gaprnt (0,"  File name is: grads.stnwrt\n");
+      return;
+    }
+  }
+  stn = pcm->result[0].stn;
+  rpt = stn->rpt;
+  while (rpt) {
+    if (rpt->umask!=0) {
+      for (i=0; i<8; i++) hdr.id[i] = rpt->stid[i];
+      hdr.lon = rpt->lon;  hdr.lat = rpt->lat;
+      hdr.t = 0.0; hdr.nlev = 1;  hdr.flag = 1;
+      fwrite (&(hdr), sizeof(struct rpthdr), 1, pcm->sfile);
+      val = rpt->val;
+      fwrite (&(val), sizeof(float), 1, pcm->sfile);
+    }
+    rpt = rpt->rpt;
+  }
+  hdr.nlev = 0;
+  fwrite (&(hdr), sizeof(struct rpthdr), 1, pcm->sfile);
+}
+
+/* Do 2-D grid fill plots */
+
+void gafgrd (struct gacmn *pcm) {
+struct gagrid *pgr;
+gaint i,j,k,iv,col,scol,isav,ii,siz;
+gadouble *xybuf,*xy,*r;
+char *rmask;
+size_t sz;
+
+  pgr = pcm->result[0].pgr;
+
+  if ((pcm->rotate && (pgr->idim!=2 || pgr->jdim!=3)) ||
+      (!pcm->rotate && pgr->idim==2 && pgr->jdim==3)) 
+    pgr = gaflip(pgr,pcm);
+
+  gas2d (pcm, pgr, 0);     /* Set up scaling */
+  idiv = 1.0; jdiv = 1.0;
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+
+  /* Allocate point buffer */
+
+  siz = (pgr->isiz+2)*4;
+  sz = sizeof(gadouble)*siz;
+  xybuf = (gadouble *)galloc(sz,"xybuf");
+  if (xybuf==NULL) {
+    gaprnt(0,"Memory allocation error in FGRID\n");
+    return;
+  }
+  *(xybuf+siz-1) = -1;
+
+  /* Fill grid "boxes" */
+
+  r = pgr->grid;
+  rmask = pgr->umask;
+  for (j=1; j<=pgr->jsiz; j++) {
+    col = -1; scol = -1;
+    isav = 1;
+    for (i=1; i<=pgr->isiz; i++) {
+      col = -1;
+      if (*rmask != 0) {
+        iv = floor(*r+0.5);   /* check with bdoty */
+        for (k=0; k<pcm->fgcnt; k++) {
+          if (iv==pcm->fgvals[k]) col = pcm->fgcols[k];
+        }
+      }
+      if (col!=scol) {
+        if (scol>-1) {
+          xy = xybuf;
+          for (ii=isav; ii<=i; ii++) {
+            gxconv ((gadouble)(ii)-0.5,(gadouble)(j)+0.5,xy,xy+1,3);
+            xy+=2;
+          }
+          for (ii=i; ii>=isav; ii--) {
+            gxconv ((gadouble)(ii)-0.5,(gadouble)(j)-0.5,xy,xy+1,3);
+            xy+=2;
+          }
+          *xy = *xybuf;  
+	  *(xy+1) = *(xybuf+1);
+          gxcolr(scol);
+          gxfill (xybuf,(1+i-isav)*2+1);
+        }
+        isav = i;
+        scol = col;
+      }
+      r++; rmask++;
+    }
+    if (scol>-1) {
+      xy = xybuf;
+      for (ii=isav; ii<=pgr->isiz+1; ii++) {
+        gxconv ((gadouble)(ii)-0.5,(gadouble)(j)+0.5,xy,xy+1,3);
+        xy+=2;
+      }
+      for (ii=pgr->isiz+1; ii>=isav; ii--) {
+        gxconv ((gadouble)(ii)-0.5,(gadouble)(j)-0.5,xy,xy+1,3);
+        xy+=2;
+      }
+      *xy = *xybuf;  *(xy+1) = *(xybuf+1);
+      gxcolr(scol);
+      gxfill (xybuf,(2+pgr->isiz-isav)*2+1);
+    }
+  }
+  if (*(xybuf+siz-1) != -1) {
+    gaprnt (0,"Logic Error 16 in gafgrd.  Please report error.\n");
+  }
+  gree(xybuf,"f290");
+  if (pgr->idim==0 && pgr->jdim==1) gawmap (pcm, 0);
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide(pcm->annthk-3);
+  if (pcm->pass==0 && pcm->grdsflg)
+        gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+  if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+  gaaxpl(pcm,pgr->idim,pgr->jdim);
+  gafram (pcm);
+  gagsav (5,pcm,pgr);
+}
+
+/* Do 2-D contour plots */
+/* filflg:  
+   0  line contours
+   1  shaded contours
+   2  grfill
+   3  imap
+   4,5  gxshad2
+
+   shpflg:
+   0  no shapefile
+   1  line or shaded contours for shapefile output 
+
+   return code ignored in all cases except when shpflg=1, in which case
+   rc=0 contours created
+   rc=1 no contours
+
+*/
+
+gaint gacntr (struct gacmn *pcm, gaint filflg, gaint shpflg) {
+struct gagrid *pgr;
+gadouble cmin,cmax,cint;
+gadouble rl,rr,rrb,rmin,rmax, *rrr=0,*r;
+gadouble pmin,pmax,tt;
+gaint smooth, irb, clcnt, clflg, clopt;
+gaint i,iexp,jexp,isz=0,jsz=0,ii,ii2=0,isav,cnt;
+gaint cntrcnt,cntrcol;
+char chlab[50],*rmask,*rrrmask=NULL,umin=0;
+struct gxcntr scntr;
+size_t sz;
+
+  pgr = pcm->result[0].pgr;
+
+  /* If gxout imap, check for validity.  Must by x/y plot and all must be linear. */
+  if (filflg==3 && 
+     (pcm->mproj<1 || pcm->mproj>2 || pgr->idim != 0 || pgr->jdim != 1) ) {
+    gaprnt (0,"Invalid dimension and/or scaling environment for gxout imap\n");
+    gaprnt (0,"   Mproj latlon or scaled required; x/y varying plot required\n");
+    return 1;
+  }
+
+  /* check if user-provided contour levels are strictly increasing for shaded output */
+  if (filflg && pcm->cflag) {
+    for (i=1; i<pcm->cflag; i++) {
+      if (pcm->clevs[i] <= pcm->clevs[i-1]) {
+	gaprnt(2,"Invalid user-specified contour levels for shaded output.\n");
+	gaprnt(2,"   Contour levels must be strictly increasing.\n");
+	return 1;
+      }
+    }
+  }
+
+  /* flip axes for Z-T plots (skip this for shapefile output )*/
+  if (shpflg==0) {
+    if ( (pcm->rotate && (pgr->idim!=2 || pgr->jdim!=3)) ||
+	 (!pcm->rotate && pgr->idim==2 && pgr->jdim==3)) pgr = gaflip(pgr,pcm);
+    
+    gxstyl (1);
+    gxwide (1);
+    if (filflg) gas2d (pcm, pgr, 0);   /* No map yet if shaded cntrs */
+    else gas2d (pcm, pgr, 1);          /* Scaling plus map */
+  }
+
+  /* Determine data min/max */
+  gamnmx (pgr);
+  if (pgr->umin==0) {
+    gaprnt (1,"Cannot contour grid - all undefined values \n");
+    gxcolr(1);
+    if (pcm->dwrnflg) gxchpl ("Entire Grid Undefined",21,3.0,4.5,0.3,0.25,0.0);
+    return 1;
+  }
+
+  /* Determine contour interval */
+  if (!pcm->cflag) {
+    gacsel (pgr->rmin,pgr->rmax,&(pcm->cint),&cmin,&cmax);
+    cint = pcm->cint;
+    if (cint==0.0) {  /* field is a constant */
+      if (pcm->dwrnflg && shpflg==0) {
+	/* use fgrid and red to display the grid, print message to user */
+        isav=pcm->gout2a;
+        pcm->fgvals[0]=pgr->rmin;
+	if (pcm->ccolor>0)
+	  pcm->fgcols[0]=pcm->ccolor;
+	else
+	  pcm->fgcols[0]=2;
+        pcm->gout2a = 6;
+        pcm->fgcnt = 1;
+        gaplot (pcm);
+        pcm->gout2a = isav;
+        pcm->fgcnt = 0;
+        snprintf(pout,255,"Constant field.  Value = %g\n",pgr->rmin);
+        gaprnt (1,pout);
+      } else {
+	/* just print the message */
+        snprintf(pout,255,"Constant field.  Value = %g\n",pgr->rmin);
+        gaprnt (1,pout);
+      }
+      return 1;
+    }
+    /* make sure there aren't too many levels */
+    pmin = cmin;
+    if (pmin<pcm->cmin) pmin = pcm->cmin;
+    pmax = cmax;
+    if (pmax>pcm->cmax) pmax = pcm->cmax;
+    if ((pmax-pmin)/cint>100.0) {
+      gaprnt (0,"Too many contour levels -- adjusting cint\n");
+      while ((pmax-pmin)/cint>100.0) cint*=10.0;
+      pcm->cint = cint;
+      gacsel (pgr->rmin,pgr->rmax,&cint,&cmin,&cmax);
+    }
+  }
+
+  if (pcm->ccolor>=0) gxcolr(pcm->ccolor);
+  if (pcm->ccolor<0 && pcm->rainmn==0.0 && pcm->rainmx==0.0 && !pcm->cflag) {
+    pcm->rainmn = cmin;
+    pcm->rainmx = cmax;
+  }
+
+  /* Expand grid if smoothing was requested */
+  idiv = 1.0; jdiv = 1.0;
+  smooth = 0;
+  rmin = pgr->rmin; rmax = pgr->rmax;
+  if (pcm->csmth && (pgr->isiz<51 || pgr->jsiz<51)) {
+    smooth = 1;
+    iexp = 100 / pgr->isiz;
+    jexp = 100 / pgr->jsiz;
+    if (iexp>5) iexp = 4;
+    if (jexp>5) jexp = 4;
+    if (iexp<1) iexp = 1;
+    if (jexp<1) jexp = 1;
+    isz = ((pgr->isiz-1)*iexp) + 1;
+    jsz = ((pgr->jsiz-1)*jexp) + 1;
+    sz = isz*jsz*sizeof(gadouble);
+    rrr = (gadouble *)galloc(sz,"rrr");
+    if (rrr==NULL) {
+      gaprnt (0,"Memory Allocation Error:  CSMOOTH operation\n");
+      return 1;
+    }
+    sz = isz*jsz*sizeof(char);
+    rrrmask = (char *)galloc(sz,"rrrmask");
+    if (rrrmask==NULL) {
+      gaprnt (0,"Memory Allocation Error:  CSMOOTH operation\n");
+      gree(rrr,"f291b");
+      return 1;
+    }
+    idiv = (gadouble)iexp;
+    jdiv = (gadouble)jexp;
+    if (pcm->csmth==1) {
+      gagexp (pgr->grid, pgr->isiz, pgr->jsiz, rrr, iexp, jexp, pgr->umask, rrrmask);
+    } else {
+      gaglin (pgr->grid, pgr->isiz, pgr->jsiz, rrr, iexp, jexp, pgr->umask, rrrmask);
+    }
+
+    /* We may have created new contour levels.  Adjust cmin and cmax appropriately */
+    if (!pcm->cflag) {
+      rmin = 9.99e8;
+      rmax = -9.99e8;
+      r = rrr;
+      rmask = rrrmask;
+      cnt=0;
+      for (i=0;i<isz*jsz;i++) {
+        if (*rmask != 0) {
+          cnt++;
+          if (rmin>*r) rmin = *r; 
+          if (rmax<*r) rmax = *r;
+        }
+        r++; rmask++;
+      }
+      if (cnt==0 || dequal(rmin,9.99e8,1e-8)==0 || dequal(rmax,-9.99e8,1e-8)==0) 
+	umin = 0;
+      else 
+	umin = 1;
+
+      if (umin==0) {
+        gaprnt (1,"Cannot contour grid - all undefined values \n");
+        if (pcm->dwrnflg) gxchpl ("Entire Grid Undefined",21,3.0,4.5,0.3,0.25,0.0);
+        gree(rrr,"f291");
+        gree(rrrmask,"f291a");
+        return 1;
+      }
+      while (rmin<cmin) cmin -= cint;
+      while (rmax>cmax) cmax += cint;
+    }
+  }
+  if (pcm->cflag) {
+    gaprnt (2,"Contouring at clevs = ");
+    for (i=0; i<pcm->cflag; i++) {
+      snprintf(pout,255," %g",pcm->clevs[i]);
+      gaprnt (2,pout);
+    }
+    gaprnt (2,"\n");
+  } else {
+    snprintf(pout,255,"Contouring: %g to %g interval %g \n",cmin,cmax,cint);
+    gaprnt (2,pout);
+  }
+
+  gxclip (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2);
+  if (pcm->rbflg) irb = pcm->rbflg - 1;
+  else irb = 12;
+  rrb = irb+1;
+  if (filflg) {
+    gaselc (pcm,pgr->rmin,pgr->rmax);
+    if (smooth) {
+      if (filflg==1) {
+	gxshad (rrr,isz,jsz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,rrrmask);
+      } else if (filflg==2) {
+	gagfil (rrr,isz,jsz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,rrrmask);
+      } else if (filflg==3) {
+	gaimap (rrr,isz,jsz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,rrrmask,
+                    pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2);
+      } else if (filflg==4) {
+	gxshad2 (rrr,isz,jsz,pcm->shdlvs,pgr->rmax,pcm->shdcls,pcm->shdcnt,rrrmask);
+      } else if (filflg==5) {
+	gxshad2b (rrr,isz,jsz,pcm->shdlvs,pgr->rmax,pcm->shdcls,pcm->shdcnt,rrrmask);
+      }
+    } 
+    else {
+      if (filflg==1) {
+        gxshad (pgr->grid,pgr->isiz,pgr->jsiz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,pgr->umask);
+      } else if (filflg==2) {
+        gagfil (pgr->grid,pgr->isiz,pgr->jsiz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,pgr->umask);
+      } else if (filflg==3) {
+        gaimap (pgr->grid,pgr->isiz,pgr->jsiz,pcm->shdlvs,pcm->shdcls,pcm->shdcnt,
+             pgr->umask, pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2);
+      } else if (filflg==4) {
+        gxshad2 (pgr->grid,pgr->isiz,pgr->jsiz,pcm->shdlvs,pgr->rmax,pcm->shdcls,pcm->shdcnt,pgr->umask);
+      } else if (filflg==5) {
+        gxshad2b (pgr->grid,pgr->isiz,pgr->jsiz,pcm->shdlvs,pgr->rmax,pcm->shdcls,pcm->shdcnt,pgr->umask);
+      }
+    }
+    if (pgr->idim==0 && pgr->jdim==1 && shpflg==0) gawmap (pcm, 0);
+  } 
+  else {
+    gxwide (pcm->cthick);
+    cntrcnt = 0;
+    cntrcol = -1;
+    if (pcm->cflag) {          /* user has specified contour levels */
+      for (i=0; i<pcm->cflag; i++) {
+        rr = pcm->clevs[i];
+        if (rr<0.0&&pcm->cstyle==-9) gxstyl (3);
+        else gxstyl(pcm->cstyle);
+        if (pcm->ccolor < 0 && pcm->ccflg == 0) {
+          if (pcm->cflag==1) ii=irb/2;
+          else ii = (gaint)((gadouble)(i*irb)/((gadouble)(pcm->cflag-1)));
+          if (ii>irb) ii=irb;
+          if (ii<0) ii=0;
+          if (pcm->rbflg>0) {
+            if (pcm->ccolor==-1) {
+	      gxcolr(pcm->rbcols[ii]);
+	      cntrcol = pcm->rbcols[ii];
+	    }
+            else {
+	      gxcolr(pcm->rbcols[irb-ii]);
+	      cntrcol = pcm->rbcols[irb-ii];
+	    }
+          } else {
+	    if (pcm->ccolor==-1) {
+	      gxcolr(rcols[ii]);
+	      cntrcol = rcols[ii];
+	    }
+            else {
+	      gxcolr(rcols[12-ii]);
+	      cntrcol = rcols[12-ii];
+	    }
+          }
+        }
+        if (pcm->ccflg) {
+          ii = i;
+          if (ii>=pcm->ccflg) ii = pcm->ccflg-1;
+          gxcolr (pcm->ccols[ii]);
+	  cntrcol = pcm->ccols[ii];  
+        }
+	if (pcm->ccolor > 0 && pcm->ccflg == 0) cntrcol = pcm->ccolor; /* overlays */
+        if (pcm->clstr) 
+	  snprintf(chlab,49,pcm->clstr,rr);
+        else 
+	  snprintf(chlab,49,"%g",rr);
+        chlab[21] = '\0';   /* Limit length of label to 20 chars */
+        scntr.label = chlab;       scntr.spline = pcm->cterp;
+        scntr.ltype = pcm->clab;   scntr.ccol = gxqclr();
+        scntr.labcol = pcm->clcol; scntr.labwid = pcm->clthck;
+        scntr.labsiz = pcm->clsiz; scntr.val = rr;
+	/* label masking and shpflag must be turned on for shapefiles */
+        if (pcm->clab==3 || shpflg==1) {
+	  scntr.mask=1; 
+	  if (shpflg) scntr.shpflg=1;
+	  else scntr.shpflg=0;
+	}
+	else {
+	  scntr.mask=0;
+	}
+        if (smooth) {
+          gxclev (rrr,isz,jsz,1,isz,1,jsz,rr,rrrmask,&scntr);
+        } else {
+          gxclev (pgr->grid,pgr->isiz,pgr->jsiz,1,pgr->isiz,1,
+                  pgr->jsiz,rr,pgr->umask,&scntr);
+        }
+	pcm->cntrcols[cntrcnt] = cntrcol; 
+	pcm->cntrlevs[cntrcnt] = rr;
+	cntrcnt++;
+      }
+      pcm->cntrcnt = cntrcnt; 
+    } else {
+      clcnt = 0;
+      clopt = 0;  /* normalize clskip only when well-behaved */
+      if (fabs(cmin/cint)<1e6 || fabs(cmax/cint)<1e6) clopt=1; 
+      for (rl=cmin;rl<=cmax+(cint/2.0);rl+=cint) {
+	if (dequal(rl,0.0,1e-15)==0) rl=0.0; /* a quick patch */
+        if (rl<pcm->cmin || rl>pcm->cmax) continue;
+        if (pcm->blkflg && rl>=pcm->blkmin && rl<=pcm->blkmax) continue;
+        rr = rl;
+        if (rr<0.0 && pcm->cstyle==-9) gxstyl (3);
+        else gxstyl(pcm->cstyle);
+        if (pcm->ccolor < 0) {
+          ii = (gaint)(rrb*(rr-pcm->rainmn)/(pcm->rainmx-pcm->rainmn));
+          if (ii>irb) ii=irb;
+          if (ii<0) ii=0;
+          if (pcm->rbflg>0) {
+            if (pcm->ccolor==-1) {
+	      gxcolr(pcm->rbcols[ii]);
+	      cntrcol = pcm->rbcols[ii];
+	    }
+            else {
+	      gxcolr(pcm->rbcols[irb-ii]);
+	      cntrcol = pcm->rbcols[irb-ii];
+	    }
+          } else {
+            if (pcm->ccolor==-1) {
+	      gxcolr(rcols[ii]);
+	      cntrcol = rcols[ii];
+	    }
+            else {
+	      gxcolr(rcols[12-ii]);
+	      cntrcol = rcols[12-ii];
+	    }
+          }
+        }
+	else {
+	  cntrcol = pcm->ccolor;
+	}
+        clflg = 0;
+        if (clopt) {
+          tt = rl/(cint*(gadouble)pcm->clskip);
+          ii = (gaint)(tt+0.009);
+          ii2 = (gaint)(tt-0.009);
+          if (fabs(tt-(gadouble)ii)<0.01 || fabs(tt-(gadouble)ii2)<0.01) clflg=1;
+        } else {
+          if (clcnt == pcm->clskip) {
+            clflg = 1; clcnt = 0;
+          } else clcnt++;
+        }
+        if (clflg) {
+          if (pcm->clstr) {
+	    snprintf(chlab,49,pcm->clstr,rr);
+	  } else {
+	    snprintf(chlab,49,"%g",rr);
+	  }
+          chlab[21] = '\0';  /* Limit length to 20 chars */
+        } else {
+          chlab[0] = '\0';
+        }
+        scntr.label = chlab;       scntr.spline = pcm->cterp;
+        scntr.ltype = pcm->clab;   scntr.ccol = gxqclr();
+        scntr.labcol = pcm->clcol; scntr.labwid = pcm->clthck;
+        scntr.labsiz = pcm->clsiz; scntr.val = rr;
+	/* label masking and shpflag must be turned on for shapefiles */
+        if (pcm->clab==3 || shpflg==1) {
+	  scntr.mask=1; 
+	  if (shpflg) scntr.shpflg=1;
+	  else scntr.shpflg=0;
+	}
+	else {
+	  scntr.mask=0;
+	}
+        if (smooth) {
+          gxclev (rrr,isz,jsz,1,isz,1,jsz,rr,rrrmask,&scntr);
+        } else {
+          gxclev (pgr->grid,pgr->isiz,pgr->jsiz,1,pgr->isiz,1,
+                  pgr->jsiz,rr,pgr->umask,&scntr);
+        }
+	pcm->cntrcols[cntrcnt] = cntrcol; 
+	pcm->cntrlevs[cntrcnt] = rr;
+	cntrcnt++;
+      }
+      pcm->cntrcnt = cntrcnt;
+    }
+    if (shpflg==0) {
+      if (pcm->clab == 3) {
+	gxpclin();
+      }
+      else {
+	if (pcm->clcol>-1) gxcolr (pcm->clcol);
+	if (pcm->clthck>-1) gxwide (pcm->clthck);
+	gxclab (pcm->clsiz,pcm->clab,pcm->clcol);
+      }
+      gxcrel ();
+    }
+  }
+  if (smooth) {
+    gree(rrr,"f292");
+    gree(rrrmask,"f292a");
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxcolr(pcm->anncol);
+  gxwide (pcm->annthk-3);
+  if (shpflg==0) {
+    if (pcm->pass==0 && pcm->grdsflg)
+      gxchpl("GrADS: COLA/IGES",16,0.05,0.05,0.1,0.08,0.0);
+    if (pcm->pass==0 && pcm->timelabflg) gatmlb(pcm);
+    gaaxpl(pcm,pgr->idim,pgr->jdim);
+    gafram (pcm);
+  }
+  if (filflg==1) {
+    gagsav (2,pcm,pgr);
+  }
+  else if (filflg==2) {
+    gagsav (16,pcm,pgr);
+  }
+  else if (filflg==3) {
+    gagsav (26,pcm,pgr);
+  }
+  else if (filflg==4) {
+    gagsav (27,pcm,pgr);
+  }
+  else if (filflg==5) {
+    gagsav (28,pcm,pgr);
+  }
+  else {
+    if (shpflg==0) gagsav (1,pcm,pgr);
+  }
+  return 0;
+}
+
+/* Routine to perform grid level scaling.  The address of this
+   routine is passed to gxgrid.  */
+
+void gaconv (gadouble s, gadouble t, gadouble *x, gadouble *y) {
+  s = ((s-1.0)/idiv)+1.0;
+  t = ((t-1.0)/jdiv)+1.0;
+  if (iconv==NULL) *x = s+ioffset;
+  else *x = iconv(ivars, (s+ioffset));
+  if (jconv==NULL) *y = t+joffset;
+  else *y = jconv(jvars, (t+joffset));
+}
+
+/* Draw axis labels.  axis = 1 is x axis, axis = 0 is y axis */
+
+void gaaxis (gaint axis, struct gacmn *pcm, gaint dim) {
+struct gafile *pfi;
+struct dt tstrt,tincr,addmo,twrk;
+gadouble vmin,vmax,*tvals=0,x,y,tt;
+gadouble v,vincr,vstrt,vend;
+gadouble m,b,cs,xx,cwid,pos;
+gaint ii,len,tinc=0,colr,thck,flg,i,cnt;
+char lab[30],olab[30],*chlb=NULL;
+ 
+  if (axis && pcm->xlab==0) return;
+  if (!axis && pcm->ylab==0) return;
+  addmo.yr = 0L;
+  addmo.mo = 1L;
+  addmo.dy = 0L;
+  addmo.hr = 0L;
+  addmo.mn = 0L;
+  if (axis==1) {
+    cs = pcm->xlsiz; 
+    colr = pcm->xlcol;
+    thck = pcm->xlthck;
+    if (pcm->xlside) pos = pcm->ysiz2 + pcm->xlpos;
+    else pos = pcm->ysiz1 + pcm->xlpos;
+    if (pcm->xlpos!=0.0) { 
+      gxcolr (pcm->anncol);
+      gxwide (pcm->annthk);
+      gxstyl (1);
+      gxplot (pcm->xsiz1,pos,3);
+      gxplot (pcm->xsiz2,pos,2);
+    }
+  } else {
+    cs = pcm->ylsiz;
+    colr = pcm->ylcol;
+    thck = pcm->ylthck;
+    if (pcm->ylside) pos = pcm->xsiz2 + pcm->ylpos;
+    else pos = pcm->xsiz1 + pcm->ylpos;
+    if (pcm->ylpos!=0.0) {
+      gxcolr (pcm->anncol);
+      gxwide (pcm->annthk);
+      gxstyl (1);
+      gxplot (pos,pcm->ysiz1,3);
+      gxplot (pos,pcm->ysiz2,2);
+    }
+  }
+  /* Select axis min and max */
+  vincr=0.0;
+  if (dim==5) {         /* hard coded 5 */
+    vmin = pcm->rmin; 
+    vmax = pcm->rmax;
+  } 
+  else if (dim==3) {
+    pfi = pcm->pfid;
+    tvals = pfi->abvals[3];
+    vmin = t2gr(tvals,&(pcm->tmin));
+    vmax = t2gr(tvals,&(pcm->tmax));
+  } else {
+    vmin = pcm->dmin[dim];
+    vmax = pcm->dmax[dim];
+  }
+  if (axis && pcm->xlabs) {  /* doesn't allow only one label? */
+    vmin = 1.0;
+    vmax = (gadouble)pcm->ixlabs;
+    vincr = 1.0;
+    dim = 5;
+  }
+  if (!axis && pcm->ylabs) {
+    vmin = 1.0;
+    vmax = (gadouble)pcm->iylabs;
+    vincr = 1.0;
+    dim = 5;
+  }
+  if (axis && pcm->axflg && (dim!=2 || pcm->zlog==0)) {
+    vmin = pcm->axmin;
+    vmax = pcm->axmax;
+    vincr = pcm->axint;
+    dim = 5;
+    gaprnt (1,"Warning:  X axis labels overridden by SET XAXIS.\n");
+    gaprnt (1,"   Labels may not reflect correct scaling for dimensions or data.\n");
+  }
+  if (!axis && pcm->ayflg && (dim!=2 || pcm->zlog==0)) {
+    vmin = pcm->aymin;
+    vmax = pcm->aymax;
+    vincr = pcm->ayint;
+    dim = 5;
+    gaprnt (1,"Warning:  Y axis labels overridden by SET YAXIS.\n");
+    gaprnt (1,"   Labels may not reflect correct scaling for dimensions or data.\n");
+  }
+  if (vmin==vmax) {   /* no precision check */
+    gaprnt(0,"gaaxis internal logic check 24\n");
+    return;
+  }
+
+  /* Handle axis flipping */
+
+  if (axis) {
+    if (pcm->xflip) {
+      m=(pcm->xsiz2-pcm->xsiz1)/(vmin-vmax);
+      b=pcm->xsiz1-(m*vmax);
+    } else {
+      m=(pcm->xsiz2-pcm->xsiz1)/(vmax-vmin);
+      b=pcm->xsiz1-(m*vmin);
+    }
+  } else {
+    if (pcm->yflip) {
+      m=(pcm->ysiz2-pcm->ysiz1)/(vmin-vmax);
+      b=pcm->ysiz1-(m*vmax);
+    } else {
+      m=(pcm->ysiz2-pcm->ysiz1)/(vmax-vmin);
+      b=pcm->ysiz1-(m*vmin);
+    }
+  }
+
+  /* Select label interval */
+
+  if (vmin>vmax) {
+    v = 1.0*vmax;  /* Avoid optimization */
+    vmax = vmin;
+    vmin = v;
+  }
+  if (dim==3) {
+    tinc = gatinc (pcm, &tstrt, &tincr);
+  } else {
+    flg = 1;
+    if (axis==1 && pcm->xlint!=0.0) {vincr=pcm->xlint; flg=0;}
+    if (axis==0 && pcm->ylint!=0.0) {vincr=pcm->ylint; flg=0;}
+    if (vincr<0.0) {
+      vincr = -1.0 * vincr;
+      vstrt = vmin;
+      vend = vmax;
+      vend = vend+(vincr*0.5);
+    } else {
+      gacsel (vmin,vmax,&vincr,&vstrt,&vend);
+      if (vincr==0.0) {  /* no precision check */
+        gaprnt (0,"gaaxis internal logic check 25\n");
+        return;
+      }
+      if (dim==1 && flg) {
+        if (vincr>19.9) vincr=30.0;
+        else if (vincr>10.0) vincr=10.0;
+      }
+      if (dim==0 && flg) {
+        if (vincr>74.5) vincr=90.0;
+        else if (vincr>44.5) vincr=60.0;
+        else if (vincr>24.9) vincr=30.0;
+        else if (vincr>14.5) vincr=20.0;
+        else if (vincr>10.0) vincr=10.0;
+      }
+      gacsel (vmin,vmax,&vincr,&vstrt,&vend);
+      vend = vend+(vincr*0.5);
+    }
+  }
+
+  gxcolr(colr);
+  gxwide(thck);
+  gxstyl(1);
+  if (dim!=3) {
+    if (axis==1 && pcm->xlflg>0) cnt = pcm->xlflg;
+    else if (axis==0 && pcm->ylflg>0) cnt = pcm->ylflg;
+    else {
+      cnt = 1.0 + (vend-vstrt)/vincr;
+      if (cnt>50) cnt=50;
+      for (i=0; i<cnt; i++) {
+        v = vstrt+vincr*(gadouble)i;
+        if (fabs(v/vincr)<1e-5) v=0.0;
+        if (axis) *(pcm->xlevs+i) = v;
+        else *(pcm->ylevs+i) = v;
+      }
+    }
+
+    i = 0;
+    if (axis==1 && pcm->xlabs) chlb = pcm->xlabs;
+    if (axis==0 && pcm->ylabs) chlb = pcm->ylabs;
+    while (i<cnt) {
+      if (axis) v = *(pcm->xlevs+i);
+      else v = *(pcm->ylevs+i);
+      if (axis==1 && pcm->xlstr) snprintf(lab,29,pcm->xlstr,v);
+      else if (axis==0 && pcm->ylstr) snprintf(lab,29,pcm->ylstr,v);
+      else if ( ( axis==1 && pcm->xlabs ) || ( axis==0 && pcm->ylabs) ) {
+        snprintf(lab,29,chlb,v);
+        while (*chlb) chlb++;
+        chlb++;
+      }
+      else {
+        if (dim==0 && pcm->mproj>0) len = galnch(v,lab);
+        else if (dim==1 && pcm->mproj>0) len = galtch(v,lab);
+        else snprintf(lab,29,"%g",v);
+      }
+      len=0;
+      while (lab[len]) len++;
+      cwid = (gadouble)len*cs;
+      gxchln (lab,len,cs,&cwid);
+      if (axis) {
+        x = (v*m)+b;
+        if (dim==2 && pcm->zlog) gxconv(v,pos,&x,&tt,2);
+        else if (dim==1 && pcm->coslat) gxconv(v,pos,&x,&tt,2); 
+        else if (pcm->log1d) gxconv(v,pos,&x,&tt,2); 
+        if (x<pcm->xsiz1-0.05 || x>pcm->xsiz2+0.05) {
+          i++;
+          continue;
+        }
+        gxplot (x,pos,3);
+        if (pcm->xlside) gxplot (x,pos+(cs*0.4),2);
+        else gxplot (x,pos-(cs*0.4),2);
+        if (pcm->grflag==1 || pcm->grflag==3) {
+          gxwide (1);
+          gxstyl (pcm->grstyl);
+          gxcolr (pcm->grcolr);
+          gxplot (x,pcm->ysiz1,3);
+          gxplot (x,pcm->ysiz2,2);
+          gxcolr(colr);
+          gxwide(thck);
+          gxstyl(1);
+        }
+        x = x - cwid*0.4;
+        if (pcm->xlside) y = pos + (cs*0.7);
+        else y = pos - (cs*1.7);
+      } else {
+        y = (v*m)+b;
+        if (dim==2 && pcm->zlog) gxconv(pcm->xsiz1,v,&tt,&y,2);
+        else if (dim==1 && pcm->coslat) gxconv(pcm->xsiz1,v,&tt,&y,2); 
+        else if (pcm->log1d) gxconv(pcm->xsiz1,v,&tt,&y,2); 
+        if (y<pcm->ysiz1-0.05 || y>pcm->ysiz2+0.05) {
+          i++;
+          continue;
+        }
+        gxplot (pos,y,3);
+        if (pcm->ylside) {
+          gxplot (pos+(cs*0.4),y,2);
+          x = pos + cs*0.8;
+        } else {
+          gxplot (pos-(cs*0.4),y,2);
+          x = pos - (cwid+cs)*0.8;
+          if (pcm->yllow<(cwid+cs)*0.8) pcm->yllow = (cwid+cs)*0.8;
+        }
+        if (pcm->grflag==1 || pcm->grflag==2) {
+          gxwide (1);
+          gxstyl (pcm->grstyl);
+          gxcolr (pcm->grcolr);
+          gxplot (pcm->xsiz1,y,3);
+          gxplot (pcm->xsiz2,y,2);
+          gxwide(thck);
+          gxcolr(colr);
+          gxstyl(1);
+        }
+        y = y - (cs*0.5);
+      }
+      gxchpl(lab,len,x,y,cs,cs*0.8,0.0);
+      lab[9] = '\0';
+      i++;
+    }
+  } else {
+
+    /*  Do Date/Time labeling  */
+
+    strcpy (olab,"mmmmmmmmmmmmmmmm");
+    while (timdif(&tstrt,&(pcm->tmax))>-1L) {
+      len = gat2ch(&tstrt,tinc,lab,30);
+      v = t2gr(tvals,&tstrt);
+      if (axis) {
+        x = (v*m)+b;
+        gxplot (x,pos,3);
+        if (pcm->xlside) gxplot (x,pos+(cs*0.4),2);
+        else gxplot (x,pos-(cs*0.4),2);
+        if (pcm->grflag==1 || pcm->grflag==3) {
+          gxwide (1);
+          gxstyl (pcm->grstyl);
+          gxcolr (pcm->grcolr);
+          gxplot (x,pcm->ysiz1,3);
+          gxplot (x,pcm->ysiz2,2);
+          gxwide(thck);
+          gxcolr(colr);
+          gxstyl(1);
+        }
+        if (pcm->xlside) y = pos + (cs*0.7);
+        else y = pos - (cs*1.7);
+        ii = 0;
+        if (tinc>3) {
+          if (tinc==5) len = 6;
+          if (tinc==4) len = 3;
+          if (cmpch(&(lab[ii]),&(olab[ii]),len)) {
+            cwid = len*cs;
+            gxchln(&lab[ii],len,cs,&cwid);
+            xx = x - cwid*0.4;
+            gxchpl(&lab[ii],len,xx,y,cs,cs*0.8,0.0);
+          }
+          if (pcm->xlside) y = y + cs*1.4;
+          else y = y - cs*1.4;
+          ii = len;
+        }
+        if (tinc>1 && pcm->tlsupp<2) {
+          len = 5;
+          if (tinc==2) len=3;
+          if (cmpch(&(lab[ii]),&(olab[ii]),len)) {
+            if (lab[ii]=='0') {ii++; len--;}
+            cwid = len*cs;
+            gxchln(&lab[ii],len,cs,&cwid);
+            xx = x - cwid*0.4;
+            gxchpl(&lab[ii],len,xx,y,cs,cs*0.8,0.0);
+          }
+          if (pcm->xlside) y = y + cs*1.4;
+          else y = y - cs*1.4;
+          ii += len;
+        }
+        len = 4;
+        if (tinc!=2 || tstrt.yr!=9999) {
+          if (pcm->tlsupp==0) {
+          if (cmpch(&(lab[ii]),&(olab[ii]),len)) {
+            cwid = len*cs;
+            gxchln(&lab[ii],len,cs,&cwid);
+            xx = x - cwid*0.4;
+            gxchpl(&lab[ii],len,xx,y,cs,cs*0.8,0.0);
+          }
+          }
+        }
+        strcpy (olab,lab);
+      } else {
+        y = (v*m)+b;
+        gxplot (pos,y,3);
+        if (pcm->ylside) gxplot (pos+(cs*0.4),y,2);
+        else gxplot (pos-(cs*0.4),y,2);
+        if (pcm->grflag==1 || pcm->grflag==2) {
+          gxwide (1);
+          gxstyl (pcm->grstyl);
+          gxcolr (pcm->grcolr);
+          gxplot (pcm->xsiz1,y,3);
+          gxplot (pcm->xsiz2,y,2);
+          gxwide(thck);
+          gxcolr(colr);
+          gxstyl(1);
+        }
+        ii = 0;
+        if (pcm->tlsupp==1) len = len - 4;
+        if (pcm->tlsupp==2) len = len - 9;
+        if (len > 1) {
+          if (tinc==3&&lab[0]=='0') {ii=1; len--;}
+          y = y - (cs*0.5);
+          cwid = len*cs;
+          gxchln(&lab[ii],len,cs,&cwid);
+          if (pcm->ylside) {
+            x = pos + cs*0.8;
+          } else {
+            x = pos - (cwid+cs)*0.8;
+            if (pcm->yllow<(cwid+cs)*0.8) pcm->yllow = (cwid+cs)*0.8;
+          }
+          gxchpl(&lab[ii],len,x,y,cs,cs*0.8,0.0);
+        }
+      }
+
+      /* Get next date/time. */
+
+      twrk = tincr;
+      timadd (&tstrt, &twrk);
+      tstrt = twrk;
+      if (tincr.dy>1L&&(tstrt.dy==31L||(tstrt.dy==29L&&tstrt.dy==2))) {
+        tstrt.dy = 1L;
+        twrk = addmo;
+        timadd (&tstrt, &twrk);
+        tstrt = twrk;
+      }
+      if (tincr.dy>3&&tstrt.dy==3&&(tstrt.dy==2||tstrt.dy==3)) tstrt.dy = 1;
+    }
+  }
+}
+
+/* Set up map projection scaling.  */
+
+void gamscl (struct gacmn *pcm) {
+gaint rc=0, flag;
+
+  if (pcm->paflg) {
+    mpj.xmn = pcm->pxmin;
+    mpj.xmx = pcm->pxmax;
+    mpj.ymn = pcm->pymin;
+    mpj.ymx = pcm->pymax;
+  } else {
+    mpj.xmn = 0.5;
+    mpj.xmx = pcm->xsiz - 0.5;
+    mpj.ymn = 0.75;
+    mpj.ymx = pcm->ysiz - 0.75;
+  }
+  if (pcm->mpflg==4 && pcm->mproj>2 && pcm->mproj!=7) {
+    mpj.lnmn = pcm->mpvals[0]; mpj.lnmx = pcm->mpvals[1];
+    mpj.ltmn = pcm->mpvals[2]; mpj.ltmx = pcm->mpvals[3];
+  } else {
+    mpj.lnmn = pcm->dmin[0]; mpj.lnmx = pcm->dmax[0];
+    mpj.ltmn = pcm->dmin[1]; mpj.ltmx = pcm->dmax[1];
+  }
+  flag = 0;
+  if (pcm->mproj==3) {
+    rc = gxnste (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for NPS\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  } else if (pcm->mproj==4) {
+    rc = gxsste (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for SPS\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  } else if (pcm->mproj==5) {
+    rc = gxrobi (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for Robinson\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  } else if (pcm->mproj==6) {
+    rc = gxmoll (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for Mollweide\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  } else if (pcm->mproj==7) {
+    if (pcm->mpflg==4) {
+      mpj.axmn = pcm->mpvals[0]; mpj.axmx = pcm->mpvals[1];
+      mpj.aymn = pcm->mpvals[2]; mpj.aymx = pcm->mpvals[3];
+    } else mpj.axmn = -999.9;
+    rc = gxortg (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for Orthographic Projection\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  } else if (pcm->mproj==13) {
+    rc = gxlamc (&mpj);
+    if (rc) {
+      gaprnt (0,"Map Projection Error:  Invalid coords for Lambert conformal Projection\n");
+      gaprnt (0,"  Will use linear lat-lon projection\n");
+      flag = 1;
+    }
+  }
+
+  if (pcm->mproj==2 || flag) rc = gxltln (&mpj);
+  else if (pcm->mproj<2) rc = gxscld (&mpj, pcm->xflip, pcm->yflip);
+  if (rc) {
+    gaprnt (0,"Map Projection Error:  Internal Logic check\n");
+    return;
+  };
+
+  pcm->xsiz1 = mpj.axmn;
+  pcm->xsiz2 = mpj.axmx;
+  pcm->ysiz1 = mpj.aymn;
+  pcm->ysiz2 = mpj.aymx;
+}
+
+/* Plot map with proper data set, line style, etc. */
+/* If iflg true, check pass number */
+
+void gawmap (struct gacmn *pcm, gaint iflg) {
+struct mapopt mopt;
+gaint i;
+
+  if (pcm->mproj==0 || (pcm->pass > 0 && iflg)) return;
+  if (pcm->mpdraw==0) return;
+  gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+  if (pcm->mapcol<0) {
+    if (iflg) {
+      mopt.dcol = pcm->mcolor;
+      mopt.dstl = 1;
+      mopt.dthk = 1;
+    } else {
+      mopt.dcol = 1;
+      mopt.dstl = 1;
+      mopt.dthk = 4;
+    }
+  } else {
+    mopt.dcol = pcm->mapcol;
+    mopt.dstl = pcm->mapstl;
+    mopt.dthk = pcm->mapthk;
+  }
+  mopt.lnmin = pcm->dmin[0]; mopt.lnmax = pcm->dmax[0];
+  mopt.ltmin = pcm->dmin[1]; mopt.ltmax = pcm->dmax[1];
+  mopt.mcol = pcm->mpcols;
+  mopt.mstl = pcm->mpstls;
+  mopt.mthk = pcm->mpthks;
+  i = 0;
+  while (pcm->mpdset[i]) {
+    mopt.mpdset = pcm->mpdset[i];
+    gxdmap (&(mopt));
+    i++;
+  }
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+}
+
+/* Select a contour interval.  */
+
+void gacsel (gadouble rmin, gadouble rmax, gadouble *cint, gadouble *cmin, gadouble *cmax) {
+  gadouble rdif,ndif,norml,w1,w2,t1,t2,absmax;
+
+  /* determine if field is a constant */
+  absmax = ( fabs(rmin)+fabs(rmax) + fabs(fabs(rmin)-fabs(rmax)) )/2;
+  if (absmax > 0.0) {
+    ndif = (fabs(rmax-rmin))/absmax;
+  }
+  else {
+    /* rmin and rmax are both zero */
+    *cint=0.0;
+    *cmin=0.0;
+    *cmax=0.0;
+    return;
+  }
+      
+  if (ndif > 0) {
+    rdif = rmax-rmin;
+  }
+  else {
+    /* rmin and rmax are the same */
+    *cint=0.0;
+    *cmin=0.0;
+    *cmax=0.0;
+    return;
+  }
+ 
+  /* determine appropriate contour min, max, and interval */
+  if (*cint==0.0) {            /* no precision check */
+    rdif = rdif/10.0;          /* appx. 10 contour intervals */
+    w2 = floor(log10(rdif));
+    w1 = pow(10.0,w2);
+    norml = rdif/w1;           /* normalized contour interval */
+    if     (norml>=1.0 && norml<=1.5) *cint=1.0;
+    else if (norml>1.5 && norml<=2.5) *cint=2.0;
+    else if (norml>2.5 && norml<=3.5) *cint=3.0;
+    else if (norml>3.5 && norml<=7.5) *cint=5.0;
+    else *cint=10.0;
+    *cint = *cint*w1;
+  }
+  *cmin = *cint * ceil(rmin/(*cint));  
+  *cmax = *cint * floor(rmax/(*cint));
+
+  /* Check for interval being below machine epsilon for these values */
+  t1 = rmin + *cint;
+  t2 = rmax - *cint;
+  if ((dequal(rmin, t1, 1.0e-16)==0) ||
+      (dequal(rmax, t2, 1.0e-16)==0)) {
+    *cint=0.0;
+    *cmin=0.0;
+    *cmax=0.0;
+  }
+  return;
+}
+
+/* Convert longitude to character */
+
+gaint galnch (gadouble lon, char *ch) {
+gaint len;
+
+  while (lon<=-180.0) lon+=360.0;
+  while (lon>180.0) lon-=360.0;
+
+  snprintf(ch,29,"%g",fabs(lon));
+  len=0;
+  while (ch[len]) len++;
+  if (lon<0.0) {
+    ch+=len;
+    *ch='W';
+    *(ch+1)='\0';
+    len++;
+  }
+  if (lon>0.0 && lon<180.0) {
+    ch+=len;
+    *ch='E';
+    *(ch+1)='\0';
+    len++;
+  }
+  return (len);
+}
+
+/* Convert latitude to character */
+
+gaint galtch (gadouble lat, char *ch) {
+
+gaint len;
+
+  snprintf(ch,29,"%g",fabs(lat));
+  len=0;
+  while (ch[len]) len++;
+  if (lat<0.0) {
+    ch+=len;
+    *ch='S';
+    *(ch+1)='\0';
+    len++;
+  } else if (lat>0.0) {
+    ch+=len;
+    *ch='N';
+    *(ch+1)='\0';
+    len++;
+  } else {
+    *ch='E';
+    *(ch+1)='Q';
+    *(ch+2)='\0';
+    len=2;
+  }
+  return (len);
+}
+
+/* Expand a grid using bi-linear interpolation.  Same args as  gagexp.  */
+
+void gaglin (gadouble *g1, gaint cols, gaint rows, 
+	     gadouble *g2, gaint exp1, gaint exp2, char *g1u, char *g2u) {
+gadouble v1,v2,xoff,yoff,x,y,xscl,yscl;
+gaint i,j,p1,p2,p3,p4,isiz,jsiz;
+
+  isiz = (cols-1)*exp1+1;
+  jsiz = (rows-1)*exp2+1;
+  xscl = (gadouble)(cols-1)/(gadouble)(isiz-1);
+  yscl = (gadouble)(rows-1)/(gadouble)(jsiz-1);
+  for (j=0; j<jsiz; j++) {
+  for (i=0; i<isiz; i++) {
+    x = (gadouble)i*xscl;
+    y = (gadouble)j*yscl;
+    if (x<0.0) x=0.0;
+    if (y<0.0) y=0.0;
+    if (x>=(gadouble)cols) x=(gadouble)cols-0.001;  /* fudge the edges  */ 
+    if (y>=(gadouble)rows) y=(gadouble)rows-0.001;  /* check with bdoty */
+    p1 = (gaint)x + cols*(gaint)y;
+    p2 = p1+1;
+    p4 = p1+cols;
+    p3 = p4+1;
+    if (g1u[p1]==0 || g1u[p2]==0 || g1u[p3]==0 || g1u[p4]==0) {
+      *g2u = 0;
+    } else {
+      xoff = x-floor(x);
+      yoff = y-floor(y);
+      v1 = g1[p1] + (g1[p2]-g1[p1])*xoff;
+      v2 = g1[p4] + (g1[p3]-g1[p4])*xoff;
+      *g2 = v1 + (v2-v1)*yoff;
+      *g2u = 1;
+    }
+    g2++; g2u++;
+  }}
+}
+
+/*   gagexp 
+
+    Routine to expand a grid (Grid EXPand) into a larger grid
+    using bi-directional cubic interpolation.  It is expected that this
+    routine will be used to make a finer grid for a more pleasing
+    contouring result.
+
+    g1 -   addr of smaller grid
+    cols - number of columns in smaller grid
+    rows - number of rows in smaller grid
+    g2   - addr of where larger grid is to go
+    exp1 - expansion factor for rows (1=no expansion, 20 max);
+    exp2 - expansion factor for columns (1=no expansion, 20 max);
+    mval - missing data value
+
+    number of output columns = (cols-1)*exp1+1
+    number of output rows    = (rows-1)*exp2+1   */
+
+
+void gagexp (gadouble *g1, gaint cols, gaint rows, 
+	     gadouble *g2, gaint exp1, gaint exp2, char *g1u, char *g2u) {
+
+gadouble *p1, *p2;
+gadouble s1,s2,a,b,t;
+gadouble pows1[20],pows2[20],pows3[20];
+gadouble kurv;
+gaint ii,jj,k,c,d,e;
+char *p1u,*p2u;
+
+ kurv=1.0;     /* Curviness factor for spline */
+
+ /* First go through each row and interpolate the missing columns.
+    Edge conditions (sides and missing value boundries) are handled
+    by assuming a linear slope at the edge.  */
+
+  for (k=0; k<exp1; k++) {
+    t=( (gadouble)k ) / ( (gadouble)exp1 ) ;
+    pows1[k]=t;
+    pows2[k]=t*t;
+    pows3[k]=t*pows2[k];
+  }
+  
+  p1=g1;  
+  p2=g2;
+  p1u=g1u;
+  p2u=g2u;
+  
+  c=((cols-1)*exp1)+1;
+  d=c*exp2;
+  e=c*(exp2-1);
+  
+  for (jj=0; jj<rows; jj++) {
+    for (ii=0; ii<cols-1; ii++,p1++,p1u++) {
+      if (*p1u==0 || *(p1u+1)==0) {
+	*p2u = 0;
+	p2++; p2u++;
+	for (k=1; k<exp1; k++,p2++,p2u++) *p2u=0;
+      } else {
+	if (ii==0 || *(p1u-1)==0) 
+	  s1 = *(p1+1) - *p1;
+	else  
+	  s1 = ( *(p1+1) - *(p1-1) )*0.5;
+	if (ii==(cols-2) || *(p1u+2)==0) 
+	  s2 = *(p1+1) - *p1;
+	else  
+	  s2 = ( *(p1+2) - *p1 )*0.5;
+	s1*=kurv; 
+	s2*=kurv;
+	a = s1 + 2.0*(*p1) - 2.0*(*(p1+1)) + s2;
+	b = 3.0*(*(p1+1)) - s2 - 2.0*s1 - 3.0*(*p1);
+	*p2 = *p1;
+	*p2u = 1;
+	p2++; p2u++;
+	for (k=1; k<exp1; k++,p2++,p2u++) {
+	  *p2 = a*pows3[k] + b*pows2[k] + s1*pows1[k] + *p1;
+	  *p2u = 1;
+	}
+      }
+    }
+    *p2 = *p1;
+    *p2u = *p1u;
+    p1++; p1u++;
+    p2+=e+1; p2u+=e+1;
+  }
+
+  /* Now go through each column and interpolate the missing rows.
+     This is done purely within the output grid, since we have already
+     filled in as much info as we can from the input grid.  */
+  
+  if (exp2==1) return;
+  
+  for (k=0; k<exp2; k++) {
+    t=( (gadouble)k ) / ( (gadouble)exp2 ) ;
+    pows1[k]=t;
+    pows2[k]=t*t;
+    pows3[k]=t*pows2[k];
+  }
+  
+  p2=g2;
+  p2u=g2u;
+  
+  for (jj=0; jj<rows-1; jj++) {
+    for (ii=0; ii<c; ii++,p2++,p2u++) {
+      if (*p2u==0 || *(p2u+d)==0) {
+	for (k=1; k<exp2; k++) *(p2u+(c*k))=0;
+      } else {
+	if (jj==0 || *(p2u-d)==0) 
+	  s1 = *(p2+d) - *p2;
+	else  
+	  s1 = ( *(p2+d) - *(p2-d) )*0.5;
+	if (jj==(rows-2) || *(p2u+(2*d))==0) 
+	  s2 = *(p2+d) - *p2;
+	else  
+	  s2 = ( *(p2+(2*d)) - *p2 )*0.5;
+	s1*=kurv; 
+	s2*=kurv;
+	a = s1 + 2.0*(*p2) - 2.0*(*(p2+d)) + s2;
+	b = 3.0*(*(p2+d)) - s2 - 2.0*s1 - 3.0*(*p2);
+	for (k=1; k<exp2; k++) {
+	  *(p2+(c*k)) = a*pows3[k] + b*pows2[k] + s1*pows1[k] + *p2;
+	  *(p2u+(c*k)) = 1;
+	}
+      }
+    }
+    p2+=e; p2u+=e;
+  }
+  return;
+}
+
+/* Rotate a grid.  Return rotated grid. */
+
+struct gagrid *gaflip (struct gagrid *pgr, struct gacmn *pcm) {
+struct gagrid *pgr2;
+gadouble *gr1, *gr2;
+char *gru1, *gru2;
+gaint i, j, size;
+size_t sz;
+
+  sz = sizeof(struct gagrid);
+  pgr2 = (struct gagrid *)galloc(sz,"pgrflip");
+  if (pgr2==NULL) {
+    gaprnt (0,"Memory Allocation Error:  gaflip pgr2 \n");
+    return (NULL);
+  }
+  *pgr2 = *pgr;
+  size = pgr->isiz * pgr->jsiz;
+  sz = size*sizeof(gadouble);
+  pgr2->grid = (gadouble *)galloc(sz,"grflip");
+  if (pgr2->grid == NULL) {
+    gaprnt (0,"Memory Allocation Error:  gaflip grid \n");
+    gree(pgr2,"f265");
+    return (NULL);
+  }
+  sz = size*sizeof(char);
+  pgr2->umask = (char *)galloc(sz,"gruflip");
+  if (pgr2->umask == NULL) {
+    gaprnt (0,"Memory Allocation Error:  gaflip umask \n");
+    gree(pgr2->grid,"f266");
+    gree(pgr2,"f267");
+    return (NULL);
+  }
+
+  gr1 = pgr->grid;
+  gru1 = pgr->umask;
+  for (j=0; j<pgr->jsiz; j++) {
+    gr2  = pgr2->grid + j;
+    gru2 = pgr2->umask + j;
+    for (i=0; i<pgr->isiz; i++) {
+      *gr2 = *gr1;
+      *gru2 = *gru1;
+      gr1++; gru1++;
+      gr2 += pgr->jsiz;
+      gru2 += pgr->jsiz;
+    }
+  }
+
+  pgr2->idim = pgr->jdim;
+  pgr2->jdim = pgr->idim;
+  pgr2->iwrld = pgr->jwrld; pgr2->jwrld = pgr->iwrld;
+  pgr2->isiz = pgr->jsiz;
+  pgr2->jsiz = pgr->isiz;
+  pgr2->igrab = pgr->jgrab;
+  pgr2->jgrab = pgr->igrab;
+  pgr2->ivals = pgr->jvals;
+  pgr2->jvals = pgr->ivals;
+  pgr2->ilinr = pgr->jlinr;
+  pgr2->jlinr = pgr->ilinr;
+
+  /* Add new grid to list to be freed later */
+
+  i = pcm->relnum;
+  pcm->type[i] = 1;
+  pcm->result[i].pgr = pgr2;
+  pcm->relnum++;
+
+  return (pgr2);
+}
+
+/* Figure out appropriate date/time increment for time axis.  */
+
+gaint gatinc (struct gacmn *pcm, struct dt *tstrt, struct dt *tincr) {
+gaint tdif;
+gadouble y1,y2;
+gadouble c1,c2,c3;
+struct dt twrk,temp;
+
+  tincr->yr = 0L;
+  tincr->mo = 0L;
+  tincr->dy = 0L;
+  tincr->hr = 0L;
+  tincr->mn = 0L;
+  twrk.yr = 0L;
+  twrk.mo = 0L;
+  twrk.dy = 0L;
+  twrk.hr = 0L;
+  twrk.mn = 0L;
+
+  /* Check for a time period that covers a period of years.  */
+
+  if (pcm->tmax.yr-pcm->tmin.yr>4) {
+    y1 = pcm->tmin.yr;
+    y2 = pcm->tmax.yr;
+    c1 = 0.0;
+    gacsel (y1,y2,&c1,&c2,&c3);
+    tincr->yr = (gaint)(c1+0.5);
+    if (tincr->yr==3) tincr->yr=5;
+    goto cont;
+  }
+
+  /* Get time difference in minutes */
+
+  tdif = timdif (&(pcm->tmin),&(pcm->tmax));
+
+  /* Set time increment based on different time differences.
+     The test is entirely arbitrary. */
+
+  if (tdif>1576800L) tincr->mo = 6L;
+  else if (tdif>788400L) tincr->mo = 3L;
+  else if (tdif>262800L) tincr->mo = 1L;
+  else if (tdif>129600L) tincr->dy = 15L;
+  else if (tdif>42000L) tincr->dy = 5L;
+  else if (tdif>14399L) tincr->dy = 2L;
+  else if (tdif>7199L) tincr->dy = 1L;
+  else if (tdif>3599L) tincr->hr = 12L;
+  else if (tdif>1799L) tincr->hr = 6L;
+  else if (tdif>899L) tincr->hr = 3L;
+  else if (tdif>299L) tincr->hr = 1L;
+  else if (tdif>149L) tincr->mn = 30L;
+  else if (tdif>74L)  tincr->mn = 15L;
+  else if (tdif>24L)  tincr->mn = 5L;
+  else if (tdif>9L)   tincr->mn = 2L;
+  else tincr->mn = 1L;
+
+  /* Round tmin to get the correct starting time for this increment.
+     Note that this algorithm assumes that only the above increment
+     settings are possible.  So you can change the range tests
+     (tdiff>something), but do not change the possible increments. */
+
+cont:
+  *tstrt = pcm->tmin;
+
+  if (tincr->mn>0L) {
+    tdif =  tincr->mn*(tstrt->mn/tincr->mn);
+    if (tdif!=tstrt->mn) tstrt->mn = tdif+tincr->mn;
+    if (tstrt->mn>59) {
+      tstrt->mn = 0L;
+      temp = twrk;
+      temp.hr = 1L;
+      timadd (tstrt,&temp);
+      *tstrt = temp;
+    }
+    return(5);
+  }
+  if (tstrt->mn>0L) {
+    tstrt->mn = 0L;
+    temp = twrk;
+    temp.hr = 1L;
+    timadd (tstrt,&temp);
+    *tstrt = temp;
+  }
+
+  if (tincr->hr>0L) {
+    tdif = tincr->hr*(tstrt->hr/tincr->hr);
+    if (tdif!=tstrt->hr) tstrt->hr = tdif+tincr->hr;
+    if (tstrt->hr>23) {
+      tstrt->hr = 0L;
+      temp = twrk;
+      temp.dy = 1L;
+      timadd (tstrt,&temp);
+      *tstrt = temp;
+    }
+    return (4);
+  }
+  if (tstrt->hr>0L) {
+    tstrt->hr = 0L;
+    temp = twrk;
+    temp.dy = 1L;
+    timadd (tstrt,&temp);
+    *tstrt = temp;
+  }
+
+  if (tincr->dy>0L) {
+    tdif = 1L+tincr->dy*((tstrt->dy-1L)/tincr->dy);
+    if (tdif!=tstrt->dy) {
+      tstrt->dy = tdif+tincr->dy;
+      if (tstrt->dy==29L || tstrt->dy==31L) {
+        tstrt->dy = 1L;
+        temp = twrk;
+        temp.mo = 1L;
+        timadd (tstrt,&temp);
+        *tstrt = temp;
+      }
+    }
+    return (3);
+  }
+  if (tstrt->dy>1L) {
+    tstrt->dy = 1L;
+    temp = twrk;
+    temp.mo = 1L;
+    timadd (tstrt,&temp);
+    *tstrt = temp;
+  }
+
+  if (tincr->mo>0L) {
+    tdif = 1L+tincr->mo*((tstrt->mo-1L)/tincr->mo);
+    if (tdif!=tstrt->mo) tstrt->mo = tdif+tincr->mo;
+    if (tstrt->mo>12) {
+      tstrt->mo = 1L;
+      temp = twrk;
+      temp.yr = 1L;
+      timadd (tstrt,&temp);
+      *tstrt = temp;
+    }
+    return (2);
+  }
+  if (tstrt->mo>1L) {
+    tstrt->mo = 1L;
+    temp = twrk;
+    temp.yr = 1L;
+    timadd (tstrt,&temp);
+    *tstrt = temp;
+  }
+
+  tdif = tincr->yr*(tstrt->yr/tincr->yr);
+  if (tdif!=tstrt->yr) tstrt->yr = tdif+tincr->yr;
+  return(1);
+}
+
+/* Plot lat/lon lines when polar stereographic plots are done */
+
+void gampax (struct gacmn *pcm) {
+gadouble x1,y1,x2,y2;
+gadouble lnmin,lnmax,ltmin,ltmax;
+gadouble lnincr,ltincr,lnstrt,lnend,ltstrt,ltend;
+gadouble v,s,plincr,lndif,ln,lt,cs;
+
+  if (!pcm->grflag) return;
+
+  if (pcm->mproj==5) {
+    lnmin = pcm->dmin[0]; lnmax = pcm->dmax[0];
+    ltmin = pcm->dmin[1]; ltmax = pcm->dmax[1];
+    for (ln=lnmin; ln<lnmax+10.0; ln+=45.0) {
+      if (ln<lnmin+10.0 || ln>lnmax-10.0) {
+        gxstyl (1);
+        gxcolr (1);
+        gxwide (5);
+      } else {
+        gxstyl (pcm->grstyl);
+        gxcolr (pcm->grcolr);
+        gxwide (1);
+      }
+      gxconv (ln,ltmin,&x1,&y1,2);
+      gxplot (x1,y1,3);
+      for (lt=ltmin; lt<ltmax+1.0; lt+=2.0) {
+        gxconv (ln,lt,&x1,&y1,2);
+        gxplot (x1,y1,2);
+      }
+    }
+    for (lt=ltmin; lt<ltmax+10.0; lt+=30.0) {
+      if (lt<ltmin+10.0 || lt>ltmax-10.0) {
+        gxstyl (1);
+        gxcolr (1);
+        gxwide (5);
+      } else {
+        gxstyl (pcm->grstyl);
+        gxcolr (pcm->grcolr);
+        gxwide (1);
+      }
+      gxconv (lnmin,lt,&x1,&y1,2);
+      gxplot (x1,y1,3);
+      for (ln=lnmin; ln<lnmax+1.0; ln+=2.0) {
+        gxconv (ln,lt,&x1,&y1,2);
+        gxplot (x1,y1,2);
+      }
+    }
+    /* these are labels when lon ranges from -180 to 180 */
+    if (fabs(lnmin+180.0)<1.0 && fabs(lnmax-180.0)<1.0 && fabs(ltmin+90.0)<1.0 && fabs(ltmax-90.0)<1.0) {
+      cs = 0.10;
+      gxconv (-180.0,90.0,&x1,&y1,2);   gxchpl ("180",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (-90.0,90.0,&x1,&y1,2);    gxchpl ("90W",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (0.0,90.0,&x1,&y1,2);      gxchpl ("0",  1,x1-cs*0.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (90.0,90.0,&x1,&y1,2);     gxchpl ("90E",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (180.0,90.0,&x1,&y1,2);    gxchpl ("180",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+
+      gxconv (-180.0,-90.0,&x1,&y1,2);  gxchpl ("180",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (-90.0,-90.0,&x1,&y1,2);   gxchpl ("90W",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (0.0,-90.0,&x1,&y1,2);     gxchpl ("0",  1,x1-cs*0.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (90.0,-90.0,&x1,&y1,2);    gxchpl ("90E",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (180.0,-90.0,&x1,&y1,2);   gxchpl ("180",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+
+      gxconv (-180.0,-60.0,&x1,&y1,2);  gxchpl ("60S",3,x1-cs*4.5,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (-180.0,-30.0,&x1,&y1,2);  gxchpl ("30S",3,x1-cs*4.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (-180.0,0.0,&x1,&y1,2);    gxchpl ("EQ", 2,x1-cs*2.7,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (-180.0,30.0,&x1,&y1,2);   gxchpl ("30N",3,x1-cs*4.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (-180.0,60.0,&x1,&y1,2);   gxchpl ("60N",3,x1-cs*4.5,y1-cs*0.55,cs*1.1,cs,0.0);
+
+      gxconv (180.0,-60.0,&x1,&y1,2);   gxchpl ("60S",3,x1+cs*1.5,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (180.0,-30.0,&x1,&y1,2);   gxchpl ("30S",3,x1+cs*1.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (180.0,0.0,&x1,&y1,2);     gxchpl ("EQ", 2,x1+cs*0.7,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (180.0,30.0,&x1,&y1,2);    gxchpl ("30N",3,x1+cs*1.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (180.0,60.0,&x1,&y1,2);    gxchpl ("60N",3,x1+cs*1.5,y1-cs*0.55,cs*1.1,cs,0.0);
+
+    }
+    /* these are labels when lon ranges from 0 to 360 */
+    else if (fabs(lnmin+0.0)<1.0 && fabs(lnmax-360.0)<1.0 && fabs(ltmin+90.0)<1.0 && fabs(ltmax-90.0)<1.0) {
+      cs = 0.10;
+      gxconv (0.0,90.0,&x1,&y1,2);      gxchpl ("0",  1,x1-cs*0.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (90.0,90.0,&x1,&y1,2);     gxchpl ("90E",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (180.0,90.0,&x1,&y1,2);    gxchpl ("180",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (270.0,90.0,&x1,&y1,2);    gxchpl ("90W",3,x1-cs*1.5,y1+cs*0.6,cs*1.1,cs,0.0);
+      gxconv (360.0,90.0,&x1,&y1,2);    gxchpl ("0",  1,x1-cs*0.5,y1+cs*0.6,cs*1.1,cs,0.0);
+
+      gxconv (0.0,-90.0,&x1,&y1,2);     gxchpl ("0",  1,x1-cs*0.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (90.0,-90.0,&x1,&y1,2);    gxchpl ("90E",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (180.0,-90.0,&x1,&y1,2);   gxchpl ("180",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (270.0,-90.0,&x1,&y1,2);   gxchpl ("90W",3,x1-cs*1.5,y1-cs*1.6,cs*1.1,cs,0.0);
+      gxconv (360.0,-90.0,&x1,&y1,2);   gxchpl ("0",  1,x1-cs*0.5,y1-cs*1.6,cs*1.1,cs,0.0);
+
+      gxconv (0.0,-60.0,&x1,&y1,2);     gxchpl ("60S",3,x1-cs*4.5,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (0.0,-30.0,&x1,&y1,2);     gxchpl ("30S",3,x1-cs*4.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (0.0,0.0,&x1,&y1,2);       gxchpl ("EQ", 2,x1-cs*2.7,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (0.0,30.0,&x1,&y1,2);      gxchpl ("30N",3,x1-cs*4.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (0.0,60.0,&x1,&y1,2);      gxchpl ("60N",3,x1-cs*4.5,y1-cs*0.55,cs*1.1,cs,0.0);
+
+      gxconv (360.0,-60.0,&x1,&y1,2);   gxchpl ("60S",3,x1+cs*1.5,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (360.0,-30.0,&x1,&y1,2);   gxchpl ("30S",3,x1+cs*1.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (360.0,0.0,&x1,&y1,2);     gxchpl ("EQ", 2,x1+cs*0.7,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (360.0,30.0,&x1,&y1,2);    gxchpl ("30N",3,x1+cs*1.0,y1-cs*0.55,cs*1.1,cs,0.0);
+      gxconv (360.0,60.0,&x1,&y1,2);    gxchpl ("60N",3,x1+cs*1.5,y1-cs*0.55,cs*1.1,cs,0.0);
+    }
+    return;
+  }  /* end of robinson projection case */
+
+  /* Choose grid interval for longitude */
+
+  lnincr=0.0;
+  lnmin = pcm->dmin[0];
+  lnmax = pcm->dmax[0];
+  gacsel (lnmin,lnmax,&lnincr,&lnstrt,&lnend);
+  if (lnincr==0.0)  {
+    gaprnt (0,"gaaxis internal logic check 25\n");
+    return;
+  }
+  if (lnincr>24.9) lnincr=30.0;
+  else if (lnincr>14.5) lnincr=20.0;
+  else if (lnincr>10.0) lnincr=10.0;
+  gacsel (lnmin,lnmax,&lnincr,&lnstrt,&lnend);
+  lndif = lnmax - lnmin;
+
+  if(pcm->xlint!=0.0) lnincr=pcm->xlint;   /*mf 960402 set the lon increment from xlint */
+
+  /* Choose grid interval for latitude */
+
+  ltincr=0.0;
+  ltmin = pcm->dmin[1];
+  ltmax = pcm->dmax[1];
+  gacsel (ltmin,ltmax,&ltincr,&ltstrt,&ltend);
+  if (ltincr==0.0)  {
+    gaprnt (0,"gaaxis internal logic check 25\n");
+    return;
+  }
+  if (lndif>300.0) {
+    if (ltincr>9.9) ltincr = 20.0;
+    else if (ltincr>4.9) ltincr = 10.0;
+    else if (ltincr>1.9) ltincr = 5.0;
+    else if (ltincr>0.8) ltincr = 2.0;
+    else if (ltincr>0.4) ltincr = 1.0;
+    else if (ltincr>0.2) ltincr = 0.5;
+  } else {
+    if (ltincr>14.9) ltincr = 20.0;
+    else if (ltincr>7.9) ltincr = 10.0;
+    else if (ltincr>2.9) ltincr = 5.0;
+    else if (ltincr>1.4) ltincr = 2.0;
+    else if (ltincr>0.6) ltincr = 1.0;
+    else if (ltincr>0.2) ltincr = 0.5;
+  }
+
+  if(pcm->ylint!=0.0) ltincr=pcm->ylint;   /*mf 960402 set the lat increment from ylint */
+
+  if (ltstrt<-89.9) {
+    ltstrt = ltstrt + ltincr;
+    ltmin = ltstrt;
+  }
+  if (ltend>89.9) {
+    ltend = ltend - ltincr;
+    ltmax = ltend;
+  }
+
+  gxstyl (pcm->grstyl);
+  gxcolr (pcm->grcolr);
+  gxwide (1);
+  gxclip (pcm->xsiz1,pcm->xsiz2,pcm->ysiz1,pcm->ysiz2);
+  for (v=lnstrt; v<lnend+lnincr*0.5; v+=lnincr) {
+    gxconv (v,ltmin,&x1,&y1,2);
+    gxconv (v,ltmax,&x2,&y2,2);
+    gxplot (x1,y1,3);
+    gxplot (x2,y2,2);
+  }
+
+  if (lndif>180.0) plincr = lndif/100.0;
+  else if (lndif>60.0) plincr = lndif/50.0;
+  else plincr = lndif/25.0;
+  for (v=ltstrt; v<ltend+ltincr*0.5; v+=ltincr) {
+    gxconv (lnmin,v,&x1,&y1,2);
+    gxplot (x1,y1,3);
+    for (s=lnmin+plincr; s<lnmax+plincr*0.5; s+=plincr) {
+      gxconv (s,v,&x1,&y1,2);
+      gxplot (x1,y1,2);
+    }
+  }
+
+  /* Plot circular frame if user requested such a thing */
+
+  if (pcm->frame==2) {
+    gxcolr(pcm->anncol);
+    gxwide (pcm->annthk-3);
+    gxstyl (1);
+    /* for orthographic projections */
+    if (pcm->mproj==7) {
+      /* draw line along min longitude */
+      v=lnmin;
+      gxconv (v,ltmin,&x1,&y1,2);
+      gxplot (x1,y1,3);
+      for (s=ltmin+plincr; s<ltmax+plincr*0.5; s+=plincr) {
+	gxconv (v,s,&x1,&y1,2);
+	gxplot (x1,y1,2);
+      }
+      /* draw 2nd line along max longitude */
+      v=lnmax;
+      gxconv (v,ltmin,&x1,&y1,2);
+      gxplot (x1,y1,3);
+      for (s=ltmin+plincr; s<ltmax+plincr*0.5; s+=plincr) {
+	gxconv (v,s,&x1,&y1,2);
+	gxplot (x1,y1,2);
+      }
+    }
+    /* for other projections: nps, sps */
+    else {
+      if (pcm->mproj==3) v = ltmin;
+      else v = ltmax;
+      /* draw line around latitude circle */
+      gxconv (lnmin,v,&x1,&y1,2);
+      gxplot (x1,y1,3);
+      for (s=lnmin+plincr; s<lnmax+plincr*0.5; s+=plincr) {
+	gxconv (s,v,&x1,&y1,2);
+	gxplot (x1,y1,2);
+      }
+    }
+  }
+
+  gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+  gxstyl(1);
+}
+
+/* Plot weather symbol */
+
+void wxsym (gaint type, gadouble xpos, gadouble ypos, gadouble scale, gaint colr, gaint *wxcols) {
+gaint ioff,len,i,part,icol;
+gadouble x=0,y=0;
+
+  wxymin = 9e30;
+  wxymax = -9e30;
+  if (type<1||type>43) return;
+  ioff = strt[type-1]-1;
+  len = scnt[type-1];
+  for (i=0; i<len; i++) {
+    part = stype[i+ioff]-1;
+    if (colr<0) {
+      if (type==25) icol=0;
+      else if (type==14 || type==15) icol=1;
+      else if (type==19 || type==20) icol=2;
+      else if (type==31 || type==32) icol=0;
+      else icol = scol[part];
+      gxcolr (*(wxcols+icol));
+    } else gxcolr (colr);
+    x = xpos + sxpos[i+ioff]*scale;
+    y = ypos + sypos[i+ioff]*scale;
+    wxprim (part, x, y, scale);
+  }
+  if (type==40 || type==42) gxmark (2,x,y,scale*0.4);
+  if (type==41 || type==43) gxmark (3,x,y,scale*0.4);
+}
+
+
+/* Plot primitive wx symbol */
+
+void wxprim (gaint part, gadouble xpos, gadouble ypos, gadouble scale) {
+gaint i,len,pos;
+gadouble x,y, xy[40];
+
+  len = slen[part];
+  pos = soff[part]-1;
+  for (i=0; i<len; i++) {
+    x = xpts[i+pos];
+    y = ypts[i+pos];
+    x = x*scale + xpos;
+    y = y*scale + ypos;
+    if (part==1 || part==2) {
+      xy[i*2] = x;
+      xy[i*2+1] = y;
+    } else {
+      gxplot (x,y,spens[i+pos]);
+    }
+    if (y<wxymin) wxymin = y;
+    if (y>wxymax) wxymax = y;
+  }
+  if (part==1 || part==2) gxfill(xy,len);
+}
+
+void gagsav (gaint type, struct gacmn *pcm, struct gagrid *pgr) {
+  pcm->lastgx = type;
+}
+
+/* Log axis scaling */
+
+void galnx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = log(xin);
+  *yout = yin;
+}
+
+void galny (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = log(yin);
+}
+
+void gaalnx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = pow(2.71829,xin);
+  *yout = yin;
+}
+
+void gaalny (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = pow(2.71829,yin);
+}
+
+void galogx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = log10(xin);
+  *yout = yin;
+}
+
+void galogy (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = log10(yin);
+}
+
+void galog2 (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = log10(xin);
+  *yout = log10(yin);
+}
+
+void gaalogx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = pow(10.0,xin);
+  *yout = yin;
+}
+
+void gaalogy (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = pow(10.0,yin);
+}
+
+void gaalog2 (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = pow(10.0,xin);
+  *yout = pow(10.0,yin);
+}
+
+
+/* cos lat scaling */
+
+void gaclx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = sin(xin*M_PI/180);
+  *yout = yin;
+}
+
+void gacly (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = sin(yin*M_PI/180);
+}
+
+void gaaclx (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = asin(xin)*180/M_PI;
+  *yout = yin;
+}
+
+void gaacly (gadouble xin, gadouble yin, gadouble *xout, gadouble *yout) {
+  *xout = xin;
+  *yout = asin(yin)*180/M_PI;
+}
+
+
+/* Grid fill -- using color ranges as in shaded contours */
+
+void gagfil (gadouble *r, gaint is, gaint js, gadouble *vs, gaint *clrs, gaint lvs, char *ru) {
+gadouble x,y,*v,xybox[10];
+gaint i,j,k,flag;
+char *vu;
+
+  v = r;
+  vu = ru;
+  for (j=1; j<=js; j++) {
+    for (i=1; i<=is; i++) {
+      if (*vu != 0) {
+	flag = 1;
+	for (k=0; k<lvs-1; k++) {
+	  if (*v>*(vs+k) && *v<=*(vs+k+1)) {
+	    gxcolr(*(clrs+k));
+	    gxconv ((gadouble)(i)-0.5,(gadouble)(j)-0.5,&x,&y,3);
+	    xybox[0] = x; xybox[1] = y;
+	    gxconv ((gadouble)(i)+0.5,(gadouble)(j)-0.5,&x,&y,3);
+	    xybox[2] = x; xybox[3] = y;
+	    gxconv ((gadouble)(i)+0.5,(gadouble)(j)+0.5,&x,&y,3);
+	    xybox[4] = x; xybox[5] = y;
+	    gxconv ((gadouble)(i)-0.5,(gadouble)(j)+0.5,&x,&y,3);
+	    xybox[6] = x; xybox[7] = y;
+	    gxconv ((gadouble)(i)-0.5,(gadouble)(j)-0.5,&x,&y,3);
+	    xybox[8] = x; xybox[9] = y;
+	    gxfill (xybox,5);
+	    flag = 0;
+	    break;
+	  }
+	}
+	if (flag) {
+	  gxcolr(*(clrs+lvs-1));
+	  gxconv ((gadouble)(i)-0.5,(gadouble)(j)-0.5,&x,&y,3);
+	  xybox[0] = x; xybox[1] = y;
+	  gxconv ((gadouble)(i)+0.5,(gadouble)(j)-0.5,&x,&y,3);
+	  xybox[2] = x; xybox[3] = y;
+	  gxconv ((gadouble)(i)+0.5,(gadouble)(j)+0.5,&x,&y,3);
+	  xybox[4] = x; xybox[5] = y;
+	  gxconv ((gadouble)(i)-0.5,(gadouble)(j)+0.5,&x,&y,3);
+	  xybox[6] = x; xybox[7] = y;
+	  gxconv ((gadouble)(i)-0.5,(gadouble)(j)-0.5,&x,&y,3);
+	  xybox[8] = x; xybox[9] = y;
+	  gxfill (xybox,5);
+	}
+      }
+      v++; vu++;
+    } 
+  }
+}
+
+/* Direct image map to X display.  Bypasses metafile (ie, no refresh on
+   resize and no hardcopy output */
+
+void gaimap (gadouble *r, gaint is, gaint js, gadouble *vs, gaint *clrs, gaint lvs, 
+	     char *ru, gadouble xlo, gadouble xhi, gadouble ylo, gadouble yhi) {
+gadouble x,y,*xvals,*yvals,xscl,yscl;
+gaint i,j,k,off,ii,jj,*imap,*im,flag,imn,imx,jmn,jmx,iz,jz,*ivals,*jvals;
+
+  /* Determine the pixel size of our image, which is the clipping area.
+     We assume a linear trasform from grid to physical page.  ie, only latlon
+     and scaled map projections. */
+ 
+  gxdgcoord(xlo,ylo,&imn,&jmn);
+  gxdgcoord(xhi,yhi,&imx,&jmx);
+  if (imn<-900) return;   /* indicates batch mode */
+
+  /* pixel to page scaling */
+
+  xscl = (xhi-xlo)/(gadouble)(imx-imn);
+  yscl = (yhi-ylo)/(gadouble)(jmx-jmn);
+
+  /* Allocate memory for the image and some work arrays */
+
+  if (imx>imn) iz = 1+imx-imn;
+  else iz = 1+imn-imx;
+  if (jmx>jmn) jz = 1+jmx-jmn;
+  else jz = 1+jmn-jmx;
+
+  imap = NULL; xvals = NULL; yvals = NULL; ivals = NULL; jvals = NULL;
+  imap = (gaint *)malloc(sizeof(gaint)*iz*jz);
+  if (imap == NULL) goto err;
+  xvals = (gadouble *)malloc(sizeof(gadouble)*is);
+  if (xvals == NULL) goto err;
+  yvals = (gadouble *)malloc(sizeof(gadouble)*js);
+  if (yvals == NULL) goto err;
+  ivals = (gaint *)malloc(sizeof(gaint)*iz);
+  if (ivals == NULL) goto err;
+  jvals = (gaint *)malloc(sizeof(gaint)*jz);
+  if (jvals == NULL) goto err;
+
+  /* Get x,y page coord values for the grid axes */
+
+  for (i=1; i<=is; i++) {
+    gxconv ((gadouble)i,(gadouble)1.0,&x,&y,3);
+    *(xvals+i-1) = x; 
+  }
+  for (j=1; j<=js; j++) {
+    gxconv ((gadouble)1.0,(gadouble)j,&x,&y,3);
+    *(yvals+j-1) = y; 
+  }
+
+  /* For each pixel (for one row and one column), convert from pixel space
+     to page space, and then search through the list of xvals/yvals to 
+     find the nearest grid i and j to this pixel.  */
+
+  /* First do a row */
+
+  for (i=0; i<iz; i++) {
+    ii = i;
+    if (imn>imx) ii = 1+i-iz;
+    x = xlo + xscl * (gadouble)ii;
+    ii = 1;
+    while (ii<is) {
+      if ( (*(xvals+ii) >= x && *(xvals+ii-1) <= x ) ||
+           (*(xvals+ii) <= x && *(xvals+ii-1) >= x ) ) {
+        if ( (fabs(*(xvals+ii)-x)) > (fabs(*(xvals+ii-1)-x)) ) ii = ii - 1;
+        break;
+      }
+      ii++;
+    }
+    if (ii==is) *(ivals+i) = -999;
+    else *(ivals+i) = ii;
+  }
+
+  /* Now do a column */
+
+  for (j=0; j<jz; j++) {
+    jj = j;
+    if (jmn>jmx) jj = 1+j-jz;
+    y = ylo + yscl * (gadouble)jj;
+    jj = 1;
+    while (jj<js) {
+      if ( (*(yvals+jj) >= y && *(yvals+jj-1) <= y ) ||
+           (*(yvals+jj) <= y && *(yvals+jj-1) >= y ) ) {
+        if ((fabs(*(yvals+jj)-y)) > (fabs(*(yvals+jj-1)-y)) ) jj = jj - 1;
+        break;
+      }
+      jj++;
+    }
+    if (jj==js) *(jvals+j) = -999;
+    else *(jvals+j) = jj;
+  }
+
+  /* Fill image with appropriate color numbers, based on the grid 
+     values closest to each pixel.  */
+
+  im = imap;
+  for (j=0; j<jz; j++) {
+    for (i=0; i<iz; i++) {
+      *im = 255;
+      if (*(ivals+i)>=0 && *(jvals+j)>=0) {
+        off = *(jvals+j)*is + *(ivals+i);
+        if (*(ru+off) != 0) {
+          flag = 1;
+          for (k=0; k<lvs-1; k++) {
+            if (*(r+off)>*(vs+k) && *(r+off)<=*(vs+k+1)) {
+              *im = *(clrs+k);
+              flag = 0;
+	      break;
+            }
+	  }
+          if (flag) {
+	    *im = *(clrs+lvs-1);
+          }
+        }
+      }
+      im++; 
+    } 
+  }
+
+  /* Dump image to X screen */
+
+  ii = imn;
+  if (imn>imx) ii=imx;
+  jj = jmn;
+  if (jmn>jmx) jj=jmx;
+  gxdimg(imap,ii,jj,iz,jz);
+
+  free (imap);
+  free (xvals); free (yvals);
+  free (ivals); free (jvals);
+  return;
+
+err:
+  gaprnt (0,"Memory error in gaimap\n");
+  if (imap) free(imap);
+  if (xvals) free(xvals);
+  if (yvals) free(yvals);
+  if (ivals) free(ivals);
+  return;
+}
+
+void gafram(struct gacmn *pcm) {
+
+  if (pcm->frame==0) return;
+  if (pcm->frame==2 && pcm->mproj>2) return;
+  if (pcm->mproj>4) return;
+
+  gxcolr (pcm->anncol);
+  gxwide (pcm->annthk);
+  gxstyl (1);
+  gxplot (pcm->xsiz1,pcm->ysiz1,3);
+  gxplot (pcm->xsiz2,pcm->ysiz1,2);
+  gxplot (pcm->xsiz2,pcm->ysiz2,2);
+  gxplot (pcm->xsiz1,pcm->ysiz2,2);
+  gxplot (pcm->xsiz1,pcm->ysiz1,2);
+}
+
+void gaaxpl (struct gacmn *pcm, gaint idim, gaint jdim) {
+
+  if (idim==0 && jdim==1 && pcm->mproj>2) gampax(pcm);
+  else {
+    gaaxis(1,pcm,idim);
+    gaaxis(0,pcm,jdim);
+  }
+}
+
+/* Select colors and intervals for colorized items such as
+   colorized vectors, streamlines, barbs, scatter, etc.  */
+
+void gaselc (struct gacmn *pcm, gadouble rmin, gadouble rmax) {
+  gadouble rdif,w1,norml,cint,cmin,cmax,ndif,absmax;
+  gadouble t1,t2,fact,rr,rrb,smin,ci,ccnt;
+  gaint i,ii,irb,lcnt;
+
+  /* determine if field is a constant */
+  absmax = ( fabs(rmin)+fabs(rmax) + fabs(fabs(rmin)-fabs(rmax)) )/2;
+  if (absmax > 0.0) {
+    ndif = (fabs(rmax-rmin))/absmax;
+  }
+  else {
+    /* rmin and rmax are both zero */
+    pcm->shdcnt = 0;
+    return;
+  }
+      
+  if (ndif > 0) {
+    rdif = rmax - rmin;
+  }
+  else {
+    /* rmin and rmax are the same */
+    pcm->shdcnt = 0;
+    return;
+  }
+
+  if (pcm->rbflg) irb = pcm->rbflg - 1;
+  else irb = 12;
+  rrb = irb+1;
+
+  /* Choose a contour interval if one is needed.  We choose
+     an interval that maximizes the number of colors displayed,
+     rather than an interval that maximizes the attribute of
+     being a 'nice' interval */
+
+  if (!pcm->cflag) {
+    if (pcm->cint==0.0) {           /* no precision check */
+      if (pcm->rbflg) rdif = rdif/((gadouble)(pcm->rbflg)-0.5);
+      else rdif = rdif/12.5;
+      w1 = floor(log10(rdif));
+      w1 = pow(10.0,w1);
+
+      norml = rdif/w1;              /* normalized contour interval */
+      if (norml<2.0) fact = 10.0;
+      else if (norml>=2.0 && norml<4.0) fact = 5.0;
+      else if (norml>=4.0 && norml<7.0) fact = 2.0;
+      else fact = 1.0;
+      norml*=fact;
+      i = (gaint)(norml+0.5);
+      cint = (gadouble)i * w1 / fact;
+    } 
+    else cint = pcm->cint;
+
+    cmin = cint * ceil(rmin/cint);
+    cmax = cint * floor(rmax/cint);
+
+    /* Check for interval being below machine epsilon for these values */
+    t1 = rmin + cint;
+    t2 = rmax - cint;
+    if ((dequal(rmin, t1, 1.0e-16)==0) ||
+	(dequal(rmax, t2, 1.0e-16)==0)) {
+      pcm->shdcnt = 0;
+      return;
+    }
+
+    /* Figure out actual contour levels and colors, based on
+       possible user settings such as cmin, etc.  */
+
+    if (pcm->rainmn==0.0 && pcm->rainmx==0.0) {
+      pcm->rainmn = cmin;
+      pcm->rainmx = cmax;
+    }
+    lcnt=0;
+    smin = pcm->rainmn - cint;
+    for (rr=cmin-cint;rr<=cmax+(cint/2.0);rr+=cint) {
+      if (rr<0.0) i = (gaint)((rr/cint)-0.1);
+      else i = (gaint)((rr/cint)+0.1);
+      rr = (gadouble)i * cint;
+      pcm->shdlvs[lcnt] = rr;
+      pcm->shdcls[lcnt] = 1;
+      if (rr<pcm->cmin) pcm->shdcls[lcnt] = -1;
+      if (rr+cint>pcm->cmax) pcm->shdcls[lcnt] = -1;
+      if (pcm->blkflg && rr<pcm->blkmax && rr+cint>pcm->blkmin) pcm->shdcls[lcnt] = -1;
+      if (pcm->shdcls[lcnt]==1) {
+        ii = (gaint)(rrb*(rr-smin)/(pcm->rainmx-smin));
+        if (ii>irb) ii=irb;
+        if (ii<0) ii=0;
+        if (pcm->rbflg) pcm->shdcls[lcnt] = pcm->rbcols[ii];
+        else pcm->shdcls[lcnt] = rcols[ii];
+      }
+      if (lcnt<1 || pcm->shdcls[lcnt]!=pcm->shdcls[lcnt-1]) lcnt++;
+    }
+    pcm->shdlvs[0] -= cint*10.0;
+    pcm->shdcnt = lcnt;
+
+  /* User has specified actual contour levels.  Just use those */
+
+  } else {
+
+    if (rmin<pcm->clevs[0]) pcm->shdlvs[0] = rmin-100.0;
+    else pcm->shdlvs[0] = pcm->clevs[0]-100.0;
+    ccnt = rrb/(gadouble)(pcm->cflag+1);
+    ci = ccnt/2.0;
+    ii = (gaint)ci;
+    if (pcm->ccflg>0) pcm->shdcls[0] = pcm->ccols[0];
+    else {
+      if (pcm->rbflg>0) pcm->shdcls[0] = pcm->rbcols[ii];
+      else pcm->shdcls[0] = rcols[ii];
+    }
+    lcnt = 1;
+    for (i=0; i<pcm->cflag; i++) {
+      pcm->shdlvs[lcnt] = pcm->clevs[i];
+      if (pcm->ccflg>0) {
+        if (i+1>=pcm->ccflg) pcm->shdcls[lcnt]=15;
+        else pcm->shdcls[lcnt]=pcm->ccols[i+1];
+      } else {
+        ci += ccnt;
+        ii = (gaint)ci;
+        if (ii>irb) ii=irb;
+        if (ii<0) ii=0;
+        if (pcm->rbflg>0) pcm->shdcls[lcnt] = pcm->rbcols[ii];
+        else pcm->shdcls[lcnt] = rcols[ii];
+      }
+      if (lcnt<1 || pcm->shdcls[lcnt]!=pcm->shdcls[lcnt-1]) lcnt++;
+    }
+    pcm->shdcnt = lcnt;
+  }
+}
+
+/* Given a shade value, return the relevent color */
+
+gaint gashdc (struct gacmn *pcm, gadouble val) {
+gaint i;
+
+  if (pcm->shdcnt==0) return(1);
+  if (pcm->shdcnt==1) return(pcm->shdcls[0]);
+  if (val<pcm->shdlvs[1]) return(pcm->shdcls[0]);
+  for (i=1; i<pcm->shdcnt-1; i++) {
+    if (val>pcm->shdlvs[i] && val<=pcm->shdlvs[i+1]) {
+      return(pcm->shdcls[i]);
+    }
+  }
+  return(pcm->shdcls[pcm->shdcnt-1]);
+}
+
+struct cxclock {
+  time_t year ;
+  time_t month ;
+  time_t date ;
+  time_t hour ;
+  time_t minute ;
+  time_t second ;
+  char timezone[32] ;
+  char clockenv[64] ;
+  gaint julian_day ;
+  time_t epoch_time_in_sec ;
+} ;
+
+/* global variable of the time object */
+static struct cxclock timeobj;
+
+
+void get_tm_struct(time_t t)
+{
+  struct tm *ptr_tm ;
+  char buf[10] ;
+  time_t sec ;
+  sec=t ;
+
+  /* get tm struct from seconds */
+  ptr_tm=localtime(&sec) ;
+
+  if ( ! ptr_tm ) {
+    fprintf(stderr,"error in gmtime function,errno = %d\n",errno);
+    exit(-1) ;
+  }
+	
+  /* copy tm struct to cxclock private members */
+  timeobj.epoch_time_in_sec=sec ;
+  timeobj.year=ptr_tm->tm_year + 1900  ;
+  timeobj.month=(ptr_tm->tm_mon) + 1 ;
+  timeobj.date=ptr_tm->tm_mday ;
+  timeobj.hour=ptr_tm->tm_hour ;
+  timeobj.minute=ptr_tm->tm_min ;
+  timeobj.second=ptr_tm->tm_sec ;
+
+  /* get julian date */
+  strftime(buf, sizeof(buf),"%j", ptr_tm) ;
+  timeobj.julian_day=atoi(buf) ;
+
+}
+
+void sys_time() {
+  time_t sec ;
+  time(&sec) ; /* get the GMT offset from the local machine */
+  if (sec == -1 ) {
+    fprintf(stderr,"error in time function,errno = %d\n",errno) ;
+    exit(-1) ;
+  }
+  /* Set tm struct using new epoch time */
+  get_tm_struct(sec) ;
+  return;
+}
+
+
+void gatmlb (struct gacmn *pcm) {
+  gaint i,vcnt;
+  char dtgstr[32] ;
+
+  vcnt = 0;
+  for (i=0; i<5; i++) if (pcm->vdim[i]) vcnt++;
+  /* -- only plot if 2-D or less, i.e., turn off on looping */
+  if (vcnt<=2) {
+    sys_time();
+    snprintf(dtgstr,31,"%04ld-%02ld-%02ld-%02ld:%02ld",
+	  timeobj.year, timeobj.month, timeobj.date, timeobj.hour, timeobj.minute) ;
+    gxchpl(dtgstr,strlen(dtgstr),pcm->pxsize-1.6,0.05,0.1,0.08,0.0);
+  }
+}
+
diff --git a/src/gaio.c b/src/gaio.c
new file mode 100644
index 0000000..a758a36
--- /dev/null
+++ b/src/gaio.c
@@ -0,0 +1,5148 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty and Jennifer Adams */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include "grads.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if USENETCDF == 1
+#include "netcdf.h"
+#endif
+#if USEHDF ==1
+#include "mfhdf.h"
+#endif
+#if USEHDF5 ==1
+#include "hdf5.h"
+#endif
+
+/* global struct for warning level setting */
+extern struct gamfcmn mfcmn;
+
+gaint garead (off_t, gaint, gadouble *, char *);
+off_t gafcorlf (gaint, gaint, gaint, gaint, gaint);
+
+/* Global pointers for this file */
+static struct gafile *pfi;
+static struct gagrid *pgr;
+static struct gavar *pvr;
+static struct gaindx *pindx;
+static struct gaindxb *pindxb;
+static gaint timerr;
+static gaint msgflg=1;
+static char pout[256]; 
+
+/* For STNDALN, routines included are gaopfn, gaopnc, and gaophdf */
+#ifndef STNDALN
+
+/* GRIB I/O caching.  GRIB data is chached, as well as the bit
+   maps, if present.  Sometimes the expanded bit map is cached. */
+static char *cache;             /* I/O cache for GRIB */
+static unsigned char *bcache;   /* Bit map cache */
+static gaint cflag=0;           /* cache flag */
+static gaint bcflag=0;          /* Bit cache flag */
+static off_t bpsav = (off_t)-999;      /* Bit cache pointer */
+static gaint bssav = -999;      /* Bit cache size */
+static gaint *bpcach;           /* expanded bit map cache */
+
+/* Station data I/O caching.  We will cache fairly small I/O
+   requests that fit within the specified size buffer.  If the buffer
+   gets overfilled, we just forget the caching.  */
+static gaint scflg = 0;         /* Anything cached? */
+static gaint scuca = 0;         /* Can use cache for this request */
+static gaint scerr = 0;         /* Buffer full? */
+static gaint scok;              /* Ok to fill buffer */
+static gaint scpnt;             /* Current cache offset */
+static gaint scseq;             /* File sequence of last request */
+static struct gastn scstn;      /* Previous request */
+static char *scbuf=NULL;        /* Cache */
+
+
+#if GRIB2
+/* GRIB2 I/O cache */
+static struct gag2indx *g2indx;
+static struct g2anchor *anchor;
+static gaint debug=0;
+#define MAXG2CACHE 500100100
+#endif
+
+/* Size of cache */
+#define SCNUM 50000
+
+
+/* Routine resets flag to allow warning in regards to interpolation */
+void gaiomg () {
+  msgflg = 1;
+}
+
+/* Routine to obtain a grid.  The addresses of the gagrid
+   structure is passed to this routine.  The storage for the
+   grid is obtained and the grid is filled with data.                 */
+
+gaint gaggrd (struct gagrid *pgrid) {
+  gadouble *gr;
+  char *gru;
+  gaint x,i,id,jd,d[5],dx[5];
+  gaint incr,rc,dflag,size;
+  size_t sz;
+#if USEHDF5==1
+  hid_t dsid,vid;
+  char *vname;
+#endif
+
+  if (cflag) gree(cache,"f105");
+  cache = NULL;
+  cflag = 0;
+  if (bcflag) {
+    gree(bcache,"f106");
+    gree(bpcach,"f107");
+  }
+  bcache = NULL;
+  bpcach = NULL;
+  bcflag = 0;
+  bssav = -999;
+  bpsav = (off_t)-999;
+
+  pgr = pgrid;
+  pvr = pgr->pvar;
+  pfi = pgr->pfile;
+  timerr = 0;
+  if (pfi->idxflg==1) { 
+    pindx  = pfi->pindx;
+    pindxb = pfi->pindxb;
+  }
+#if GRIB2
+  if (pfi->idxflg==2) g2indx = pfi->g2indx;
+#endif
+  if (pfi->ppflag && msgflg) {
+    gaprnt (2,"Notice:  Automatic Grid Interpolation Taking Place\n");
+    msgflg = 0;
+  }
+
+  if (pfi->type==4) {
+    rc = gagdef();
+    return (rc);
+  }
+
+  /* Check dimensions we were given */
+  if (pgr->idim < -1 || pgr->idim > 4 ||
+      pgr->jdim < -1 || pgr->jdim > 4 ||
+      (pgr->idim == -1 && pgr->jdim!=-1)) {
+    snprintf(pout,255,"Internal logic check 16:  %i %i  \n", pgr->idim, pgr->jdim);
+    gaprnt (0,pout);
+    return (16);
+  }
+
+  /* Calc sizes and get storage for the grid */
+  id = pgr->idim;
+  jd = pgr->jdim;
+  if (id > -1)  pgr->isiz = pgr->dimmax[id] - pgr->dimmin[id] + 1;
+  else pgr->isiz = 1;
+  if (jd > -1)  pgr->jsiz = pgr->dimmax[jd] - pgr->dimmin[jd] + 1;
+  else pgr->jsiz = 1;
+  size = pgr->isiz*pgr->jsiz;
+  if (size>1) {
+    /* this is for the grid */
+    sz  = (size_t)size * sizeof(gadouble);
+    gr = (gadouble *)galloc(sz,"gr");
+    if (gr==NULL) {
+      gaprnt (0,"Memory Allocation Error:  grid storage \n");
+      return (1);
+    }
+    pgr->grid = gr;
+    /* this is for the undef mask */
+    sz = size * sizeof(char);
+    gru = (char *)galloc(sz,"gru");
+    if (gru==NULL) {
+      gaprnt (0,"Memory Allocation Error:  undef grid storage \n");
+      return (1);
+    }
+    pgr->umask = gru;
+  } 
+  else {
+    pgr->grid = &(pgr->rmin);
+    gr = pgr->grid;
+    pgr->umask = &(pgr->umin);  
+    gru = pgr->umask;
+  }
+
+  /* Handle predefined variable */
+  if (pvr->levels<-900) {
+    rc = gagpre();
+    return (rc);
+  }
+
+  /* set minimum and maximum grid indices */
+  for (i=0; i<5; i++) {
+    d[i]  = pgr->dimmin[i]; 
+    dx[i] = pfi->dnum[i];
+  }
+  /* adjust max Z index so it doesn't exceed the number of levels for this variable */
+  dx[2] = pvr->levels;
+  if (dx[2]==0) {        
+    if (id==2 || jd==2) goto nozdat;
+    dx[2] = 1;
+    d[2] = 1;
+  }
+
+  incr = pgr->isiz;
+
+  /* If X does not vary, make sure the X coordinate is normalized.    */
+  if (id!=0 && pfi->wrap) {
+    x=pgr->dimmin[0];
+    while (x<1) x=x+dx[0];
+    while (x>dx[0]) x=x-dx[0];
+    pgr->dimmin[0]=x;
+    pgr->dimmax[0]=x;
+    d[0] = x;
+  }
+
+  /* If any of the non-varying dimensions are out of bounds of the
+     file dimension limits, then we have a grid of missing data.
+     Check for this.                                                  */
+  for (i=0; i<5; i++) {
+    if (id!=i && jd!=i &&          /* dim i is non-varying */
+	(d[i]<1 || d[i]>dx[i])) {  /* dim index is <1 or >max dim size */
+      /* returned grid will be missing, except for one special case ... */
+      /* ... allow a time index offset (offt) equal to 0 */
+      if (i!=3 || pgr->toff!=1 || d[i]!=0)   /* same as !(i==3 && pgr->toff==1 && d[i]==0) */
+	goto nodat;
+    }
+  }
+
+  /* Break out point for reading 2D netcdf grids (for special cases) */
+  /* JMA still need to optimize handling of OPeNDAP pre-projected grids */
+  if ((pgr->toff != 1) &&          /* if t value is not an offset */
+      (pfi->ncflg==1) &&           /* format is netcdf */
+      (pfi->ppflag==0) &&          /* no pdef */
+      (pfi->tmplat==0)) {          /* not templated */
+    /* check the variable id, get variable attributes */
+    rc = gancsetup();          
+    if (rc) return(rc);
+    /* get the 2D grid */
+    rc = gancgrid(gr,gru,id,jd);
+    if (rc<0) goto nodat;
+    return (rc);
+  }
+
+#if USEHDF5==1
+  /* For non-templated HDF5 data sets, file is already open, 
+     but we still need to open the variable and set it up */ 
+  if (pfi->tmplat==0 && pfi->ncflg==3) {
+    /* check of variable is already opened */
+    if (pvr->h5varflg < 0) {   
+      /* get the variable name */
+      if (pvr->longnm[0] != '\0')
+	vname = pvr->longnm;
+      else
+	vname = pvr->abbrv;
+      /* open the variable */
+      rc = h5openvar(pfi->h5id,vname,&dsid,&vid);
+      if (rc) {
+	pvr->h5vid = -888;
+	snprintf(pout,255,"Error: Variable %s not in HDF5 file\n",vname);
+	gaprnt(0,pout);
+	return (rc); 
+      }
+      /* No errors, so continue with variable set up */
+      pvr->dataspace = dsid;
+      pvr->h5varflg = vid;
+      /* if we haven't looked at this variable before ... */
+      if (pvr->h5vid == -999) {  
+	/* get undef & packing attributes, check cache size */
+	rc = h5setup();   
+	if (rc) return (rc);
+      }
+      /* set h5-relevant variables in the gavar structure */
+      pvr->h5vid = (gaint)vid; 
+    }
+  }
+#endif
+
+  /* Handle case where X varies. */
+  dflag = 0;
+  if ( id == 0 ) {
+    if (jd<0) jd = 1;      
+
+    for (d[jd]=pgr->dimmin[jd]; d[jd]<=pgr->dimmax[jd]; d[jd]++) {
+
+      if (d[jd]<1 || d[jd]>dx[jd]) {
+        for (i=0; i<incr; i++) {
+	  *(gr+i) = pgr->undef;
+	  *(gru+i) = 0;
+	}
+      } 
+      else {
+        rc = gagrow(gr, gru, d);
+        if (rc > 0 ) return (1);
+        if (rc==0) dflag=1;
+      }
+      gr += incr;
+      gru += incr;
+    }
+    if (!dflag) goto nodatmsg;
+    return (0);
+  }
+
+  /* Handle cases where X does not vary. Read each point in the grid seperately. */
+  if (jd<0) {
+    if (id<0) { id=0; jd=1; }
+    else jd=0;
+  }
+  for (d[jd]=pgr->dimmin[jd]; d[jd]<=pgr->dimmax[jd]; d[jd]++) {
+    if (d[jd]<1 || d[jd]>dx[jd]) {
+      for (i=0; i<incr; i++,gr++,gru++) {
+	*gr = pgr->undef;
+	*gru = 0;
+      }
+    } else {
+      for (d[id]=pgr->dimmin[id]; d[id]<=pgr->dimmax[id]; d[id]++) {
+        if (d[id]<1 || d[id]>dx[id]) {
+	  *gr = pgr->undef;
+	  *gru = 0;
+	}
+        else {
+          rc = garrow (d[0], d[1], d[2], d[3], d[4], 1, gr, gru, pgr->toff);  
+          if (rc != 0 ) return (1);
+          dflag=1;
+        }
+        gr++; gru++;
+      }
+    }
+  }
+  if (!dflag) goto nodatmsg;
+
+  return (0);
+
+nozdat:
+  if(mfcmn.warnflg>0) {
+    gaprnt (1,"Data Request Warning:  Varying Z dimension environment...\n");
+    gaprnt (1,"  but the requested variable has no Z dimension\n");
+    gaprnt (2,"  Entire grid contents are set to missing data \n");
+  }
+  for (i=0; i<size; i++,gr++,gru++) {
+    *gr = pgr->undef;  
+    *gru = 0;
+  }
+  return (-1);
+
+nodat:
+  for (i=0; i<size; i++,gr++,gru++) {
+    *gr = pgr->undef;  
+    *gru = 0;
+  }
+
+nodatmsg:
+  if(mfcmn.warnflg>0) {
+    gaprnt (1,"Data Request Warning:  Request is completely outside file limits\n");
+    gaprnt (2,"  Entire grid contents are set to missing data \n");
+    snprintf(pout,255,"  Grid limits of file:     X = 1 %i  Y = 1 %i  Z = 1 %i  T = 1 %i  E = 1 %i \n",
+	     pfi->dnum[0],pfi->dnum[1],pfi->dnum[2],pfi->dnum[3],pfi->dnum[4]);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  Grid limits of request:  X = %i %i  Y = %i %i  Z = %i %i  T = %i %i  E = %i %i \n",
+	     pgr->dimmin[0],pgr->dimmax[0],
+	     pgr->dimmin[1],pgr->dimmax[1],
+	     pgr->dimmin[2],pgr->dimmax[2],
+	     pgr->dimmin[3],pgr->dimmax[3],
+	     pgr->dimmin[4],pgr->dimmax[4]);
+    gaprnt (2,pout);
+  }
+  return (-1);
+
+}
+
+
+/* gagrow gets a row of data from the file.  The row of data can
+   be 'wrapped' if the x direction of the grid spans the globe. 
+   return codes:  
+    0 if no errors
+   -1 if out of bounds
+    1 if errors
+              
+      */
+
+gaint gagrow (gadouble *gr, char *gru, gaint *d) {
+gaint rc,i,x,j;
+gaint y,z,t,e;
+
+  y = *(d+1);
+  z = *(d+2);
+  t = *(d+3);
+  e = *(d+4);
+
+  /* If the needed data is within the bounds of the file dimensions
+     then read the data directly.                                     */
+  if (pgr->dimmin[0] >= 1 && pgr->dimmax[0] <= pfi->dnum[0]) {
+    rc = garrow (pgr->dimmin[0], y, z, t, e, (pgr->dimmax[0]-pgr->dimmin[0]+1), gr, gru, pgr->toff);
+    if (rc != 0 ) return (1);
+    return (0);
+  }
+
+  /* If the file does not wrap, then read the data directly, if possible.  
+     If the requested data lies outside the file's bounds,
+     fill in with missing data where appropriate.                   */
+  if (!pfi->wrap) {
+    if ( pgr->dimmin[0]>=1 && pgr->dimmax[0]<=pfi->dnum[0] ) {
+      rc = garrow (pgr->dimmin[0], y, z, t, e, (pgr->dimmax[0]-pgr->dimmin[0]+1), gr, gru, pgr->toff);
+      if (rc != 0 ) return (1);
+      return (0);
+    }
+    for (i=0; i<pgr->isiz; i++) {
+      *(gr+i) = pgr->undef;
+      *(gru+i) = 0;
+    }
+    if (pgr->dimmin[0]<1 && pgr->dimmax[0]<1 ) return (-1);
+    if (pgr->dimmin[0]>pfi->dnum[0] &&
+        pgr->dimmax[0]>pfi->dnum[0] ) return (-1);
+    i = 1 - pgr->dimmin[0];
+    if (i>0) { gr+=i; gru+=i; }
+    i = 1;
+    if (pgr->dimmin[0]>1) i = pgr->dimmin[0];
+    j = pgr->dimmax[0];
+    if (j > pfi->dnum[0]) j = pfi->dnum[0];
+    j = 1 + (j - i);
+    rc = garrow (i, y, z, t, e, j, gr, gru, pgr->toff);
+    if (rc != 0 ) return (1);
+    return (0);
+  }
+
+  /* When the file wraps, we read the entire row into the row buffer, and
+     copy the values as needed into locations in the requested row.    */
+  rc = garrow (1, y, z, t, e, pfi->dnum[0], pfi->rbuf, pfi->ubuf, pgr->toff);
+  if (rc != 0 ) return (1);
+  for (x=pgr->dimmin[0];x<=pgr->dimmax[0];x++) {
+    i=x;
+    while (i<1) i = i + pfi->dnum[0];
+    while (i>pfi->dnum[0]) i = i-(pfi->dnum[0]);    /* Best way??? */
+    *gr = *((pfi->rbuf)+i-1);
+    *gru = *((pfi->ubuf)+i-1);
+    gr++; gru++;
+  }
+  return (0);
+}
+
+
+/*  Basic read of a row of data elements -- a row is always
+    in the X direction, which for grads binary is the fastest
+    varying dimension */
+
+  gaint garrow (gaint x, gaint y, gaint z, gaint t, gaint e, 
+		gaint len, gadouble *gr, char *gru, gaint toff) {
+  struct gaens *ens;
+  gaint rc,i=0,tt,ee,oflg;
+  off_t fposlf;
+#if USEHDF5==1
+  char *vname;
+  hid_t dsid,vid;
+#endif
+
+  /* change t value if offset flag is set */
+  if (toff) {
+    /* advance through chain of ensemble structure to get to ensemble 'e' */
+    ens=pfi->ens1;    
+    i=1;
+    while (i<e) { i++; ens++; }
+    /* add the forecast offset to the start time for this ensemble */
+    t = ens->gt + t;
+    /* if new t value is outside file's bounds, populate with undefs */  
+    if (t<1 || t>pfi->dnum[3]) {
+      for (i=0; i<len; i++) {
+	*(gr+i) = pfi->undef;
+	*(gru+i) = 0;
+      }
+      return (0);
+    }
+  }
+
+  tt = t;
+  if (pfi->tmplat) {
+    tt = gaopfn(t,e,&ee,&oflg,pfi);
+    if (tt==-99999) return(1);
+    if (tt==-88888) {
+      for (i=0; i<len; i++) {
+	*(gr+i) = pfi->undef;
+	*(gru+i) = 0;
+      }
+      return (0);
+    }
+    if (oflg) {
+      /* Force new bit map cache if new file opened */
+      bpsav = (off_t)-999;    
+#if USEHDF5==1
+      /* if HDF5, call h5setup and h5openvar if new file opened */
+      if (pfi->ncflg==3) {
+	/* get the variable name */
+	if (pvr->longnm[0] != '\0')
+	  vname = pvr->longnm;
+	else
+	  vname = pvr->abbrv;
+	/* open the variable */
+	rc = h5openvar(pfi->h5id,vname,&dsid,&vid);
+	if (rc) {
+	  pvr->h5vid = -888;
+	  snprintf(pout,255,"Error: Variable %s not in HDF5 file\n",vname);
+	  gaprnt(0,pout);
+	  return (rc); 
+	}
+	/* No errors, so continue with variable set up */
+	pvr->dataspace = dsid;
+	pvr->h5varflg = vid;
+	/* if we haven't looked at this variable before ... */
+	if (pvr->h5vid == -999) {  
+	  /* get undef & packing attributes, check cache size */
+	  rc = h5setup();   
+	  if (rc) return (rc);
+	}
+	/* set h5-relevant variables in the gavar structure */
+	pvr->h5vid = (gaint)vid; 
+      }
+#endif
+    }
+  }
+  else {
+    ee = e;  /* set relative ensemble number to e for non-templated data sets */
+  }
+  
+  /* Preprojected (pdef) */
+  if (pfi->ppflag) {                             
+    if (pfi->idxflg)  
+      rc = gaprow (x, y, z, t,  e, tt, len, gr, gru);  /* Grib uses e to read index file */
+    else 
+      rc = gaprow (x, y, z, t, ee, tt, len, gr, gru);  /* All other data types use ee */
+    return (rc);
+  }
+  /* netcdf */
+  if (pfi->ncflg==1) {              
+    rc = gancsetup();
+    if (rc) return(rc);
+     rc = gancrow (x, y, z, tt, ee, len, gr, gru);
+    return(rc);
+  }
+  /* HDF-SDS */
+  if (pfi->ncflg==2) {              
+    rc = gahrow(x, y, z, tt, ee, len, gr, gru);
+    return(rc);
+  }
+  /* HDF5 grids */
+  if (pfi->ncflg==3) {              
+    rc = gah5row(x, y, z, tt, ee, len, gr, gru);
+    return(rc);
+  }
+  /* Indexed (grib) */
+  if (pfi->idxflg) {               
+    rc = gairow (x, y, z, t, e, i, len, gr, gru);  
+    return (rc);
+  }
+  /* if none of the above... binary */
+  fposlf = gafcorlf (x, y, z, tt, ee);         
+  rc = garead (fposlf, len, gr, gru);
+  return (rc);
+}
+ 
+ 
+off_t gafcorlf (gaint x, gaint y, gaint z, gaint t, gaint e) {
+off_t pos;
+off_t ltmpz,ltmpy,ltmpt,ltmpe;
+off_t yy,zz;
+off_t levs;
+off_t xl, yl, zl, tl, el;
+
+  xl = x;
+  yl = y;
+  zl = z;
+  tl = t;
+  el = e;
+
+  levs=(off_t)pvr->levels;
+  if(levs == 0) levs=1;
+  if (pfi->tlpflg) {
+    tl = tl + (off_t)pfi->tlpst;
+    if (tl > (off_t)pfi->dnum[3]) tl = tl - (off_t)pfi->dnum[3];
+  }
+
+  if (pfi->yrflg) {
+    yy = (off_t)pfi->dnum[1] - yl;
+  }
+  else {
+    yy = yl - 1;
+  }
+
+  if (pfi->zrflg) {
+    if (levs==0) {
+      zz = 0;
+    }
+    else {
+      zz = levs - zl;
+    }
+  } 
+  else {
+    zz = zl - 1;
+  }
+  if (pvr->var_t) {
+    ltmpe = (el-1)*(off_t)((pfi->dnum[3])*(pfi->vnum)*levs*(pfi->gsiz)); 
+    ltmpt = (tl-1)*(off_t)(pfi->gsiz)*levs;
+    ltmpz = zz*(off_t)(pfi->gsiz);
+    ltmpy = yy*(off_t)(pfi->dnum[0]);
+  } else {
+    ltmpe=(el-1)*(pfi->dnum[3]*(off_t)pfi->tsiz);
+    ltmpt=(tl-1)*((off_t)pfi->tsiz);
+    ltmpz=zz*(off_t)(pfi->gsiz); 
+    ltmpy=yy*((off_t)pfi->dnum[0]);
+  }
+  pos = 
+    ltmpe + 
+      ltmpt +
+        (off_t)pvr->offset +
+          ltmpz +
+            ltmpy +
+              (xl-1); 
+
+  if (pfi->xyhdr) pos = pos + (off_t)pfi->xyhdr;
+  return (pos);
+}
+
+gaint garead (off_t fpos, gaint len, gadouble *gr, char *gru) {
+gafloat *fgr;
+off_t ffpos;
+gaint rc,i;
+gaint cnt,*ig;
+unsigned char *igr,*chcast;
+char *cgr;
+unsigned short usval;
+signed short sval;
+size_t sz;
+
+  if (pvr->dfrm == 1) {
+    ffpos = fpos*(off_t)sizeof(char) + (off_t)pfi->fhdr;
+  } 
+  else if (pvr->dfrm == 2 || pvr->dfrm == -2 ) {
+    ffpos = fpos*2ll + (off_t)pfi->fhdr;
+  } 
+  else if (pvr->dfrm == 4) {
+    ffpos = fpos*4ll + (off_t)pfi->fhdr;
+  } 
+  else {
+    /* use 4 instead of sizeof(gafloat) to read float data */
+    ffpos = fpos*4ll + (off_t)pfi->fhdr;
+  }
+  rc = fseeko(pfi->infile, ffpos, 0);
+  if (rc!=0) {
+    gaprnt (0,"Low Level I/O Error:  Seek error on data file \n");
+    snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+    gaprnt (0,pout);
+    snprintf(pout,255,"%d rc=%d fpos=%ld pfi->fhdr=%ld\n",__LINE__,rc,(long)fpos,pfi->fhdr);
+    gaprnt (0,pout);
+    snprintf(pout,255,"  Error occurred when seeking to byte %ld \n",(long)ffpos);
+    gaprnt (0,pout);
+    return (1);
+  }
+
+  if (pvr->dfrm == 1) {                        
+    /* read 1-byte data */
+    sz = len;
+    igr = (unsigned char *)galloc(sz,"igr");
+    if (igr==NULL) {
+      gaprnt (0,"Memory Allocation Error:  1-byte data storage \n");
+      return (1);
+    }
+    rc = fread (igr, 1, len, pfi->infile);               
+    if (rc<len) {
+      gree(igr,"f108a");
+      goto readerr;
+    }
+    for(i=0;i<len;i++) *(gr+i) = (gadouble)(*(igr+i));
+    gree(igr,"f108");
+  } 
+  else if (pvr->dfrm == 2 || pvr->dfrm == -2 ) {   
+    /* read 2-byte data */
+    sz = len*2;
+    cgr = (char *)galloc(sz,"cgr");
+    if (cgr==NULL) {
+      gaprnt (0,"Memory Allocation Error:  2-byte data storage \n");
+      return (1);
+    }
+    rc = fread (cgr, 2, len, pfi->infile);
+    if (rc<len) {
+      gree(cgr,"f109a");
+      goto readerr;
+    }
+    if (pfi->bswap) gabswp2(cgr,len);
+    cnt=0;
+    if (pvr->dfrm == -2) {
+      chcast = (unsigned char *)(&sval);
+      for(i=0;i<len;i++) {
+	*chcast = *(cgr+cnt);
+	*(chcast+1) = *(cgr+cnt+1);
+	*(gr+i) = (gadouble)sval;    
+	cnt+=2;
+      }
+    } else {
+      chcast = (unsigned char *)(&usval);
+      for(i=0;i<len;i++) {
+	*chcast = *(cgr+cnt);
+	*(chcast+1) = *(cgr+cnt+1);
+	*(gr+i) = (gadouble)usval;   
+	cnt+=2;
+      }
+    }
+    gree(cgr,"f109");
+  } 
+  else if (pvr->dfrm == 4) {                     
+    /* read 4-byte integers */
+    sz = len*4;
+    ig = (gaint *)galloc(sz,"ig");
+    if (ig==NULL) {
+      gaprnt (0,"Memory Allocation Error:  4-byte integer storage \n");
+      return (1);
+    }
+    rc = fread (ig, 4, len, pfi->infile); 
+    if (rc<len) {
+      gree(ig,"f110a");
+      goto readerr;
+    }
+    if (pfi->bswap) gabswp(ig,len); 
+    for(i=0;i<len;i++) *(gr+i) = (gadouble)(*(ig+i));
+    gree(ig,"f110");
+
+  } 
+  else {
+    /* standard direct access read, 4-byte floats */
+    sz = len*4;
+    fgr = (gafloat *)galloc(sz,"fgr");
+    rc = fread (fgr, 4, len, pfi->infile); 
+    if (rc<len) {
+      gree(fgr,"f113a");
+      goto readerr;
+    }
+    if (pfi->bswap) gabswp(fgr,len); 
+    for(i=0;i<len;i++) *(gr+i) = (gadouble)(*(fgr+i));
+    gree(fgr,"f113");
+  }
+
+  /* Test if NaN, Inf, or if grid value is within EPSILON of the missing data value.
+     If yes, set undef mask to 0. The undef mask is 1 for valid grid values */
+  for (i=0;i<len;i++) {
+    if ((*gr >= pfi->ulow && *gr <= pfi->uhi) || (isnan(*gr)) || (isinf(*gr))) {
+      *gru = 0;
+    }
+    else {
+      *gru = 1;
+    }
+    gr++; gru++;
+  }
+  
+  return (0);
+
+readerr:
+  gaprnt (0,"Low Level I/O Error:  Read error on data file \n");
+  snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+  gaprnt (0,pout);
+  snprintf(pout,255,"  Error reading %ld bytes at location %ld \n",sz,(long)ffpos);
+  gaprnt (0,pout);
+  return (1);
+
+}
+
+/* Handle a station data request */
+
+gaint gagstn (struct gastn *stn) {
+struct rpthdr ghdr, *hdr;
+gaint i,j,rc,tim,fnum,rtot,rdw,nsiz;
+gaint selflg,oflg,dummy;
+off_t fpos=0;
+gaint sizhdrf,sizhdrd,sizf,sizd,idum;
+gadouble lnmin,lnmax,ltmin,ltmax,hlon;
+char ch1[16],ch2[16],*ch;
+size_t sz;
+
+  stn->rpt = NULL;
+  for (i=0; i<BLKNUM; i++) {
+    stn->blks[i] = NULL;
+  }
+
+  if (stn->pfi->bufrflg) {         /* bufrstn */
+    rc = getbufr(stn);             /* bufrstn */
+    return (rc);                   /* bufrstn */
+  }
+
+#if USEGADAP
+  if (stn->pfi->dhandle > -999) {  /* dodstn */
+    rc = dapget(stn);              /* dodstn */
+    return (rc);                   /* dodstn */
+  }
+#endif
+
+  /* Determine cache situation */
+  if (scbuf==NULL && !scerr) {
+    sz = SCNUM;
+    scbuf = (char *)galloc(sz,"scbuf");
+    if (scbuf==NULL) {
+      gaprnt (0,"Memory allocation error:  Stn data cache buffer\n");
+      gaprnt (0,"  Station data cache disabled\n");
+      scerr = 1;
+    }
+    scflg = 0;
+  }
+
+  scuca = 0;
+  scpnt = 0;
+  if (!scerr) scok = 1;
+  if (scflg && stn->pfi->fseq != -999 && scseq == stn->pfi->fseq &&
+      scstn.pfi==stn->pfi && scstn.idim==stn->idim &&
+      scstn.jdim==stn->jdim && scstn.tmin==stn->tmin &&
+      scstn.tmax==stn->tmax && scstn.rflag==stn->rflag &&
+      scstn.sflag==stn->sflag) {
+    rc = 1;
+    if (stn->rflag && scstn.radius!=stn->radius) rc = 0;
+    if (stn->sflag) {
+      for (i=0; i<8; i++) if (scstn.stid[i]!=stn->stid[i]) rc=0;
+    } else {
+      if (scstn.dmin[0]!=stn->dmin[0]) rc = 0;
+      if (scstn.dmin[1]!=stn->dmin[1]) rc = 0;
+      if (scstn.dmax[0]!=stn->dmax[0]) rc = 0;
+      if (scstn.dmax[1]!=stn->dmax[1]) rc = 0;
+    }
+    if (rc) {
+      scuca = 1;
+      scok = 0;
+    }
+  }
+
+  pvr = stn->pvar;
+  pfi = stn->pfi;
+  hdr = &ghdr;
+
+  lnmin = stn->dmin[0]; lnmax = stn->dmax[0];
+  ltmin = stn->dmin[1]; ltmax = stn->dmax[1];
+  if (stn->rflag) {
+    lnmin = lnmin - stn->radius;
+    lnmax = lnmax + stn->radius;
+    ltmin = ltmin - stn->radius;
+    ltmax = ltmax + stn->radius;
+  }
+  stn->rnum = 0;
+
+  /* set size of the file and data hdr */
+  sizhdrf = sizeof(struct rpthdr);
+  sizhdrd = sizeof(struct rpthdr);
+
+  /* Loop through times looking for appropriate stations */
+  for (tim=stn->tmin; tim<=stn->tmax; tim++) {
+    if (tim<1) continue;
+    if (tim > pfi->dnum[3]) break;
+
+    if (!scuca && pfi->tmplat) {
+      rc = gaopfn(tim,1,&dummy,&oflg,pfi);
+      if (rc==-99999) goto err;
+      if (rc==-88888) {
+        if (scok) {
+          hdr->nlev = 0;
+          gacstn((char *)hdr, NULL, 0, sizhdrd);
+        }
+        continue;
+      }
+    }
+
+    /* Loop through stations for this time looking for valid reports */
+    if (!scuca) {
+      fpos = *(pfi->tstrt+tim-1);
+      rc = gasstn(fpos);
+      if (rc) goto err;
+    }
+
+    while (1) {
+      /* get the header */
+      if (scuca) {                             /* from the cache */
+	gagcst (sizhdrd, (char *)hdr);
+      } else {                                 /* from the file */
+        if (pfi->seqflg) {
+          rc = garstn(4,(char *)(&rdw),fpos);  
+          if (rc) goto err;
+          if (pfi->bswap) gabswp((gafloat *)(&rdw),1);
+        }
+        rc = garstn (sizhdrf, (char *)hdr, fpos);
+        if (rc) goto err;
+        if (pfi->bswap) gahswp(hdr);
+      }
+
+      if (hdr->nlev==0) break;   /* END OF DATA CHECK */
+
+      /* Left justify the station id if there are leading blanks */
+
+      j = 0;
+      while (j<7 && hdr->id[0]==' ') {
+        for (i=0; i<7; i++) hdr->id[i] = hdr->id[i+1];
+        hdr->id[7] = ' ';
+        j++;
+      }
+
+      /* Determine if we want to read the data portion of this report */
+      selflg = 1;
+      if (stn->sflag) {
+        getwrd (ch1,hdr->id,8);
+        lowcas(ch1);
+        getwrd(ch2,stn->stid,8);
+        if (!cmpwrd(ch1,ch2)) selflg = 0;
+      } else {
+        hlon = (gadouble)hdr->lon;
+        if (hlon<lnmin) hlon+=360.0;
+        if (hlon>lnmax) hlon-=360.0;
+        if (hlon<lnmin || hlon>lnmax ||
+            hdr->lat<ltmin || hdr->lat>ltmax ) selflg=0;
+        if (selflg && stn->rflag &&
+            hypot(hlon-stn->dmin[0], hdr->lat-stn->dmin[1])>stn->radius) {
+          selflg = 0;
+        }
+      }
+
+      /* Determine size of the data portion of this report */
+      if (hdr->flag) {
+	fnum = (hdr->nlev-1) * (pfi->lvnum+1) + pfi->ivnum;
+      } else {
+	fnum =  hdr->nlev * (pfi->lvnum+1);
+      }
+
+      /* calc size of floating point data section in the FILE not the machine */
+      sizd=fnum*sizeof(gafloat);
+      sizf=fnum*sizeof(gafloat);
+
+      /* Read the data portion of this report, byteswap it if needed,
+	 and set exact missing data values if specified.*/
+      if (selflg) {
+        if (scuca) {                                  /* from the cache */
+	  gagcst (sizd, (char *)pfi->sbuf);
+        } else {                                       /* from the file */
+          if (pfi->seqflg) {
+            ch = (char *)(pfi->sbuf);
+            nsiz = rdw - sizhdrf;
+            if (nsiz>0) {
+              rc = garstn(nsiz,ch,fpos);
+              if (rc) goto err;
+              ch += nsiz;
+            }
+            rtot = rdw;
+            nsiz = sizf + sizhdrf;
+            while (rtot<=nsiz) {
+              fpos = fpos + rdw + 8;
+              rc = gasstn(fpos);
+              if (rc) goto err;
+              if (rtot==nsiz) break;
+              rc = garstn(4,(char *)(&rdw),fpos); 
+              if (rc) goto err;
+              if (pfi->bswap) gabswp((gafloat *)(&rdw),1);
+              rtot +=rdw;
+              if (rtot>nsiz) break;
+              rc = garstn(rdw,ch,fpos);
+
+              if (rc) goto err;
+	      idum=rdw*2;
+              ch += idum;
+            }
+            if (rtot>nsiz) {
+              gaprnt (0,"Low Level I/O Error:  Sequential read error\n");
+              gaprnt (0,"  Record size exceeds report size\n");
+              snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+              gaprnt (0,pout);
+              goto err;
+            }
+
+	  /* normal read -- NON sequential */
+          } else {
+            rc = garstn (sizf, (char *)pfi->sbuf, fpos+sizhdrf);
+            fpos = fpos + sizf + sizhdrf;
+            if (rc) goto err;
+          }
+          if (pfi->bswap) gabswp(pfi->sbuf,fnum);
+        }
+
+	/* Test if data read from file or the cache is NaN, Inf, or 
+	   if value is within EPSILON of the missing data value.
+	   If yes, set undef mask to 0. The undef mask is 1 for valid data */
+	for (i=0; i<fnum; i++) {
+	  if (((*(pfi->sbuf+i) >= pfi->ulow) && (*(pfi->sbuf+i) <= pfi->uhi)) || 
+	      (isnan(*(pfi->sbuf+i))) || 
+	      (isinf(*(pfi->sbuf+i)))) {
+	    *(pfi->ubuf+i) = 0;
+	  }
+	  else {
+	    *(pfi->ubuf+i) = 1;
+	  }
+	}
+
+        /* Check the data portion for any matches.  */
+        rc = gaglvs (tim,hdr,stn);
+        if (rc) goto err;
+
+        /* Cache this report if appropriate */
+        if (scok) gacstn((char *)hdr,(char *)pfi->sbuf,sizd,sizhdrd);
+
+      /* Skip the data portion of this report.*/
+      } else {
+        if (scuca) {
+          gaprnt (0,"Logic Error 8 in gaio\n");
+          goto err;
+        }
+        if (pfi->seqflg) {
+          rtot = rdw;
+          sizf += sizhdrf;
+          while (rtot<=sizf) {
+            fpos = fpos + rdw + 8;
+            rc = gasstn(fpos);
+            if (rc) goto err;
+            if (rtot==sizf) break;
+            rc = garstn(4,(char *)(&rdw),fpos);  
+            if (rc) goto err;
+            if (pfi->bswap) gabswp((float *)(&rdw),1);
+            rtot +=rdw;
+          }
+          if (rtot>sizf) {
+            gaprnt (0,"Low Level I/O Error:  Sequential read error\n");
+            gaprnt (0,"  Record size exceeds report size\n");
+            snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+            gaprnt (0,pout);
+            goto err;
+          }
+        } else {
+          fpos = fpos + sizf + sizhdrf;
+          rc = gasstn(fpos);
+          if (rc) goto err;
+        }
+      }  /* END OF if (scuca) -- use the cache or not */
+    }    /* END OF  while (1) */
+
+    if (scok) {
+      hdr->nlev = 0;
+      gacstn((char *)hdr, NULL, 0,sizhdrd);
+    }
+  }
+  if (scok) {
+    scflg = 1;
+    scstn = *stn;
+    scseq = stn->pfi->fseq;
+  } else scflg = 0;
+  if (scuca) scflg = 1;
+  return (0);
+
+err:
+  for (i=0; i<BLKNUM; i++) {
+    if (stn->blks[i] != NULL) free (stn->blks[i]);
+  }
+  return (1);
+}
+
+/* Select appropriate variable and levels from report, and chain
+   them off the stn block.  */
+
+gaint gaglvs (gaint tim, struct rpthdr *hdr, struct gastn *stn) {
+struct garpt *rpt;
+gafloat *vals,*pval;
+gaint i,k,voff,mlev;
+char *uvals,*upval;
+
+  vals  = pfi->sbuf;
+  uvals = pfi->ubuf;
+  voff = pvr->offset;
+  if (pvr->levels==0) {
+    if (hdr->flag) {
+      pval  =  vals+voff;
+      upval = uvals+voff;
+      rpt = gaarpt (stn);
+      if (rpt==NULL) return(1);
+      rpt->lat = (gadouble)hdr->lat;
+      rpt->lon = (gadouble)hdr->lon;
+      rpt->lev = -9.99e8;
+      rpt->tim = (gadouble)(tim + hdr->t);
+      rpt->val = (gadouble)(*pval);
+      rpt->umask = *upval;
+      for (k=0; k<8; k++) *(rpt->stid+k) = *(hdr->id+k);
+      stn->rnum++;
+    }
+  } else {
+    if (hdr->flag) {
+      vals  =  vals + pfi->ivnum;
+      uvals = uvals + pfi->ivnum;
+    }
+    mlev = hdr->nlev;
+    if (hdr->flag) mlev--;
+    for (i=0; i<mlev; i++) {
+      pval  =  vals+(i*(pfi->lvnum+1));
+      upval = uvals+(i*(pfi->lvnum+1));
+      if (dequal(stn->dmax[2],stn->dmin[2],1e-08)==0) {
+	if (fabs(*pval-stn->dmin[2])>0.01) continue; 
+      } else {
+        if (*pval<stn->dmax[2] || *pval>stn->dmin[2]) continue;
+      }
+      rpt = gaarpt (stn);
+      if (rpt==NULL) return(1);
+      rpt->lat = (gadouble)hdr->lat;
+      rpt->lon = (gadouble)hdr->lon;
+      rpt->lev = (gadouble)(*pval);
+      rpt->tim = (gadouble)(tim + hdr->t);
+      rpt->val = (gadouble)(*(pval+voff+1)); 
+      rpt->umask = *(upval+voff+1);
+      for (k=0; k<8; k++) *(rpt->stid+k) = *(hdr->id+k);
+      stn->rnum++;
+    }
+  }
+  return (0);
+}
+
+/* Allocate a rpt structure, return pointer to allocated buffer.
+   On the first request, stn->rpt should be set to NULL. */
+
+struct garpt *gaarpt (struct gastn *stn) {
+struct garpt *rpt;
+gaint i;
+size_t sz;
+
+  /* First time through, define the static variables. */
+
+  if (stn->rpt == NULL) {
+    stn->prev = &(stn->rpt);
+    for (i=0; i<BLKNUM; i++) {
+      stn->blks[i] = NULL;
+    }
+    stn->rptcnt = RPTNUM;    /* Force new block allocation */
+    stn->blkcnt = -1;
+  }
+
+  stn->rptcnt++;
+  rpt = stn->crpt;
+
+  if (stn->rptcnt>=RPTNUM) {
+    stn->blkcnt++;
+    if (stn->blkcnt==BLKNUM) {
+      gaprnt (0,"Out of memory blocks to allocate \n");
+      return(NULL);
+    }
+    sz = sizeof(struct garpt)*(RPTNUM+2);
+    rpt = (struct garpt *)galloc(sz,"rpt");
+    if (rpt==NULL) {
+      gaprnt (0,"Couldn't allocate memory for stn block \n");
+      return(NULL);
+    }
+    stn->blks[stn->blkcnt] = rpt;
+    stn->rptcnt = 0;
+  } else rpt++;
+
+  *(stn->prev) = rpt;
+  stn->prev = &(rpt->rpt);
+  rpt->rpt = NULL;
+  stn->crpt = rpt;
+  return(rpt);
+}
+
+void gacstn (char *hdr, char *rdat, gaint siz, gaint sizhdr) {
+gaint i;
+  if (scpnt+sizhdr*2+siz+10 > SCNUM) {
+    scok = 0;
+  } else {
+    for (i=0; i<sizhdr; i++) *(scbuf+scpnt+i) = *(hdr+i);
+    scpnt += sizhdr;
+    if (siz>0) {
+      for (i=0; i<siz; i++) *(scbuf+scpnt+i) = *(rdat+i);
+      scpnt += siz;
+    }
+  }
+}
+
+/* Return info from the station data cache */
+
+void gagcst (gaint siz, char *ch) {
+gaint i;
+  for (i=0; i<siz; i++) *(ch+i) = *(scbuf+scpnt+i);
+  scpnt += siz;
+}
+
+/* Seek to specified location in a station data file */
+
+gaint gasstn (off_t fpos) {
+gaint rc;
+
+  rc = fseeko(pfi->infile, fpos, 0);
+  if (rc!=0) {
+    gaprnt (0,"Low Level I/O Error:  Seek error on data file \n");
+    snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+    gaprnt (0,pout);
+    snprintf(pout,255,"%d  rc=%d pos=%ld pfi->fhdr =%ld \n",__LINE__,rc,(long)fpos,pfi->fhdr);
+    gaprnt (0,pout);
+    snprintf(pout,255,"  Error occurred when seeking to byte %ld \n",(long)fpos);
+    gaprnt (0,pout);
+    return (1);
+  }
+  return (0);
+}
+
+/* Read specified amount of data from a station data file */
+
+gaint garstn (gaint siz, char *val, off_t fpos) {
+
+gaint rc;
+
+  rc = fread (val, siz, 1, pfi->infile);
+  if (rc<1) {
+    gaprnt (0,"Low Level I/O Error:  Read error on data file \n");
+    snprintf(pout,255,"  Data file name = %s \n",pfi->name);
+    gaprnt (0,pout);
+    snprintf(pout,255,"  Error reading %i bytes at location %ld \n", siz, (long)fpos);
+    gaprnt (0,pout);
+    return (1);
+  }
+  return (0);
+}
+
+/*  Obtain user requested grid from defined variable */
+
+gaint gagdef (void) {
+gaint id, jd, i, flag;
+gaint ys,zs,ts,es,siz;
+off_t pos;
+gaint d[5],d1min=0,d1max=0,d2min=0,d2max=0,xt,yt;
+gadouble *v;
+char *vmask;
+size_t sz;
+
+  /* If a dimension is a fixed dimension in the defined
+     variable, it must be a fixed dimension in the output
+     grid.  */
+
+  id = pgr->idim;
+  jd = pgr->jdim;
+  if (jd>-1) {
+    if (pfi->dnum[jd]==1) {
+      jd = -1;
+      pgr->jdim = -1;
+      pgr->jsiz = -1;
+    }
+  }
+  if (id>-1) {
+    if (pfi->dnum[id]==1) {
+      id = jd;
+      pgr->idim = pgr->jdim;
+      pgr->isiz = pgr->jsiz;
+      pgr->igrab = pgr->jgrab;
+      pgr->iabgr = pgr->jabgr;
+      pgr->ivals = pgr->jvals;
+      pgr->iavals = pgr->javals;
+      pgr->ilinr = pgr->jlinr;
+      jd = -1;
+      pgr->jdim = -1;
+      pgr->jsiz = 1;
+    }
+  }
+
+  /* Set up constants for array subscripting */
+
+  ys = pfi->dnum[0];
+  zs = ys * pfi->dnum[1];
+  ts = zs * pfi->dnum[2];
+  es = ts * pfi->dnum[3];
+
+  /* Set up dimension ranges */
+
+  for (i=0; i<5; i++) d[i] = pgr->dimmin[i] - pfi->dimoff[i] - 1;
+  for (i=0; i<5; i++) if (pfi->dnum[i]==1) d[i] = 0;
+  if (id>-1) {
+    d1min = d[id];
+    d1max = pgr->dimmax[id] - pfi->dimoff[id] - 1;
+  }
+  if (jd>-1) {
+    d2min = d[jd];
+    d2max = pgr->dimmax[jd] - pfi->dimoff[jd] - 1;
+  }
+
+  /* Get storage for output grid */
+
+  pgr->isiz = 1;
+  pgr->jsiz = 1;
+  if (id>-1) pgr->isiz = 1 + d1max - d1min;
+  if (jd>-1) pgr->jsiz = 1 + d2max - d2min;
+  siz = pgr->isiz * pgr->jsiz;
+  if (siz>1) {
+    sz = sizeof(gadouble)*siz;
+    pgr->grid = (gadouble *)galloc(sz,"pgrg");
+    sz = sizeof(char)*siz;
+    pgr->umask = (char *)galloc(sz,"pgrgu");
+    if (pgr->grid==NULL) {
+      gaprnt (0,"Memory Allocation Error: Grid Request\n");
+      return (2);
+    }
+    if (pgr->umask==NULL) {
+      gaprnt (0,"Memory Allocation Error: Grid Request\n");
+      return (2);
+    }
+  } else {
+    pgr->grid = &(pgr->rmin);
+    pgr->umask = &(pgr->umin); 
+  }
+
+  /* Normalize time coordinate if not varying */
+  /* JMA: This does not handle leap years properly!!!!  Gotta fix this someday */
+
+  if (pfi->climo && id!=3 && jd!=3) clicyc(d+3);
+
+  /* Check for entirely undefined grid */
+
+  flag = 0;
+  for (i=0; i<5; i++) {
+    if (i!=id && i!=jd && (d[i]<0 || d[i]>=pfi->dnum[i])) flag = 1;
+  }
+  if (flag) {
+    for (i=0; i<siz; i++) {
+      *(pgr->grid+i) = pfi->undef;
+      *(pgr->umask+i) = 0;
+    }
+    return (0);
+  }
+
+  /* Move appropriate grid values */
+
+  if (id==-1 && jd==-1) {
+    pos = (off_t)d[0] + (off_t)d[1]*(off_t)ys + (off_t)d[2]*(off_t)zs + (off_t)d[3]*(off_t)ts + (off_t)d[4]*(off_t)es;
+    pgr->rmin = *(pfi->rbuf+pos);
+    pgr->umin = *(pfi->ubuf+pos);
+    return (0);
+  }
+
+  v = pgr->grid;
+  vmask = pgr->umask;
+
+  if (jd==-1) {
+    for (xt=d1min; xt<=d1max; xt++) {
+      d[id] = xt;
+      if (id==3 && pfi->climo) clicyc(d+3);
+      if (d[id]<0 || d[id]>=pfi->dnum[id]) {
+	*v = pfi->undef;
+	*vmask = 0;
+      }
+      else {
+        pos = (off_t)d[0] + (off_t)d[1]*(off_t)ys + (off_t)d[2]*(off_t)zs + (off_t)d[3]*(off_t)ts + (off_t)d[4]*(off_t)es;
+        *v     = *(pfi->rbuf+pos);
+	*vmask = *(pfi->ubuf+pos);
+      }
+      v++;vmask++;
+    }
+    return (0);
+  }
+
+  for (yt=d2min; yt<=d2max; yt++) {
+    d[jd] = yt;
+    if (jd==3 && pfi->climo) clicyc(d+3);
+    for (d[id]=d1min; d[id]<=d1max; d[id]++) {
+      if (d[jd]<0 || d[jd]>=pfi->dnum[jd] ||
+          d[id]<0 || d[id]>=pfi->dnum[id]) {
+	*v = pfi->undef;
+	*vmask = 0;
+      }
+      else {
+        pos = (off_t)d[0] + (off_t)d[1]*(off_t)ys + (off_t)d[2]*(off_t)zs + (off_t)d[3]*(off_t)ts + (off_t)d[4]*(off_t)es;
+        *v     = *(pfi->rbuf+pos);
+	*vmask = *(pfi->ubuf+pos);
+      }
+      v++;vmask++;
+    }
+  }
+  return(0);
+}
+
+void clicyc (gaint *ti) {
+  if (pfi->climo>0) {
+    while (*ti>pfi->cysiz-1) *ti = *ti - pfi->cysiz;
+    while (*ti<0) *ti = *ti + pfi->cysiz;
+  }
+}
+
+/* Fill in grid for predefined variable */
+
+gaint gagpre (void) {
+gadouble (*conv)(gadouble *, gadouble);
+gaint d[5],id,jd,i,dim;
+gadouble *gr,*vals,t;
+char *gru;
+
+  id = pgr->idim;
+  jd = pgr->jdim;
+  for (i=0; i<5; i++) d[i] = pgr->dimmin[i];
+
+  dim = pvr->offset;
+  conv = pfi->gr2ab[dim];
+  vals = pfi->grvals[dim];
+
+  gr = pgr->grid;
+  gru = pgr->umask;
+
+  if (id>-1 && jd>-1) {
+    for (d[jd]=pgr->dimmin[jd]; d[jd]<=pgr->dimmax[jd]; d[jd]++) {
+      for (d[id]=pgr->dimmin[id]; d[id]<=pgr->dimmax[id]; d[id]++) {
+        t = (gadouble)(d[dim]);
+        *gr = conv(vals, t);
+	*gru = 1;
+        gr++;gru++;
+      }
+    }
+  } else if (id>-1) {
+    for (d[id]=pgr->dimmin[id]; d[id]<=pgr->dimmax[id]; d[id]++) {
+      t = (gadouble)(d[dim]);
+      *gr = conv(vals, t);
+      *gru = 1;
+      gr++;gru++;
+    }
+  } else {
+    t = (gadouble)(d[dim]);
+    *gr = conv(vals, t);
+    *gru = 1;
+  }
+  return (0);
+}
+
+
+/* Read index data, in this case GRIB type data.
+   Currently assumes no pole point, and only one record
+   per grid.  */
+
+gaint gairow (gaint x, gaint y, gaint z, gaint t, gaint e, gaint offset, gaint len, 
+	      gadouble *gr, char *gru) {
+gaint irec,ioff,bstrt,bend,blen,cstrt,cend,clen,rc;
+gaint brec;
+gaint ival,i,yy,boff,siz,gtyp,xsiz,ysiz;
+off_t fpos,bpos,seek;
+float dsf,bsf,ref;
+size_t sz;
+#if GRIB2
+struct g2buff *buff=NULL;
+g2int ifld;
+gaint g2off,ng2elems=2;
+#endif
+
+ if (pfi->idxflg==0) return (1); 
+
+ /* code that grib1 and grib2 data sets can share */
+ if (pfi->ppflag) {
+   xsiz = pfi->ppisiz; 
+   ysiz = pfi->ppjsiz;
+ }
+ else {
+   xsiz = pfi->dnum[0]; 
+   ysiz = pfi->dnum[1];
+ }
+ 
+
+ /* GRIB1 */
+ if (pfi->idxflg==1) {
+   /* Figure out position and length of the I/O */
+   gtyp = *(pindx->hipnt+3);
+   irec = (e-1)*pfi->dnum[3]*pfi->trecs + (t-1)*pfi->trecs + pvr->recoff + z - 1;
+   brec = irec;
+   if (gtyp==29) {
+     xsiz = 145;
+     irec = irec*6;
+     if (y<37) y--;
+     else { irec+=3; y-=37; }
+     yy = y;
+   } else {
+     irec = irec*3;
+     if (pfi->yrflg) yy = ysiz - y;
+     else yy = y-1;
+   }
+   if (pfi->ppflag) 
+     ioff = offset;               
+   else 
+     ioff = yy*xsiz + x - 1;      
+   boff = ioff;
+   if (pindx->type==4) blen = *(pindx->intpnt + brec);
+   else blen = *(pindx->intpnt + irec + 2);
+   if (blen<0) {
+     for (i=0; i<len; i++) *(gr+i) = pfi->undef;
+     for (i=0; i<len; i++) *(gru+i) = 0;
+     return (0);
+   }
+   if (pindx->type==4) bpos = *(pindxb->bigpnt + brec*2 + 1);
+   else bpos = (off_t)(*(pindx->intpnt + irec + 1));
+   dsf = *(pindx->fltpnt+irec);
+   bsf = *(pindx->fltpnt+irec+1);
+   ref = *(pindx->fltpnt+irec+2);
+   if (bpos>(off_t)-900 && bpos!=bpsav) {
+     bpsav = bpos;
+     siz = 2+(xsiz*ysiz)/8;
+     if (siz>bssav) {
+       if (bcflag) {
+	 gree(bcache,"f114");
+	 gree(bpcach,"f115");
+       }
+       sz = siz;
+       bcache = (unsigned char *)galloc(sz,"bcache");
+       sz = sizeof(gaint)*(xsiz*ysiz+1);
+       bpcach = (gaint *)galloc(sz,"bpcach");
+       if (bcache==NULL||bpcach==NULL) {
+	 gaprnt(0,"Memory Allocation Error During GRIB I/O\n");
+	 return (1);
+       }
+       bssav = siz;
+       bcflag = 1;
+     }
+     rc = fseeko(pfi->infile, bpos, 0);
+     rc = fread(bcache,1,siz,pfi->infile);
+     if (rc!=siz) {
+       gaprnt(0,"GRIB I/O Error: Bit Map I/O\n");
+       return(1);
+     }
+     boff=1;
+     for (i=0; i<xsiz*ysiz; i++) {
+       if (gagbb(bcache,i,1)) {
+	 *(bpcach+i) = boff;
+	 boff++;
+       } else {
+	 *(bpcach+i) = -1*boff;
+       }
+     }
+     *(bpcach+xsiz*ysiz) = boff;  /* Provide an ending offset */
+   }
+   if (bpos>(off_t)-900) {
+     boff = *(bpcach+ioff);
+     if (boff<0) boff = -1*boff;
+     boff--;
+     bstrt = blen * boff;
+     boff = *(bpcach+ioff+len);
+     if (boff<0) boff = -1*boff;
+     boff--;
+     bend = blen * boff - 1;
+   } else {
+     bstrt = blen * boff;
+     bend = bstrt + blen*len;
+   }
+   cstrt = bstrt/8;
+   cend = bend/8;
+   clen = cend-cstrt+2;
+   if (pindx->type==4) fpos = *(pindxb->bigpnt+brec*2);
+   else fpos = (off_t)(*(pindx->intpnt+irec));
+   rc = gaird(fpos,cstrt,clen,xsiz,ysiz,blen);
+   if (rc) return(rc);
+   bstrt = bstrt - cstrt*8;
+   for (i=0; i<len; i++) {
+     if (bpos>(off_t)-900 && *(bpcach+ioff+i)<0) {
+       *(gr+i) = pfi->undef;
+       *(gru+i) = 0;
+     }
+     else {
+       ival = gagbb(pfi->pbuf,bstrt,blen);
+       *(gr+i) = ( ref + (gadouble)ival * bsf )/dsf;
+       *(gru+i) = 1;
+       bstrt += blen;
+     }
+   }
+   return (0);
+ }
+
+#if GRIB2
+ /* GRIB 2 */
+ if (pfi->idxflg==2) {
+   
+  /* figure out which record to retrieve from index file */
+  irec = (e-1)*pfi->dnum[3]*pfi->trecs + (t-1)*pfi->trecs + pvr->recoff + z - 1;
+  if (pfi->g2indx->version==1) irec = irec * ng2elems;
+  if (irec > pfi->g2indx->g2intnum) {
+    snprintf(pout,255,"GRIB2 I/O error: irec=%d is greater than g2intnum=%d\n",irec,pfi->g2indx->g2intnum);
+    gaprnt(0,pout);
+    return(1);
+  }
+
+  /* get file position offset and field number from grib2map file */
+  if (pfi->g2indx->version==2) {
+    seek = *(pfi->g2indx->g2bigpnt+irec);
+    ifld = *(pfi->g2indx->g2intpnt+irec);
+  } else {
+    seek = (off_t)(*(pfi->g2indx->g2intpnt+irec+0));
+    ifld = *(pfi->g2indx->g2intpnt+irec+1);
+  }
+  if (debug==2) {
+    snprintf(pout,255,"gairow debug: seek,ifld = %jd %ld\n",seek, ifld);
+    gaprnt(0,pout);
+  }
+
+  if (seek<(off_t)-900 && ifld<-900) {             /* grid is missing */
+    for (i=0; i<len; i++) *(gru+i) = 0;
+    return(0);
+  }
+  buff = g2check(z,t,e);                           /* check if grid is already in the cache */
+  if (buff==NULL) buff = g2read(seek,ifld,z,t,e);  /* if not in cache, read the grid */
+  if (buff==NULL) return(1);                       /* give up */
+
+  /* copy required data from grid */
+  if (pfi->ppflag) {
+    g2off = offset;                    
+  }
+  else {
+    g2off = (y-1)*xsiz + x - 1;        
+  }
+  for (i=0; i<len; i++) {
+    if (buff->mask[g2off+i]==1) {  
+      *(gr+i)  = (gadouble) buff->fld[g2off+i];
+      *(gru+i) = 1;
+    }
+    else {
+      *(gru+i) = 0;
+    }
+  }
+  return(0);    
+ }
+#endif
+ return(0);
+}
+
+
+#if GRIB2
+/* Routine to read a grib2 message.
+   New blocks are added to the end of the chain.
+   If the cache is too large, the first block in the chain is released. */
+struct g2buff * g2read (off_t seek, g2int ifld, gaint z, gaint t, gaint e) {
+struct g2buff *newbuff,*buff1,*buff2,*lastbuff;
+gaint i,x,y,rc,unpack,expand,ierr,newbuffsize,buff1size,roff,field;
+gaint sbit1,sbit2,sbit3,sbit4,gdt,soct,nx,ny,missflg,cpbm=0,numdp;
+gaint flag,A,pos,yfac1,yfac2,yadd1,yadd2,xfac1,xfac2,xadd1,xadd2;
+g2int lgrib=-999;
+unsigned char  *cgrib,*mycgrib;
+unsigned char s0[16];
+size_t  lengrib,sz;
+gafloat *fld,miss1,miss2;
+char *mask;
+unsigned char *sect,*s1,*s2,*s3,*s4,*s5,*s6,*s7;
+gribfield *gfld;
+gaint diag=0; 
+
+  /* move file pointer to the start of the grib record */
+  rc = fseeko(pfi->infile,seek,SEEK_SET);
+  if (rc) {
+    gaprnt(0,"GRIB2 I/O error: fseeko failed \n");
+    return(NULL);     
+  }
+  
+  /* read section 0, get the record length */
+  rc = fread(s0,sizeof(unsigned char),16,pfi->infile);
+  if (rc!=16) {
+    gaprnt(0,"GRIB2 I/O error: failed to read Section 0 \n");
+    return(NULL);     
+  }
+
+  /* check for the GRIB message indicator */
+  if (s0[0]!='G' || s0[1]!='R' || s0[2]!='I' || s0[3]!='B') {
+    gaprnt(0,"GRIB2 I/O error: GRIB message indicator not found\n");
+    return(NULL);
+  }
+
+  lgrib = gagby (s0,12,4);   /* Here we are getting just the last 4 bytes of
+                                the length.  GRIB2 allows for the length to be
+                                encoded as 8 bytes, and we are ignoring the 4 
+                                high order bytes.  This will eventually be a 
+                                problem. In gagmap, there is a test to make 
+			        sure the high order bytes aren't in use. */
+  if (lgrib<=0) {
+    gaprnt(0,"GRIB2 I/O error: unable to retrieve message length \n");
+    return(NULL);     
+  }
+
+  /* allocate memory for the record */
+  sz = lgrib;
+  cgrib=(unsigned char *)galloc(sz,"cgrib");
+  if (cgrib == NULL) {
+    gaprnt(0,"GRIB2 I/O error: unable to allocate memory for cgrib \n");
+    return(NULL);
+  }
+  mycgrib = cgrib;
+
+  /* move file pointer past stuff to skip at beginning of record */
+  rc=fseeko(pfi->infile,seek,SEEK_SET);
+  if (rc) {
+    gaprnt(0,"GRIB2 I/O error: fseek failed \n");
+    goto g2err;
+  }
+
+  /* read the grib record */
+  lengrib=fread(cgrib,sizeof(unsigned char),lgrib,pfi->infile);
+  if (lengrib < lgrib) {
+    gaprnt(0,"GRIB2 I/O Error: unable to read record \n");
+    goto g2err;
+  }
+
+  /* we need to extract certain octets from the grib record, so set pointers to each section */
+  s1 = s2 = s3 = s4 = s5 = s6 = s7 = NULL;
+  /* Section 0, always 16 octets long */
+  roff = 16;                         
+  /* Section 1, the Identification Section */
+  sect = mycgrib+roff;  
+  i = gagby(sect,4,1);
+  if (i==1) {
+    s1 = mycgrib+roff;  
+    if (diag) printf("Sec1   %d\n",gagby(s1,0,4));
+    roff += gagby(s1,0,4);     
+  } else {
+    snprintf(pout,255,"GRIB2 I/O Error: reading header, section 1 expected, found %i\n",i);
+    gaprnt (0,pout);
+    goto g2err;
+  }
+  field=1;
+  while (field<=ifld) {
+    /* Section 2, the Local Use Section */
+    sect = mycgrib + roff;
+    i = gagby(sect,4,1);
+    if (i==2) {
+      s2 = mycgrib + roff;
+      if (diag) printf("Sec2.%d %d\n",field,gagby(s2,0,4));
+      roff += gagby(s2,0,4);
+    } else {
+      if (diag) printf("Sec2.%d not present\n",field);
+    }
+
+    /* Section 3, the Grid Definition Section */
+    sect = mycgrib + roff;
+    i = gagby(sect,4,1);
+    if (i==3) {
+      s3 = mycgrib + roff;
+      if (diag) printf("Sec3.%d %d\n",field,gagby(s3,0,4));
+      roff += gagby(s3,0,4);  
+    } 
+    else if (field==1) {
+      snprintf(pout,255,"GRIB2 I/O Error: reading header, section 3 expected, found %i\n",i);
+      gaprnt (0,pout);
+      goto g2err;
+    } 
+    else if (field>1) {
+      if (diag) printf("Sec3.%d not present\n",field);
+    }
+    /* Section 4, the Product Definition Section */
+    sect = mycgrib + roff;
+    i = gagby(sect,4,1);
+    if (i==4) {
+      s4 = mycgrib + roff;
+      if (diag) printf("Sec4.%d %d\n",field,gagby(s4,0,4));
+      roff += gagby(s4,0,4);
+    }
+    else if (field==1) {
+      snprintf(pout,255,"GRIB2 I/O Error: reading header, section 4 expected, found %i\n",i);
+      gaprnt (0,pout);
+      goto g2err;
+    }
+    else if (field>1) {
+      if (diag) printf("Sec4.%d not present\n",field);
+    }
+    /* Section 5, the Data Representation Section */
+    sect = mycgrib + roff;
+    i = gagby(sect,4,1);
+    if (i==5) {
+      s5 = mycgrib + roff;
+      if (diag) printf("Sec5.%d %d\n",field,gagby(s5,0,4));
+      roff += gagby(s5,0,4);
+    }
+    else if (field==1) {
+      snprintf(pout,255,"GRIB2 I/O Error: reading header, section 5 expected, found %i\n",i);
+      gaprnt (0,pout);
+      goto g2err;
+    }
+    else if (field>1) {
+      if (diag) printf("Sec5.%d not present\n",field);
+    }
+    /* Section 6, the Bit Map Section*/
+    sect = mycgrib + roff;
+    i = gagby(sect,4,1);
+    if (i==6) {
+      s6 = mycgrib + roff;
+      if (diag) printf("Sec6.%d %d\n",field,gagby(s6,0,4));
+      roff += gagby(s6,0,4);
+    }
+    else {
+      if (diag) printf("Sec6.%d not present\n",field);
+    }
+    
+    /* Section 7, the Data Section */
+    sect = mycgrib+roff;
+    i = gagby(sect,4,1);
+    if (i==7) {
+      s7 = mycgrib + roff;
+      if (diag) printf("Sec7.%d %d\n",field,gagby(s7,0,4));
+      roff += gagby(s7,0,4);
+    }
+    else if (field==1) {
+      snprintf(pout,255,"GRIB2 I/O Error: reading header, section 7 expected, found %i\n",i);
+      gaprnt(0,pout);
+      goto g2err;
+    }
+    else if (field>1) {
+      if (diag) printf("Sec7.%d not present\n",field);
+    }
+    field++;
+  }
+
+  /* get the scanning mode */
+  gdt = gagby(s3,12,2);
+  switch (gdt) {
+    case  0:
+    case  1:
+    case  2:
+    case  3: soct = 71; break;
+    case 10: soct = 59; break;
+    case 20:
+    case 30:
+    case 31: soct = 64; break;
+    case 40:
+    case 41:
+    case 42: soct = 71; break;
+    case 90: soct = 63; break;
+    case 204: soct = 71; break; 
+    default: 
+      snprintf(pout,255,"g2read error: Grid Definition Template %d not handled\n",gdt);
+      gaprnt (0,pout);
+      goto g2err;
+  };
+  sbit1 = gagbb(s3+soct,0,1);
+  sbit2 = gagbb(s3+soct,1,1);
+  sbit3 = gagbb(s3+soct,2,1);
+  sbit4 = gagbb(s3+soct,3,1);
+  numdp = gagby(s3,6,4); /* number of data points */
+  nx = gagby(s3,30,4);   /* these seem to be in the same location */
+  ny = gagby(s3,34,4);   /* for for all grid definition templates */
+
+  /* Use the g2clib routine g2_getfld to unpack the desired field in the record */
+  unpack=1;
+  expand=1;
+  ierr=g2_getfld(cgrib,ifld,unpack,expand,&gfld);
+  if (ierr) {
+    snprintf(pout,255,"GRIB2 I/O Error: g2_getfld failed, ierr=%d\n",ierr);
+    gaprnt (0,pout);
+    goto g2err;
+  }
+  /* set up a new block to add to the grib2 cache */
+  newbuff = NULL;
+  sz = sizeof(struct g2buff);
+  if ((newbuff = (struct g2buff *)galloc(sz,"g2buff1"))==NULL) {
+    gaprnt (0,"GRIB2 I/O error: unable to allocate memory for cache buffer\n");
+    goto g2err;
+  }
+  fld=NULL;
+  sz = gfld->ngrdpts*sizeof(gafloat);
+  if ((fld = (gafloat *)galloc(sz,"g2fld1"))==NULL) {
+    gaprnt (0,"GRIB2 I/O error: unable to allocate memory for cache grid \n");
+    gree(newbuff,"f253");
+    goto g2err;
+  }
+  mask=NULL;
+  sz = gfld->ngrdpts*sizeof(char);
+  if ((mask = (char *)galloc(sz,"g2mask1"))==NULL) {
+    gaprnt (0,"GRIB2 I/O error: unable to allocate memory for cache undef mask \n");
+    gree(fld,"f255");
+    gree(newbuff,"f256");
+    goto g2err;
+  }
+  /* populate the new cache block  */
+  newbuff->fld  = fld;
+  newbuff->mask = mask;
+  newbuff->prev = NULL;
+  newbuff->next = NULL;
+  newbuff->fseq = pfi->fseq;
+  newbuff->z    = z;
+  newbuff->t    = t;
+  newbuff->e    = e;
+  newbuff->size = gfld->ngrdpts;
+  for (i=0;i<16;i++) *(newbuff->abbrv+i)=*(pvr->abbrv+i);
+  /* size = structure + data + undef mask */
+  newbuffsize = sizeof(struct g2buff) + newbuff->size*(sizeof(gafloat) + sizeof(char));
+
+  /* create the undef mask */
+  if (gfld->ibmap!=0 && gfld->ibmap!=254 && gfld->ibmap!=255) {
+    snprintf(pout,255,"GRIB2 I/O Error: Predefined bitmap applies (ibmap=%ld) \n",gfld->ibmap);
+    gaprnt (0,pout);
+    goto g2err1;
+  }
+  else if (gfld->ibmap==255) {  
+    /* bitmap doesn't apply -- all data are good */
+    for (i=0;i<newbuff->size;i++) *(newbuff->mask+i) = 1;
+    cpbm = 0;
+  }
+  else if (gfld->ibmap==0 || gfld->ibmap==254) {       
+    /* copy the bit map */
+    cpbm = 1;
+  } 
+  /* complex packing with spatial diff uses special missing value management */
+  missflg = miss1 = miss2 = 0;
+  if (gfld->idrtnum==2 || gfld->idrtnum==3) {
+    if (gfld->idrtmpl[6] == 1) {
+      /* primary missing value substitute */
+      missflg=1;
+      miss1 = ieee2flt(&s5[23]);
+      miss2 = miss1;
+    }
+    else if (gfld->idrtmpl[6] == 2) {
+    /* primary and secondary missing value substitutes */
+      missflg=1;
+      miss1 = ieee2flt(&s5[23]);
+      miss2 = ieee2flt(&s5[27]);
+    }
+  }
+
+  /* use scanning mode bits to set up coefficients for proper placement in rows/columns */
+  if (sbit3!=0) {
+    printf("Contact GrADS developers and tell them you have grib2 data written out columnwise\n");
+    goto g2err1;
+  }
+  if (sbit2==1) {  /* columns scan south to north (normal) */
+    yfac1 = 1;
+    yfac2 = 1;
+    yadd1 = 0;
+    yadd2 = 0;
+  } else {
+    yfac1 = -1;
+    yfac2 = -1;
+    yadd1 = ny - 1;
+    yadd2 = ny - 1;
+  }
+  if (sbit4==0) {   /* all rows scan in the same direction */
+    if (sbit1==0) { /* 1st row scans west to east (normal) */
+      xfac1 = +1;
+      xfac2 = +1;
+      xadd1 = 0;
+      xadd2 = 0;
+    }
+    else {
+      xfac1 = -1; 
+      xfac2 = -1;
+      xadd1 = nx - 1;
+      xadd2 = nx - 1;
+    }
+  }
+  else {             /* rows scan in alternating directions */
+    if (sbit1==0) {  /* 1st row scans west to east (normal) */
+      xfac1 = +1; 
+      xfac2 = -1;
+      xadd1 = 0;
+      xadd2 = nx - 1;
+    }
+    else {
+      xfac1 = -1; 
+      xfac2 = +1;
+      xadd1 = nx - 1;
+      xadd2 = 0;
+    }
+  }
+
+  if (nx==-1) {
+    /* copy each element in the grib2 field and mask grids as a 1D array */
+    for (i=0; i<numdp; i++) {
+      if (cpbm) 
+	(gfld->bmap[i]==1) ? (*(newbuff->mask+i) = 1) : (*(newbuff->mask+i) = 0) ;
+      if (missflg && (gfld->fld[i]==miss1 || gfld->fld[i]==miss2)) 
+	*(newbuff->mask+i) = 0;
+      else 
+	*(newbuff->fld+i) = gfld->fld[i];
+    }
+  }
+  else {
+    /* copy each element in the grib2 field and mask grids 
+       into the right row/column in the cache grids */
+    flag=1;
+    pos=0;
+    for (y=0; y<ny; y++) {
+      for (x=0; x<nx; x++) {
+	if (flag) {
+	  A = (yadd1+(yfac1*y))*nx + (xadd1+(xfac1*x));
+	  if (cpbm) {
+	    (gfld->bmap[pos]==1) ? (*(newbuff->mask+A) = 1) : (*(newbuff->mask+A) = 0) ;
+	  }
+	  if (missflg && (gfld->fld[pos]==miss1 || gfld->fld[pos]==miss2)) 
+	    *(newbuff->mask+A) = 0;
+	  else
+	    *(newbuff->fld+A) = gfld->fld[pos];
+	} 
+	else {
+	  A = (yadd2+(y*yfac2))*nx + (xadd2+(xfac2*x));
+	  if (cpbm) {
+	    (gfld->bmap[pos]==1) ? (*(newbuff->mask+A) = 1) : (*(newbuff->mask+A) = 0) ;
+	  }
+	  if (missflg && (gfld->fld[pos]==miss1 || gfld->fld[pos]==miss2)) 
+	    *(newbuff->mask+A) = 0;
+	  else
+	    *(newbuff->fld+A) = gfld->fld[pos];
+	}
+	pos++;
+      }
+      flag = flag==0 ? 1 : 0 ;
+    }
+  }
+
+  /* set up or adjust the anchor's pointers */
+  if (anchor==NULL) {
+    /* make sure cache will be big enough for the new block */
+    if (newbuffsize > MAXG2CACHE) {
+      gaprnt(0,"GRIB2 I/O error: size of cache (MAXG2CACHE) is too small\n");
+      goto g2err1;
+    }
+    /* allocate space for a new anchor and initialize */
+    sz = sizeof(struct g2anchor);
+    if ((anchor = (struct g2anchor *)galloc(sz,"anchor"))==NULL) {
+      gaprnt(0,"GRIB2 I/O error: unable to allocate memory for cache anchor \n");
+      goto g2err1;
+    }
+    anchor->start = newbuff;
+    anchor->end   = newbuff;
+    anchor->total = newbuffsize;
+  } 
+  else {
+    /* make sure there's room in the cache buffer for the new block */
+    while ((newbuffsize + anchor->total) > MAXG2CACHE) {
+      /* point to the first block in the chain and get its size */
+      buff1 = anchor->start;
+      buff1size = sizeof(struct g2buff) + buff1->size*(sizeof(gafloat) + sizeof(char));
+      if (buff1->next==NULL) {   
+	/* the first block was the only block */
+	anchor->start = NULL; 
+	anchor->end   = NULL; 
+	anchor->total = 0;
+      }
+      else {                    
+      /* move the start of the chain from 1st to 2nd block  */
+	buff2 = buff1->next;  
+	buff2->prev = NULL;     
+	anchor->start = buff2;     
+	/* adjust total size of cache */
+	anchor->total = anchor->total - buff1size;
+      }
+      /* release memory from 1st block */
+      gree(buff1->fld,"f262");
+      gree(buff1->mask,"f263");
+      gree(buff1,"f264");
+    }
+    /* now add the new block onto the end of the chain */
+    if (anchor->end==NULL) {
+      /* no blocks are hanging off anchor */
+      newbuff->prev = NULL;
+      newbuff->next = NULL;
+      anchor->start = newbuff;
+      anchor->end   = newbuff;
+      anchor->total = newbuffsize;
+
+    } 
+    else {
+      lastbuff = anchor->end;
+      lastbuff->next = newbuff;
+      newbuff->prev = lastbuff;
+      newbuff->next = NULL;
+      anchor->end = newbuff;
+      anchor->total = anchor->total + newbuffsize;
+    }
+  }
+  
+  /* release memory */
+  (void)g2_free(gfld);
+  gree(cgrib,"f262");
+  return (anchor->end);
+
+g2err1:
+  gree(newbuff->fld,"f257");
+  gree(newbuff->mask,"f258");
+  gree(newbuff,"f259");
+  goto g2err;
+g2err:
+  gree(cgrib,"f261");
+  return(NULL);
+}
+
+/* Routine to check if a requested grid already exists in the grib2 cache.
+   Blocks are checked starting from the end of the chain because 
+   the most recently read grid is most likely to be the one we need 
+*/
+struct g2buff * g2check (gaint z, gaint t, gaint e) {
+struct g2buff *buff;
+gaint size; 
+
+  if (anchor!=NULL) {
+    buff = anchor->end; 
+    if (pfi->ppflag) {
+      size = pfi->ppisiz * pfi->ppjsiz;
+    }
+    else {
+      size = pfi->dnum[0]*pfi->dnum[1];
+    }
+    while (buff != NULL) {
+      if ((buff->fseq == pfi->fseq) &&              
+	  (buff->z == z) &&
+	  (buff->t == t) &&
+	  (buff->e == e) &&
+	  (cmpwrd(buff->abbrv,pvr->abbrv)) &&
+	  (buff->size == size)) {
+	/* found grid in the cache */
+	return(buff);
+      }
+      else {
+	/* next block */
+	buff = buff->prev;
+      }
+    }
+    /* grid not found in cache */
+    return(NULL);
+  }
+  else {
+    /* no existing cache */
+    return (NULL);
+  }
+}
+
+/* Routine to clear the grib2 cache. */
+void g2clear (void) {
+struct g2buff *buff1,*buff2;
+
+ if (anchor!=NULL) {
+   /* release the first block in chain until there's only one block left */
+   while (anchor->end->prev != NULL) {
+     /* move the start of the chain from 1st to 2nd block  */
+     buff1 = anchor->start;
+     buff2 = buff1->next;
+     buff2->prev = NULL;
+     anchor->start = buff2;
+     /* release memory from 1st block */
+     gree(buff1->fld,"f270a");
+     gree(buff1->mask,"f271a");
+     gree(buff1,"f272a");
+   }
+   /* free the last block */
+   buff1 = anchor->start;
+   gree(buff1->fld,"f270");
+   gree(buff1->mask,"f271");
+   gree(buff1,"f272");
+   gree(anchor,"f273");
+   anchor = NULL;
+ }
+}
+#endif  /* matches #if GRIB2 */
+
+gaint gaird (off_t fpos, gaint cstrt, gaint clen, gaint xsiz, gaint ysiz, gaint blen) {
+gaint rc,siz,i;
+size_t sz;
+
+  if (pfi->ppflag && pgr->idim==0 && pgr->jdim==1) {
+    if (!cflag) {
+      cflag = 1;
+      siz = 5 + xsiz*ysiz*blen/8;  /* qqq  Warning:  siz calc does not */
+                                   /* qqq  take into account bms!!! */
+      sz = siz;
+      cache = (char *)galloc(sz,"cache");
+      if (cache==NULL) {
+        gaprnt(0,"GRIB Memory Allocation Error\n");
+        return (1);
+      }
+      rc = fseeko(pfi->infile, fpos, 0);
+      rc = fread(cache,sizeof(char),siz,pfi->infile);
+      if (rc==0) {
+        snprintf(pout,255,"GRIB I/O Error reading %i bytes at %ld\n",siz,(long)fpos);
+        gaprnt (0,pout);
+        gaprnt (0,"  File name is: ");
+        if (pfi->tempname) gaprnt(0,pfi->tempname);
+        else gaprnt(0,pfi->name);
+        gaprnt (0,"\n");
+        return (1);
+      }
+    }
+    if (cache==NULL) return(1);
+    for (i=0; i<clen; i++) {
+      *(pfi->pbuf+i) = *(cache+cstrt+i);
+    }
+  } else {
+    rc = fseeko(pfi->infile, fpos+cstrt, 0);
+    rc = fread (pfi->pbuf, sizeof(char), clen, pfi->infile);
+    if (rc==0) {
+      snprintf(pout,255,"GRIB I/O Error reading %i bytes at %ld\n",clen,(long)fpos+cstrt);
+      gaprnt (0,pout);
+      gaprnt (0,"  File name is: ");
+      if (pfi->tempname) gaprnt(0,pfi->tempname);
+      else gaprnt(0,pfi->name);
+      gaprnt (0,"\n");
+      return(1);
+    }
+  }
+  return(0);
+}
+
+/* Read in a row of data from a pre-projected grid data set.
+   This involves doing interpolation to the lat-lon
+   grid */
+
+gaint gaprow (gaint x, gaint y, gaint z, gaint t, gaint e, gaint tt, 
+	      gaint len, gadouble *gr, char *gru) {
+  gadouble p[4],dx,dy,g1,g2;
+  gadouble vals[9],wts[9],sum,wt;
+  char umask[9];
+  gaint ioffs[9],cnt,ig0,goflg;
+  gaint rc,i,j,ig,ioff,ncig=0,ncjg=0;
+  off_t pos,pos0;
+  
+  /* Handle generalized arbitrary points + weights */
+  
+  if (pfi->ppflag==8) {
+    /* "cnt"  is the number of interpolation grids provided in pdef file ("num" in PDEF entry) 
+       "pos0" is the file position of the native lat/lon grid we're going to read 
+       "ig0"  is the offset into the 2-D grid where the I/O will begin (N.B. when x=1 and y=1, ig0=0)
+     */
+    cnt  = (gaint)(pfi->ppvals[0]+0.1);   
+    pos0 = (e-1)*(pfi->dnum[3]*pfi->tsiz) + (tt-1)*(pfi->tsiz) + pvr->offset + (z-1)*(pfi->gsiz);
+    ig0  = (y-1) * pfi->dnum[0] + x - 1;
+    /* loop over all grid points in the row */
+    for (i=0; i<len; i++) {
+      ig = ig0 + i;
+      goflg = 0;
+      /* get the interpolation indices (ioffs) and their weights (wts) that were read
+	 from the pdef file -- for ppflag==8, these index values start at 1, not 0 */
+      for (j=0; j<cnt; j++) {
+        ioffs[j] = *(pfi->ppi[j]+ig);
+        if (ioffs[j] >= 1 && ioffs[j] <= pfi->gsiz) goflg = 1; 
+        wts[j] = *(pfi->ppf[j]+ig);
+      }
+      if (!goflg) {
+	*gr = pgr->undef;
+	*gru = 0;
+      }
+      else {
+	/* now read the interpolation data values from the native grid */
+        goflg = 1;
+        j = 0;
+        sum = 0.0; wt = 0.0;
+        while (j<cnt) {
+          if (ioffs[j] >= 1) {
+            if (pfi->idxflg) {
+	      /* gairow wants the grid offset to be 0-referenced
+		 so shift ioffs index back by 1  */
+	      rc = gairow(x,y,z,t,e,ioffs[j]-1,1,vals+j,umask+j);    /* grib */
+	    }
+            else if (pfi->ncflg==1) {
+	      rc = gancsetup();
+	      if (rc) return (rc);
+	      /* ncig and ncjg are the i,j indices of the interpolation data value to be read.
+		 They are required instead of ioffs for reading data from NetCDF and HDF grids.
+	         The grid indices ioffs, ncig, and ncjg all start at 1, not 0. The code in 
+		 gancrow and gahrow will shift the indices back so they start at 0 for the I/O */
+	      ncig = (gaint)(1+((ioffs[j]-1)%pfi->ppisiz)); 
+	      ncjg = (gaint)(1+((ioffs[j]-1)/pfi->ppisiz));
+	      rc = gancrow(ncig,ncjg,z,tt,e,1,vals+j,umask+j);    /* netcdf */
+	    }
+            else if (pfi->ncflg==2) {
+	      /* see comment above */
+	      ncig = (gaint)(1+((ioffs[j]-1)%pfi->ppisiz)); 
+	      ncjg = (gaint)(1+((ioffs[j]-1)/pfi->ppisiz));
+	      rc = gahrow(ncig,ncjg,z,tt,e,1,vals+j,umask+j);     /* hdfsds */
+	    }
+            else if (pfi->ncflg==3) {
+	      /* see comment above */
+	      ncig = (gaint)(1+((ioffs[j]-1)%pfi->ppisiz)); 
+	      ncjg = (gaint)(1+((ioffs[j]-1)/pfi->ppisiz));
+	      rc = gah5row(ncig,ncjg,z,tt,e,1,vals+j,umask+j);     /* hdf5 */
+	    }
+            else {
+	      /* the ioffs index is shifted back by 1 here */
+	      pos = pos0 + ioffs[j] - 1;
+	      rc = garead(pos,1,vals+j,umask+j);                  /* binary */
+	    }
+            if (rc) return(rc);
+            if (*(umask+j)==0) {
+              goflg = 0;
+              break;
+            }
+            sum = sum + *(vals+j) * *(wts+j);
+            wt = wt + *(wts+j);
+          }
+          j++;
+        }
+        if (goflg && wt!=0.0) {
+	  /* Result is weighted average */
+	  *gr = sum/wt;
+	  *gru = 1;
+	}
+        else {
+	  *gr = pgr->undef;
+	  *gru = 0;
+	}
+      }
+      gr++; gru++;
+    }
+  }  /* matches if (pfi->ppflag==8)  */
+  else {
+    for (i=0; i<len; i++) {
+      ig = (y-1) * pfi->dnum[0] + x + i - 1;
+      ioff = *(pfi->ppi[0]+ig);              /* ioff index values start at 0 */
+      if (ioff<0) {
+	*gr = pgr->undef;
+	*gru = 0;
+      }
+      else {
+        dx = (gadouble)*(pfi->ppf[0]+ig);
+        dy = (gadouble)*(pfi->ppf[1]+ig);
+        pos = (e-1)*(pfi->dnum[3]*pfi->tsiz) + (tt-1)*(pfi->tsiz) + pvr->offset + (z-1)*(pfi->gsiz) + ioff;
+
+	/* Get the first two pre-projected grid values */
+        if (pfi->idxflg) {                      
+	  rc = gairow(x,y,z,t,e,ioff,2,p,umask);                   /* grib */ 
+	}
+        else if (pfi->ncflg==1) {               
+	  rc = gancsetup();
+	  if (rc) return(rc);
+	  ncig = (gaint)(1 + ioff%pfi->ppisiz);
+          ncjg = (gaint)(1 + ioff/pfi->ppisiz);
+	  rc = gancrow(ncig,ncjg,z,tt,e,2,p,umask);                /* netcdf */  
+	}
+        else if (pfi->ncflg==2) {              
+	  ncig = (gaint)(1 + ioff%pfi->ppisiz);
+          ncjg = (gaint)(1 + ioff/pfi->ppisiz);
+	  rc = gahrow(ncig,ncjg,z,tt,e,2,p,umask);                 /* hdf */  
+	}
+        else if (pfi->ncflg==3) {              
+	  ncig = (gaint)(1 + ioff%pfi->ppisiz);
+          ncjg = (gaint)(1 + ioff/pfi->ppisiz);
+	  rc = gah5row(ncig,ncjg,z,tt,e,2,p,umask);                 /* hdf5 */  
+	}
+        else {                               
+	  rc = garead(pos,2,p,umask);                              /* binary */
+	}
+        if (rc) return(rc);
+
+	/* Get the second two pre-projected grid values */
+        if (pfi->idxflg) {
+	  rc = gairow(x,y,z,t,e,ioff+pfi->ppisiz,2,p+2,umask+2);   /* grib */
+	}
+        else if (pfi->ncflg==1) {
+          ncjg++;
+	  rc = gancrow(ncig,ncjg,z,tt,e,2,p+2,umask+2);            /* netcdf */
+	}
+        else if (pfi->ncflg==2) {
+          ncjg++; 
+	  rc = gahrow(ncig,ncjg,z,tt,e,2,p+2,umask+2);             /* hdf */  
+	}
+        else if (pfi->ncflg==3) {
+          ncjg++; 
+	  rc = gah5row(ncig,ncjg,z,tt,e,2,p+2,umask+2);             /* hdf5 */  
+	}
+        else {
+	  rc = garead(pos+pfi->ppisiz,2,p+2,umask+2);              /* binary */  
+	}
+        if (rc) return(rc);
+
+	/* Do the bilinear interpolation, as long as we have no undefs */
+        if (umask[0]==0 || umask[1]==0 || umask[2]==0 || umask[3]==0) {
+	  *gr = pgr->undef;
+	  *gru = 0;
+	}
+        else {
+          g1 = p[0] + (p[1]-p[0])*dx;
+          g2 = p[2] + (p[3]-p[2])*dx;
+          *gr = g1 + (g2-g1)*dy;
+	  *gru = 1;
+        }
+      }
+      gr++; gru++;
+    }
+  }
+  return(0);
+}
+ 
+
+/* Set up variable ID, undef value, and unpacking values for NetCDF variables */
+gaint gancsetup (void) {
+#if USENETCDF == 1
+  gaint vid,error,rc,oldncopts,storage;
+  gadouble val;
+  gaint ndims,i;  
+  size_t *chsize,nelems,size,cachesz;
+  nc_type type;
+
+  /* Turn off automatic error handling. */
+  ncopts = NC_VERBOSE ;
+  oldncopts = ncopts ;
+  ncopts = 0;
+
+  /* Get the varid if we haven't already done that for this file */
+  if (pvr->ncvid == -888) {
+    ncopts = oldncopts ;
+    return(1);  /* already tried and failed */
+  }
+  if (pvr->ncvid == -999) {
+    error=0;
+    if (pvr->longnm[0] != '\0') {
+      rc = nc_inq_varid(pfi->ncid, pvr->longnm, &vid);
+    }
+    else {
+      rc = nc_inq_varid(pfi->ncid, pvr->abbrv, &vid);
+    }
+    if (rc != NC_NOERR) error=1;
+    if (error) {
+      pvr->ncvid = -888;  /* set flag so we won't try this variable ever again */
+      if (pvr->longnm[0] != '\0') {
+	snprintf(pout,255,"Error: Variable %s not in netcdf file\n",pvr->longnm);
+     }
+      else {
+	snprintf(pout,255,"Error: Variable %s not in netcdf file\n",pvr->abbrv);
+      }
+      gaprnt (0,pout);
+      ncopts = oldncopts ;
+      return (1);
+    }
+    /* No errors, so we can set the varid in the gavar structure */
+    pvr->ncvid = vid;
+    
+    /* If undef attribute name is given, get the undef value */
+    if (pfi->undefattrflg) {
+      if (nc_get_att_double(pfi->ncid, pvr->ncvid, pfi->undefattr, &val) != NC_NOERR) {
+	snprintf(pout,255,"Warning: Could not retrieve \"%s\" -- using %g instead\n",
+		pfi->undefattr,pfi->undef);
+	gaprnt(1,pout);
+	pvr->undef = pfi->undef;
+      }
+      else {
+	pvr->undef = val;
+      }
+    }
+    else {
+      /* If no undef attribute name is given, copy the file-wide undef */
+      pvr->undef = pfi->undef;
+    }
+
+    /* If data are packed, get the scale factor and offset attribute values */
+    if (pfi->packflg) {
+      /* initialize values */
+      pvr->scale=1.0;
+      pvr->add=0.0;
+      /* get the scale factor attribute value */
+      if (pfi->packflg == 1 || pfi->packflg == 2) {
+	if (nc_get_att_double(pfi->ncid, pvr->ncvid, pfi->scattr, &val) != NC_NOERR) {
+	  gaprnt(1,"Warning: Could not retrieve scale factor -- setting to 1.0\n");
+	  pvr->scale = 1.0;
+	}
+	else {
+	  pvr->scale = val;
+	}
+      }
+      /* get add offset if required */
+      if (pfi->packflg == 2 || pfi->packflg == 3) {
+	/* get the add offset attribute value */
+	if (nc_get_att_double(pfi->ncid, pvr->ncvid, pfi->ofattr, &val) != NC_NOERR) {
+	  gaprnt(1,"Warning: Could not retrieve add offset -- setting to 0.0\n");
+	  pvr->add = 0.0;
+	}
+	else {
+	  pvr->add = val;
+	}
+      } 
+    }  
+#if HAVENETCDF4 == 1
+    /* Check the chunk size */
+    ndims = pvr->nvardims;
+    if ((chsize = (size_t*)galloc(ndims*sizeof(size_t),"chsize"))!=NULL) {
+      if ((nc_inq_var_chunking(pfi->ncid, pvr->ncvid, &storage, chsize)) == NC_NOERR) {
+	if (storage == NC_CHUNKED) {
+	  if ((nc_inq_vartype(pfi->ncid, pvr->ncvid, &type)) == NC_NOERR) {
+	    if ((nc_inq_type(pfi->ncid, type, NULL, &size)) == NC_NOERR) {
+	      nelems = 1;
+	      for (i=0; i<ndims; i++) nelems *= chsize[i];
+	      if (nelems*size > pfi->cachesize) {
+		gaprnt(1,"*** WARNING! ***\n");
+		gaprnt(1,"*** The I/O for this variable will be extremely slow \n");
+		gaprnt(1,"*** because the chunks are too big to fit in the cache \n");
+		snprintf(pout,255,"*** chunk size = %ld bytes  (",(long)(nelems*size));
+		gaprnt(1,pout);
+		for (i=ndims-1; i>=0; i--) { 
+		  snprintf(pout,255,"%ld * ",(long)chsize[i]); gaprnt(1,pout); 
+		}
+		snprintf(pout,255,"%ld bytes)\n",(long)size);
+		gaprnt(1,pout);
+		snprintf(pout,255,"*** cache size = %ld bytes \n",cachesz);
+		gaprnt(1,pout);
+		gaprnt(1,"*** There are two ways to control the cache size: \n");
+		gaprnt(1,"*** add a CACHESIZE entry to the descriptor file \n");
+		gaprnt(1,"*** or change the cache size scale factor with 'set cachesf' \n");
+		gaprnt(1,"*** Please read http://iges.org/grads/gadoc/compression.html \n");
+	      }
+	    }
+	  }
+	}
+      }
+      gree(chsize,"f274");
+    }
+#endif
+  }   /* matches if (pvr->ncvid == -999)   */
+  return(0); 
+#endif
+  return(0); 
+}
+
+
+
+/* A shortcut for netcdf grids (intended to speed up OPeNDAP requets) */
+
+gaint gancgrid (gadouble *gr, char *gru, gaint id, gaint jd) {
+#if USENETCDF == 1
+gaint rc,rtrn,i,j,got1,grsize,wflag=0,nilen,njlen,nid,njd;
+gaint xlen,ylen,zlen,tlen,elen;
+gaint x,offset,xx,yy,zz,tt,ee,min,max;
+gaint ifac,jfac,iadd,jadd,pos,ipad,jpad,ilen,jlen;
+gaint xpad,ypad,zpad,tpad,epad,padmin,padmax;
+gaint jbeg,jend,groff,tmpoff,itmp,jtmp,jlimit;
+gaint dimswap,nrows,ncols;
+size_t sz,start[16],count[16];
+gadouble ulow,uhi;
+gadouble unitsvals[5]={-100,-101,-102,-103,-104};
+gadouble *grtmp=NULL,*grtmp2=NULL;
+char *grutmp=NULL;
+gaint oldncopts ;         /* to save and restore setting for automatic error handling */
+  
+  /* Turn off automatic error handling. */
+  ncopts = NC_VERBOSE ;
+  oldncopts = ncopts ;
+  ncopts = 0;
+
+  /* Get the starting point and length for the X dimension */
+  if (pgr->dimmin[0] >= 1 && pgr->dimmax[0] <= pfi->dnum[0]) {
+    /*  the requested data is within the bounds of the file dimensions */
+    xx = pgr->dimmin[0] - 1;
+    xlen = pgr->dimmax[0] - pgr->dimmin[0] + 1;
+    xpad = 0;
+  }
+  else {     
+    /* the requested data lies outside the file's bounds */
+    if (!pfi->wrap) {
+      /* file doesn't wrap the globe, so adjust limits */
+      xpad = 0;
+      min = pgr->dimmin[0];
+      if (min < 1) {                   /* adjust min to be within file limits */
+	min = 1;
+	xpad = 1 - pgr->dimmin[0];     /* save diff between requested min and file min */
+      }
+      max = pgr->dimmax[0];
+      if (max > pfi->dnum[0]) {        /* adjust max to be within file limits */
+	max = pfi->dnum[0];
+      }
+      if (max<min) {  /* requested data lies entirely outside the file's bounds */
+	rtrn=-1;
+	goto cleanup;
+      }
+      xlen = max - min + 1;            /* set length */
+      xx = min - 1 ;                   /* set start value */
+    }
+    else {
+      /* file wraps the globe, so read the entire row */
+      wflag = 1;
+      xx = 0;
+      xpad = 0; 
+      xlen = pfi->dnum[0];
+    }
+  }
+
+  /* Get the starting point and length for the Y dimension */
+  if (pgr->dimmin[1] >= 1 && pgr->dimmax[1] <= pfi->dnum[1]) {
+    /*  the requested data is within the bounds of the file dimensions */
+    if (pfi->yrflg) yy = pfi->dnum[1] - pgr->dimmax[1];
+    else yy = pgr->dimmin[1] - 1;
+    ylen = pgr->dimmax[1] - pgr->dimmin[1] + 1;
+    ypad = 0;
+  }
+  else {     
+    /* the requested data lies outside the file's bounds */
+    ypad = padmin = padmax = 0;  /* padding for part of requested grid outside boundaries */
+    min = pgr->dimmin[1];
+    if (min < 1) {                  /* adjust min to be within file limits */
+      min = 1;
+      padmin = 1 - pgr->dimmin[1];  /* save diff between requested min and file min */
+    }
+    max = pgr->dimmax[1];
+    if (max > pfi->dnum[1]) {                 /* adjust max to be within file limits */
+      max = pfi->dnum[1];
+      padmax = pgr->dimmax[1] - pfi->dnum[1]; /* save diff between requested max and file max */
+    }
+    if (max<min) {  /* requested data lies entirely outside the file's bounds */
+      rtrn=-1;
+      goto cleanup;
+    }
+    ylen = max - min + 1;                     /* set length */
+    if (pfi->yrflg) {         
+      yy = pfi->dnum[1] - max;                /* set start value */  
+      ypad = ypad + padmax;                   /* set padding */
+    }
+    else {
+      yy = min - 1;
+      ypad = ypad + padmin;
+    }
+  }
+
+  /* Get the starting point and length for the Z dimension */
+  if (pgr->dimmin[2] >= 1 && pgr->dimmax[2] <= pfi->dnum[2]) {
+    /*  the requested data is within the bounds of the file dimensions */
+    if (pfi->zrflg) {
+      if (pvr->levels==0) zz = 0;
+      else zz = pvr->levels - pgr->dimmax[2];  /* use var nlevs instead of dnum[[2] */
+    }
+    else zz = pgr->dimmin[2] - 1;
+    zlen = pgr->dimmax[2] - pgr->dimmin[2] + 1;
+    zpad = 0;
+  }
+  else {     
+    /* the requested data lies outside the file's bounds */
+    /* set limits to what's in the file boundaries */
+    zpad = padmin = padmax = 0;     /* padding for part of requested grid outside boundaries */
+    min = pgr->dimmin[2];
+    if (min < 1) {                  /* adjust min to be within file limits */
+      min = 1;
+      padmin = 1 - pgr->dimmin[2];  /* save diff between requested min and file min */
+    }
+    max = pgr->dimmax[2];
+    if (max > pfi->dnum[2]) {       /* adjust max to be within file limits */
+      max = pfi->dnum[2];           
+      padmax = pgr->dimmax[2] - pfi->dnum[2]; /* save diff between requested max and variable max */
+    }
+    if (max<min) {  /* requested data lies entirely outside the file's bounds */
+      rtrn=-1;
+      goto cleanup;
+    }
+    zlen = max - min + 1;                  /* set length */
+    if (pfi->zrflg) {
+      if (pvr->levels==0) zz = 0;          /* set start value */
+      else zz = pvr->levels - max;         
+      zpad = zpad + padmax;                /* set padding */
+    }
+    else {
+      zz = min - 1;
+      zpad = zpad + padmin;
+    }
+  }
+
+  /* Get the starting point and length for the T dimension */
+  if (pgr->dimmin[3] >= 1 && pgr->dimmax[3] <= pfi->dnum[3]) {
+    /*  the requested data is within the bounds of the file dimensions */
+    tt = pgr->dimmin[3] - 1;
+    tlen = pgr->dimmax[3] - pgr->dimmin[3] + 1;
+    tpad = 0;
+  }
+  else {     
+    /* the requested data lies outside the file's bounds */
+    tpad = 0;
+    min = pgr->dimmin[3];
+    if (min < 1) {                /* adjust min to be within file limits */
+      min = 1;
+      tpad = 1 - pgr->dimmin[3];  /* save diff between requested min and file min */
+    }
+    max = pgr->dimmax[3];
+    if (max > pfi->dnum[3]) {     /* adjust max to be within file limits */
+      max = pfi->dnum[3];
+    }
+    if (max<min) {  /* requested data lies entirely outside the file's bounds */
+      rtrn=-1; goto cleanup;
+    }
+    tlen = max - min + 1;         /* set length */
+    tt = min - 1;                 /* set start value */
+  }
+
+  /* Get the starting point and length for the E dimension */
+  if (pgr->dimmin[4] >= 1 && pgr->dimmax[4] <= pfi->dnum[4]) {
+    /*  the requested data is within the bounds of the file dimensions */
+    ee = pgr->dimmin[4] - 1;
+    elen = pgr->dimmax[4] - pgr->dimmin[4] + 1;
+    epad = 0;
+  }
+  else {     
+    /* the requested data lies outside the file's bounds */
+    epad = 0;
+    min = pgr->dimmin[4];
+    if (min < 1) {                /* adjust min to be within file limits */
+      min = 1;
+      epad = 1 - pgr->dimmin[4];  /* diff between requested min and file min */
+    }
+    max = pgr->dimmax[4];
+    if (max > pfi->dnum[4]) {     /* adjust max to be within file limits */
+      max = pfi->dnum[4];
+    }
+    if (max<min) {  /* requested data lies entirely outside the file's bounds */
+      rtrn=-1;
+      goto cleanup;
+    }
+    elen = max - min + 1;         /* set length */
+    ee = min - 1;                 /* set start value */
+  }
+
+  /* size of the grid to be read */
+  grsize = xlen * ylen * zlen * tlen * elen;
+
+  /* allocate memory for temporary grids to hold data 
+     before being placed properly in requested block */
+  sz = grsize * sizeof(gadouble);
+  grtmp = (gadouble *)galloc(sz,"grtmp");
+  if (grtmp==NULL) {
+    gaprnt (0,"gancgrid error: unable to allocate memory for grtmp grid storage \n");
+    snprintf(pout,255,"  grid size = xlen * ylen * zlen * tlen * elen = %d * %d * %d * %d * %d\n",
+	    xlen,ylen,zlen,tlen,elen);
+    gaprnt (0,pout);
+    rtrn=1; goto cleanup;
+  }
+  sz = grsize * sizeof(char);
+  grutmp = (char *)galloc(sz,"grutmp");
+  if (grutmp==NULL) {
+    gaprnt (0,"gancgrid error: unable to allocate memory for grutmp grid storage \n");
+    snprintf(pout,255,"  grid size = xlen * ylen * zlen * tlen * elen = %d * %d * %d * %d * %d\n",
+	    xlen,ylen,zlen,tlen,elen);
+    gaprnt (0,pout);
+    rtrn=1; goto cleanup;
+  }
+
+  /* Set up the start and count arrays  */
+  /* The units values provided for each variable indicate the mapping 
+     of the netcdf variable shape into the grads dimensions */
+  for (i=0; i<16; i++) {
+    start[i] = -999;
+    count[i] = -999;
+    if (pvr->units[i] == -100) { start[i] = xx; count[i] = xlen; }
+    if (pvr->units[i] == -101) { start[i] = yy; count[i] = ylen; }
+    if (pvr->units[i] == -102) { start[i] = zz; count[i] = zlen; }
+    if (pvr->units[i] == -103) { start[i] = tt; count[i] = tlen; }
+    if (pvr->units[i] == -104) { start[i] = ee; count[i] = elen; }
+    if (pvr->units[i] >=0) { start[i] = pvr->units[i];  count[i] = 1; }
+  }
+
+  /* what is the real order of dimension sizes in grtmp? */
+  got1 = 0;
+  nid = njd = -1 ; 
+  nilen = njlen = 1;
+  /* loop over variable's dimensions, starting with slowest varying */
+  for (i=pvr->nvardims-1;i>=0;i--) {   
+    /* compare units vals to see which dimensions in the variable correspond to id and jd */
+    if ((id!=-1 && pvr->units[i] == unitsvals[id]) || 
+	(jd!=-1 && pvr->units[i] == unitsvals[jd])) {
+      /* this dimension is in our request */
+      if (got1==0) {
+	/* this dimension is the idim in grtmp */
+	got1=1;
+	if (pvr->units[i] == -100) {nilen = xlen; nid=0;}
+	if (pvr->units[i] == -101) {nilen = ylen; nid=1;}
+	if (pvr->units[i] == -102) {nilen = zlen; nid=2;}
+	if (pvr->units[i] == -103) {nilen = tlen; nid=3;}
+	if (pvr->units[i] == -104) {nilen = elen; nid=4;}
+      } else {
+	/* this dimension is the jdim in grtmp */
+	if (pvr->units[i] == -100) {njlen = xlen; njd=0;}
+	if (pvr->units[i] == -101) {njlen = ylen; njd=1;}
+	if (pvr->units[i] == -102) {njlen = zlen; njd=2;}
+	if (pvr->units[i] == -103) {njlen = tlen; njd=3;}
+	if (pvr->units[i] == -104) {njlen = elen; njd=4;}
+
+      }
+    }
+  }
+
+  /* define constants to determine how data will be placed into requested grid */
+  if ((id==1 && pfi->yrflg) || (id==2 && pfi->zrflg)) {  /* the i-dimension is reversed */
+    ifac = -1;
+    iadd = pgr->isiz - 1;
+  }
+  else {
+    ifac = 1;
+    iadd = 0;
+  }
+  if ((jd==1 && pfi->yrflg) || (jd==2 && pfi->zrflg)) {  /* the j-dimension is reversed */
+    jfac = -1;
+    jadd = pgr->jsiz - 1;
+  }
+  else {
+    jfac = 1;
+    jadd = 0;
+  }
+  ipad = jpad = ilen = jlen = 0;
+  if      (id==-1) { ipad = 0;    ilen = 1;    }
+  else if (id==0)  { ipad = xpad; ilen = xlen; }
+  else if (id==1)  { ipad = ypad; ilen = ylen; }
+  else if (id==2)  { ipad = zpad; ilen = zlen; }
+  else if (id==3)  { ipad = tpad; ilen = tlen; }
+  else if (id==4)  { ipad = epad; ilen = elen; }
+
+  if      (jd==-1) { jpad = 0;    jlen = 1;    }
+  else if (jd==0)  { jpad = xpad; jlen = xlen; }
+  else if (jd==1)  { jpad = ypad; jlen = ylen; }
+  else if (jd==2)  { jpad = zpad; jlen = zlen; }
+  else if (jd==3)  { jpad = tpad; jlen = tlen; }
+  else if (jd==4)  { jpad = epad; jlen = elen; }
+  
+  /* make sure native grid and request grid are ordered the same way */
+  dimswap=0;
+  if (id!=nid || jd!=njd) { /* dims are not the same */
+    if (id==njd && jd==nid) { /* dims are swapped */
+      dimswap=1;
+      /* allocate memory for temporary grid to swap i/j dims */
+      sz = grsize * sizeof(gadouble);
+      grtmp2 = (gadouble *)galloc(sz,"grtmp2");
+      if (grtmp2==NULL) {
+	gaprnt (0,"gancgrid error: unable to allocate memory for grtmp2 grid storage \n");
+	snprintf(pout,255,"  grid size = xlen * ylen * zlen * tlen * elen = %d * %d * %d * %d * %d\n",
+		xlen,ylen,zlen,tlen,elen);
+	gaprnt (0,pout);
+	rtrn=1; goto cleanup;
+      }
+    } 
+  }
+  
+  /* do we need to swap the dims of the data grid */
+  if (dimswap) {
+    /* Do the I/O into temporary grid grtmp2 */
+    rc = nc_get_vara_double(pfi->ncid, pvr->ncvid, start, count, grtmp2);
+    if (rc != NC_NOERR) {
+      snprintf(pout,255,"gancgrid error: nc_get_vara_double failed; %s\n",nc_strerror(rc));
+      gaprnt(0,pout);
+      rtrn=1; goto cleanup;
+    }
+    /* pos moves through the data in grtmp2 by rows, we populate grtmp by columns */
+    nrows=nilen;
+    ncols=njlen;
+    pos=0;
+    for (i=0; i<ncols; i++) {
+      for (j=0; j<nrows; j++) {
+	offset=j*ncols+i;
+	*(grtmp+offset) = *(grtmp2+pos);
+	pos++;
+      }
+    }
+  }
+  else {
+    /* Do the I/O and put data directly into grtmp */
+    rc = nc_get_vara_double(pfi->ncid, pvr->ncvid, start, count, grtmp);
+    if (rc != NC_NOERR) {
+      snprintf(pout,255,"gancgrid error: nc_get_vara_double failed; %s\n",nc_strerror(rc));
+      gaprnt(0,pout);
+      rtrn=1; goto cleanup;
+    }
+  }
+
+  /* Set missing data mask values and then unpack grid data if necessary */
+  /* use the gavar undef to set the fuzzy test limits */
+  /* If gavar undef equals zero, change it to 1/EPSILON */
+  if (dequal(pvr->undef, 0.0, 1e-08)==0) {   
+    ulow = 1e-5; 
+  } 
+  else {
+    ulow = fabs(pvr->undef/EPSILON);   
+  }
+  uhi  = pvr->undef + ulow;
+  ulow = pvr->undef - ulow;
+  /* now set the gagrid undef equal to the gafile undef */
+  pgr->undef = pfi->undef;           
+
+  /* Test for NaN, Inf, and the fuzzy test for undef values. Then unpack */
+  for (i=0;i<grsize;i++) {
+    if ((*(grtmp+i)>=ulow && *(grtmp+i)<=uhi) || (isnan(*(grtmp+i))) || (isinf(*(grtmp+i)))) {
+      *(grutmp+i) = 0;
+    }
+    else {
+      /* Data value is good */ 
+      *(grutmp+i) = 1;
+      /* unpack with scale and offset if necessary */
+      if (pfi->packflg) {
+	*(grtmp+i) = *(grtmp+i)*pvr->scale + pvr->add; 
+      }
+    }
+  }
+ 
+  /* initialize the result grid with missing flags */
+  for (i=0; i<pgr->isiz*pgr->jsiz; i++) *(gru+i) = 0;
+
+  /* copy each element in the tmp grid into the right place in the result grid */
+  if (!wflag) {
+    /* no globe-wrapping issues to worry about */
+    pos=0;
+    for (j=0; j<jlen; j++) {
+      for (i=0; i<ilen; i++) {
+	offset = (jadd+(jfac*(j+jpad)))*pgr->isiz + (iadd + (ifac*(i+ipad)));
+	*(gr+offset)  = *(grtmp+pos);
+	*(gru+offset) = *(grutmp+pos);
+	pos++;
+      }
+    }
+  }
+  else {
+    /* jbeg and jend are limits of tmp grid within user requested grid */
+    if (jd==-1) {
+      jbeg = jadd; 
+      jend = jbeg;
+    }
+    else {
+      jbeg = jadd+(jfac*(0+jpad));
+      jend = jadd+(jfac*((jlen-1)+jpad));
+    }
+    /* i,j are result grid coordinates */
+    /* itmp,jtmp are tmp grid coordinates */
+    jtmp=0; 
+    j = jbeg;
+    jlimit = jend+=jfac; /* this is jend +/-1, the limit for the while loop below */
+    while (j != jlimit) {
+      /* x are user-requested limits */
+      i=0;
+      for (x=pgr->dimmin[0]; x<=pgr->dimmax[0]; x++,i++) {   
+	/* groff is where point lies inside requested grid */
+	groff = j*pgr->isiz + i;       
+	/* figure out where x index lies inside tmp grid */
+	itmp=x;
+	while (itmp<1) itmp = itmp + pfi->dnum[0];
+	while (itmp>pfi->dnum[0]) itmp = itmp-(pfi->dnum[0]);  
+	/* tmpoff is where this point lies in the grtmp grid */
+	tmpoff = jtmp*pfi->dnum[0] + (itmp-1);
+	*(gr+groff)  = *(grtmp+tmpoff);
+	*(gru+groff) = *(grutmp+tmpoff);
+      }
+      jtmp++;
+      j+=jfac;
+    }
+  }
+  
+  rtrn=0; /* everything worked */
+
+ cleanup:
+  if (grtmp!=NULL)  gree(grtmp,"f121");
+  if (grutmp!=NULL) gree(grutmp,"f122");
+  if (grtmp2!=NULL) gree(grtmp2,"f122a");
+  ncopts = oldncopts ;
+  return(rtrn);
+
+#else 
+  gaprnt(0,"Reading NetCDF files is not supported in this build\n");
+  return(1);  
+#endif
+}
+
+/* Read a row varying in the X direction from a netcdf grid */
+gaint gancrow (gaint x, gaint y, gaint z, gaint t, gaint e, gaint len, gadouble *gr, char *gru) {
+#if USENETCDF == 1
+  gaint rc,i,yy,zz;
+  size_t  start[16],count[16];
+  gadouble   ulow,uhi;
+  gaint oldncopts ;         /* to save and restore setting for automatic error handling */
+  
+  /* Turn off automatic error handling. */
+  ncopts = NC_VERBOSE ;
+  oldncopts = ncopts ;
+  ncopts = 0;
+
+  /* Change the Y indexes if yrev flag is set */
+  if (pfi->yrflg) {
+    /* one day we might encounter a pre-projected file written upside down... */
+    if (pfi->ppflag)             
+      yy = pfi->ppjsiz - y;
+    else
+      yy = pfi->dnum[1] - y;
+  }
+  else {
+    yy = y-1;
+  }
+  /* Change the Z indexes if zrev flag is set */
+  if (pfi->zrflg) {
+    if (pvr->levels==0) {
+      zz=0;
+    }
+    else {
+      zz = pvr->levels-z;
+    }
+  } 
+  else {
+    zz = z-1;
+  }
+
+  /* Set up the start and count array.  The units values
+     provided for each variable indicate the mapping of the 
+     netcdf variable shape into the grads dimensions */
+  for (i=0; i<16; i++) {
+    start[i] = -999;
+    count[i] = -999;
+    if (pvr->units[i] == -100) { start[i] = x-1; count[i] = len; }
+    if (pvr->units[i] == -101) { start[i] = yy;  count[i] = 1; }
+    if (pvr->units[i] == -102) { start[i] = zz;  count[i] = 1; }
+    if (pvr->units[i] == -103) { start[i] = t-1; count[i] = 1; }
+    if (pvr->units[i] == -104) { start[i] = e-1; count[i] = 1; }
+    if (pvr->units[i] >=0) { start[i] = pvr->units[i];  count[i] = 1; }
+  }
+
+  /* Now we are ready to do the I/O  */
+  rc = nc_get_vara_double(pfi->ncid, pvr->ncvid, start, count, gr);
+  if (rc != NC_NOERR) {
+    snprintf(pout,255,"NetCDF Error (gancrow, nc_get_vara_double): %s\n",nc_strerror(rc));
+    gaprnt(0,pout);
+    ncopts = oldncopts ;
+    return (1);
+  }
+
+  /* Set missing data values to gafile undef and then unpack if necessary */
+  /* use the gavar undef to set the fuzzy test limits */
+  /* If gavar undef equals zero, change it to 1/EPSILON */
+  if (dequal(pvr->undef, 0.0, 1e-08)==0) {   
+    ulow = 1e-5;
+  } 
+  else {
+    ulow = fabs(pvr->undef/EPSILON);   
+  }
+  uhi  = pvr->undef + ulow;
+  ulow = pvr->undef - ulow;
+  /* set the gagrid undef equal to the gafile undef */
+  pgr->undef = pfi->undef;           
+  
+  /* Do the NaN, Inf, and fuzzy test for undef values before unpacking */
+  for (i=0;i<len;i++) {
+    if ((*(gr+i) >= ulow && *(gr+i) <= uhi) || (isnan(*(gr+i))) || (isinf(*(gr+i)))) {
+      *(gru+i) = 0;
+    }
+    else {
+      /* Data is not missing, so unpack with scale and offset if necessary */
+      *(gru+i) = 1; 
+      if (pfi->packflg) {
+	*(gr+i) = *(gr+i)*pvr->scale + pvr->add; 
+      }
+    }
+  }
+
+  ncopts = oldncopts ;
+  return(0);
+#else 
+  gaprnt(0,"Reading NetCDF files is not supported in this build\n");
+  return(1);  
+#endif
+}
+
+
+/* Read a row varying in the X direction from an HDF-SDS grid */
+gaint gahrow (gaint x, gaint y, gaint z, gaint t, gaint e, gaint len, gadouble *gr, char *gru) {
+#if USEHDF == 1
+gaint rc,i,yy,zz;
+int32  start[16],count[16];
+int32  sd_id, v_id, sds_id;
+int32  data_dtype, n_atts, rank, dim_sizes[H4_MAX_VAR_DIMS];
+gadouble  val,ulow,uhi;
+int8    *bval=NULL;
+uint8   *ubval=NULL;
+int16   *sval=NULL;
+uint16  *usval=NULL;
+int32   *ival=NULL;
+uint32  *uival=NULL;
+float32 *fval=NULL;
+size_t sz;
+
+  /* Get the vid if we haven't already done that for this file */
+  if (pvr->sdvid == -888) return(1);  /* already tried and failed */
+
+  sd_id = pfi->sdid; 
+  if (pvr->sdvid == -999) {
+
+    /* Get the variable index number from the variable name */
+    if (pvr->longnm[0] != '\0') {
+      v_id = SDnametoindex(sd_id, pvr->longnm);
+    }
+    else {
+      v_id = SDnametoindex(sd_id, pvr->abbrv);
+    }
+    if (v_id==FAIL) {
+      pvr->sdvid = -888;
+      if (pvr->longnm[0] != '\0') {
+	snprintf(pout,255,"Error: Variable %s not in HDF-SDS file\n",pvr->longnm);
+      }
+      else {
+	snprintf(pout,255,"Error: Variable %s not in HDF-SDS file\n",pvr->abbrv);
+      }
+      gaprnt(0,pout);
+      return (1);
+    }
+    pvr->sdvid = v_id; 
+
+    /* If undef attribute name is used, get the undef value */
+    if (pfi->undefattrflg) {
+      /* Select the variable (get sds_id) */
+      v_id = pvr->sdvid;
+      sds_id = SDselect(sd_id,v_id);
+      if (sds_id==FAIL) {
+	if (pvr->longnm[0] != '\0') {
+	  snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->longnm);
+	}
+	else {
+	  snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->abbrv);
+	}
+	gaprnt(0,pout);
+	return (1);
+      }
+      /* Retrieve the HDF undef attribute value */
+      if (hdfattr(sds_id, pfi->undefattr, &val) != 0) {
+	snprintf(pout,255,"Warning: Could not retrieve undef attribute \"%s\" -- using %g instead\n",
+		pfi->undefattr,pfi->undef);
+	gaprnt(1,pout);
+	pvr->undef = pfi->undef;
+      }
+      else {
+	pvr->undef = val;
+      }
+    }
+    /* If undef attribute name is not given, copy the file-wide undef */
+    else {
+      pvr->undef = pfi->undef;
+    }
+ 
+
+    /* If data are packed, get the scale factor and offset attribute values */
+    if (pfi->packflg) {
+      /* initialize values */
+      pvr->scale=1.0;
+      pvr->add=0.0;
+
+      /* Select the variable (get sds_id) */
+      v_id = pvr->sdvid;
+      sds_id = SDselect(sd_id,v_id);
+      if (sds_id==FAIL) {
+	if (pvr->longnm[0] != '\0') {
+	  snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->longnm);
+	}
+	else {
+	  snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->abbrv);
+	}
+	gaprnt(0,pout);
+	return (1);
+      }
+      /* Retrieve the scale factor attribute value */
+      if (pfi->packflg == 1 || pfi->packflg == 2) {
+	if (hdfattr(sds_id, pfi->scattr, &pvr->scale) != 0) {
+	  snprintf(pout,255,"Warning: Could not retrieve \"%s\" -- setting to 1.0\n",pfi->scattr);
+	  gaprnt(1,pout);
+	  pvr->scale = 1.0;
+	}
+      }
+      /* Retrieve the add offset attribute value if required */
+      if (pfi->packflg == 2 || pfi->packflg == 3) {
+	if (hdfattr(sds_id, pfi->ofattr, &pvr->add) != 0) {
+	  snprintf(pout,255,"Warning: Could not retrieve \"%s\" -- setting to 0.0\n",pfi->ofattr);
+	  gaprnt(1,pout);
+	  pvr->add = 0.0;
+	}
+      }
+    }
+  }
+
+  /* Select the variable (get sds_id) */
+  v_id = pvr->sdvid;
+  sds_id = SDselect(sd_id,v_id);
+
+  if (sds_id==FAIL) {
+    if (pvr->longnm[0] != '\0') {
+      snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->longnm);
+    }
+    else {
+      snprintf(pout,255,"Error: SDselect failed for %s \n",pvr->abbrv);
+    }
+    gaprnt(0,pout);
+    return (1);
+  }
+
+  /* Change the Y indexes if yrev flag is set */
+  if (pfi->yrflg) {
+    /* one day we might encounter a pre-projected file written upside down... */
+    if (pfi->ppflag)             
+      yy = pfi->ppjsiz - y;
+    else
+      yy = pfi->dnum[1] - y;
+  }
+  else {
+    yy = y-1;
+  }
+
+  /* Change the Z indexes if zrev flag is set */
+  if (pfi->zrflg) {
+    if (pvr->levels==0) {
+      zz=0;
+    }
+    else {
+      zz = pvr->levels-z;
+    }
+  } 
+  else {
+    zz = z-1;
+  }
+
+  /* Set up the start and count array.  The units records in the
+     descriptor file for each variable indicate the mapping of the 
+     hdf-sds variable shape into the grads dimensions */
+  for (i=0; i<16; i++) {
+    start[i] = -999;
+    count[i] = -999;
+    if (pvr->units[i] == -100) { start[i] = x-1; count[i] = len;}
+    if (pvr->units[i] == -101) { start[i] = yy;  count[i] = 1; }
+    if (pvr->units[i] == -102) { start[i] = zz;  count[i] = 1; }
+    if (pvr->units[i] == -103) { start[i] = t-1; count[i] = 1; }
+    if (pvr->units[i] == -104) { start[i] = e-1; count[i] = 1; }
+    if (pvr->units[i] >= 0) { start[i] = pvr->units[i];   count[i] = 1; }
+  }
+
+  /* Get the data type */
+  if (pvr->longnm[0] != '\0') {
+    rc = SDgetinfo(sds_id, pvr->longnm, &rank, dim_sizes, &data_dtype, &n_atts);
+  }
+  else {
+    rc = SDgetinfo(sds_id, pvr->abbrv,  &rank, dim_sizes, &data_dtype, &n_atts);
+  }
+
+  /* Data types that are handled are 8-bit ints (int8 and uint8), shorts (int16), 
+     ints (int32) and float. shorts and ints are converted to float. 
+     Unpacking done after I/O is finished  */
+  switch (data_dtype)
+  {
+    case (DFNT_INT8):   /* definition value 20 */
+      sz = len * sizeof (int8);
+      bval = (int8 *)galloc(sz,"bval3");
+      if (bval==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype INT8\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)bval) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype INT8\n");
+	gree(bval,"f126");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)bval[i];  /* Cast int8 to gadouble */
+      }
+      gree(bval,"f126");
+      break;
+
+    case (DFNT_UINT8):   /* definition value 21 */
+      sz = len * sizeof (uint8);
+      ubval = (uint8 *)galloc(sz,"ubval");
+      if (ubval==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype UINT8\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)ubval) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype UINT8\n");
+	gree(ubval,"f127");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)ubval[i];  /* Cast uint8 to gadouble */
+      }
+      gree(ubval,"f127");
+      break;
+
+    case (DFNT_INT16):    /* definition value 22 */
+      sz = len * sizeof(int16);
+      sval = (int16 *)galloc(sz,"sval3");
+      if (sval==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype INT16\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)sval) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype INT16\n");
+	return(1);
+      }
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)sval[i];  /* Cast int16 to gadouble */
+      }
+      gree(sval,"f128");
+      break;
+
+    case (DFNT_UINT16):   /* definition value 23 */
+      sz = len * sizeof (uint16);
+      usval = (uint16 *)galloc(sz,"usval");
+      if (usval==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype UINT16\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)usval) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype UINT16\n");
+	gree(usval,"f129");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)usval[i];  /* Cast uint16 to gadouble */
+      }
+      gree(usval,"f129");
+      break;
+
+    case (DFNT_INT32):    /* definition value 24 */
+      sz = len * sizeof (int32);
+      ival = (int32 *)galloc(sz,"ival3");
+      if (ival==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype INT32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)ival) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype INT32\n");
+	gree(ival,"f130");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)ival[i];  /* Cast int32 to gadouble */
+      }
+      gree(ival,"f130");
+      break;
+
+    case (DFNT_UINT32):   /* definition value 25 */
+      sz = len * sizeof (uint32);
+      uival = (uint32 *)galloc(sz,"uival");
+      if (uival==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype UINT32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)uival) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype UINT32\n");
+	gree(uival,"f131");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)uival[i];  /* Cast uint32 to gadouble */
+      }
+      gree(uival,"f131");
+      break;
+
+    case (DFNT_FLOAT32):  /* definition value  5 */
+      sz = len * sizeof (float32);
+      fval = (float32 *)galloc(sz,"fval");
+      if (fval==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype float32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)fval) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype float32\n");
+	gree(fval,"f131");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)fval[i];  /* Cast uint32 to gadouble */
+      }
+      gree(fval,"f131");
+      break;
+
+
+    case (DFNT_FLOAT64):  /* definition value  6 */
+      if (SDreaddata(sds_id, start, NULL, count, (VOIDP *)gr) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype FLOAT64\n");
+	return(1);
+      } 
+      break;
+
+    default:
+      snprintf(pout,255,"HDF-SDS Error: Data type %d not handled\n", data_dtype);
+      gaprnt(0,pout);
+      return(1);
+  };
+
+  /* Set missing data values to exact value if specified */
+  /* Use the gavar undef to set the fuzzy test limits */
+  /* If gavar undef equals zero, change it to 1/EPSILON */
+  if (dequal(pvr->undef, 0.0, 1.0e-08)==0) {   
+    ulow = 1e-5;
+  } 
+  else {
+    ulow = fabs(pvr->undef/EPSILON);   
+  }
+  uhi  = pvr->undef + ulow;
+  ulow = pvr->undef - ulow;
+  /* set the gagrid undef equal to the gafile undef */
+  pgr->undef = pfi->undef;           
+  
+  /* Do the NaN, Inf, and fuzzy test for undef values before unpacking */
+  for (i=0;i<len;i++) {
+    if ((*(gr+i) >= ulow && *(gr+i) <= uhi) || (isnan(*(gr+i))) || (isinf(*(gr+i)))) {
+      *(gru+i) = 0;
+    }
+    else {
+      /* Data is good */ 
+      *(gru+i) = 1;
+      /* unpack with scale and offset if necessary */
+      if (pfi->packflg) {
+	*(gr+i) = *(gr+i)*pvr->scale + pvr->add; 
+      }
+    }
+  }
+
+return (0);
+
+#endif
+  gaprnt(0,"Reading HDF-SDS files is not supported in this build\n");
+  return(1);
+}
+
+
+/* Sets up an hdf5 variable:
+     makes sure the variable exists in the file
+     gets the undef value
+     gets the scale factor and add offset attributes 
+*/
+
+gaint h5setup(void) {
+#if USEHDF5 == 1
+  hid_t vid=0, dsid, plid, tid;
+  gadouble val;
+  char *vname;
+  gaint i,ndims,rank; 
+  size_t size;
+  hsize_t *chsize=NULL,nelems;
+
+  if (pvr->h5vid == -888) return(1);  /* already tried and failed */
+  if (pvr->h5varflg > 0) vid = pvr->h5varflg;
+  if (pvr->dataspace > 0) dsid = pvr->dataspace;
+
+  /* get the variable name */
+  if (pvr->longnm[0] != '\0')
+    vname = pvr->longnm;
+  else
+    vname = pvr->abbrv;
+
+  /* Retrieve the HDF5 undef attribute value */
+  if (pfi->undefattrflg) {
+    if (h5attr(vid, vname, pfi->undefattr, &val) != 0) {
+      snprintf(pout,255,"h5setup warning: Could not retrieve undef attribute \"%s\" -- using %g instead\n",
+	      pfi->undefattr,pfi->undef);
+      gaprnt(1,pout);
+      pvr->undef = pfi->undef;
+    }
+    else {
+      pvr->undef = val;
+    }
+  }
+  else {
+    /* If no undef attribute name is given, copy the file-wide undef */
+    pvr->undef = pfi->undef;
+  }
+  
+  /* Retrieve the HDF5 scale factor and add offset attributes */
+  if (pfi->packflg) {
+    /* start with default values */
+    pvr->scale=1.0;
+    pvr->add=0.0;
+    
+    /* Retrieve the scale factor attribute value */
+    if (pfi->packflg == 1 || pfi->packflg == 2) {
+      if (h5attr(vid, vname, pfi->scattr, &val) != 0) {
+	snprintf(pout,255,"Warning: Could not retrieve \"%s\" -- setting to 1.0\n",pfi->scattr);
+	gaprnt(1,pout);
+      }
+      else { 
+	pvr->scale = val;
+      }
+    }
+    /* Retrieve the add offset attribute value if required */
+    if (pfi->packflg == 2 || pfi->packflg == 3) {
+      if (h5attr(vid, vname, pfi->ofattr, &val) != 0) {
+	snprintf(pout,255,"Warning: Could not retrieve \"%s\" -- setting to 0.0\n",pfi->ofattr);
+	gaprnt(1,pout);
+      }
+      else {
+	pvr->add = val;
+      }
+    }
+  }
+  
+  /* Check the chunk size */
+  ndims = pvr->nvardims;
+  if ((chsize = (hsize_t*)galloc(ndims*sizeof(hsize_t),"chsize"))!=NULL) {
+    if ((plid = H5Dget_create_plist(vid)) > 0) {
+      if ((rank = H5Pget_chunk(plid,ndims,chsize)) > 0) {
+	if ((tid  = H5Dget_type(vid)) > 0) {
+	  if ((size = H5Tget_size(tid)) > 0) {
+	    nelems = 1;
+	    for (i=0; i<ndims; i++) nelems *= chsize[i];
+	    if (nelems*size > pfi->cachesize) {
+	      gaprnt(1,"*** WARNING! ***\n");
+	      gaprnt(1,"*** The I/O for this variable will be extremely slow \n");
+	      gaprnt(1,"*** because the chunks are too big to fit in the cache \n");
+	      snprintf(pout,255,"*** chunk size = %ld bytes  (",(long)(nelems*size));
+	      gaprnt(1,pout);
+	      for (i=ndims-1; i>=0; i--) { 
+		snprintf(pout,255,"%ld * ",(long)chsize[i]); gaprnt(1,pout); 
+	      }
+	      snprintf(pout,255,"%ld bytes)\n",(long)size);
+	      gaprnt(1,pout);
+	      snprintf(pout,255,"*** cache size = %ld bytes \n",pfi->cachesize);
+	      gaprnt(1,pout);
+	      gaprnt(1,"*** There are two ways to control the cache size: \n");
+	      gaprnt(1,"*** add a CACHESIZE entry to the descriptor file \n");
+	      gaprnt(1,"*** or use the 'set cachesf' command \n");
+	      gaprnt(1,"*** Please read http://iges.org/grads/gadoc/compression.html \n");
+	    }
+	  }
+	}
+      }
+    }
+    gree(chsize,"f274");
+  }
+#endif
+  return(0); 
+}
+
+/* Opens an HDF5 variable and allocates the chunk cache 
+   takes a file id and a variable name as arguments
+   returns a dataspace id and variable id
+*/
+
+#if USEHDF5==1
+gaint h5openvar (gaint h5id, char *vname, hid_t *dataspace, hid_t *h5varflg) {
+  hid_t fid,vid,plid,dsid;
+  size_t nslots;
+  gadouble pp;
+
+  /* create a property list, and change the cache settings with two hard-coded args */ 
+  plid = H5Pcreate (H5P_DATASET_ACCESS);
+  nslots = 51203;
+  pp = 0.75;
+  H5Pset_chunk_cache(plid, nslots, pfi->cachesize, pp);
+
+  /* now open the variable with the modified property list */
+  fid = (hid_t)h5id;
+  vid = H5Dopen2 (fid, vname, plid);
+  if (vid<0) {
+    snprintf(pout,255,"Error: H5Dopen2 failed for variable %s \n",vname);
+    gaprnt(0,pout);
+    return (1); 
+  }
+
+  /* close the property list */
+  H5Pclose (plid);
+  
+  /* get variable's dataspace handle */
+  if ((dsid = H5Dget_space(vid))<0) {
+    gaprnt(0,"HDF5 Error: unable to retrieve data space\n");
+    return (1);
+  }  
+
+  /* success */
+  *h5varflg = vid;
+  *dataspace = dsid;
+  return (0);
+}
+#endif  
+
+/* close an HDF5 variable and relelase the chunk cache */
+
+#if USEHDF5==1
+gaint h5closevar (hid_t dsid, hid_t vid) {
+  /* release variable dataspace */
+  if (dsid > (hid_t)0) {
+    if ((H5Sclose(dsid))<0) {
+      snprintf(pout,255,"H5Sclose failed to close dataspace %d\n",(gaint)dsid);
+      gaprnt(1,pout);
+      return (1);
+    }
+  }
+  /* close variable */
+  if (vid > (hid_t)0) {
+    if ((H5Dclose(vid))<0) {
+      snprintf(pout,255,"H5Dclose failed to close varid %d\n",(gaint)vid);
+      gaprnt(1,pout);
+      return (1);
+    }
+  }
+  return (0);
+}
+#endif
+
+/* Read a row varying in the X direction from an HDF5 grid */
+gaint gah5row (gaint x, gaint y, gaint z, gaint t, gaint e, gaint len, gadouble *gr, char *gru) {
+#if USEHDF5 == 1
+gaint i,yy,zz;
+hsize_t  start[16], count[16];
+hid_t vid, datatype, memspace;
+size_t sz, datasize;
+H5T_class_t dataclass; 
+H5T_sign_t datasign;
+gadouble ulow,uhi;
+char *cval;
+unsigned char *ucval;
+short *sval;
+unsigned short *usval;
+int *ival;
+unsigned int *uival;
+long *lval;
+unsigned long *ulval;
+gafloat *fval;
+
+  /* copy the varid from the h5varflg */
+  vid = pvr->h5varflg;
+
+  /* Change the Y indexes if yrev flag is set */
+  if (pfi->yrflg) {
+    yy = pfi->dnum[1] - y;
+  }
+  else {
+    yy = y-1;
+  }
+
+  /* Change the Z indexes if zrev flag is set */
+  if (pfi->zrflg) {
+    if (pvr->levels==0) {
+      zz=0;
+    }
+    else {
+      zz = pvr->levels-z;
+    }
+  } 
+  else {
+    zz = z-1;
+  }
+
+  /* Set up the start and count array.  The units records in the
+     descriptor file for each variable indicate the mapping of the 
+     hdf-sds variable shape into the grads dimensions */
+  for (i=0; i<16; i++) {
+    start[i] = -999;
+    count[i] = -999;
+    if (pvr->units[i] == -100) { start[i] = x-1; count[i] = len; }
+    if (pvr->units[i] == -101) { start[i] = yy;  count[i] = 1;   }
+    if (pvr->units[i] == -102) { start[i] = zz;  count[i] = 1;   }
+    if (pvr->units[i] == -103) { start[i] = t-1; count[i] = 1;   }
+    if (pvr->units[i] == -104) { start[i] = e-1; count[i] = 1;   }
+    if (pvr->units[i] >= 0) { start[i] = pvr->units[i];   count[i] = 1; }
+  }
+
+  /* select the desired hyperslab in the source dataspace */
+  if ((H5Sselect_hyperslab(pvr->dataspace, H5S_SELECT_SET, start, NULL, count, NULL))<0) {
+    gaprnt(0,"HDF5 Error: unable to select dataspace hyperslab\n");
+    return (1);
+  }
+  /* create a new destination dataspace  and open it for access */
+  if ((memspace  = H5Screate_simple(pvr->nvardims,count,NULL))<0) {
+    gaprnt(0,"HDF5 Error: unable to create memspace\n");
+    return (1);
+  }
+  /* Get the data type, class, and size */
+  if ((datatype = H5Dget_type(vid))<0) {
+    gaprnt(0,"HDF5 Error: unable to retrieve data type\n");
+    return (1);
+  }
+  if ((dataclass = H5Tget_class(datatype))<0) {
+    gaprnt(0,"HDF5 Error: unable to retrieve data class\n");
+    return (1);
+  }
+  if ((datasize = H5Tget_size(datatype))<0) {
+    gaprnt(0,"HDF5 Error: unable to retrieve data size\n");
+    return (1);
+  }
+
+  if (dataclass == H5T_FLOAT) {
+    if (datasize == 4) {
+      sz = len * sizeof (gafloat);
+      if ((fval = (gafloat *)galloc(sz,"fval")) == NULL) {
+	gaprnt(0,"HDF5 Error: unable to allocate memory for float data\n"); return(1);
+      }
+      if ((H5Dread(vid, H5T_NATIVE_FLOAT, memspace, pvr->dataspace, H5P_DEFAULT, fval)) < 0) {
+	gaprnt(0,"HDF5 read error for float data \n");
+	gree(fval,"f131a");
+	return(1);
+      } 
+      else {
+	for (i=0; i<len; i++) gr[i] = (gadouble)fval[i]; 
+      }
+      gree(fval,"f131a");
+    }
+    else if (datasize == 8) {
+      if ((H5Dread(vid, H5T_NATIVE_DOUBLE, memspace, pvr->dataspace, H5P_DEFAULT, gr)) < 0) {
+	gaprnt(0,"HDF5 read error for double data \n"); return(1);
+      } 
+    }
+    else {
+      snprintf(pout,255,"H5T_FLOAT of size %d not handled\n",(int)datasize);
+      gaprnt(0,pout);
+      return (1);
+    }
+  }
+  else if (dataclass == H5T_INTEGER) {
+    /* signed or unsigned? */
+    if ((datasign = H5Tget_sign(datatype))<0) {
+      gaprnt(2,"H5Tget_sign failed\n"); return (1);
+    } 
+    /* byte */
+    if (datasize == 1) {
+      if (datasign==H5T_SGN_NONE) {  
+	sz = len * sizeof (unsigned char);
+	if ((ucval = (unsigned char *)galloc(sz,"ucval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for unsigned char data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_UCHAR, memspace, pvr->dataspace, H5P_DEFAULT, ucval))<0) {
+	  gaprnt(0,"H5Dread failed for unsigned char data \n"); 
+	  gree(ucval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)ucval[i];  
+	}
+	gree(ucval,"f131b");
+      }
+      else {
+	sz = len * sizeof (char);
+	if ((cval = (char *)galloc(sz,"cval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for char data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_CHAR, memspace, pvr->dataspace, H5P_DEFAULT, cval))<0) {
+	  gaprnt(0,"H5Dread failed for char data \n"); 
+	  gree(cval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)cval[i];  
+	}
+	gree(cval,"f131b");
+      }
+    }
+    /* short */
+    else if (datasize == 2) {
+      if (datasign==H5T_SGN_NONE) {  
+	sz = len * sizeof (unsigned short);
+	if ((usval = (unsigned short *)galloc(sz,"usval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for unsigned short data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_USHORT, memspace, pvr->dataspace, H5P_DEFAULT, usval))<0) {
+	  gaprnt(0,"H5Dread failed for unsigned short data \n"); 
+	  gree(usval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)usval[i];  
+	}
+	gree(usval,"f131b");
+      }
+      else {
+	sz = len * sizeof (short);
+	if ((sval = (short *)galloc(sz,"sval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for short data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_SHORT, memspace, pvr->dataspace, H5P_DEFAULT, sval))<0) {
+	  gaprnt(0,"H5Dread failed for short data \n"); 
+	  gree(sval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)sval[i];  
+	}
+	gree(sval,"f131b");
+      }
+    }
+    /* int */
+    else if (datasize == 4) {
+      if (datasign==H5T_SGN_NONE) {  
+	sz = len * sizeof (unsigned int);
+	if ((uival = (unsigned int *)galloc(sz,"uival")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for unsigned int data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_UINT, memspace, pvr->dataspace, H5P_DEFAULT, uival))<0) {
+	  gaprnt(0,"H5Dread failed for unsigned int data \n"); 
+	  gree(uival,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)uival[i];  
+	}
+	gree(uival,"f131b");
+      }
+      else {
+	sz = len * sizeof (int);
+	if ((ival = (int *)galloc(sz,"ival")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for int data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_INT, memspace, pvr->dataspace, H5P_DEFAULT, ival))<0) {
+	  gaprnt(0,"H5Dread failed for int data \n"); 
+	  gree(ival,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)ival[i];  
+	}
+	gree(ival,"f131b");
+      }
+    }
+    /* long */
+    else if (datasize == 8) {
+      if (datasign==H5T_SGN_NONE) {  
+	sz = len * sizeof (unsigned long);
+	if ((ulval = (unsigned long *)galloc(sz,"ulval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for unsigned long data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_ULONG, memspace, pvr->dataspace, H5P_DEFAULT, ulval))<0) {
+	  gaprnt(0,"H5Dread failed for unsigned long data \n"); 
+	  gree(ulval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)ulval[i];  
+	}
+	gree(ulval,"f131b");
+      }
+      else {
+	sz = len * sizeof (long);
+	if ((lval = (long *)galloc(sz,"lval")) == NULL) {
+	  gaprnt(0,"HDF5 Error: unable to allocate memory for long data\n"); return(1);
+	}
+	if ((H5Dread(vid, H5T_NATIVE_LONG, memspace, pvr->dataspace, H5P_DEFAULT, lval))<0) {
+	  gaprnt(0,"H5Dread failed for long data \n"); 
+	  gree(lval,"f131b");
+	  return (1);
+	}
+	else {
+	  for (i=0; i<len; i++) gr[i] = (gadouble)lval[i];  
+	}
+	gree(lval,"f131b");
+      }
+    }
+    else {
+      snprintf(pout,255,"H5T_INTEGER of size %d not handled\n",(int)datasize);
+      gaprnt(2,pout);
+      return (1);
+    }
+  }
+  else {
+    snprintf(pout,255,"HDF5 Error: Data class %d not handled\n", dataclass);
+    gaprnt(0,pout);
+    return(1);
+  }
+
+  /* Set missing data values to exact value if specified */
+  /* Use the gavar undef to set the fuzzy test limits */
+  /* If gavar undef equals zero, change it to 1/EPSILON */
+  if (dequal(pvr->undef, 0.0, 1.0e-08)==0) {   
+    ulow = 1e-5;
+  } 
+  else {
+    ulow = fabs(pvr->undef/EPSILON);   
+  }
+  uhi  = pvr->undef + ulow;
+  ulow = pvr->undef - ulow;
+  /* set the gagrid undef equal to the gafile undef */
+  pgr->undef = pfi->undef;           
+  
+  /* Do the NaN, Inf, and fuzzy test for undef values before unpacking */
+  for (i=0;i<len;i++) {
+    if ((*(gr+i) >= ulow && *(gr+i) <= uhi) || (isnan(*(gr+i))) || (isinf(*(gr+i)))) {
+      *(gru+i) = 0;
+    }
+    else {
+      /* Data is good */ 
+      *(gru+i) = 1;
+      /* unpack with scale and offset if necessary */
+      if (pfi->packflg) {
+	*(gr+i) = *(gr+i)*pvr->scale + pvr->add; 
+      }
+    }
+  }
+  /* clean up HDF5 resources */
+  H5Tclose(datatype);
+  H5Sclose(memspace);
+
+
+return (0);
+
+#endif
+  gaprnt(0,"Reading HDF5 grids is not supported in this build\n");
+  return(1);
+}
+
+/* Retrieves a numeric HDF5 Attribute. */
+
+gaint h5attr(gaint varid, char *vname, char *aname, gadouble *value) {
+#if USEHDF5 == 1
+hid_t vid,aid,atype,aspace,rc;    
+H5T_class_t aclass;
+H5T_sign_t asign;
+size_t asize;
+gaint rank;
+char cval;
+unsigned char ucval;
+short sval;
+unsigned short usval;
+gaint ival;
+gauint uival;
+long lval;
+unsigned long ulval;
+float fval;
+gadouble dval;
+
+  vid=(hid_t)varid;
+
+  /* get the attribute id */
+  if ((aid = H5Aopen_by_name(vid, vname, aname, H5P_DEFAULT, H5P_DEFAULT))<0) {
+    snprintf(pout,255,"HDF5 attribute named \"%s\" does not exist\n",aname);
+    gaprnt(2,pout);
+    return(1);
+  } 
+  /* get the attribute rank, make sure it is 1 */
+  if ((aspace = H5Aget_space(aid))<0) { gaprnt(2,"H5Aget_space failed\n"); return (1); }
+  if ((rank   = H5Sget_simple_extent_ndims(aspace))!=1) { gaprnt(2,"rank != 1\n"); return (1); }
+  /* get the attribute type, class, and size */
+  if ((atype  = H5Aget_type(aid))<0) { gaprnt(2,"H5Aget_type failed\n"); return (1); } 
+  if ((aclass = H5Tget_class(atype))<0) { gaprnt(2,"H5Tget_class failed\n"); return (1); } 
+  if ((asize  = H5Tget_size(atype))<0) { gaprnt(2,"H5Tget_size failed\n"); return (1); } 
+  
+  if (aclass == H5T_FLOAT) {
+    if (asize == 4) {
+      if ((rc = H5Aread(aid,H5T_NATIVE_FLOAT,(void*)&fval))<0) {
+	gaprnt(2,"H5Aread failed\n"); return (1);
+      }
+      *value = (gadouble)fval;
+    }
+    else if (asize == 8) {
+      if ((rc = H5Aread(aid,H5T_NATIVE_DOUBLE,(void*)&dval))<0) {
+	gaprnt(2,"H5Aread failed\n"); return (1);
+      }
+      *value = dval;
+    } 
+    else {
+      gaprnt(2,"H5T_FLOAT attribute size is not 4 or 8\n");
+      return (1);
+    }
+  }
+  else if (aclass == H5T_INTEGER) {
+    /* signed or unsigned? */
+    if ((asign = H5Tget_sign(atype))<0) { gaprnt(2,"H5Tget_sign failed\n"); return (1); } 
+    /* byte */
+    if (asize == 1) {
+      if (asign==H5T_SGN_NONE) {  
+	if ((rc = H5Aread(aid,H5T_NATIVE_UCHAR,(void*)&ucval))<0) {
+	  gaprnt(2,"H5Aread failed for type UCHAR\n"); return (1);
+	}
+	*value = (gadouble)ucval;
+      }
+      else {
+	if ((rc = H5Aread(aid,H5T_NATIVE_CHAR,(void*)&cval))<0) {
+	  gaprnt(2,"H5Aread failed for type CHAR\n"); return (1);
+	}
+	*value = (gadouble)cval;
+      }
+    }
+    /* short */
+    else if (asize == 2) {
+      if (asign==H5T_SGN_NONE) {  
+	if ((rc = H5Aread(aid,H5T_NATIVE_USHORT,(void*)&usval))<0) {
+	  gaprnt(2,"H5Aread failed for type USHORT\n"); return (1);
+	}
+	*value = (gadouble)usval;
+      }
+      else {
+	if ((rc = H5Aread(aid,H5T_NATIVE_SHORT,(void*)&sval))<0) {
+	  gaprnt(2,"H5Aread failed for type SHORT\n"); return (1);
+	}
+	*value = (gadouble)sval;
+      }
+    }
+    /* int */
+    else if (asize == 4) {
+      if (asign==H5T_SGN_NONE) {  
+	if ((rc = H5Aread(aid,H5T_NATIVE_UINT,(void*)&uival))<0) {
+	  gaprnt(2,"H5Aread failed for type UINT\n"); return (1);
+	}
+	*value = (gadouble)uival;
+      }
+      else {
+	if ((rc = H5Aread(aid,H5T_NATIVE_INT,(void*)&ival))<0) {
+	  gaprnt(2,"H5Aread failed for type INT\n"); return (1);
+	}
+	*value = (gadouble)ival;
+      }
+    }
+    /* long */
+    else if (asize == 8) {
+      if (asign==H5T_SGN_NONE) {  
+	if ((rc = H5Aread(aid,H5T_NATIVE_ULONG,(void*)&ulval))<0) {
+	  gaprnt(2,"H5Aread failed for type ULONG\n"); return (1);
+	}
+	*value = (gadouble)ulval;
+      }
+      else {
+	if ((rc = H5Aread(aid,H5T_NATIVE_LONG,(void*)&lval))<0) {
+	  gaprnt(2,"H5Aread failed for type LONG\n"); return (1);
+	}
+	*value = (gadouble)lval;
+      }
+    }
+    else {
+      gaprnt(2,"H5T_INTEGER attribute size is not 1, 2, 4, or 8\n");
+      return (1);
+    }
+  }
+  else {
+    gaprnt(2,"HDF5 attribute is not a numeric data type \n");
+    return(1);
+  }
+  
+  H5Aclose(aid);
+  H5Tclose(atype);
+  return (0);
+
+#endif
+  return(0);
+}
+
+
+/* Retrieves a non-character HDF-SDS Attribute. */
+
+gaint hdfattr(gaint sds_id, char *attr_name, gadouble *value) {
+#if USEHDF == 1
+int32   attr_index, attr_dtype, attr_count;
+int8    *battr_val;
+uint8   *ubattr_val;
+int16   *sattr_val;
+uint16  *usattr_val;
+int32   *iattr_val;
+uint32  *uiattr_val;
+float32 *fattr_val;
+float64 *dattr_val;
+size_t sz;
+
+  /* Get the attribute index number from its name */
+  attr_index = SDfindattr(sds_id, attr_name);
+  if (attr_index == -1) {
+    snprintf(pout,255,"Warning: HDF attribute named \"%s\" does not exist\n",attr_name);
+    gaprnt(1,pout);
+    return(1);
+  } 
+
+  /* Get info about the attribute, make sure there's only one value */
+  if (SDattrinfo(sds_id, attr_index, attr_name, &attr_dtype, &attr_count) == -1) {
+    gaprnt(1,"Warning: SDattrinfo failed\n");
+    return(1);
+  } 
+  else {
+    if (attr_count != 1) {
+      snprintf(pout,255,"Warning: HDF attribute named \"%s\" has more than one value\n",attr_name);
+      gaprnt(1,pout);
+      return(1);
+    }
+
+    /* Read the attribute value */
+    switch (attr_dtype)
+      {
+      case (DFNT_INT8):    /* definition value 20 */
+	sz = attr_count * sizeof (int8);
+	battr_val = galloc(sz,"battrval");
+	if (SDreadattr(sds_id, attr_index, battr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type INT8\n");
+	  return(1);
+	}
+	else {
+	  *value = *battr_val;
+	}
+	gree(battr_val,"f132");
+	break;
+	
+      case (DFNT_UINT8):    /* definition value 21 */
+	sz = attr_count * sizeof (uint8);
+	ubattr_val = galloc(sz,"ubattrval");
+	if (SDreadattr(sds_id, attr_index, ubattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type UINT8\n");
+	  return(1);
+	}
+	else {
+	  *value = *ubattr_val;
+	}
+	gree(ubattr_val,"f132a");
+	break;
+	
+      case (DFNT_INT16):    /* definition value 22 */
+	sz = attr_count * sizeof (int16);
+	sattr_val = galloc(sz,"sattrval");
+	if (SDreadattr(sds_id, attr_index, sattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type INT16\n");
+	  return(1);
+	}
+	else {
+	  *value = *sattr_val;
+	}
+	gree(sattr_val,"f133");
+	break;
+	
+      case (DFNT_UINT16):   /* definition value 23 */
+	sz = attr_count * sizeof (uint16);
+	usattr_val = galloc(sz,"usattrval");
+	if (SDreadattr(sds_id, attr_index, usattr_val) == -1)  {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type UINT16\n");
+	  return(1);
+	}
+	else {
+	  *value = *usattr_val;
+	}
+	gree(usattr_val,"f134");
+	break;
+	
+      case (DFNT_INT32):    /* definition value 24 */
+	sz = attr_count * sizeof (int32);
+	iattr_val = galloc(sz,"iattrval");
+	if (SDreadattr(sds_id, attr_index, iattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type INT32\n");
+	  return(1);
+	}
+	else {
+	  *value = *iattr_val;
+	}
+	gree(iattr_val,"f135");
+	break;
+	
+      case (DFNT_UINT32):   /* definition value 25 */
+	sz = attr_count * sizeof (uint32);
+	uiattr_val = galloc(sz,"uiattrval");
+	if (SDreadattr(sds_id, attr_index, uiattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type UINT32\n");
+	  return(1);
+	}
+	else {
+	  *value = *uiattr_val;
+	}
+	gree(uiattr_val,"f136");
+	break;
+	
+      case (DFNT_FLOAT32):  /* definition value  5 */
+	sz = attr_count * sizeof (float32);
+	fattr_val = galloc(sz,"fattrval");
+	if (SDreadattr(sds_id, attr_index, fattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type FLOAT32\n");
+	  return(1);
+	}
+	else {
+	  *value = *fattr_val;
+	}
+	gree(fattr_val,"f137");
+	break;
+	
+      case (DFNT_FLOAT64):  /* definition value  6 */
+	sz = attr_count * sizeof (float64);
+	dattr_val = galloc(sz,"dattrval");
+	if (SDreadattr(sds_id, attr_index, dattr_val) == -1) {
+	  gaprnt(1,"Warning: SDreadattr failed for attribute type FLOAT64\n");
+	  return(1);
+	}
+	else {
+	  *value = *dattr_val;
+	}
+	gree(dattr_val,"f138");
+	break;
+	
+      default:
+	snprintf(pout,255,"Warning: HDF Attribute \"%s\" is not a numeric data type (%d)\n", 
+		attr_name, attr_dtype);
+	gaprnt(1,pout);
+	return(1);
+      };
+  }
+  return(0);
+
+#endif
+  gaprnt(0,"Reading HDF-SDS files is not supported in this build\n");
+  return(1);
+}
+
+
+/* Subroutine to print out NetCDF attributes */
+gaint ncpattrs(gaint ncid, char *varnam, char *abbrv, gaint hdrflg, gaint fnum, char* ftit) {
+#if USENETCDF == 1
+gadouble *dattr_val;
+gafloat  *fattr_val;
+long   *iattr_val;
+short  *sattr_val;
+char   *cattr_val;
+char   *battr_val;
+char attr_name[MAX_NC_NAME];
+nc_type attr_dtype;
+gaint error=0, aindx=-999, rc, i, varid, n_atts;
+size_t sz,asize;
+
+/* Get the variable id and number of attributes */
+  if (cmpwrd("global",abbrv)) {
+    varid = NC_GLOBAL;
+    rc = nc_inq_natts(ncid,&n_atts);
+    if (rc != NC_NOERR) error=1;
+  }
+  else {
+    rc = nc_inq_varid(ncid, varnam, &varid);
+    if (rc != NC_NOERR) error=1;
+    if (!error) {
+      rc = nc_inq_varnatts(ncid, varid, &n_atts);
+      if (rc != NC_NOERR) error=1;
+    }
+  }
+
+  /* Print out the header */
+  if (!error) {
+    if (hdrflg) {
+      if (n_atts > 0) {
+	snprintf(pout,255,"Native Attributes for File %i : %s \n",fnum,ftit);
+	gaprnt(2,pout);
+      }
+    }
+  }
+  else {
+    return(0);  /* zero attributes printed */
+  }
+  
+  /* Loop through list of attributes, print the name of each one */ 
+  for (aindx=0; aindx<n_atts; aindx++) {
+
+    /* Get current attribute's name */
+    if (nc_inq_attname(ncid, varid, aindx, attr_name) == -1) {
+      snprintf(pout,255,"nc_inq_attname failed for variable %s, attribute number %d\n", abbrv, aindx);
+      gaprnt(2,pout);
+    }
+    else {
+      /* Get current attribute's data type and length */
+      if (nc_inq_att(ncid, varid, attr_name, &attr_dtype, &asize) == -1) {
+	snprintf(pout,255,"nc_inq_att failed for variable %s, attribute number %d\n", abbrv, aindx);
+	gaprnt(2,pout);
+      }
+      else {
+        if (asize>0) {
+	  /* Retrieve and print out the attribute */
+	  switch (attr_dtype) 
+	    {
+	    case (NC_BYTE):
+	      sz = (asize+1) * sizeof (NC_BYTE);
+	      battr_val = (char *) galloc(sz,"battrval1");
+	      if (nc_get_att_schar(ncid, varid, attr_name, (signed char*)battr_val) == -1) {
+		gaprnt(2,"nc_get_att_schar failed for type NC_BYTE\n"); 
+	      }
+	      else {
+		gaprnt(2,abbrv); 
+		gaprnt(2," Byte "); 
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		for (i=0; i<asize; i++) {
+		  snprintf(pout,255,"%d ", (gaint)(battr_val[i])); 
+		  gaprnt(2,pout);
+		}
+		gaprnt(2,"\n");
+	      }
+	      gree(battr_val,"f139");
+	      break;
+	    case (NC_CHAR):
+	      sz = (asize+1) * sizeof (NC_CHAR);
+	      cattr_val = (char *) galloc(sz,"cattrval1");
+	      if (nc_get_att_text(ncid, varid, attr_name, cattr_val) == -1) {
+		gaprnt(2,"nc_get_att_text failed for type NC_CHAR\n"); 
+	      }
+	      else {
+		cattr_val[asize]='\0';
+		gaprnt(2,abbrv); 
+		gaprnt(2," String ");
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		prntwrap(abbrv, attr_name, cattr_val);
+	      }
+	      gree(cattr_val,"f140");
+	      break;
+	    case (NC_SHORT):
+	      sz = asize * sizeof (NC_SHORT);
+	      sattr_val = (short *) galloc(sz,"sattrval1");
+	      if (nc_get_att_short(ncid, varid, attr_name, sattr_val) == -1) {
+		gaprnt(2,"nc_get_att_short failed for type NC_SHORT\n"); 
+	      }
+	      else {
+		gaprnt(2,abbrv); 
+		gaprnt(2," Int16 "); 
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		for (i=0; i<asize; i++) {
+		  snprintf(pout,255,"%d", (gaint)(sattr_val[i])); 
+		  gaprnt(2,pout);
+		  if (i<asize-1) gaprnt(2,",");
+		}
+		gaprnt(2,"\n");
+	      }
+	      gree(sattr_val,"f141");
+	      break;
+	    case (NC_LONG):
+	      sz = asize * sizeof (NC_LONG);
+	      iattr_val = (long *) galloc(sz,"iattrval1");
+	      if (nc_get_att_long(ncid, varid, attr_name, iattr_val) == -1) {
+		gaprnt(2,"nc_get_att_long failed for type NC_LONG\n"); 
+	      }
+	      else {
+		gaprnt(2,abbrv); 
+		gaprnt(2," Int32 "); 
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		for (i=0; i<asize; i++) {
+		  snprintf(pout,255,"%ld", iattr_val[i]); 
+		  gaprnt(2,pout);
+		  if (i<asize-1) gaprnt(2,",");
+		}
+		gaprnt(2,"\n");
+	      }
+	      gree(iattr_val,"f142");
+	      break;
+	    case (NC_FLOAT):
+	      sz = asize * sizeof (gafloat);
+	      fattr_val = (gafloat *) galloc(sz,"fattrval1");
+	      if (nc_get_att_float(ncid, varid, attr_name, fattr_val) == -1) {
+		gaprnt(2,"nc_get_att_float failed for type NC_FLOAT\n"); 
+	      }
+	      else {
+		gaprnt(2,abbrv); 
+		gaprnt(2," Float32 "); 
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		for (i=0; i<asize; i++) {
+		  snprintf(pout,255,"%g", fattr_val[i]);
+		  gaprnt(2,pout);
+		  if (i<asize-1) gaprnt(2,",");
+		}
+		gaprnt(2,"\n");
+	      }
+	      gree(fattr_val,"f143");
+	      break;
+	    case (NC_DOUBLE): 
+	      sz = asize * sizeof (gadouble);
+	      dattr_val = (gadouble *) galloc(sz,"dattrval1");
+	      if (nc_get_att_double(ncid, varid, attr_name, dattr_val) == -1) {
+		gaprnt(2,"nc_get_att_double failed for type NC_FLOAT\n"); 
+	      }
+	      else {
+		gaprnt(2,abbrv); 
+		gaprnt(2," Float64 "); 
+		gaprnt(2,attr_name); 
+		gaprnt(2," ");
+		for (i=0; i<asize; i++) {
+		  snprintf(pout,255,"%g", dattr_val[i]); 
+		  gaprnt(2,pout);
+		  if (i<asize-1) gaprnt(2,",");
+		}
+		gaprnt(2,"\n");
+	      }
+	      gree(dattr_val,"f144");
+	      break;
+	    default:
+	      snprintf(pout,255,"Failed to retrieve attribute %d of type %d \n", aindx, attr_dtype);
+	      gaprnt(2,pout);
+	    };
+	} /* end of if statement for asize >0 */
+      } /* end of if-else statement for ncattinq */
+    } /* end of if-else statement for ncattname */
+  } /* end of for loop on aindx */
+  return(n_atts);
+#endif
+  gaprnt(0,"Reading NetCDF attributes is not supported in this build\n");
+  return(1);
+}
+
+
+/* Subroutine to print out HDF attributes */
+gaint hdfpattrs(gaint sdid, char *varname, char *abbrv, gaint hdrflg, gaint fnum, char* ftit) {
+#if USEHDF == 1
+gaint     attr_index, rc, i;
+char    attr_name[H4_MAX_NC_NAME];
+int32   attr_dtype, attr_count;
+char8   *cattr_val=NULL;
+uchar8  *ucattr_val=NULL;
+int8    *icattr_val=NULL;
+uint8   *uicattr_val=NULL;
+int16   *sattr_val=NULL;
+uint16  *usattr_val=NULL;
+int32   *iattr_val=NULL;
+uint32  *uiattr_val=NULL;
+float32 *fattr_val=NULL;
+float64 *dattr_val=NULL;
+gaint error=0;
+char name[H4_MAX_NC_NAME];
+int32 sds_id, n_atts, n_dsets, rank, type, dim_sizes[4];
+size_t sz;
+
+  /* Get the dataset id and number of attributes */
+  if (cmpwrd("global",abbrv)) {
+    sds_id = sdid;
+    rc = SDfileinfo(sdid, &n_dsets, &n_atts);
+    if (rc == -1) error=1;
+  }
+  else {
+    sds_id = SDnametoindex(sdid, varname);
+    if (sds_id == -1) error=1;
+    if (!error) {
+      sds_id = SDselect(sdid,sds_id);
+      rc = SDgetinfo(sds_id, name, &rank, dim_sizes, &type, &n_atts);
+      if (rc == -1) error=1;
+    }
+  }
+  /* Print out the header */
+  if (!error) {
+    if (hdrflg) {
+      if (n_atts > 0) {
+	snprintf(pout,255,"Native Attributes for File %i : %s \n",fnum,ftit);
+	gaprnt(2,pout);
+      }
+    }
+  }
+  else {
+    return(0);  /* zero attributes printed */
+  }
+
+  /* Loop through list of attributes, print the name of each one */ 
+  for (attr_index = 0 ; attr_index < n_atts ; attr_index++) {
+	 
+    /* Get info about the current attribute and then print out Name, Type, and Value */
+    if (SDattrinfo(sds_id, attr_index, attr_name, &attr_dtype, &attr_count) == -1) {
+      snprintf(pout,255,"SDattrinfo failed for variable %s, attribute number %d\n", abbrv, attr_index);
+      gaprnt(2,pout);
+    }
+    else {
+      switch (attr_dtype) 
+	{
+	case (DFNT_CHAR8):    /* definition value 4 */
+	  sz = (attr_count+1) * sizeof (char8);
+	  cattr_val = (char8*)galloc(sz,"cattrval2");
+	  if (SDreadattr(sds_id, attr_index, cattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type CHAR8\n"); 
+	  }
+	  else {
+	    cattr_val[attr_count]='\0';
+	    snprintf(pout,255,"%s String %s ",abbrv,attr_name); 
+	    gaprnt(2,pout);
+	    prntwrap(abbrv, attr_name, cattr_val);
+	  }
+	  gree(cattr_val,"f145");
+	  break;
+	case (DFNT_UCHAR8):   /* definition value 3 */
+	  sz = (attr_count+1) * sizeof (uchar8);
+	  ucattr_val = (uchar8*)galloc(sz,"ucattrval");
+	  if (SDreadattr(sds_id, attr_index, ucattr_val) == -1) { 
+	    gaprnt(2,"SDreadattr failed for type UCHAR8\n"); 
+	  }
+	  else {
+	    ucattr_val[attr_count]='\0';
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," String ");
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    prntwrap(abbrv, attr_name, (char*)ucattr_val);
+	  }
+	  gree(ucattr_val,"f146");
+	  break;
+	case (DFNT_INT8):     /* definition value 20 */
+	  sz = (attr_count+1) * sizeof (int8);
+	  icattr_val = (int8*)galloc(sz,"icattrval2");
+	  if (SDreadattr(sds_id, attr_index, icattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type INT8\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Byte "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%d ", (gaint)(icattr_val[i])); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(icattr_val,"f147");
+	  break;
+	case (DFNT_UINT8):    /* definition value 21 */
+	  sz = attr_count * sizeof (uint8);
+	  uicattr_val = (uint8*)galloc(sz,"uicattrval");
+	  if (SDreadattr(sds_id, attr_index, cattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type UINT8\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Byte "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%u ", (gauint)(uicattr_val[i])); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(uicattr_val,"f148");
+	  break;
+	case (DFNT_INT16):    /* definition value 22 */
+	  sz = attr_count * sizeof (int16);
+	  sattr_val = (int16*)galloc(sz,"sattrval2");
+	  if (SDreadattr(sds_id, attr_index, sattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type INT16\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Int16 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%d ", (gaint)(sattr_val[i])); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(sattr_val,"f149");
+	  break;
+	case (DFNT_UINT16):   /* definition value 23 */
+	  sz = attr_count * sizeof (uint16);
+	  usattr_val = (uint16*)galloc(sz,"usattrval2");
+	  if (SDreadattr(sds_id, attr_index, usattr_val) == -1) { 
+	    gaprnt(2,"SDreadattr failed for type UINT16\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," UInt16 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%u ", (gauint)(usattr_val[i])); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(usattr_val,"f150");
+	  break;
+	case (DFNT_INT32):    /* definition value 24 */
+	  sz = attr_count * sizeof (int32);
+	  iattr_val = (int32*)galloc(sz,"iattrval3");
+	  if (SDreadattr(sds_id, attr_index, iattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type INT32\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Int32 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%d ", iattr_val[i]); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(iattr_val,"f151");
+	  break;
+	case (DFNT_UINT32):   /* definition value 25 */
+	  sz = attr_count * sizeof (uint32);
+	  uiattr_val = (uint32*)galloc(sz,"uiattrval3");
+	  if (SDreadattr(sds_id, attr_index, uiattr_val) == -1) { 
+	    gaprnt(2,"SDreadattr failed for type UINT32\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," UInt32 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%u ", uiattr_val[i]); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(uiattr_val,"f152");
+	  break;
+	case (DFNT_FLOAT32):  /* definition value  5 */
+	  sz = attr_count * sizeof (float32);
+	  fattr_val = (float32*)galloc(sz,"fattrval3");
+	  if (SDreadattr(sds_id, attr_index, fattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type FLOAT32\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Float32 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%g ", fattr_val[i]);
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(fattr_val,"f153");
+	  break;
+	case (DFNT_FLOAT64):  /* definition value  6 */
+	  sz = attr_count * sizeof (float64);
+	  dattr_val = (float64*)galloc(sz,"dattrval3");
+	  if (SDreadattr(sds_id, attr_index, dattr_val) == -1) {
+	    gaprnt(2,"SDreadattr failed for type FLOAT64\n"); 
+	  }
+	  else {
+	    gaprnt(2,abbrv); 
+	    gaprnt(2," Float64 "); 
+	    gaprnt(2,attr_name); 
+	    gaprnt(2," ");
+	    for (i=0; i<attr_count; i++) {
+	      snprintf(pout,255,"%g ", dattr_val[i]); 
+	      gaprnt(2,pout);
+	    }
+	    gaprnt(2,"\n");
+	  }
+	  gree(dattr_val,"f154");
+	  break;
+	default:
+	  snprintf(pout,255,"Failed to retrieve attribute %d of type %d \n", attr_index, attr_dtype);
+	  gaprnt(2,pout);
+	};
+    }  /* end of if-else statment following call to SDattrinfo */
+  } 
+  return(n_atts);
+#endif
+  gaprnt(0,"Reading HDF-SDS attributes is not supported in this build\n");
+  return(1);
+}
+
+/* Subroutine to print out HDF5 (variable) attributes */
+gaint h5pattrs(gaint fid, char *vname, char *abbrv, gaint hdrflg, gaint fnum, char* ftit) {
+#if USEHDF5 == 1
+H5O_info_t oinfo;
+H5T_class_t aclass=-1;
+H5T_sign_t asign;
+hid_t   h5id,vid,dsid,aid,atype=-1,aspace=-1;
+hsize_t ai,stosize;
+size_t sz,asize,len=0;
+gaint   aindex,n_atts=0,rc,i,rank=-1,err=0;
+char    *aname=NULL;
+char    *cval=NULL,*string=NULL;
+unsigned char *ucval=NULL;
+short   *sval=NULL;
+unsigned short  *usval=NULL;
+gaint   *ival=NULL;
+gauint  *uival=NULL;
+long    *lval=NULL;
+unsigned long *ulval=NULL;
+gafloat  *fval=NULL;
+gadouble *dval=NULL;
+
+
+  /* Get the variable id and number of attributes */
+  h5id = (hid_t)fid;
+  rc = h5openvar(fid, vname, &vid, &dsid);
+  if (rc) err=1;
+  if (!err) {
+    if ((rc = H5Oget_info(vid,&oinfo))<0) err=1;
+  }
+  if (err) return (0); /* zero attributes printed */
+
+  /* Print out the header */
+  n_atts = (gaint)oinfo.num_attrs;
+  if (hdrflg) {
+    if (n_atts > 0) {
+      snprintf(pout,255,"Native Attributes for File %i : %s \n",fnum,ftit);
+      gaprnt(2,pout);
+    }
+  }
+
+  /* Loop through list of attributes, print the name of each one */ 
+  for (aindex = 0 ; aindex < n_atts ; aindex++) {
+	 
+    /* get the attribute id */
+    err=0;
+    ai = (hsize_t)aindex;
+    aid = H5Aopen_by_idx(vid,".",H5_INDEX_CRT_ORDER,H5_ITER_INC,ai,H5P_DEFAULT,H5P_DEFAULT); if (aid<0) err=1;
+    /* get the attribute name */
+    if (!err) len    = H5Aget_name(aid,0,NULL); if (len<0) err=1;
+    sz = (len+1)*sizeof(char);
+    if (!err) aname  = (char*)galloc(sz,"aname"); if (aname==NULL) err=1;
+    if (!err) rc     = H5Aget_name(aid,len+1,aname); if (rc<0) err=1;
+    /* get the attribute rank */
+    if (!err) aspace = H5Aget_space(aid); if (aspace<0) err=1;
+    if (!err) rank   = H5Sget_simple_extent_ndims(aspace); if (rank<0) err=1;
+    /* get the attribute type, class, and size */
+    if (!err) atype  = H5Aget_type(aid); if (atype<0) err=1;
+    if (!err) aclass = H5Tget_class(atype); if (aclass<0) err=1;
+    if (!err) asize  = H5Tget_size(atype); if (asize<0) err=1;
+    if (err) {
+      snprintf(pout,255,"Unable to retrieve required info for attribute number %d for variable %s \n",aindex,abbrv);
+      gaprnt(2,pout);
+      continue; /* move on to the next attribute */
+    }
+    else {
+      /* Print out Name, Type, and Values */
+      if (aclass == H5T_FLOAT)	{
+	/* float */
+	if (asize == 4) {
+	  sz = rank*sizeof(gafloat);
+	  if ((fval = (gafloat*)galloc(sz,"fval"))!=NULL) {
+	    if ((rc = H5Aread(aid,H5T_NATIVE_FLOAT,fval))>=0) {
+	      snprintf(pout,255,"%s Float32 %s ",abbrv,aname); gaprnt(2,pout);
+	      for (i=0; i<rank; i++) {
+		snprintf(pout,255,"%g ", fval[i]); gaprnt(2,pout);
+	      }
+	      gaprnt(2,"\n");
+	    }
+	    gree(fval,"f153a");
+	  }
+	}
+	/* double */
+	else if (asize == 8) {
+	  sz = rank*sizeof(gadouble);
+	  if ((dval = (gadouble*)galloc(sz,"dval"))!=NULL) {
+	    if ((rc = H5Aread(aid,H5T_NATIVE_DOUBLE,dval))>=0) {
+	      snprintf(pout,255,"%s Float64 %s ",abbrv,aname); gaprnt(2,pout);
+	      for (i=0; i<rank; i++) {
+		snprintf(pout,255,"%g ", dval[i]); gaprnt(2,pout);
+	      }
+	      gaprnt(2,"\n");
+	    }
+	    gree(dval,"f153b");
+	  }
+	}
+      }
+      else if (aclass == H5T_INTEGER) {
+	/* signed or unsigned? */
+	if ((asign = H5Tget_sign(atype))>=0) {
+	  /* byte */
+	  if (asize == 1) {
+	    if (asign==H5T_SGN_NONE) {  
+	      sz = rank*sizeof(unsigned char);
+	      if ((ucval = (unsigned char*)galloc(sz,"ucval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_UCHAR,(void*)ucval))>=0) {
+		  snprintf(pout,255,"%s Byte %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%u ", (gaint)ucval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(ucval,"f153c");
+	      }
+	    }
+	    else {
+	      sz = rank*sizeof(char);
+	      if ((cval = (char*)galloc(sz,"cval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_CHAR,(void*)cval))>=0) {
+		  snprintf(pout,255,"%s Byte %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%d ", (gaint)cval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(cval,"f153d");
+	      }
+	    }
+	  }
+	  /* short */
+	  else if (asize == 2) {
+	    if (asign==H5T_SGN_NONE) {  
+	      sz = rank*sizeof(unsigned short);
+	      if ((usval = (unsigned short*)galloc(sz,"usval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_USHORT,(void*)usval))>=0) {
+		  snprintf(pout,255,"%s UInt16 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%u ", (gaint)usval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(usval,"f153e");
+	      }
+	    }
+	    else {
+	      sz = rank*sizeof(short);
+	      if ((sval = (short*)galloc(sz,"sval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_SHORT,(void*)sval))>=0) {
+		  snprintf(pout,255,"%s Int16 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%d ", (gaint)sval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(sval,"f153f");
+	      }
+	    }
+	  }
+	  /* int */
+	  else if (asize == 4) {
+	    if (asign==H5T_SGN_NONE) {  
+	      sz = rank*sizeof(gauint);
+	      if ((uival = (gauint*)galloc(sz,"uival"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_UINT,(void*)uival))>=0) {
+		  snprintf(pout,255,"%s UInt32 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%u ", uival[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(uival,"f153g");
+	      }
+	    }
+	    else {
+	      sz = rank*sizeof(gaint);
+	      if ((ival = (gaint*)galloc(sz,"ival"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_INT,(void*)ival))>=0) {
+		  snprintf(pout,255,"%s Int32 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%d ", ival[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(ival,"f153h");
+	      }
+	    }
+	  }
+	  /* long */
+	  else if (asize == 8) {
+	    if (asign==H5T_SGN_NONE) {  
+	      sz = rank*sizeof(unsigned long);
+	      if ((ulval = (unsigned long*)galloc(sz,"ulval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_ULONG,(void*)ulval))>=0) {
+		  snprintf(pout,255,"%s UInt32 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%lu ", ulval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(ulval,"f153i");
+	      }
+	    }
+	    else {
+	      sz = rank*sizeof(long);
+	      if ((lval = (long*)galloc(sz,"lval"))!=NULL) {
+		if ((rc = H5Aread(aid,H5T_NATIVE_LONG,(void*)lval))>=0) {
+		  snprintf(pout,255,"%s Int32 %s ",abbrv,aname); gaprnt(2,pout);
+		  for (i=0; i<rank; i++) {
+		    snprintf(pout,255,"%ld ", lval[i]); 
+		    gaprnt(2,pout);
+		  }
+		  gaprnt(2,"\n");
+		}
+		gree(lval,"f153j");
+	      }
+	    }
+	  }
+	  else {
+	    snprintf(pout,255,"HDF5 class H5T_INTEGER of size %d not handled\n",(gaint)asize);
+	    gaprnt(2,pout);
+	  }
+	}
+      }
+      else if (aclass == H5T_STRING) {
+	if ((stosize = H5Aget_storage_size(aid))>=0) {
+	  if ((string = (char*)malloc((stosize+1)*sizeof(char)))!=NULL) {
+	    if ((rc = H5Aread(aid,atype,(void*)string))>=0) {
+	      string[stosize]='\0';
+	      snprintf(pout,255,"%s String %s ",abbrv,aname);
+	      gaprnt(2,pout);
+	      prntwrap(abbrv,aname,string);
+	    }
+	    free(string);
+	  }
+	}
+      }
+    }
+    gree(aname,"f153l");
+    H5Aclose(aid);
+    H5Tclose(atype);
+  }
+  h5closevar(dsid,vid);
+  return(n_atts);
+#endif
+  return(0);
+}
+
+/* routine to print out a string attribute that may have carriage returns in it */
+void prntwrap(char *vname, char *aname, char *str ) {
+  char *pos, *line;
+  pos = line = str;        
+  while (*pos != '\0') { 
+    if (*pos == '\n') {
+      *pos = '\0';         /* swap null for carriage return */
+      gaprnt(2,line);
+      /* add varname, attr_type, and attr_name after carriage return */
+      snprintf(pout,255," \n%s String %s ",vname,aname); 
+      gaprnt(2,pout);
+      *pos = '\n';         /* put the carriage return back in */
+      line = pos+1;
+    }
+    pos++;
+  }
+  if (line < pos) {    /* Print string that has no carriage returns in it */
+    gaprnt(2,line); 
+  }
+  gaprnt(2,"\n");
+}
+
+
+#endif  /* matches #ifndef STNDALN */
+
+/* Routine to open appropriate file when using file templates */
+/* Warning -- changes time value to time with respect to this file */
+/* Warning -- also changes ensemble value */
+
+gaint gaopfn(gaint t, gaint e, gaint *ee, gaint *oflg, struct gafile *pfi) {
+struct dt dtim, dtimi;
+struct gaens *ens;
+gaint i,rc,flag,endx,need_new_file;
+char *fn=NULL;
+
+  *oflg = 0;
+  /* make sure e and t are within range of grid dimensions */
+  if (t<1 || t>pfi->dnum[3]) return(-99999);
+  if (e<1 || e>pfi->dnum[4]) return(-99999);
+  i = pfi->fnums[(e-1)*pfi->dnum[3]+t-1];
+  if (i == -1) {
+    /* there is no data file associated with this time and ensemble member */
+      pfi->fnumc = 0;
+      pfi->fnume = 0;
+      return(-88888);
+  }  
+
+  /* find out if we need to open a new file */
+  /* tmplat = 3 means templating on E and T 
+     tmplat = 2 means templating only on E 
+     tmplat = 1 means templating only on T */
+
+  need_new_file=0;
+  if (pfi->tmplat==3 && ((i != pfi->fnumc) || (e != pfi->fnume))) need_new_file=1;
+  if (pfi->tmplat==2 && (e != pfi->fnume)) need_new_file=2;
+  if (pfi->tmplat==1 && (i != pfi->fnumc)) need_new_file=3;
+
+  /* the current file is not the one we need */
+  if (need_new_file) {
+    /* close SDF file */
+    if (pfi->ncflg) {
+      if (pfi->ncflg==1) {
+	gaclosenc(pfi); 
+      }
+      else if (pfi->ncflg==2) {
+	gaclosehdf(pfi);
+      }
+      else if (pfi->ncflg==3) {
+	gacloseh5(pfi);
+      }
+    } 
+    /* close BUFR file*/
+    else if (pfi->bufrflg) {
+      if (pfi->bufrdset) {
+	gabufr_close(pfi->bufrdset);  /* release memory */
+	pfi->bufrdset=NULL;           /* reset the pointer */
+      }
+    } 
+    /* close non-SDF, non-BUFR file */
+    else {
+      if (pfi->infile!=NULL) fclose(pfi->infile);
+    }
+    /* release old file name */
+    if (pfi->tempname!=NULL) {
+      gree(pfi->tempname,"f116");
+    }
+
+    /* advance through chain of ensemble structure to get to ensemble 'e' */
+    ens=pfi->ens1;    
+    endx=1;
+    while (endx<e) { endx++; ens++; }
+    /* find the filename that goes with current time and ensemble member */
+    gr2t(pfi->grvals[3], (gadouble)t, &dtim);   /* current t value */
+    gr2t(pfi->grvals[3], ens->gt, &dtimi);      /* initial t for this ensemble member */
+    fn = gafndt(pfi->name, &dtim, &dtimi, pfi->abvals[3], pfi->pchsub1, pfi->ens1, t, e, &flag);
+    if (fn==NULL) return (-99999);
+    /* Open the data file */
+    rc = 0;
+    pfi->tempname = fn;
+    pfi->fnumc = i;
+    pfi->fnume = e;
+
+    /* open netcdf */
+    if (pfi->ncflg==1) {  
+      rc = gaopnc (pfi,1,0);
+      if (rc) pfi->ncid = -999;
+    }
+    /* open hdfsds */
+    else if (pfi->ncflg==2) { 
+      rc = gaophdf (pfi,1,0);
+      if (rc) pfi->sdid = -999;
+    }
+    /* open hdf5 */
+    else if (pfi->ncflg==3) { 
+      rc = gaoph5 (pfi,1,0);
+      if (rc) pfi->h5id = -999;
+    }
+    /* open all others except BUFR */
+    else if (!pfi->bufrflg) {        
+      pfi->infile = fopen (fn, "rb");
+      if (pfi->infile == NULL) rc = 1;
+    } 
+
+    /* Error checking on file open */
+    if (rc) {
+      if (pfi->errflg && timerr!=t) {
+        gaprnt(1,"Warning: Open error, fn = ");
+        gaprnt(1,fn);
+        gaprnt(1,"\n");
+        timerr = t;
+      }
+      pfi->fnumc = 0;
+      pfi->fnume = 0;
+      return(-88888);
+    }
+    *oflg = 1;
+  } /* matches if (need_new_file)  */
+
+  if (pfi->tmplat==1) { /* templating on T but not E */
+    *ee = e;                /* set relative ensemble number to E for this file */ 
+  }
+  else {
+    *ee = 1;                /* set relative ensemble number to 1 for this file */ 
+  }
+
+  t = 1 + t - pfi->fnumc;   /* set relative t for this file */
+  return (t);
+}
+
+/* Open a netcdf file */
+gaint gaopnc (struct gafile *pfil, gaint tflag, gaint eflag) {
+#if  USENETCDF == 1
+gaint i,rc;
+char *filename;
+
+  if (tflag) {
+    filename = pfil->tempname;
+  } 
+  else {
+    filename = pfil->name;
+  }
+  rc = nc_open(filename, NC_NOWRITE, &i);
+  if (rc != NC_NOERR) {
+    if (eflag) {
+      snprintf(pout,255,"Error: nc_open failed to open file %s\n",filename);
+      gaprnt(0,pout);
+      snprintf(pout,255,"%s\n",nc_strerror(rc));
+      gaprnt(0,pout);
+    }
+    return (1);
+  }
+  /* set the ncid in the gafile structure */
+  pfil->ncid = i;     
+#endif
+  return (0);
+}
+
+
+/* Open an HDF-SDS file */
+gaint gaophdf (struct gafile *pfil, gaint tflag, gaint eflag) {
+#if USEHDF == 1
+  int32 sd_id=-999;
+  char *filename; 
+
+  /* set the filename */
+  if (tflag) {
+    filename = pfil->tempname;
+  } 
+  else {
+    filename = pfil->name;
+  }
+  /* open the file, set the file id in the gafile structure */
+  if ((sd_id = SDstart(filename, DFACC_READ))==FAIL) {
+    if (eflag) {
+      snprintf(pout,255,"gaophdf error: SDstart failed to open hdf-sds file %s\n",filename);
+      gaprnt(0,pout);
+    }
+    return (1);
+  }
+  pfil->sdid = sd_id;     
+#endif
+  return (0);
+}
+
+
+
+/* Open an HDF5 file */
+gaint gaoph5 (struct gafile *pfil, gaint tflag, gaint eflag) {
+#if USEHDF5 == 1
+  hid_t fapl,h5id=-999;
+  char* filename;
+  gaint op=0;
+  
+  /* set the filename */
+  if (tflag) {
+    filename = pfil->tempname;
+  }
+  else {
+    filename = pfil->name;
+  }
+  /* open the hdf5 file */
+  if ((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) {
+    if ((H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG))>=0) {
+      if ((h5id = H5Fopen(filename, H5F_ACC_RDONLY, fapl))>=0) {
+	op=1;
+      }
+    }
+  }
+
+  H5Pclose(fapl);
+  /* if file opened, set the file id in the gafile structure */
+  if (op) {
+    pfil->h5id = (gaint)h5id;     
+    return (0);
+  }
+  else {
+    if (eflag) {
+      snprintf(pout,255,"Error: Unable to open HDF5 file %s \n",filename);
+      gaprnt(0,pout);
+    }
+    return (1);
+  }
+#endif
+  return (0);
+}
+
+/* close a netCDF file, reset ncid in gafile structure */
+gaint gaclosenc (struct gafile *pfi) {
+#if USENETCDF==1
+  gaint rc;
+  gaint oldncopts ;     
+  oldncopts = ncopts ;
+  ncopts = 0;
+  if (pfi->ncid != -999) {
+    rc = nc_close(pfi->ncid);
+    if (rc != NC_NOERR) {
+      gaprnt(0,"Error: nc_close failed\n");
+      snprintf(pout,255,"%s\n",nc_strerror(rc));
+      gaprnt(0,pout);
+      return (1);
+    }
+    pfi->ncid = -999;
+  }
+  ncopts = oldncopts ;
+#endif
+  return (0);
+}
+
+/* close an HDF file, reset sdid in gafile structure */
+gaint gaclosehdf (struct gafile *pfi) {
+#if USEHDF==1
+  if (pfi->sdid != -999) {
+    if ((SDend(pfi->sdid)) != 0) {
+      gaprnt(0,"Error: SDend failed\n");
+      return (1);
+    }
+    pfi->sdid = -999;
+  }
+#endif
+  return (0);
+}
+
+/* close an HDF5 file, reset h5id in gafile structure */
+gaint gacloseh5 (struct gafile *pfi) {
+#if USEHDF5==1
+  struct gavar *lclvar;
+  gaint i,rc;
+  hid_t fid;
+
+  if (pfi->h5id != -999) {
+    fid = (hid_t)pfi->h5id;
+    /* loop over all variables, make sure they are closed */
+    lclvar = pfi->pvar1;
+    for (i=0; i<pfi->vnum; i++) {
+      rc = h5closevar(lclvar->dataspace,lclvar->h5varflg);
+      if (rc) return (1);
+      /* reset flags */
+      lclvar->dataspace = -999; 
+      lclvar->h5varflg = -999;  
+      lclvar++; 
+    }
+    /* now we can close the file */
+    if ((H5Fclose(fid)) < 0) {
+      gaprnt(1,"Error: H5Fclose failed\n");
+      return (1);
+    }
+    pfi->h5id = -999;
+  }
+#endif
+  return (0);
+}
diff --git a/src/galloc.c b/src/galloc.c
new file mode 100644
index 0000000..7862a3e
--- /dev/null
+++ b/src/galloc.c
@@ -0,0 +1,236 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's present */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "grads.h"
+#define LISTSIZE  100000 
+#define LISTSIZEB 900000 
+
+/* These routines replace malloc and free with galloc and gree, 
+   and track memory usage in a program.  The program is modified so
+   that all calls to malloc and free instead call galloc and gree
+   (which then call malloc and free).  The pointers returned by
+   malloc are tracked, and checked when free is called.  Also, 
+   an extra 8 bytes are allocated at the end of each malloc and
+   filled with character A's; these are checked when gree is called
+   to see if an overlay ocurred.   galloc requires an additional
+   argument which is a short identifier "tag" of the memory being called.
+   So, if you were calling malloc like this:
+        
+         pbuff = malloc(sizeof(struct foo));
+
+   You might change this call to:  
+
+         pbuff = galloc(sizeof(struct foo),"pbuff");
+
+   In addition to galloc and gree, two other routines are
+   provided:  glook, which when called will list all memory
+   currently allocated plus its "tag".  gsee is called with
+   a memory pointer, and checks to see if that memory block
+   is currently allocated and if an overlay has occurred 
+   (this so that gsee can be called at various points in the 
+   code to determine where an overlay is happening).   gree also
+   is called with a "tag" so that if it prints out an error
+   you know where the error is coming from.  */
+
+static char *ptrs[LISTSIZE];
+static size_t lens[LISTSIZE];
+static char cbuf[LISTSIZEB];
+static int first = 1;
+static char msg[501];
+
+void *galloc (size_t, char *);
+void gree (char *, char *);
+void glook(void);
+int verbo=0;
+int buferr=0;   /* flag error on buffer exceeded */
+
+/*  replacement for malloc */
+
+void *galloc (size_t len,char *ch) {
+char *mem=NULL,*mmm;
+int i,j;
+size_t llen;
+
+  /* initialize ptrs to null */
+  if (first) {
+    first = 0;
+    for (i=0; i<LISTSIZE; i++) ptrs[i] = NULL;
+  }
+  /* allocate the memory */
+  llen = len + 8;
+  mem = (char *)malloc(llen);
+  if (mem==NULL) {
+    return (NULL);
+  }
+  if (buferr) return(mem);
+  /* add 8 characters 'A' to the tail of the allocated memory */
+  mmm = mem + len;
+  for (i=0; i<8; i++) *(mmm+i) = 'A';
+  /* move to the first non-NULL ptr */
+  i = 0;                
+  while (ptrs[i]!=NULL) i++;
+  if (i>LISTSIZE-2) {
+    /* if hard-coded limit of ptrs has been exceeded, 
+       trip the flag to stop memory tracking */
+    if (!buferr) {
+      gaprnt(2,"Galloc memory tracking buffers exceeded. \n");
+      buferr = 1;
+    }
+    return(mem);
+  }
+  ptrs[i] = mem;               /* pointer to allocated memory */
+  lens[i] = len;               /* length of allocated memory  */
+  for (j=0; j<8; j++) cbuf[i*8+j] = ' ';
+  j = 0;
+  while (j<8 && *(ch+j)) {
+    cbuf[i*8+j] = *(ch+j);      /* tag name of allocated memory   */
+    j++;
+  }
+  return(mem);
+}
+
+/* replacement for free */
+
+void gree (char *mem, char *ch) {
+int i,j,flag;
+size_t len;
+char *mmm;
+  
+  /* if we have stopped tracking memory, just free it and return */
+  if (buferr) {
+    free (mem);
+    return;
+  }
+  /* move through the list of ptrs to the one we're going to free */
+  i = 0;
+  while (1) {
+    if (i>LISTSIZE-2) break;
+    if (ptrs[i]==mem) break; 
+    i++;
+  }
+  if (i>LISTSIZE-2) {
+    if (verbo) { 
+      snprintf(msg,500,"!*!*!      freeing unallocated space! %s %p\n",ch,mem); 
+      gaprnt(2,msg);
+    }
+  } 
+  else {
+    /* reset this pointer to NULL */
+    ptrs[i] = NULL;
+    /* check if tail of allocated memory still has 8 'A' characters */
+    len = lens[i];
+    mmm = mem + len;
+    flag = 0;
+    for (j=0; j<8; j++) if (*(mmm+j)!='A') flag = 1;
+    if (flag) {
+      if (verbo) {
+	gaprnt(2,"Overlay!!! -->");
+	for (j=0; j<8; j++) {
+	  snprintf(msg,500,"%c",*(mmm+j));        /* show the overlay */
+	  gaprnt(2,msg);
+	}
+	gaprnt(2,"<-- -->");
+	for (j=0; j<8; j++) {
+	  snprintf(msg,500,"%c",cbuf[i*8+j]);    /* show the galloc tag */
+	  gaprnt(2,msg);
+	}
+	snprintf(msg,500,"<-- %s\n",ch);                           /* show the gree tag */
+	gaprnt(2,msg);
+      }
+    }
+    if (cbuf[i*8+4]=='?') {
+      if (verbo) {
+	snprintf(msg,500,"Freeing %i %p %s ",i,mem,ch);
+	gaprnt(2,msg);
+	for (j=0; j<8; j++) {snprintf(msg,500,"%c",cbuf[i*8+j]); gaprnt(2,msg);}
+	gaprnt(2,"<--\n");
+      }
+    }
+  }
+  free (mem);
+}
+
+
+/* lists currently allocated memory chunks */
+
+void glook(void) {
+int i,j,flag;
+size_t len;
+char *mmm;
+
+  if (buferr) {
+    gaprnt(2,"Mem tracking buffer was exceeded. \n");
+  }
+  for (i=0; i<LISTSIZE; i++) {
+    if (ptrs[i]!=NULL) {
+      /* list the index, ptr, length, and name of each allocated memory chunk */
+      snprintf(msg,500,"pos=%i  ptr=%p  len=%ld  type=",i,ptrs[i],lens[i]);
+      gaprnt(2,msg);
+      for (j=0; j<8; j++) { snprintf(msg,500,"%c",cbuf[i*8+j]); gaprnt(2,msg);}
+      len = lens[i];
+      mmm = ptrs[i] + len;
+      flag = 0;
+      for (j=0; j<8; j++) if (*(mmm+j)!='A') flag = 1;
+      if (verbo && flag) gaprnt(2,"   *** Overlay *** ");
+      gaprnt(2,"\n");
+    }
+  }
+  if (buferr) {
+    gaprnt(2,"Mem tracking buffer was exceeded. \n");
+  }
+}
+
+/* Checks on a particular memory chunk */
+
+void gsee (char *mem) {
+int i,j,flag,len;
+char *mmm;
+  if (buferr) {
+    gaprnt(2,"Mem tracking buffer was exceeded. \n");
+  }
+  i = 0;
+  while (1) {
+    if (i>LISTSIZE-1) break;
+    if (ptrs[i]==mem) break; 
+    i++;
+  }
+  if (i>LISTSIZE-1) {
+    if (verbo) {
+      snprintf(msg,500,"unallocated space! %p\n",mem);
+      gaprnt(2,msg);
+    }
+  } else {
+    len = lens[i];
+    mmm = mem + len;
+    flag = 0;
+    if (verbo) {
+      snprintf(msg,500,"pos=%d  ptr=%p  len=%i  tag=",i,mem,len);
+      gaprnt(2,msg);
+    }
+    for (j=0; j<8; j++) if (*(mmm+j)!='A') flag = 1;
+    if (verbo) {
+      for (j=0; j<8; j++) {snprintf(msg,500,"%c",cbuf[i*8+j]); gaprnt(2,msg);}
+      if (flag) {
+	gaprnt(2,"   * * * Overlay!!! * * * -->");
+	for (j=0; j<8; j++) {snprintf(msg,500,"%c",*(mmm+j)); gaprnt(2,msg);}
+	gaprnt(2,"<--");
+      }
+      gaprnt(2,"\n");
+    }
+  }
+  if (buferr) {
+    gaprnt(2,"Mem tracking buffer was exceeded. \n");
+  }
+}
diff --git a/src/gamach.c b/src/gamach.c
new file mode 100644
index 0000000..66677fc
--- /dev/null
+++ b/src/gamach.c
@@ -0,0 +1,482 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include "gatypes.h"
+/* #include "grads.h" */
+
+/* Machine dependent routines.  These routines depend on machine word
+   length any byte ordering. */
+
+/* Get bit string value from the character string starting
+   at bit offset ioff and number of bits ilen.  ilen should not
+   be greater than 24 bits unless byte aligned. */
+
+static char masks[8] = {0,127,63,31,15,7,3,1};
+
+#if GRADS_CRAY == 1
+
+/* 64-bit gagby 
+   routine to get an integer length one to eight and return it as a long int. */
+
+gaint gagby (unsigned char *ch, gaint ioff, gaint ilen) {
+gaint ival;
+unsigned char *ch1;
+
+  ch1 = (unsigned char *)(&ival);
+  ival = 0;
+  if (BYTEORDER) {
+    if (ilen==1) *(ch1+7) = *(ch+ioff);
+    else if (ilen==2) {
+      *(ch1+6) = *(ch+ioff);
+      *(ch1+7) = *(ch+ioff+1);
+    } else if (ilen==3) {
+      *(ch1+5) = *(ch+ioff);
+      *(ch1+6) = *(ch+ioff+1);
+      *(ch1+7) = *(ch+ioff+2);
+    } else {
+      *(ch1+4) = *(ch+ioff);
+      *(ch1+5) = *(ch+ioff+1);
+      *(ch1+6) = *(ch+ioff+2);
+      *(ch1+7) = *(ch+ioff+3);
+    }
+  } else {
+    if (ilen==1) *ch1 = *(ch+ioff);
+    else if (ilen==2) {
+      *(ch1+7) = *(ch+ioff);
+      *ch1 = *(ch+ioff+7);
+    } else if (ilen==3) {
+      *(ch1+7) = *(ch+ioff+5);
+      *(ch1+6) = *(ch+ioff+6);
+      *(ch1+5) = *(ch+ioff+4);
+    } else {
+      *(ch1+7) = *(ch+ioff+4);
+      *(ch1+6) = *(ch+ioff+5);
+      *(ch1+5) = *(ch+ioff+6);
+      *(ch1+4) = *(ch+ioff+3);
+    }
+  }
+  return (ival);
+}
+
+/* 64-bit gagbb */
+
+gaint gagbb (unsigned char *ch, gaint ioff, gaint ilen) {
+gaint ival,istrt,iend,cstrt;
+gaint i,ispac,ioff2,ileav,numb;
+unsigned char *ch1,cc;
+
+  ch1 = (char *)(&ival);
+  ival = 0;
+  istrt = ioff/8;
+  ispac = ioff - istrt*8;
+  /* Fast path for byte alignment */
+  if (ispac==0 && (ilen==8 || ilen==16 || ilen==24 || ilen==32)) {
+    if (BYTEORDER) {
+      if (ilen==8) *(ch1+7) = *(ch+istrt);
+      else if (ilen==16) {
+        *(ch1+6) = *(ch+istrt);
+        *(ch1+7) = *(ch+istrt+1);
+      } else if (ilen==24) {
+        *(ch1+5) = *(ch+istrt);
+        *(ch1+6) = *(ch+istrt+1);
+        *(ch1+7) = *(ch+istrt+2);
+      } else {
+        *(ch1+4) = *(ch+istrt);
+        *(ch1+5) = *(ch+istrt+1);
+        *(ch1+6) = *(ch+istrt+2);
+        *(ch1+7) = *(ch+istrt+3);
+      }
+    } else {
+      if (ilen==8) *ch1 = *(ch+istrt);
+      else if (ilen==16) {
+        *(ch1+1) = *(ch+istrt);
+        *ch1 = *(ch+istrt+1);
+      } else if (ilen==24) {
+        *(ch1+2) = *(ch+istrt);
+        *(ch1+1) = *(ch+istrt+1);
+        *ch1 = *(ch+istrt+2);
+      } else {
+        *(ch1+3) = *(ch+istrt);
+        *(ch1+2) = *(ch+istrt+1);
+        *(ch1+1) = *(ch+istrt+2);
+        *ch1 = *(ch+istrt+3);
+      }
+    }
+    return (ival);
+  }
+  /* Do it the hard way */
+  ioff2 = ioff+ilen-1;
+  iend = ioff2/8;
+  ileav = (iend+1)*8 - ioff2;
+  numb = iend - istrt;
+  if (BYTEORDER) {
+    cstrt = 7-numb;
+    if (ispac>0) *(ch1+cstrt) = *(ch+istrt) & masks[ispac];
+    else *(ch1+cstrt) = *(ch+istrt);
+    for (i=1; i<=numb; i++) {
+      *(ch1+cstrt+i) = *(ch+istrt+i);
+    }
+  } else {
+    if (ispac>0) *(ch1+numb) = *(ch+istrt) & masks[ispac];
+    else *(ch1+numb) = *(ch+istrt);
+    for (i=0; i<numb; i++) {
+      *(ch1+i) = *(ch+iend-i);
+    }
+  }
+  ival = ival >> (ileav-1);
+  return (ival);
+}
+
+/* 64-bit gapby
+   routine to put an integer length one to four into a char stream */
+
+gaint gapby (gaint ival, unsigned char *ch, gaint ioff, gaint ilen) {
+unsigned char *ch1;
+
+  ch1 = (unsigned char *)(&ival);
+  if (BYTEORDER) {
+    if (ilen==1) *(ch+ioff) = *(ch1+7);
+    else if (ilen==2) {
+      *(ch+ioff) = *(ch1+6);
+      *(ch+ioff+1) = *(ch1+7);
+    } else if (ilen==3) {
+      *(ch+ioff) = *(ch1+5);
+      *(ch+ioff+1) = *(ch1+6);
+      *(ch+ioff+2) = *(ch1+7);
+    } else {
+      *(ch+ioff) = *(ch1+4);
+      *(ch+ioff+1) = *(ch1+5);
+      *(ch+ioff+2) = *(ch1+6);
+      *(ch+ioff+3) = *(ch1+7);
+    }
+  } else {
+    if (ilen==1)  *(ch+ioff) = *ch1;
+    else if (ilen==2) {
+      *(ch+ioff) = *(ch1+1);
+      *(ch+ioff+1) = *ch1 ;
+    } else if (ilen==3) {
+      *(ch+ioff) = *(ch1+2) ;
+      *(ch+ioff+1) = *(ch1+1) ;
+      *(ch+ioff+2) = *ch1 ;
+    } else {
+      *(ch+ioff) = *(ch1+3) ;
+      *(ch+ioff+1) = *(ch1+2) ;
+      *(ch+ioff+2) = *(ch1+1) ;
+      *(ch+ioff+3) = *ch1;
+    }
+  }
+  return;
+}
+
+
+/* 64-bit gapbb 
+
+  Put bit string value into a character string 
+  starting at bit offset ioff and number of bits ilen.  
+  ilen should not be greater than 24 bits unless byte aligned.  
+  Note that ch cannot be longer than 32K on a PC. */
+
+void gapbb (gaint ival, unsigned char *ch, gaint ioff, gaint ilen) {
+unsigned char *ch1,cc;
+gaint istrt,iend,cstrt;
+gaint i,ispac,ioff2,ileav,numb;
+
+  ch1 = (unsigned char *)(&ival);
+  istrt = ioff/8;
+  ispac = ioff - istrt*8;
+  /* Fast path for byte alignment */
+  if (ispac==0 && (ilen==8 || ilen==16 || ilen==24 || ilen==32)) {
+    if (BYTEORDER) {
+      if (ilen==8) *(ch+istrt) = *(ch1+7);
+      else if (ilen==16) {
+        *(ch+istrt)   = *(ch1+6) ;
+        *(ch+istrt+1) = *(ch1+7);
+      } else if (ilen==24) {
+        *(ch+istrt)   = *(ch1+5);
+        *(ch+istrt+1) = *(ch1+6);
+        *(ch+istrt+2) = *(ch1+7);
+      } else {
+        *(ch+istrt)   = *(ch1+4);
+        *(ch+istrt+1) = *(ch1+5);
+        *(ch+istrt+2) = *(ch1+2);
+        *(ch+istrt+3) = *(ch1+7);
+      }
+    } else {
+      if (ilen==8) *(ch+istrt) = *ch1;
+      else if (ilen==16) {
+        *(ch+istrt)   = *(ch1+1);
+        *(ch+istrt+1) = *ch1;
+      } else if (ilen==24) {
+        *(ch+istrt)   = *(ch1+2);
+        *(ch+istrt+1) = *(ch1+1);
+        *(ch+istrt+2) = *ch1;
+      } else {
+        *(ch+istrt)   = *(ch1+3);
+        *(ch+istrt+1) = *(ch1+2);
+        *(ch+istrt+2) = *(ch1+1);
+        *(ch+istrt+3) = *ch1;
+      }
+    }
+    return;
+  }
+  /* Do it the hard way */
+  ioff2 = ioff+ilen-1;
+  iend = ioff2/8;
+  ileav = (iend+1)*8 - ioff2;
+  numb = iend - istrt;
+  ival <<= (ileav-1);
+  if (BYTEORDER) {
+    cstrt = 7-numb;
+    if (ispac>0) *(ch+istrt) |= *(ch1+cstrt) ;
+    else *(ch+istrt) = *(ch1+cstrt);
+    for (i=1; i <= numb; i++) {
+      *(ch+istrt+i) = *(ch1+cstrt+i);
+    }
+  } else {
+    if (ispac>0) *(ch+istrt) |= *(ch1+numb) ;
+    else *(ch+istrt) = *(ch1+numb);
+    for (i=0; i<numb; i++) {
+      *(ch+iend-i) = *(ch1+i);
+    }
+  }
+  return;
+}
+
+#else
+
+/*  32-bit gagby */
+gaint gagby (unsigned char *ch, gaint ioff, gaint ilen) {
+gaint ival;
+unsigned char *ch1;
+
+  ch1 = (unsigned char *)(&ival);
+  ival = 0;
+  if (BYTEORDER) {
+    if (ilen==1) *(ch1+3) = *(ch+ioff);
+    else if (ilen==2) {
+      *(ch1+2) = *(ch+ioff);
+      *(ch1+3) = *(ch+ioff+1);
+    } else if (ilen==3) {
+      *(ch1+1) = *(ch+ioff);
+      *(ch1+2) = *(ch+ioff+1);
+      *(ch1+3) = *(ch+ioff+2);
+    } else {
+      *ch1 = *(ch+ioff);
+      *(ch1+1) = *(ch+ioff+1);
+      *(ch1+2) = *(ch+ioff+2);
+      *(ch1+3) = *(ch+ioff+3);
+    }
+  } else {
+    if (ilen==1) *ch1 = *(ch+ioff);
+    else if (ilen==2) {
+      *(ch1+1) = *(ch+ioff);
+      *ch1 = *(ch+ioff+1);
+    } else if (ilen==3) {
+      *(ch1+2) = *(ch+ioff);
+      *(ch1+1) = *(ch+ioff+1);
+      *ch1 = *(ch+ioff+2);
+    } else {
+      *(ch1+3) = *(ch+ioff);
+      *(ch1+2) = *(ch+ioff+1);
+      *(ch1+1) = *(ch+ioff+2);
+      *ch1     = *(ch+ioff+3);
+    }
+  }
+  return (ival);
+}
+
+/* 32-bit gagbb */
+
+gaint gagbb (unsigned char *ch, gaint ioff, gaint ilen) {
+gaint ival,istrt,iend,cstrt;
+gaint i,ispac,ioff2,ileav,numb;
+unsigned char *ch1;
+
+  ch1 = (unsigned char *)(&ival);
+  ival = 0;
+  istrt = ioff/8;
+  ispac = ioff - istrt*8;
+  /* Fast path for byte alignment */
+  if (ispac==0 && (ilen==8 || ilen==16 || ilen==24 || ilen==32)) {
+    if (BYTEORDER) {
+      if (ilen==8) *(ch1+3) = *(ch+istrt);
+      else if (ilen==16) {
+        *(ch1+2) = *(ch+istrt);
+        *(ch1+3) = *(ch+istrt+1);
+      } else if (ilen==24) {
+        *(ch1+1) = *(ch+istrt);
+        *(ch1+2) = *(ch+istrt+1);
+        *(ch1+3) = *(ch+istrt+2);
+      } else {
+        *ch1 = *(ch+istrt);
+        *(ch1+1) = *(ch+istrt+1);
+        *(ch1+2) = *(ch+istrt+2);
+        *(ch1+3) = *(ch+istrt+3);
+      }
+    } else {
+      if (ilen==8) *ch1 = *(ch+istrt);
+      else if (ilen==16) {
+        *(ch1+1) = *(ch+istrt);
+        *ch1 = *(ch+istrt+1);
+      } else if (ilen==24) {
+        *(ch1+2) = *(ch+istrt);
+        *(ch1+1) = *(ch+istrt+1);
+        *ch1 = *(ch+istrt+2);
+      } else {
+        *(ch1+3) = *(ch+istrt);
+        *(ch1+2) = *(ch+istrt+1);
+        *(ch1+1) = *(ch+istrt+2);
+        *ch1 = *(ch+istrt+3);
+      }
+    }
+    return (ival);
+  }
+  /* Do it the hard way */
+  ioff2 = ioff+ilen-1;
+  iend = ioff2/8;
+  ileav = (iend+1)*8 - ioff2;
+  numb = iend - istrt;
+  if (BYTEORDER) {
+    cstrt = 3-numb;
+    if (ispac>0) *(ch1+cstrt) = *(ch+istrt) & masks[ispac];
+    else *(ch1+cstrt) = *(ch+istrt);
+    for (i=1; i<=numb; i++) {
+      *(ch1+cstrt+i) = *(ch+istrt+i);
+    }
+  } else {
+    if (ispac>0) *(ch1+numb) = *(ch+istrt) & masks[ispac];
+    else *(ch1+numb) = *(ch+istrt);
+    for (i=0; i<numb; i++) {
+      *(ch1+i) = *(ch+iend-i);
+    }
+  }
+  ival = ival >> (ileav-1);
+  return (ival);
+}
+
+/* 32-bit gapby
+  routine to put an integer length one to four into a char stream */
+
+void gapby (gaint ival, unsigned char *ch, gaint ioff, gaint ilen) {
+unsigned char *ch1;
+
+  ch1 = (unsigned char *)(&ival);
+  if (BYTEORDER) {
+    if (ilen==1) *(ch+ioff) = *(ch1+3);
+    else if (ilen==2) {
+      *(ch+ioff) = *(ch1+2);
+      *(ch+ioff+1) = *(ch1+3);
+    } else if (ilen==3) {
+      *(ch+ioff) = *(ch1+1);
+      *(ch+ioff+1) = *(ch1+2);
+      *(ch+ioff+2) = *(ch1+3);
+    } else {
+      *(ch+ioff) = *ch1;
+      *(ch+ioff+1) = *(ch1+1);
+      *(ch+ioff+2) = *(ch1+2);
+      *(ch+ioff+3) = *(ch1+3);
+    }
+  } else {
+    if (ilen==1)  *(ch+ioff) = *ch1;
+    else if (ilen==2) {
+      *(ch+ioff) = *(ch1+1);
+      *(ch+ioff+1) = *ch1 ;
+    } else if (ilen==3) {
+      *(ch+ioff) = *(ch1+2) ;
+      *(ch+ioff+1) = *(ch1+1) ;
+      *(ch+ioff+2) = *ch1 ;
+    } else {
+      *(ch+ioff) = *(ch1+3) ;
+      *(ch+ioff+1) = *(ch1+2) ;
+      *(ch+ioff+2) = *(ch1+1) ;
+      *(ch+ioff+3) = *ch1;
+    }
+  }
+  return;
+}
+
+/* 32-bit gapbb 
+
+  Put bit string value into a character string 
+  starting at bit offset ioff and number of bits ilen.  
+  ilen should not be greater than 24 bits unless byte aligned.  
+  Note that ch cannot be longer than 32K on a PC. */
+
+void gapbb (gaint ival, unsigned char *ch, gaint ioff, gaint ilen) {
+unsigned char *ch1;
+gaint istrt,iend,cstrt;
+gaint i,ispac,ioff2,ileav,numb;
+
+  ch1 = (unsigned char *)(&ival);
+  istrt = ioff/8;
+  ispac = ioff - istrt*8;
+  /* Fast path for byte alignment */
+  if (ispac==0 && (ilen==8 || ilen==16 || ilen==24 || ilen==32)) {
+    if (BYTEORDER) {
+      if (ilen==8) *(ch+istrt) = *(ch1+3);
+      else if (ilen==16) {
+        *(ch+istrt)   = *(ch1+2) ;
+        *(ch+istrt+1) = *(ch1+3);
+      } else if (ilen==24) {
+        *(ch+istrt)   = *(ch1+1);
+        *(ch+istrt+1) = *(ch1+2);
+        *(ch+istrt+2) = *(ch1+3);
+      } else {
+        *(ch+istrt)   = *ch1;
+        *(ch+istrt+1) = *(ch1+1);
+        *(ch+istrt+2) = *(ch1+2);
+        *(ch+istrt+3) = *(ch1+3);
+      }
+    } else {
+      if (ilen==8) *(ch+istrt) = *ch1;
+      else if (ilen==16) {
+        *(ch+istrt)   = *(ch1+1);
+        *(ch+istrt+1) = *ch1;
+      } else if (ilen==24) {
+        *(ch+istrt)   = *(ch1+2);
+        *(ch+istrt+1) = *(ch1+1);
+        *(ch+istrt+2) = *ch1;
+      } else {
+        *(ch+istrt)   = *(ch1+3);
+        *(ch+istrt+1) = *(ch1+2);
+        *(ch+istrt+2) = *(ch1+1);
+        *(ch+istrt+3) = *ch1;
+      }
+    }
+    return;
+  }
+  /* Do it the hard way */
+  ioff2 = ioff+ilen-1;
+  iend = ioff2/8;
+  ileav = (iend+1)*8 - ioff2;
+  numb = iend - istrt;
+  ival <<= (ileav-1);
+  if (BYTEORDER) {
+    cstrt = 3-numb;
+    if (ispac>0) *(ch+istrt) |= *(ch1+cstrt) ;
+    else *(ch+istrt) = *(ch1+cstrt);
+    for (i=1; i <= numb; i++) {
+      *(ch+istrt+i) = *(ch1+cstrt+i);
+    }
+  } else {
+    if (ispac>0) *(ch+istrt) |= *(ch1+numb) ;
+    else *(ch+istrt) = *(ch1+numb);
+    for (i=0; i<numb; i++) {
+      *(ch+iend-i) = *(ch1+i);
+    }
+  }
+  return;
+}
+
+
+#endif
diff --git a/src/gasdf.c b/src/gasdf.c
new file mode 100644
index 0000000..d18d101
--- /dev/null
+++ b/src/gasdf.c
@@ -0,0 +1,4138 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/*  
+   Reads the metadata from a Self-Describing File 
+   and fill in the information into a gafile structure.
+   Authored by Don Hooper and modified by Jennifer M. Adams 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if (USENETCDF==1 || USEHDF==1)
+
+#define Success	0
+#define Failure	1
+#define XINDEX 0
+#define YINDEX 1
+#define ZINDEX 2
+#define TINDEX 3
+#define EINDEX 4
+#define DFLTORIGIN " since 1-1-1 00:00:0.0"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include "grads.h"
+#if USENETCDF==1
+#include "netcdf.h"
+#include "gasdf_std_time.h"
+#endif
+#include "udunits.h"
+#include "gasdf.h"
+#if USEHDF == 1
+#include "mfhdf.h"
+#endif
+
+
+extern struct gamfcmn mfcmn ;
+extern FILE *descr ;
+
+char *gxgnam(char *) ;     /* This is also in gx.h */
+static char pout[256];    /* Build error msgs here */
+gaint utISinit = 0 ;
+
+
+/* STNDALN requires gaxdfopen routine and others contained therein, 
+   which turns out to be everything except the gasdfopen() routine. 
+   It is used for parsing a descriptor file to see if GrADS will open it. */
+#ifndef STNDALN
+
+
+/* Open a self-describing file by reading the metadata 
+   and filling in a gafile structure. Chain the gafile 
+   structure on to the list anchored in the gastat. */
+
+gaint gasdfopen (char *args, struct gacmn *pcm) {
+  struct gafile *pfi, *pfio;
+  gaint rc, len;
+  char pathname[4096];
+  GASDFPARMS parms ;
+
+  /* allocate memory for the gafile structure */
+  pfi = getpfi();
+  if (pfi == NULL) {
+    gaprnt (0,"sdfopen: Memory Allocation Error (getpfi failed)\n");
+    return Failure;
+  }
+  getwrd(pathname, args, 4095) ;
+  gaprnt (2, "Scanning self-describing file:  ");
+  gaprnt (2, pathname);
+  gaprnt (2, "\n");
+
+  /* set a flag for detecting sdf file type: HDF or NetCDF */
+  pfi->ncflg = 1;             /* NetCDF */
+#if USEHDF==1
+  rc = Hishdf(pathname);
+  if (rc==1) pfi->ncflg = 2;  /* HDF-SDS */
+#endif
+  len=strlen(pathname);
+  strncpy(pfi->name,pathname,len);
+  strncpy(pfi->dnam,pathname,len);
+  pfi->name[len]='\0';
+  pfi->dnam[len]='\0';
+  pfi->tmplat = 0 ;     /* no more templating with sdfopen */
+  initparms(&parms) ;   /* set up for sdfopen calling gadsdf */
+
+  rc = gadsdf(pfi, parms);
+  if (rc==Failure) {
+    frepfi (pfi, 0) ;
+    freeparms (&parms);
+    return Failure ;
+  }
+  if (pcm->pfi1==NULL) {
+    pcm->pfi1 = pfi;
+  } else {
+    pfio = pcm->pfi1;
+    while (pfio->pforw!=NULL) pfio = pfio->pforw;
+    pfio->pforw = pfi;
+  }
+  pfi->pforw = NULL;
+  pcm->fnum++;
+
+  if (pcm->fnum==1) {
+    pcm->pfid = pcm->pfi1; 
+    pcm->dfnum = 1;
+  }
+  snprintf(pout,255,"SDF file %s is open as file %i\n",pfi->name,pcm->fnum);
+  gaprnt (2,pout);
+
+  /* If first file open, set up some default dimension ranges for the user */
+  if (pcm->fnum==1) {
+    if (pfi->wrap) {
+      gacmd ("set lon 0 360",pcm,0);
+    }
+    else {
+      snprintf(pout,255,"set x 1 %i",pfi->dnum[0]);
+      gacmd (pout,pcm,0);
+    }
+    snprintf(pout,255,"set y 1 %i",pfi->dnum[1]);
+    gacmd (pout,pcm,0);
+    gacmd ("set z 1",pcm,0);
+    gacmd ("set t 1",pcm,0);
+    gacmd ("set e 1",pcm,0);
+  }
+  if (pfi->pa2mb) {
+    gaprnt(1,"Notice: Z coordinate pressure values have been converted from Pa to mb\n");
+  }
+  freeparms(&parms);
+  return Success;
+}
+
+#endif  /* matches #ifndef STNDALN */
+
+
+/* Open an XDF data set by parsing the descriptor and 
+   reading the metadata to fill-in a gafile structure. 
+   Chain the gafile structure on to the list anchored in the gastat.  */
+
+gaint gaxdfopen (char *args, struct gacmn *pcm) {
+  struct gafile *pfi, *pfio;
+  gaint rc, idummy,len ;
+  char pathname[256];
+  char *fileone;
+  struct dt tdefi;
+  gaint flag;
+  GASDFPARMS parms ;
+
+  /* allocate memory for gafile structure */
+  pfi = getpfi();
+  if (pfi == NULL) {
+    gaprnt (0,"xdfopen: Memory Allocation Error (getpfi failed)\n");
+    return Failure;
+  }
+  getwrd(pathname, args, 255) ;
+  gaprnt (2, "Scanning Descriptor File:  ");
+  gaprnt (2, pathname);
+  gaprnt (2, "\n");
+  len = strlen(pathname);
+  strncpy(pfi->dnam,pathname,len);
+  pfi->dnam[len]='\0';
+  pfi->tmplat = 0 ;     /* may be reset when parsing xdf descriptor */
+  pfi->ncflg = 1;       /* may be reset when parsing dtype in descriptor */
+
+  /* get metadata from the descriptor file */
+  rc = gadxdf(pfi, &parms) ;
+  if (rc==Failure) {
+    freeparms(&parms);
+    frepfi (pfi, 0) ;
+    return Failure ;
+  }
+  if (pcm->pfi1==NULL) {
+    pcm->pfi1 = pfi;
+  } 
+  else {
+    pfio = pcm->pfi1;
+    while (pfio->pforw!=NULL) pfio = pfio->pforw;
+    pfio->pforw = pfi;
+  }
+  pfi->pforw = NULL;
+  pcm->fnum++;
+  if (pcm->fnum==1) {
+    pcm->pfid = pcm->pfi1; 
+    pcm->dfnum = 1;
+  }
+
+  /* see if the file format is HDF*/
+#if USEHDF==1
+  if (pfi->tmplat==0) {
+    rc = Hishdf(pfi->name);
+    if (rc==1) pfi->ncflg = 2;  /* HDF-SDS */
+  }
+  else {
+    gr2t(pfi->grvals[3], 1.0, &tdefi);
+    fileone = gafndt(pfi->name, &tdefi, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+    rc = Hishdf(fileone);
+    if (rc==1) pfi->ncflg = 2;  /* HDF-SDS */
+  }
+#endif
+
+  /* get remaining required metadata */
+  rc = gadsdf(pfi, parms) ;
+  if (rc==Failure) {
+    snprintf(pout,255, "SDF Descriptor file %s was not successfully opened & parsed.\n", pfi->dnam) ;
+    gaprnt(0, pout) ;
+    frepfi (pfi, 0) ;
+    freeparms(&parms);
+    if (pcm->fnum <= 1) { 
+      pcm->pfid = pcm->pfi1 = (struct gafile *) 0 ;
+      pcm->fnum  = 0 ; 
+      pcm->dfnum = 0 ;
+    } else {
+      pcm->fnum-- ;
+      for (idummy = 1, pfi = pcm->pfi1 ; (idummy < pcm->fnum) && pfi ; ++idummy) {
+	pfi = pfi->pforw ;
+      }
+      if (pfi) {
+	pfi->pforw = (struct gafile *) 0 ;
+      }
+    }
+    pfi = (struct gafile *) 0 ;
+    return Failure;
+  } 
+  else {
+    snprintf(pout,255, "SDF file %s is open as file %i\n", pfi->name, pcm->fnum);
+    gaprnt(2, pout);
+  }
+
+  /* If SDF is first file open, set up some default dimension ranges for the user */
+  if (pcm->fnum==1) {
+    if (pfi->wrap) {
+      gacmd ("set lon 0 360",pcm,0);
+    }
+    else {
+      snprintf(pout,255,"set x 1 %i",pfi->dnum[0]);
+      gacmd (pout,pcm,0);
+    }
+    snprintf(pout,255,"set y 1 %i",pfi->dnum[1]);
+    gacmd (pout,pcm,0);
+    gacmd ("set z 1",pcm,0);
+    gacmd ("set t 1",pcm,0);
+    gacmd ("set e 1",pcm,0);
+  }
+  if (pfi->pa2mb) {
+    gaprnt(1,"Notice: Z coordinate pressure values have been converted from Pa to mb\n");
+  }
+  freeparms(&parms);
+  return Success;
+}
+
+
+
+/* Retrieves self-describing file metadata and fills in the gafile structure. */
+
+gaint gadsdf(struct gafile *pfi, GASDFPARMS parms) {
+struct gavar *pvar,*newpvar,*savepvar;
+struct gavar *Xcoord=NULL,*Ycoord=NULL,*Zcoord=NULL,*Tcoord=NULL,*Ecoord=NULL ;
+struct gaattr *attr,*attr1,*attr2,*deltat_attr,*timeunits_attr;
+struct sdfnames *varnames;
+struct gaens *ens;
+struct dt dt2,tdef,tdefi,tdefe;
+gadouble v1,v2,*zvals,*tvals=NULL,*evals=NULL;
+gadouble time1,time2,lat1,lat2,lev1,lev2,incrfactor,sf;
+gafloat dsec;
+size_t len_time_units,trunc_point,sz ;
+gaint len,noname,notinit,nolength;
+gaint i,j,c,rc,flag,numdvars,e,t;
+gaint iyr,imo,idy,ihr,imn,isec,ispress,isDatavar ;
+gaint xdimid,ydimid,zdimid,tdimid,edimid ;
+gaint istart,icount,havesf,haveao;
+char *ch,*utname,*pos=NULL,*pos1=NULL,*pos2=NULL; 
+char *time_units=NULL,*trunc_units=NULL,*temp_str ;
+utUnit timeunit ;
+
+  /* Enable griping, disable aborting, from within NetCDF library */
+#if USENETCDF==1
+  ncopts = NC_VERBOSE ;
+#endif
+  if (!utISinit) {
+    utname = gxgnam("udunits.dat") ;
+    if (utname != NULL) {
+      if (utInit(utname)) {
+	gaprnt(0, "gadsdf: UDUNITS package initialization failure.\n") ;
+	return Failure ;
+      }
+    }
+    utISinit = 1 ;
+  } 
+
+  /* Grab the metadata */
+  if (read_metadata(pfi) == Failure) {
+    gaprnt(0, "gadsdf: Couldn't ingest SDF metadata.\n") ;
+    return Failure ;
+  }
+  if (!parms.isxdf) {
+    pfi->calendar = 0 ;  /* 365 day kind not available under COARDS */
+  }
+
+  /* Get the title */
+  if (parms.needtitle) {
+    attr = NULL;
+    attr = find_att("global", pfi->attr, "title") ;
+    if (attr) {
+      if ((attr->len) > 510) {
+	getstr(pfi->title, (char *)(attr->value), 511) ;
+      } else {
+	getstr(pfi->title, (char *)(attr->value), attr->len) ;
+      }
+    }
+  }
+
+  /* Handle undef attribute */
+  if (parms.needundef) {
+    attr = NULL;
+    attr = find_att("ALL", pfi->attr, "missing_value") ;
+    if (!attr) {
+      attr = find_att("ALL", pfi->attr, "_FillValue") ;
+    }
+    if (!attr) {
+      pfi->undef =  -9.99e33;  /* must use default */
+      pfi->undefattrflg = 0;
+    } else {
+      /* set the undef attribute name and trip the flag */
+      pfi->undefattrflg = 1;
+      len = strlen(attr->name);
+      sz = len+1;
+      if ((pfi->undefattr = (char *)galloc(sz,"undefattr1")) == NULL) goto err1;
+      strncpy(pfi->undefattr, attr->name, len);
+      *(pfi->undefattr+len) = '\0';
+      /* If undef type is NC_FLOAT or NC_DOUBLE, use it for file-wide, otherwise use default */
+      if (attr->len == 1) {
+	if (attr->nctype == 5) {
+	  pfi->undef = *(gafloat*)(attr->value);
+	  }
+	else if (attr->nctype == 6) {
+	  pfi->undef = *(gadouble*)(attr->value);
+	}
+	else {
+	  pfi->undef = -9.99e33;
+	}
+      }
+      else {
+	pfi->undef = -9.99e33;
+      }
+    }
+  } 
+
+  /* Look for scale factor or slope attribute */
+  if (parms.needunpack) {
+    havesf = 0; 
+    haveao = 0;
+    attr = NULL;
+    attr = find_att("ALL", pfi->attr, "scale_factor") ;
+    if (!attr) {
+      attr = find_att("ALL", pfi->attr, "slope") ;
+    }
+    if (attr) {
+      len = strlen(attr->name);
+      sz = len+1;
+      if ((pfi->scattr = (char *)galloc(sz,"scattr1")) == NULL) goto err1;
+      strncpy(pfi->scattr,attr->name,len);
+      *(pfi->scattr+len) = '\0';
+      havesf = 1;
+      if (!strncmp(pfi->scattr, "NULL", 4) || !strncmp(pfi->scattr, "null", 4)) havesf = 0;
+    }
+    /* Look for add offset or intercept attribute */
+    attr = NULL;
+    attr = find_att("ALL", pfi->attr, "add_offset") ;
+    if (!attr) {
+      attr = find_att("ALL", pfi->attr, "intercept") ;
+    }
+    if (attr) {
+      len = strlen(attr->name);
+      sz = len+1;
+      if ((pfi->ofattr = (char *)galloc(sz,"ofattr1")) == NULL) goto err1;
+      strncpy(pfi->ofattr,attr->name,len);
+      *(pfi->ofattr+len) = '\0';
+      haveao = 1;
+      if (!strncmp(pfi->ofattr, "NULL", 4) || !strncmp(pfi->ofattr, "null", 4)) haveao = 0;
+    }
+    /* set the packflg */
+    if (havesf) {
+      pfi->packflg = haveao == 1 ? 2 : 1 ;
+    } else {
+      pfi->packflg = haveao == 1 ? 3 : 0 ;
+    }
+  }
+
+  /* Set up the X Coordinate */
+  if (parms.xsetup) {
+    if (parms.xsrch) {   
+    /* find an X axis */
+      rc = findX(pfi, &Xcoord);
+      if ((rc==Failure) || (Xcoord == NULL)) {
+	gaprnt(0, "gadsdf: SDF file has no discernable X coordinate.\n") ;
+	gaprnt(0,"  To open this file with GrADS, use a descriptor file with an XDEF entry.\n");
+	gaprnt(0,"  Documentation is at http://iges.org/grads/gadoc/SDFdescriptorfile.html\n"); 
+	return Failure ;
+      }
+    }
+    else {    
+      /* find the axis named in the descriptor file */
+      Xcoord = find_var(pfi, parms.xdimname) ;
+      if (!Xcoord) {
+	snprintf(pout,255, "gadsdf: Can't find variable %s for X coordinate.\n",parms.xdimname);
+	gaprnt(0,pout);
+	return Failure ;
+      }
+    } 
+    /* set the dimension size */
+    for (i=0;i<pfi->nsdfdims;i++) {
+      if (pfi->sdfdimids[i] == Xcoord->vardimids[0]) {
+	pfi->dnum[XINDEX] = pfi->sdfdimsiz[i];
+	break;
+      }
+    }
+
+    /* set the axis values */
+    if ((sdfdeflev(pfi, Xcoord, XINDEX, 0)) == Failure)  {
+      gaprnt(0, "gadsdf: Failed to define X coordinate values.\n") ;
+      return Failure;
+    }
+
+  }
+  /* set the xdimid */
+  if (parms.isxdf && (!parms.xsrch)) {
+    xdimid = find_dim(pfi, parms.xdimname) ;
+    if (xdimid == -1) {
+      snprintf(pout,255, "gadsdf: Lon dimension %s is not an SDF dimension.\n",parms.xdimname);
+      gaprnt(0,pout);
+      return Failure;
+    }
+  } else {
+    if (Xcoord) {
+      xdimid = find_dim(pfi, Xcoord->longnm) ;
+    } else {
+      xdimid = -1 ;
+    }
+  }
+
+  /* Set up the Y coordinate */
+  if (parms.ysetup) {
+    /* find a Y axis */
+    if (parms.ysrch) {
+      rc=0;
+      rc = findY(pfi, &Ycoord);
+      if ((rc==Failure) || (Ycoord == NULL)) {
+	gaprnt(0, "gadsdf: SDF file has no discernable Y coordinate.\n") ;
+	gaprnt(0,"  To open this file with GrADS, use a descriptor file with a YDEF entry.\n");
+	gaprnt(0,"  Documentation is at http://iges.org/grads/gadoc/SDFdescriptorfile.html\n"); 
+	return Failure ;
+      }
+    }
+    else {
+      /* find the axis named in the descriptor file */
+      Ycoord = find_var(pfi, parms.ydimname) ;
+      if (!Ycoord) {
+	snprintf(pout,255, "gadsdf: Can't find variable %s for Y coordinate.\n",parms.ydimname);
+	gaprnt(0,pout);
+	return Failure ;
+      }
+    } 
+    /* set the dimension size */
+    for (i=0;i<pfi->nsdfdims;i++) {
+      if (pfi->sdfdimids[i] == Ycoord->vardimids[0]) {
+	pfi->dnum[YINDEX] = pfi->sdfdimsiz[i];
+	break;
+      }
+    }
+
+    /* Read first two values to deduce YREV flag */
+    if (pfi->dnum[YINDEX] > 1)  {
+      istart = 0;
+      icount = 1; 
+      if (read_one_dimension(pfi, Ycoord, istart, icount, &lat1) == Failure) {
+	gaprnt(0, "gadsdf: Error reading first latitude value in SDF file.\n") ;
+	return Failure;
+      }
+      istart = 1;
+      icount = 1;
+      if (read_one_dimension(pfi, Ycoord, istart, icount, &lat2) == Failure) {
+	gaprnt(0, "gadsdf: Error reading second latitude value in SDF file.\n") ;
+	return Failure;
+      }
+      /* Set yrev flag */
+      if (lat2 < lat1) pfi->yrflg = 1 ;
+    } 
+    
+    /* Read the axis values */
+    if ((sdfdeflev(pfi, Ycoord, YINDEX, pfi->yrflg)) == Failure)  {
+      gaprnt(0, "gadsdf: Failed to define Y coordinate values.\n") ;
+      return Failure;
+    }
+
+  }
+  /* set the ydimid */
+  if (parms.isxdf && (!parms.ysrch)) {
+    ydimid = find_dim(pfi, parms.ydimname) ;
+    if (ydimid == -1) {
+      snprintf(pout,255,"gadsdf: Lat dimension %s is not an SDF dimension.\n",parms.ydimname);
+      gaprnt(0,pout);
+      return Failure;
+    }
+  } 
+  else {
+    if (Ycoord) {
+      ydimid = find_dim(pfi, Ycoord->longnm) ;
+    } else {
+      ydimid = -1 ;
+    }
+  }
+
+  /* Set up the Z coordinate */
+  if (parms.zsetup) {
+    /* find a Z axis */
+    if (parms.zsrch) {
+      (void) findZ(pfi, &Zcoord, &ispress);
+    }
+    else {
+      /* find the axis named in the descriptor file */
+      Zcoord = find_var(pfi, parms.zdimname) ;
+      if (!Zcoord) {
+	snprintf(pout,255,"gadsdf: Can't find variable %s for Z coordinate.\n",parms.zdimname);
+	gaprnt(0,pout);
+	return Failure ;
+      }
+    }
+    if (!Zcoord) {
+      /* set up a dummy zaxis; the equivalent of "zdef 1 linear 0 1" */
+      pfi->dnum[ZINDEX] = 1 ;
+      sz = sizeof(gadouble)*6;
+      if ((zvals = (gadouble *)galloc(sz,"zvals")) == NULL) {
+	gaprnt(0,"gadsdf: Unable to allocate memory for dummy Z coordinate axis values\n");
+	goto err1;
+      }
+      *(zvals) = 1.0;
+      *(zvals+1) = 0.0 - 1.0;
+      *(zvals+2) = -999.9;
+      pfi->grvals[ZINDEX] = zvals;
+      *(zvals+3) = 1.0;
+      *(zvals+4) = 1.0;
+      *(zvals+5) = -999.9;
+      pfi->abvals[ZINDEX] = zvals+3;
+      pfi->ab2gr[ZINDEX] = liconv;
+      pfi->gr2ab[ZINDEX] = liconv;
+      pfi->linear[ZINDEX] = 1;
+    }
+    else {
+      /* set the dimension size */
+      for (i=0;i<pfi->nsdfdims;i++) {
+	if (pfi->sdfdimids[i] == Zcoord->vardimids[0]) {
+	  pfi->dnum[ZINDEX] = pfi->sdfdimsiz[i];
+	  break;
+	}
+      }
+      /* Read first two values to deduce ZREV flag */
+      if (pfi->dnum[ZINDEX] > 1)  {
+	istart = 0;
+	icount = 1; 
+	if (read_one_dimension(pfi, Zcoord, istart, icount, &lev1) == Failure) {
+	  gaprnt(0, "gadsdf: Error reading first Zcoord value in SDF file.\n") ;
+	  return Failure;
+	}
+	istart = 1;
+	icount = 1;
+	if (read_one_dimension(pfi, Zcoord, istart, icount, &lev2) == Failure) {
+	  gaprnt(0, "gadsdf: Error reading second Zcoord value in SDF file.\n") ;
+	  return Failure;
+	}
+	/* Set zrev flag */
+	attr = NULL;
+	attr = find_att(Zcoord->longnm, pfi->attr, "positive") ;
+	if (attr != NULL) {
+	  if (!strncmp("down", (char *)attr->value, 4)) {
+	    if (lev2 > lev1) pfi->zrflg = 1 ;	    /* positive:down */
+	  } 
+	  else {
+	    if (lev2 < lev1) pfi->zrflg = 1 ;        /* positive:up */
+	  }
+	}
+	else if (ispress) {
+	  if (lev2 > lev1) pfi->zrflg = 1 ;  /* pressure is always positive down */
+	} else {
+	  if (lev2 < lev1) pfi->zrflg = 1 ;  /* default is positive up */
+	}
+      } 
+      /* Read the axis values */
+      if ((sdfdeflev(pfi, Zcoord, ZINDEX, pfi->zrflg)) == Failure)  {
+	gaprnt(0, "gadsdf: Failed to define Z coordinate values.\n") ;
+	return Failure;
+      }
+    }
+  }
+  /* set the zdimid */
+  if (parms.isxdf && (!parms.zsrch)) {
+    zdimid = find_dim(pfi, parms.zdimname) ;
+    if (zdimid == -1) {
+      snprintf(pout,255, "gadsdf: Lev dimension %s is not an SDF dimension.\n",parms.zdimname);
+      gaprnt(0,pout);
+      return Failure;
+    }
+  } else {
+    if (Zcoord) {
+      zdimid = find_dim(pfi, Zcoord->longnm) ;
+    } else {
+      zdimid = -1 ;
+    }
+  }
+
+  /* Set up the T coordinate */
+  if (parms.tsetup) {
+    if (parms.tsrch) {
+      /* find a T axis */
+      (void) findT(pfi, &Tcoord);
+    }
+    else {
+      /* find the axis named in the descriptor file */
+      Tcoord = find_var(pfi, parms.tdimname) ;
+      if (!Tcoord) {
+	snprintf(pout,255, "gadsdf: Can't find variable %s for T coordinate.\n",parms.tdimname);
+	gaprnt(0,pout);
+	return Failure ;
+      }
+    }
+    if (!Tcoord) {
+      /* initialize a dummy time coordinate */
+      pfi->dnum[TINDEX] = 1 ;
+      sz = sizeof(gadouble)*8;
+      if ((tvals = (gadouble *) galloc(sz,"tvals1")) == NULL) {
+	gaprnt(0, "gadsdf: memory allocation failed for dummy time coordinate info.\n") ;
+	return Failure ;
+      }
+      tvals[0] = 1.0 ; /* initial year */
+      tvals[1] = 1.0 ; /* initial month */
+      tvals[2] = 1.0 ; /* initial day */
+      tvals[3] = 0.0 ; /* initial hour */
+      tvals[4] = 0.0 ; /* initial minutes */
+      tvals[5] = 0.0 ; /* step in months */
+      tvals[6] = 1.0 ; /* step in minutes */
+      tvals[7] = -999.9 ;
+      pfi->grvals[TINDEX] = tvals ;
+      pfi->abvals[TINDEX] = tvals ;
+      pfi->linear[TINDEX] = 1 ;
+      gaprnt(2, "SDF file has no discernable time coordinate -- using default values.\n") ;
+    }
+    else {
+      /* make sure it's not a 360- or 365-day calendar */
+      attr = NULL;
+      attr = find_att(Tcoord->longnm, pfi->attr, "calendar") ;
+      if (attr) {
+        if (!strncasecmp((char *)attr->value,"360_day", 7)) {
+	  gaprnt(0,"SDF Error: 360 day calendars are not supported by sdfopen.\n"); 
+	  return Failure;
+	}
+	if ((!strncasecmp((char *)attr->value,"cal365",      6)) ||
+	    (!strncasecmp((char *)attr->value,"altcal365",   9)) ||
+	    (!strncasecmp((char *)attr->value,"common_year",11)) ||
+	    (!strncasecmp((char *)attr->value,"365_day",     7)) ||
+	    (!strncasecmp((char *)attr->value,"noleap",      6))) {
+	  
+	  gaprnt(0,"SDF Error: 365 day calendars are no longer supported by sdfopen.\n"); 
+	  gaprnt(0,"  To open this file with GrADS, use a descriptor file with \n");
+	  gaprnt(0,"  a complete TDEF entry and OPTIONS 365_day_calendar. \n");
+	  gaprnt(0,"  Documentation is at http://iges.org/grads/gadoc/SDFdescriptorfile.html\n"); 
+	  return Failure;
+	}
+      }
+      /* set dimension size */
+      for (i=0;i<pfi->nsdfdims;i++) {
+	if (pfi->sdfdimids[i] == Tcoord->vardimids[0]) {
+	  pfi->dnum[TINDEX] = pfi->sdfdimsiz[i];
+	  break;
+	}
+      }
+      /* Set time axis values */
+      /* Get the units attribute */
+      timeunits_attr = NULL;
+      timeunits_attr = find_att(Tcoord->longnm, pfi->attr, "units") ;
+      if (!timeunits_attr) {
+	gaprnt(0, "gadsdf: Couldn't find units attribute for Time coordinate.\n") ;
+	return Failure;
+      }
+      /* Read first two values to deduce time increment */
+      istart = 0;
+      icount = 1; 
+      if (read_one_dimension(pfi, Tcoord, istart, icount, &time1) == Failure) {
+	gaprnt(0, "gadsdf: Error reading first time value in SDF file.\n") ;
+	return Failure;
+      }
+      if (pfi->dnum[TINDEX] > 1)  {
+	istart = 1;
+	icount = 1;
+	if (read_one_dimension(pfi, Tcoord, istart, icount, &time2) == Failure) {
+	  gaprnt(0, "gadsdf: Error reading second time values in SDF file.\n") ;
+	  return Failure;
+	}
+      } 
+      else {
+	time2 = time1;
+      }
+      sz = sizeof(gadouble)*8;
+      if ((tvals = (gadouble *) galloc(sz,"tvals2")) == NULL) {
+	gaprnt(0,"Error finding storage to define time coordinate in SDF file.\n") ;
+	return Failure; 
+      }
+	
+      /* Handle YYMMDDHH time */
+      if ((timeunits_attr->nctype==1) && 
+	  (timeunits_attr->len < 10) &&  
+	  (!strncmp((char *)timeunits_attr->value, "YYMMDDHH", 8))) {
+	tvals[0] = (((gaint) time1) / 1000000) ;
+	tvals[1] = ((((gaint) time1) / 10000) % 100) ;
+	tvals[2] = ((((gaint) time1) / 100) % 100) ;
+	tvals[3] = (((gaint) time1) % 100) ;
+	tvals[4] =  0.0 ;
+	/* If more than one time step, deduce increment */ 
+	if (pfi->dnum[TINDEX] > 1) {
+	  dt2.yr = (((gaint) time2) / 1000000) - (((gaint) time1) / 1000000) ;
+	  dt2.mo = ((((gaint) time2) / 10000) % 100) - ((((gaint) time1) / 10000) % 100) ;
+	  dt2.dy = ((((gaint) time2) / 100) % 100) - ((((gaint) time1) / 100) % 100) ;
+	  dt2.hr = (((gaint) time2) % 100) - (((gaint) time1) % 100) ;
+	  dt2.mn = 0 ;
+	  if ((dt2.yr > 0) || (dt2.mo > 0)) {
+	    tvals[5] = (dt2.yr * 12.0) + dt2.mo ;
+	    tvals[6] = 0.0 ;
+	  } else {
+	    tvals[5] = 0.0 ;
+	    tvals[6] = (dt2.dy * 1440.0) + (dt2.hr * 60.0) + dt2.mn ;
+	    if (tvals[6] < 1.0) {
+	      gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+	      goto err2;
+	    }
+	  }
+	} 
+	else  {
+	  /* only one time step*/
+	  tvals[5] = 0.0 ;
+	  tvals[6] = 1.0 ; /* one time-step files get a (meaningless) delta t of one minute */
+	}
+      } 
+      /* Handle YYYYMMDDHHMMSS time */
+      else if (pfi->time_type == CDC) {
+	if (!decode_standard_time(time1, &iyr, &imo, &idy, &ihr, &imn, &dsec)) {
+	  gaprnt(0, "gadsdf: Error deciphering initial time value in SDF file.\n") ;
+	  goto err2;
+	}
+	if (iyr <= 0) iyr = 1 ;
+	if (imo <= 0) imo = 1 ;
+	if (idy <= 0) idy = 1 ;
+	tvals[0] = iyr ;
+	tvals[1] = imo ;
+	tvals[2] = idy ;
+	tvals[3] = ihr ;
+	tvals[4] = imn ;
+	/* If more than one time step, deduce increment */ 
+	if (pfi->dnum[TINDEX] > 1) {
+	  /* For YYYYMMDDHHMMSS time type, delta_t attribute must be present. */
+	  deltat_attr = NULL;
+	  deltat_attr = find_att(Tcoord->longnm, pfi->attr, "delta_t") ;
+	  if (!deltat_attr) {
+	    gaprnt(0, "gadsdf: Error in determining time increment in SDF file.\n") ;
+	    goto err2;
+	  }
+	  ch = (char *) deltat_attr->value ;
+	  if (!decode_delta_t(ch, &dt2.yr, &dt2.mo, &dt2.dy, &dt2.hr, &dt2.mn, &isec)) {
+	    gaprnt(0, "gadsdf: Error deciphering time increment in SDF file.\n") ;
+	    goto err2;
+	  }
+	  if ((dt2.yr > 0) || (dt2.mo > 0)) {
+	    tvals[5] = (dt2.yr * 12.0) + dt2.mo ;
+	    tvals[6] = 0.0 ;
+	  } else {
+	    tvals[5] = 0.0 ;
+	    tvals[6] = (dt2.dy * 1440.0) + (dt2.hr * 60.0) + dt2.mn ;
+	    if (tvals[6] < 1.0) {
+	      gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+	      goto err2;
+	    }
+	  }
+	} 
+	else {
+	  /* only one time step*/
+	  tvals[5] = 0.0 ;
+	  tvals[6] = 1.0 ; /* one time-step files get a (meaningless) delta t of one minute */
+	}
+      } 
+      /* Handle all other udunits-compatible times */ 
+      else {
+	/* check if units field has an origin */  
+	if (!strstr((char *)timeunits_attr->value, " since ")) {    
+	  /* no origin, use a default */
+	  len_time_units = strlen((char *)timeunits_attr->value) + strlen(DFLTORIGIN) + 1 ;
+	  sz = len_time_units;
+	  time_units = (char *) galloc(sz,"time_un1") ;
+	  if (time_units==NULL) {
+	    gaprnt(0, "gadsdf: Memory allocation error for time_units\n") ;
+	    goto err2;
+	  }
+	  strcpy(time_units, (char *) timeunits_attr->value);
+	  strcat(time_units, DFLTORIGIN);
+	} 
+	else {
+	  len_time_units = strlen((char *)timeunits_attr->value) + 1;
+	  sz = len_time_units;
+	  time_units = (char *) galloc(sz,"time_un2") ;
+	  if (time_units==NULL) {
+	    gaprnt(0, "gadsdf: Memory allocation error for time_units\n");
+	    goto err2;
+	  }
+	  strcpy(time_units, (char *) timeunits_attr->value);
+	} 
+	/* convert unit string to a udunits format */
+	if (utScan(time_units, &timeunit)) {
+	  gaprnt(0, "gadsdf: Error parsing time_units for SDF file.\n") ;
+	  goto err2;
+	}
+	/* convert udunits-formatted time to integer values for yr, mo, etc. */
+	if (utCalendar (time1, &timeunit, &iyr, &imo, &idy, &ihr, &imn, &dsec)) {
+	  gaprnt(0,"gadsdf: Error decoding initial udunits time value in SDF file.\n") ;
+	  goto err2;
+	}
+	if (imo == 0) imo = 1 ;
+	if (idy == 0) idy = 1 ;
+	tvals[0] = iyr ;
+	tvals[1] = imo ;
+	tvals[2] = idy ;
+	tvals[3] = ihr ;
+	tvals[4] = imn ;
+
+	/* If more than one time step, deduce increment */
+	if (pfi->dnum[TINDEX] > 1) {
+	  temp_str = strstr(time_units, " since ") ;
+	  if (!temp_str) {
+	    trunc_point = strlen(time_units) ;
+	  } else {
+	    trunc_point = strlen(time_units)-strlen(temp_str)+1;
+	  }
+	  sz = trunc_point+1;
+          trunc_units = (char *) galloc(sz,"trunc_units");
+	  if (trunc_units==NULL) {
+	    gaprnt(0,"gadsdf: Memory Allocation Error for trunc_units\n");
+	    goto err2;
+	  }
+	  strncpy(trunc_units, time_units, trunc_point) ;
+	  trunc_units[trunc_point] = '\0' ;
+	  istart = 1 ;
+	  incrfactor = time2 - time1 ;
+	    
+	  if (compare_units("year", trunc_units) == Success) /* match is 1 */ {
+	    tvals[5] = 12.0 * incrfactor;
+	    if (tvals[5] < 1.0) {
+	      gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+	      goto err2;
+	    }
+	    tvals[6] = 0.0 ;
+	  } 
+	  else {
+	    /* COARDS conventions say only year, day, hour, and minute are OK, not month */
+	    /* But I've accepted Camiel's patch for "months since ..."  -Hoop 2K/07/25 */
+	    tvals[5] = 0.0 ;
+	    if ((!strncmp(time_units, "month", 5)) ||
+		(!strncmp(time_units, "common_year/12", 14)) ||
+		(!strncmp(time_units, "common_years/12", 15))) {
+	      tvals[5] = incrfactor;
+	      tvals[6] = 0.0 ;
+	      if (tvals[5] < 1.0) {
+		gaprnt(0, "gadsdf: Fractional months are ill-defined and not supported by GrADS\n") ;
+		goto err2;
+	      }
+	    } 
+	    else if (compare_units("day", trunc_units) == Success) {
+	      if (incrfactor < 28.0) {
+		tvals[6] = incrfactor * 24.0 * 60.0 ;  /* convert units from days to minutes */
+		/* round this to the nearest minute */
+		tvals[6]=floor(tvals[6]+0.5);
+		if (tvals[6] < 1.0) {
+		  gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		  goto err2;
+		}
+	      } 
+	      else if (incrfactor < 360.0) /* assume really months */ {
+		/* This dirty trick should get the right number of months for monthly, */
+		/* bi-monthly, and seasonal data.  If there's anything between that and */
+		/* annual data (which should have units of "year(s) since"), we're broken */
+		tvals[5] = ((gaint) (incrfactor + 0.5)) / 28;
+		tvals[6] = 0.0 ;
+		if (tvals[5] < 1.0) {
+		  gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		  goto err2;
+		}
+	      } 
+	      else /* annual or multi-annual w/"days since" */{
+		/* also a dirty trick to figure out how many years & mult. by 12 */
+		tvals[5] = 12.0 * ((gadouble)(((gaint) (incrfactor + 0.5))/360)) ;
+		tvals[6] = 0.0 ;
+	      }
+	    } 
+	    else if (compare_units("hour", trunc_units) == Success) {
+	      if (incrfactor < (28.0 * 24.0)) {
+		tvals[6] = incrfactor * 60.0 ;
+		if (tvals[6] < 1.0) {
+		  gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		  goto err2;
+		}
+	      } 
+	      else  {
+		if (incrfactor >= (360 * 24)) /* try years? */{
+		  tvals[5] = 12.0 * ((gadouble) ((gaint)
+						  (((gaint)(incrfactor + 0.5)) / (360.0 * 24.0)))) ;
+		  tvals[6] = 0.0 ;
+		} 
+		else /* assume really months */ {
+		  tvals[5] = ((gaint) (incrfactor + 0.5)) / (28 * 24);
+		  tvals[6] = 0.0 ;
+		}
+		if (tvals[5] < 1.0) {
+		  gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		  goto err2;
+		}
+	      }
+	    } 
+	    else if (compare_units("minute", trunc_units) == Success) {
+	      if (incrfactor < (60.0 * 24.0 * 28.0)) {
+		tvals[5] = 0.0 ;
+		tvals[6] = incrfactor ;
+		if (tvals[6] < 1.0) {
+		  gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		  goto err2;
+		}
+	      } 
+	      else /* monthly or greater */ {
+		if (tvals[6] < (60.0 * 24.0 * 360.0)) {
+		  tvals[5] = ((gaint) ((incrfactor / (60.0 * 24.0)) + 0.5)) / 28;
+		  tvals[6] = 0.0 ;
+		} 
+		else {
+		  gaprnt(0,"gadsdf: Time increment too large for 'minutes since' time units attribute\n");
+		  goto err2;
+		}
+	      }
+	    } 
+	    else if (compare_units("seconds", trunc_units) == Success) {
+	      if (incrfactor < 60.0) {
+		gaprnt(0, "gadsdf: Time unit has too small an increment (min. 1 minute).\n") ;
+		goto err2;
+	      } 
+	      else {
+		if (incrfactor < (60.0 * 60.0 * 24.0 * 28.0)) {
+		  /* less than monthly, so use tvals[6] */
+		  tvals[6] = incrfactor / 60.0 ;
+		} 
+		else /* monthly or greater */ {
+		  if (incrfactor < (60.0 * 60.0 * 24.0 * 360)) {
+		    /* assume monthly */
+		    tvals[5] = ((gaint) ((incrfactor/(60.0 * 60.0 * 24.0)) + 0.5)) / 28;
+		    tvals[6] = 0.0 ;
+		  } 
+		  else {
+		    gaprnt(0,"gadsdf: Time increment too large for 'seconds since' time units attribute\n");
+		    goto err2;
+		  }
+		}
+	      }
+	    } 
+	    else {
+	      gaprnt(0, "gadsdf: Error parsing time units in SDF file.\n") ;
+	      goto err2;
+	    }
+	  } /* finer than years resolution */
+	}
+	else {
+	  /* only one time step */
+	  tvals[5] = 0.0 ;
+	  tvals[6] = 1.0 ; /* one time-step files get a (meaningless) delta t of one minute */
+	} 
+	if (time_units)  gree(time_units,"f1");
+	if (trunc_units) gree(trunc_units,"f2") ;
+      } /* end if udunits time */
+
+      /* Set scaling values */
+      tvals[7] = -999.9 ;
+      pfi->grvals[TINDEX] = tvals ;
+      pfi->abvals[TINDEX] = tvals ;
+      pfi->linear[TINDEX] = 1 ;
+
+    } /* has a T coordinate */
+  } /* doing T setup */
+
+  /* Set the tdimid */
+  if (parms.isxdf && (!parms.tsrch)) {
+    if (parms.tdimname != NULL) {
+      tdimid = find_dim(pfi, parms.tdimname) ;
+      if (tdimid == -1) {
+	snprintf(pout,255, "gadsdf: Time dimension %s is not an SDF dimension.\n",parms.tdimname);
+	gaprnt(0,pout);
+	return Failure;
+      }
+    }
+    else tdimid = -1;  /* this is for the %nodim% option in TDEF */
+  }
+  else {
+    if (Tcoord) {
+      tdimid = find_dim(pfi, Tcoord->longnm) ;
+    } else {
+      tdimid = -1 ;
+    }
+  }
+  
+   /* Set up the E coordinate */
+  if (parms.esetup) {
+    if (parms.esrch) {   
+    /* find an E axis */
+      (void) findE(pfi, &Ecoord);
+    }
+    else {    
+      /* find the axis named in the descriptor file */
+      Ecoord = find_var(pfi, parms.edimname) ;
+      if (!Ecoord) {
+	snprintf(pout,255,"gadsdf: Can't find variable %s for Ensemble coordinate.\n",parms.edimname);
+	gaprnt(0,pout);
+	return Failure ;
+      }
+    } 
+    if (!Ecoord) {  /* no ensemble dimension found */
+      if (parms.esetup != 4 && pfi->ens1==NULL ) { /* the dummy E axis was not set up in gadxdf */
+	/* set up the default values */
+	pfi->dnum[EINDEX] = 1;
+	/* set up linear scaling */
+	sz = sizeof(gadouble)*6;
+	if ((evals = (gadouble *)galloc(sz,"evals")) == NULL) {
+	  gaprnt(0,"gadsdf: memory allocation failed for default ensemble dimension scaling values\n");
+	  goto err1;
+	}
+	v1=v2=1;
+	*(evals+1) = v1 - v2;
+	*(evals) = v2;
+	*(evals+2) = -999.9;
+	*(evals+4) = -1.0 * ( (v1-v2)/v2 );
+	*(evals+3) = 1.0/v2;
+	*(evals+5) = -999.9;
+	pfi->grvals[EINDEX] = evals;
+	pfi->abvals[EINDEX] = evals+3;
+	pfi->ab2gr[EINDEX] = liconv;
+	pfi->gr2ab[EINDEX] = liconv;
+	pfi->linear[EINDEX] = 1;
+	/* allocate a single ensemble structure */
+	sz = sizeof(struct gaens);
+	if ((ens = (struct gaens *)galloc(sz,"ens1")) == NULL) {
+	  gaprnt(0,"gadsdf: memory allocation failed for default E axis values\n");
+	  goto err1;
+	}
+	pfi->ens1 = ens;
+	snprintf(ens->name,15,"1");
+	ens->length = pfi->dnum[TINDEX];
+	ens->gt = 1;
+	gr2t(pfi->grvals[TINDEX],1.0,&ens->tinit);
+	/* set grib codes to default values */
+	for (j=0;j<4;j++) ens->grbcode[j]=-999;
+      }
+    }
+    else { 
+      /* We have a dimension */  
+      if (parms.esetup == 3) {   /* we still need size, ensemble names, time metadata */
+	/* set the dimension size */
+	for (i=0;i<pfi->nsdfdims;i++) {
+	  if (pfi->sdfdimids[i] == Ecoord->vardimids[0]) {
+	    pfi->dnum[EINDEX] = pfi->sdfdimsiz[i];
+	    break;
+	  }
+	}
+	/* set up linear scaling */
+	sz = sizeof(gadouble)*6;
+	if ((evals = (gadouble *)galloc(sz,"evals1")) == NULL) {
+	  gaprnt(0,"gadsdf: memory allocation failed for ensemble dimension scaling values\n");
+	  goto err1;
+	}
+	v1=v2=1;
+	*(evals+1) = v1 - v2;
+	*(evals) = v2;
+	*(evals+2) = -999.9;
+	*(evals+4) = -1.0 * ( (v1-v2)/v2 );
+	*(evals+3) = 1.0/v2;
+	*(evals+5) = -999.9;
+	pfi->grvals[EINDEX] = evals;
+	pfi->abvals[EINDEX] = evals+3;
+	pfi->ab2gr[EINDEX] = liconv;
+	pfi->gr2ab[EINDEX] = liconv;
+	pfi->linear[EINDEX] = 1;
+       
+	/* allocate an array of ensemble structures */
+	sz = pfi->dnum[EINDEX] * sizeof(struct gaens); 
+	if ((ens = (struct gaens *)galloc(sz,"ens2")) == NULL) {
+	  gaprnt(0,"gadsdf: memory allocation failed for E axis values\n");
+	  goto err1;
+	}
+	pfi->ens1 = ens;
+      }
+      if (parms.esetup >= 2) {   /* still need ensemble names, time metadata */
+	/* first see if there is an attribute containing ensemble names in the file */
+	noname=1;
+	if (pfi->ncflg==2) {
+	  gaprnt(0,"Contact the GrADS developers if you have an HDF file with ensemble metadata\n");
+	  return Failure;
+	} 
+	else {
+	  attr = NULL;
+	  attr = find_att("ens", pfi->attr, "grads_name");
+	  if (attr) {
+	    noname=0;
+	    pos = (char*)attr->value;  /* set the pointer to the beginning of the string */
+	  }
+	}
+	/* loop through array of ensemble structures, assigning names */
+	ens = pfi->ens1;
+	i=1;
+	while (i<=pfi->dnum[EINDEX]) {
+	  if (noname) {
+	    snprintf(ens->name,15,"%d",i);   /* default to ensemble index number for a name */
+	  }
+	  else {
+	    /* get the ensemble name */
+	    len=0;
+	    while (len<16 && *pos!=',' ) {
+	      ens->name[len] = *pos;
+	      len++; 
+	      pos++;
+	    }
+	    ens->name[len] = '\0';
+	    pos++;  /* advance past the comma */
+	  }
+	  i++; ens++;
+	}
+      }
+
+      /* Get the time metadata for each ensemble */
+      /* Look for attributes containing lengths and initial time indices */
+      nolength=1;
+      attr1 = NULL;
+      attr1 = find_att("ens", pfi->attr, "grads_length");
+      if (attr1) {
+	nolength=0;
+	pos1 = (char*)attr1->value;
+      }
+      notinit=1;
+      attr2 = NULL;
+      attr2 = find_att("ens", pfi->attr, "grads_tinit");
+      if (attr2) {
+	notinit=0;
+	pos2 = (char*)attr2->value;
+      }
+      /* loop through array of ensemble structures, assigning lengths and initial times */
+      ens = pfi->ens1;
+      i=1;
+      while (i<=pfi->dnum[EINDEX]) {
+	/* assign length and start time index of each ensemble member */
+	if (nolength) {
+	  ens->length = pfi->dnum[3];     /* default to length of time axis */
+	} else {
+	  /* get the ensemble length */
+	  pos1 = intprs(pos1,&ens->length);
+	  pos1++;  /* advance past the comma */
+	}
+	if (notinit) {
+	  ens->gt = 1;                     /* default to start of time axis */
+	} else {
+	  pos2 = intprs(pos2,&ens->gt);
+	  pos2++;  /* advance past the comma */
+	}
+	/* populate the tinit structure for each ensemble */
+	gr2t(pfi->grvals[TINDEX],(gadouble)ens->gt,&ens->tinit);
+	/* set grib codes to default values */
+	for (j=0;j<4;j++) ens->grbcode[j]=-999;  
+	i++; ens++;
+
+      }
+    }
+  }
+
+  /* set the edimid */
+  if (parms.isxdf && (!parms.esrch)) {
+    edimid = find_dim(pfi, parms.edimname) ;
+    if (edimid == -1) {
+      snprintf(pout,255,"gadsdf: Ensemble dimension %s is not an SDF dimension.\n",parms.edimname);
+      gaprnt(0,pout);
+      return Failure;
+    }
+  } else {
+    if (Ecoord) {
+      edimid = find_dim(pfi, Ecoord->longnm) ;
+    } else {
+      edimid = -1 ;
+    }
+  }
+
+  /* rewrite the fnums array if E > 1 */
+  if (pfi->tmplat && pfi->dnum[4]>1) {
+    /* first, free the memory used to set up fnums in gadxdf */
+    if (pfi->fnums != NULL) gree(pfi->fnums,"f20a");
+
+    /* The fnums array is the size of the time axis multiplied by the
+       size of the ensemble axis. It contains the t index which generates
+       the filename that contains the data for each timestep. If the ensemble 
+       has no data file for a given time, the fnums value will be -1 */
+    sz = sizeof(gaint)*pfi->dnum[3]*pfi->dnum[4];
+    pfi->fnums = (gaint *)galloc(sz,"fnums1");   
+    if (pfi->fnums==NULL) {
+      gaprnt(0,"Open Error: memory allocation failed for fnums\n");
+      goto err2;
+    }
+    /* get dt structure for t=1 */
+    gr2t(pfi->grvals[3],1.0,&tdefi);
+    /* loop over ensembles */
+    ens=pfi->ens1;
+    e=1;
+    while (e<=pfi->dnum[4]) {
+      j = -1; 
+      t=1;
+      /* set fnums value to -1 for time steps before ensemble initial time */
+      while (t<ens->gt) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      j = ens->gt;
+      /* get dt structure for ensemble initial time */
+      gr2t(pfi->grvals[3],ens->gt,&tdefe);
+      /* get filename for initial time of current ensemble member  */
+      ch = gafndt(pfi->name,&tdefe,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,ens->gt,e,&flag);   
+      if (ch==NULL) {
+	snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,ens->gt);
+	gaprnt(0,pout);
+	goto err2;
+      }
+      pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      /* loop over remaining valid times for this ensemble */
+      for (t=ens->gt+1; t<ens->gt+ens->length; t++) {
+	/* get filename for time index=t ens=e */
+	gr2t(pfi->grvals[3],(gadouble)t,&tdef);
+	pos = gafndt(pfi->name,&tdef,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,t,e,&flag);  
+	if (pos==NULL) {
+	  snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,t);
+	  gaprnt(0,pout);
+	  goto err2;
+	}
+	if (strcmp(ch,pos)!=0) {    /* filename has changed */
+	  j = t;   
+	  gree(ch,"f47");
+	  ch = pos;
+	}
+	else {
+	  gree(pos,"f48");
+	}
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      }
+      gree(ch,"f48a");
+      /* set fnums value to -1 for time steps after ensemble final time */
+      j = -1;
+      while (t<=pfi->dnum[3]) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      e++; ens++;
+    }
+    pfi->fnumc = 0;
+    pfi->fnume = 0;
+  }
+
+  /* Find all the data variables */
+  numdvars = 0 ;
+  pvar = pfi->pvar1;  
+  i=0;
+  /* loop through complete variable list */
+  while (i<pfi->vnum) {
+    isDatavar=0 ;
+    pvar->isdvar=0;
+    isDatavar = isdvar(pfi, pvar, xdimid, ydimid, zdimid, tdimid, edimid);
+    if (isDatavar==Success) {
+      /* Compare to varnames in the list from the xdf descriptor */
+      if (parms.isxdf && (!parms.dvsrch)) {
+	varnames = parms.names1;
+	j=0;
+        flag=1;
+	while (j<parms.dvcount && flag) {
+	  if (!strcmp(pvar->longnm, varnames->longnm)) {
+	    for (c=0; c<16; c++) pvar->abbrv[c] = varnames->abbrv[c];
+	    numdvars++;
+	    pvar->isdvar=1;
+	    flag=0;
+	  }
+	  j++; varnames++;
+	}
+      }
+      /* we'll use all data variables we can find */
+      else {  
+	numdvars++; 
+	pvar->isdvar=1;
+	/* create a GrADS-friendly variable name */
+	strncpy(pvar->abbrv, pvar->longnm, 15);
+	pvar->abbrv[15] = '\0';
+	lowcas(pvar->abbrv);
+      }
+    }
+    i++; pvar++;
+  }                                                                                      
+  if (numdvars == 0) {
+    gaprnt(0,"gadsdf: SDF file does not have any non-coordinate variables.\n") ;
+    return Failure;
+  } 
+  else {
+    /* allocate a new array of gavar structures */
+    sz = numdvars*sizeof(struct gavar);
+    if ((newpvar = (struct gavar *) galloc(sz,"newpvar")) == NULL) {
+      gaprnt(0, "gadsdf: unable to allocate memory for data variable array.\n");
+      goto err1;
+    }
+    savepvar=newpvar;
+    /* copy all the valid data variables into the new variable array */
+    pvar = pfi->pvar1;  
+    i=0;
+    while (i<pfi->vnum) {
+      if (pvar->isdvar == 1) {
+	*newpvar = *pvar;
+	newpvar->ncvid = -999; /* reset the varid so undefs will be read in gaio.c */
+	newpvar->sdvid = -999; /* reset the varid so undefs will be read in gaio.c */
+	newpvar++;
+      }
+      i++; pvar++;
+    }
+    /* update the gafile structure with the new gavar array and new vnum */
+    gree(pfi->pvar1,"f4");
+    pfi->pvar1 = savepvar;
+    pfi->vnum = numdvars;
+
+  }
+
+  /* Allocate an I/O buffer the size of one row */
+  sz = pfi->dnum[XINDEX] * sizeof(gadouble);
+  if ((pfi->rbuf = (gadouble *)galloc(sz,"rbuf")) == NULL) goto err1;
+  sz = pfi->dnum[XINDEX] * sizeof(char);
+  if ((pfi->ubuf = (char *)galloc(sz,"ubuf")) == NULL) goto err1;
+
+  /* Set one last parameter in the gafile structure */
+  pfi->gsiz = pfi->dnum[XINDEX] * pfi->dnum[YINDEX];
+
+  /* Set the default netcdf/hdf5 cache size to be big enough to contain 
+     a global 2D grid of 8-byte data values times the global cache scale factor */
+  if (pfi->cachesize == (long)-1) {
+    sf = qcachesf();
+    sf = sf * 8 * pfi->dnum[0] * pfi->dnum[1];
+    pfi->cachesize = (long)floor(sf) ;
+  }
+  /* set the netCDF-4 cache size */
+  sz = (size_t)pfi->cachesize;
+  set_nc_cache(sz);
+
+  return Success;
+
+err2:
+  if (time_units) gree(time_units,"f5");
+  if (trunc_units) gree(trunc_units,"f6") ;
+  if (tvals) gree(tvals,"f7");
+  return Failure;
+err1:
+  gaprnt (0,"gadsdf: Memory allocation error\n");
+  return Failure;
+
+}
+
+int compare_units(char *test_unit, char *trunc_unit) {
+  utUnit testing_unit, truncated_unit ;
+  gaint rc ;
+  gadouble slope, intercept ;
+    
+  rc = utScan(test_unit, &testing_unit) ;
+  if (rc != 0) return Failure ;
+
+  rc = utScan(trunc_unit, &truncated_unit) ;
+  if (rc != 0) return Failure;
+
+  rc = utConvert(&truncated_unit, &testing_unit, &slope, &intercept) ;
+  if (rc != 0) return Failure;
+
+  if (dequal(slope, 1.0, (gadouble)1.0e-8)==0 && dequal(intercept, 0.0, (gadouble)1.0e-8)==0) 
+    return Success;
+  else 
+    return Failure;
+}
+
+
+gaint isdvar(struct gafile *pfi, struct gavar *var, 
+	   gaint xdimid, gaint ydimid, gaint zdimid, gaint tdimid, gaint edimid) {
+  gaint i, hasX, hasY, hasZ, hasT, hasE;
+  struct gaattr *attr; 
+
+  /* Check if var is a coordinate variable */
+  if (var->nvardims == 1) {  /* var is 1-D */
+    for (i=0; i<pfi->nsdfdims; i++) {
+      if (var->vardimids[0] == pfi->sdfdimids[i]) { /* var dimid matches a file dimid */
+	if (!strcmp(pfi->sdfdimnam[i], var->longnm)) { /* var name matches dimension name */
+	  return Failure;
+	}
+      }
+    }
+  }
+
+  /* Determine which of var's coordinate dimensions match the 5 grid dimids */
+  hasX = hasY = hasZ = hasT = hasE = 0;
+  for (i=0 ; i<var->nvardims; i++) {
+    if      (var->vardimids[i] == xdimid) { var->units[i]=-100; hasX=1; }
+    else if (var->vardimids[i] == ydimid) { var->units[i]=-101; hasY=1; }
+    else if (var->vardimids[i] == zdimid) { var->units[i]=-102; hasZ=1; }
+    else if (var->vardimids[i] == tdimid) { var->units[i]=-103; hasT=1; }
+    else if (var->vardimids[i] == edimid) { var->units[i]=-104; hasE=1; }
+  }
+
+  if (hasX || hasY || hasZ || hasT || hasE) {
+
+    /* Check if any of var's dimids do not match the 5 grid dimids */
+    for (i=0 ; i<var->nvardims; i++) {
+      if (var->vardimids[i] != xdimid && 
+	  var->vardimids[i] != ydimid && 
+	  var->vardimids[i] != zdimid && 
+	  var->vardimids[i] != tdimid && 
+	  var->vardimids[i] != edimid) 
+	return Failure;
+    }
+
+    /* Set the number of vertical levels for var */
+    if (hasZ) {
+      var->levels = pfi->dnum[ZINDEX];
+    } 
+    else {
+      var->levels = 0;
+    }
+
+    /* Create a variable description */
+    attr = NULL;
+    attr = find_att(var->longnm, pfi->attr, "long_name");
+    if (attr == NULL) attr = find_att(var->longnm, pfi->attr, "standard_name");
+    if (attr == NULL) {
+      strncpy(var->varnm,var->longnm,126);
+      var->varnm[127] = '\0';
+    }
+    else {
+      if (attr->len < 128) {
+	strcpy(var->varnm,(char*)attr->value);
+	var->varnm[attr->len-1] = '\0';
+      }
+      else {
+	strncpy(var->varnm,(char*)attr->value,127);
+	var->varnm[127] = '\0';
+      }
+    }
+    return Success;
+  }
+  return Failure;
+}
+
+
+/* Adapted from deflev routine */
+gaint sdfdeflev(struct gafile *pfi, struct gavar *coord, gaint dim, gaint revflag) {
+gadouble *axisvals=NULL, *vals=NULL,*aptr=NULL,*vvs=NULL,*ddata=NULL;
+gadouble delta1,delta2,val1,val2,incr,v1,v2;
+gafloat  *fdata=0;
+size_t sz,start[16],count[16];
+gaint    rc,i,len,flag=0,status=0;
+#if USEHDF == 1
+int32 hstart[16],hcount[16];
+int32 rank,natts,dim_sizes[H4_MAX_VAR_DIMS],dtype,sds_id;
+int32 *idata=NULL;
+uint32 *uidata=NULL;
+#endif
+
+  /* allocate an array of doubles to hold coordinate axis values */
+  len = pfi->dnum[dim] ; 
+  sz = sizeof(gadouble)*len;
+  if ((axisvals = (gadouble *)galloc(sz,"axisvals")) == NULL) {
+    gaprnt(0,"sdfdeflev: Unable to allocate memory for reading coordinate axis values\n");
+    return Failure;
+  }
+  aptr=axisvals;  /* keep a copy of pointer to start of array */
+
+  /* initialize start and count arrays */
+#if USENETCDF==1
+  for (i=0 ; i<16 ; i++) {
+    start[i] = 0; 
+    count[i] = 1; 
+  }
+  count[0] = (size_t)len; 
+#endif
+#if USEHDF == 1    
+  for (i=0 ; i<16 ; i++) {
+    hstart[i]=0;
+    hcount[i]=0;
+  }
+  hcount[0] = (int32)len; 
+#endif
+
+  /* read the data */
+#if USEHDF == 1
+  if (pfi->ncflg==2) {
+    /* get the data type */
+    if ((sds_id = SDselect(pfi->sdid,coord->sdvid))==FAIL) return Failure;
+    rc = SDgetinfo(sds_id, coord->longnm, &rank, dim_sizes, &dtype, &natts);
+    if (rc == -1) {
+      gaprnt(0,"sdfdeflev: unable to determine coordinate axis data type\n");
+      goto err1;
+    }
+    switch (dtype) {
+    case (DFNT_INT32):    /* definition value 24 */
+      sz = len * sizeof (int32);
+      if ((idata = (int32 *)galloc(sz,"idata"))==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype INT32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, hstart, NULL, hcount, (VOIDP *)idata) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype INT32\n");
+	return(1);
+      } 
+      if (revflag) {
+	for (i=len-1; i>=0; i--) {
+	  *aptr = (gadouble)idata[i]; 
+	  aptr++;
+	}
+      }
+      else {
+	for (i=0; i<len; i++) {
+	  *aptr = (gadouble)idata[i]; 
+	  aptr++;
+	}
+      }
+      gree(idata,"f130a");
+      break;
+
+    case (DFNT_UINT32):   /* definition value 25 */
+      sz = len * sizeof (uint32);
+      if ((uidata = (uint32 *)galloc(sz,"uidata"))==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype UINT32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, hstart, NULL, hcount, (VOIDP *)uidata) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype UINT32\n");
+	return(1);
+      } 
+      if (revflag) {
+	for (i=len-1; i>=0; i--) {
+	  *aptr = (gadouble)uidata[i]; 
+	  aptr++;
+	}
+      }
+      else {
+	for (i=0; i<len; i++) {
+	  *aptr = (gadouble)uidata[i]; 
+	  aptr++;
+	}
+      }
+      gree(uidata,"f131a");
+      break;
+
+    case (DFNT_FLOAT32):   /* definition value 5 */
+      sz = len * sizeof (gafloat);
+      if ((fdata = (gafloat *)galloc(sz,"fdata"))==NULL) {
+	gaprnt(0,"HDF-SDS Error: unable to allocate memory for dtype FLOAT32\n");
+	return(1);
+      }
+      if (SDreaddata(sds_id, hstart, NULL, hcount, (VOIDP *)fdata) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype FLOAT32\n");
+	return(1);
+      } 
+      if (revflag) {
+	for (i=len-1; i>=0; i--) {
+	  *aptr = (gadouble)fdata[i]; 
+	  aptr++;
+	}
+      }
+      else {
+	for (i=0; i<len; i++) {
+	  *aptr = (gadouble)fdata[i]; 
+	  aptr++;
+	}
+      }
+      gree(fdata,"f131");
+      break;
+
+    case (DFNT_FLOAT64):  /* definition value  6 */
+      sz = sizeof(gadouble)*len;
+      if ((ddata = (gadouble *)galloc(sz,"ddata")) == NULL) {
+	gaprnt(0,"sdfdeflev: unable to allocate memory for coordinate axis type NC_DOUBLE\n");
+	goto err1;
+      }
+      if (SDreaddata(sds_id, hstart, NULL, hcount, (VOIDP *)ddata) != 0) {
+	gaprnt(0,"HDF-SDS Read Error for dtype FLOAT32\n");
+	return(1);
+      } 
+      if (revflag) {
+	for (i=len-1; i>=0; i--) {
+	  *aptr = (gadouble)ddata[i]; 
+	  aptr++;
+	}
+      }
+      else {
+	for (i=0; i<len; i++) {
+	  *aptr = (gadouble)ddata[i]; 
+	  aptr++;
+	}
+      }
+      gree(ddata,"f131");
+      break;
+      
+    default:
+      snprintf(pout,255,"HDF coordinate axis data type %d not handled\n",dtype);
+      gaprnt(0,pout);
+      goto err1;
+    };
+    
+  }
+#endif
+
+#if USENETCDF==1
+  if (pfi->ncflg==1) {
+    sz = sizeof(gadouble)*len;
+    if ((ddata = (gadouble *)galloc(sz,"ddata")) == NULL) {
+      gaprnt(0,"sdfdeflev: unable to allocate memory for coordinate axis values\n");
+      goto err1;
+    }
+    status = nc_get_vara_double(pfi->ncid, coord->ncvid, start, count, ddata);
+    if (status != NC_NOERR) {
+      gaprnt(0,"sdfdeflev: nc_get_vara_double failed to read coordinate axis values \n");
+      handle_error(status);
+      gree(ddata,"f15");
+      goto err1;
+    }
+    if (revflag) {
+      for (i=len-1; i>=0; i--) {
+	*aptr = ddata[i];
+	aptr++;
+      }
+    }
+    else {
+      for (i=0; i<len; i++) {
+	*aptr = ddata[i]; 
+	aptr++;
+      }
+    }
+    if (ddata) gree(ddata,"f16");
+  }
+#endif
+  
+  /* Check if dimension is linear */
+  if (len < 3) {
+    pfi->linear[dim] = 1;
+  }
+  else {
+    flag=0;
+    delta1 = axisvals[1]-axisvals[0];
+    for (i=2; i<len; i++) {
+      delta2 = axisvals[i]-axisvals[i-1];
+      if (dequal(delta1, delta2, 1.0e-8) == 1) {
+ 	flag=1;
+	break; 
+      } 
+    }
+    if (flag) 
+      pfi->linear[dim] = 0;
+    else 
+      pfi->linear[dim] = 1;
+  }
+
+  /* Set linear scaling values */
+  if (pfi->linear[dim]==1) {
+    sz = sizeof(gadouble)*6;
+    vals = (gadouble *)galloc(sz,"linearvals");
+    if (vals==NULL) goto err1;
+    v1 = axisvals[0];
+    if (len==1)
+      v2 = 1.0;
+    else
+      v2 = axisvals[1]-axisvals[0];
+    *(vals)   = v2;
+    *(vals+1) = v1 - v2;
+    *(vals+2) = -999.9;
+    pfi->grvals[dim] = vals;
+    *(vals+3) = 1.0/v2;
+    *(vals+4) = -1.0 * ((v1-v2)/v2);
+    *(vals+5) = -999.9;
+    pfi->abvals[dim] = vals+3;
+    pfi->ab2gr[dim] = liconv;
+    pfi->gr2ab[dim] = liconv;
+  }
+  else {
+    /* set non-linear scaling values */
+    sz = (pfi->dnum[dim]+5)*sizeof(gadouble);
+    vals = (gadouble *)galloc(sz,"levelvals");
+    if (vals==NULL) goto err1;
+    
+    vvs = vals;
+    *vvs = (gadouble)pfi->dnum[dim];
+    vvs++;
+    for (i=0; i<len; i++) {
+      *vvs = axisvals[i];
+      vvs++;
+    }
+    *vvs = -999.9;
+    pfi->abvals[dim] = vals;
+    pfi->grvals[dim] = vals;
+    pfi->ab2gr[dim] = lev2gr;
+    pfi->gr2ab[dim] = gr2lev;
+  }
+
+  /* Check if we need to convert Pa to mb */
+  if ((dim==2) && (pfi->pa2mb)) {
+    for (i=1; i<=pfi->dnum[2]; i++) {
+      *(pfi->grvals[2]+i) = *(pfi->grvals[2]+i)/100;
+    }
+  }
+
+
+  /* check if longitudes wrap around the globe */
+  if ((dim==0) && (pfi->linear[dim]) && (len > 2) ) {
+    val1 = axisvals[0]; 
+    incr = axisvals[1]-axisvals[0];
+    val2 = val1 + (len * incr);
+    if (fabs((val2-360.0)-val1)<0.01) pfi->wrap = 1;
+  }
+  
+  gree(axisvals,"f17a");
+  return Success ;
+ 
+err1:
+  gree(axisvals,"f17");
+  return Failure;
+}
+
+
+/* check for coordinate variable that 
+   1) has units degrees_east, degree_east, degrees_E, or degree_E, or
+   2) has an "axis" attribute with a value of "X"
+*/
+gaint findX (struct gafile *pfi, struct gavar **Xcoordptr) {
+  struct gaattr *attr ;
+  struct gavar *lclvar ;
+  gaint iscoordvar, i, j, match;
+
+  i=0;
+  lclvar = pfi->pvar1;  
+  while (i<pfi->vnum) {
+    iscoordvar = 0 ;
+    if (lclvar->nvardims == 1) {  /* variable must be 1-D */
+      for (j=0; j<pfi->nsdfdims; j++) {
+	if (lclvar->vardimids[0] == pfi->sdfdimids[j]) { /* var dimid matches a file dimid */
+	  if (!strcmp(pfi->sdfdimnam[j], lclvar->longnm)) { /* var name matches dimension name */
+	    iscoordvar = 1 ;
+	  }
+	}
+      }
+    }
+    if (iscoordvar) {
+      /* look for "units" attribute */
+      attr = NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "units");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "degrees_east", 12)) match=1;
+	if (!strncmp(attr->value, "degree_east",  11)) match=1;
+	if (!strncmp(attr->value, "degrees_E",     9)) match=1;
+	if (!strncmp(attr->value, "degree_E",      8)) match=1;
+	if (match) {
+	  *Xcoordptr = lclvar ;
+	  return Success ;  /* got a match on one of them */
+	}
+      }
+      /* look for "axis" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "axis");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "X", 1)) match=1;
+	if (!strncmp(attr->value, "x", 1)) match=1;
+	if (match) {
+	  *Xcoordptr = lclvar ;
+	  return Success ;  /* got a match on */
+	}
+      }
+    }
+    i++; lclvar++;
+  } 
+  return Failure ;
+}
+  
+/* check for coordinate variable that 
+   1) has units degrees_north, degree_north, degrees_N, or degree_N, or
+   2) has an "axis" attribute with a value of "Y"
+*/
+gaint findY(struct gafile *pfi, struct gavar **Ycoordptr) {
+  struct gaattr *attr;
+  struct gavar *lclvar;
+  gaint iscoordvar, i, j, match;
+
+  i=0;
+  lclvar=pfi->pvar1;
+  while (i<pfi->vnum) {
+    iscoordvar = 0 ;
+    if (lclvar->nvardims == 1) {  /* variable must be 1-D */
+      for (j=0; j<pfi->nsdfdims; j++) {
+	if (lclvar->vardimids[0] == pfi->sdfdimids[j]) { /* variable dimid matches a file dimid */
+	  if (!strcmp(pfi->sdfdimnam[j], lclvar->longnm)) { /* variable name matches dimension name */
+	    iscoordvar = 1 ;
+	  }
+	}
+      } 
+    }
+    if (iscoordvar) {
+      /* look for "units" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "units");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "degrees_north", 13)) match=1;
+	if (!strncmp(attr->value, "degree_north",  12)) match=1;
+	if (!strncmp(attr->value, "degrees_N",      9)) match=1;
+	if (!strncmp(attr->value, "degree_N",       8)) match=1;
+	if (match) {
+	  *Ycoordptr = lclvar;
+	  return Success;  /* got a match on one of them */
+	}
+      }
+      /* look for "axis" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "axis");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "Y", 1)) match=1;
+	if (!strncmp(attr->value, "y", 1)) match=1;
+	if (match) {
+	  *Ycoordptr = lclvar ;
+	  return Success ;  /* got a match on */
+	}
+      }
+    }
+    i++; lclvar++;
+  }
+  return Failure;
+}
+
+/* check for coordinate variable that 
+   1) has units of pressure or another unit approved by COARDS conventions. 
+   initially, the pressure units are "millibars" or "pascals" (caseless)
+   should probably allow for prefixes through udunits package
+   Will also allow exact match on "mb" 
+   2) has an "axis" attribute with a value of "Z", or 
+*/
+gaint findZ(struct gafile *pfi, struct gavar **Zcoordptr, gaint *ispressptr) {
+  struct gaattr *attr;
+  struct gavar  *lclvar ;
+  gaint iscoordvar, i, j, match;
+  struct utUnit feet, thisguy, pascals, kelvins ;
+  gadouble slope, intcept ;
+
+  if (utScan("feet", &feet) != 0) {
+    gaprnt(0, "The udunits library doesn't know feet; giving up...\n") ;
+    return Failure;
+  }
+  if (utScan("pascals", &pascals) != 0) {
+    gaprnt(0, "The udunits library doesn't know pascals; giving up...\n") ;
+    return Failure;
+  }
+  if (utScan("kelvins", &kelvins) != 0) {
+    gaprnt(0, "The udunits library doesn't know kelvins; giving up...\n") ;
+    return Failure;
+  }
+
+  i=0;
+  lclvar=pfi->pvar1;
+  while (i<pfi->vnum) {
+    iscoordvar = 0 ;
+    if (lclvar->nvardims == 1) {  /* variable must be 1-D */
+      for (j=0; j<pfi->nsdfdims; j++) {
+	if (lclvar->vardimids[0] == pfi->sdfdimids[j]) { /* variable dimid matches a file dimid */
+	  if (!strcmp(pfi->sdfdimnam[j], lclvar->longnm)) { /* variable name matches dimension name */
+	    iscoordvar = 1 ;
+	  }
+	}
+      } 
+    }
+    if (iscoordvar) {
+      /* look for "units" attribute */
+      attr = NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "units") ;
+      if (attr) {
+	match=0;
+	if (!strncasecmp(attr->value, "hybrid_sigma_pressure", 21)) match=1;
+	if (!strncasecmp(attr->value, "mb", 2)) match=1;  
+	if (!strncasecmp(attr->value, "millibar", 8)) match=1;  
+	if (match) {
+	  *Zcoordptr = lclvar ;
+	  *ispressptr = 1 ;
+	  return Success ;
+	}
+	match=0;
+	if (!strncasecmp(attr->value, "sigma_level", 11)) match=1;
+	if (!strncasecmp(attr->value, "degreesk",     8)) match=1;
+	if (!strncasecmp(attr->value, "degrees_k",    9)) match=1;
+	if (!strncasecmp(attr->value, "level",        5)) match=1; 
+	if (!strncasecmp(attr->value, "layer",        5)) match=1;
+	if (!strncasecmp(attr->value, "layers",       6)) match=1;
+	if (match) {
+ 	  *Zcoordptr = lclvar ;
+	  *ispressptr = 0 ;
+	  return Success ;
+	}
+	/* if we can convert the units to feet, then it could be depth */
+	if (utScan(attr->value, &thisguy) == 0) {
+	  if (utConvert(&thisguy, &feet, &slope, &intcept) == 0) {
+	    *Zcoordptr = lclvar ;
+	    *ispressptr = 0 ;
+	    return Success;
+	  }
+	  /* if we can convert the units to pascals, then it could be pressure */
+	  if (utConvert(&thisguy, &pascals, &slope, &intcept) == 0) {
+	    pfi->pa2mb = 1; 
+	    *Zcoordptr = lclvar ;
+	    *ispressptr = 1 ;
+	    return Success;
+	  }
+	  /* if we can convert the units to kelvins, then it could be isothermic */
+	  if (utConvert(&thisguy, &kelvins, &slope, &intcept) == 0) {
+	    *Zcoordptr = lclvar ;
+	    *ispressptr = 0 ;
+	    return Success;
+	  }
+	} /* if utScan-able */
+      }
+      /* look for "axis" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "axis");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "Z", 1)) match=1;
+	if (!strncmp(attr->value, "z", 1)) match=1;
+	if (match) {
+	  *Zcoordptr = lclvar ;
+          *ispressptr = 0 ;
+	  return Success ;  
+	}
+      }
+    }
+    i++; lclvar++;
+  } 
+  return Failure;
+}
+
+/* find a coordinate variable 
+   1) has units that mark it as one sort of time or another, or
+   2) has an "axis" attribute with a value of "T" 
+*/
+gaint findT(struct gafile *pfi, struct gavar **Tcoordptr) {
+  struct gaattr *attr ;
+  struct gavar *lclvar ;
+  gaint iscoordvar, i, j, match;
+  utUnit timeunit ;
+
+  i=0;
+  lclvar=pfi->pvar1;
+  while (i<pfi->vnum) {
+    iscoordvar = 0 ;
+    if (lclvar->nvardims == 1) {  /* variable must be 1-D */
+      for (j=0; j<pfi->nsdfdims; j++) {
+	if (lclvar->vardimids[0] == pfi->sdfdimids[j]) { /* variable dimid matches a file dimid */
+	  if (!strcmp(pfi->sdfdimnam[j], lclvar->longnm)) { /* variable name matches dimension name */
+	    iscoordvar = 1 ;
+	  }
+	}
+      } 
+    }
+    if (iscoordvar) {
+      attr = NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "units") ;
+      if (attr) {
+	match=0;
+	if (!strncasecmp((char*)attr->value, "yyyymmddhhmmss", 14)) match=1;
+	if (!strncasecmp((char*)attr->value, "yymmddhh",        8)) match=1;
+	if (match) {
+	  *Tcoordptr = lclvar ;
+	  return Success ;
+	}
+	if ((utScan((char*)attr->value, &timeunit)) == 0) { 
+	  if (utIsTime(&timeunit)) { /* will now supply default unit */
+	    *Tcoordptr = lclvar ;
+	    return Success ;
+	  }
+	}
+      }
+      /* look for "axis" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "axis");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "T", 1)) match=1;
+	if (!strncmp(attr->value, "t", 1)) match=1;
+	if (match) {
+	  *Tcoordptr = lclvar ;
+	  return Success ;  
+	}
+      }
+    }
+    i++; lclvar++;
+  } 
+  return Failure ;
+}
+
+/* check for ensemble coordinate variable with attribute "axis" or "grads_dim" equal to "e" */
+gaint findE(struct gafile *pfi, struct gavar **Ecoordptr) {
+  struct gaattr *attr;
+  struct gavar *lclvar;
+  gaint iscoordvar, i, j, match;
+
+  i=0;
+  lclvar=pfi->pvar1;
+  while (i<pfi->vnum) {
+    iscoordvar = 0 ;
+    if (lclvar->nvardims == 1) {  /* variable must be 1-D */
+      for (j=0; j<pfi->nsdfdims; j++) {
+	if (lclvar->vardimids[0] == pfi->sdfdimids[j]) { /* variable dimid matches a file dimid */
+	  if (!strcmp(pfi->sdfdimnam[j], lclvar->longnm)) { /* variable name matches dimension name */
+	    iscoordvar = 1 ;
+	  }
+	}
+      } 
+    }
+    if (iscoordvar) {
+      /* look for "grads_dim" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "grads_dim");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "e", 1)) match = 1;
+	if (match) {
+	  *Ecoordptr = lclvar;
+	  return Success;  /* got a match */
+	}
+      }
+      /* look for "axis" attribute */
+      attr=NULL;
+      attr = find_att(lclvar->longnm, pfi->attr, "axis");
+      if (attr) {
+	match=0;
+	if (!strncmp(attr->value, "E", 1)) match=1;
+	if (!strncmp(attr->value, "e", 1)) match=1;
+	if (match) {
+	  *Ecoordptr = lclvar ;
+	  return Success ;  
+	}
+      }
+    }
+    i++; lclvar++;
+  }
+  return Failure;
+}
+
+
+/* Strip the given number of characters from the string and return the
+   new length.  If the number of characters to strip is less than
+   or equal to zero, or if the strip length is greater than the
+   string length, return Failure.  Otherwise, return Success. */
+gaint strip_char (gaint strip_num, char *str1, gaint *int_len) {
+  gaint slen;
+
+  slen = strlen (str1);
+  if (strip_num <= 0) return Failure;
+  slen -= strip_num;
+  if (slen < 0) return Failure;
+  *int_len = slen;
+  str1[slen] = '\0';
+  return Success;
+}
+
+/* Decode standard time.  Return Success if OK, Failure if error. */
+gaint decode_standard_time (gadouble time_val, gaint *year, gaint *month, 
+			   gaint *day, gaint *hour, gaint *minn, gafloat *sec) {
+char   str1[100];
+gaint  i,slen,int_len;
+
+  /* Make time value into character string. */
+  snprintf(str1,99,"%f", time_val);
+
+  /* Find decimal point. */
+  slen = strlen (str1);
+  for (i = 0; i < slen; i++) {
+    if (str1[i] == '.') {
+      int_len = i;
+      break;
+    }
+  }
+  if (int_len == 0) return Failure;
+
+  /* Get second. */
+  if (int_len <= 2) {
+      sscanf (str1, "%g", sec);
+      int_len = 0;
+  }
+  else {
+    sscanf (&str1[int_len - 2], "%g", sec);
+    str1[int_len] = '\0';
+    (void) strip_char (2, str1, &int_len);
+  }
+
+  /* Get minute. */
+  *minn = MISSING;
+  if (int_len > 0) {
+    if (int_len <= 2) {
+      sscanf (str1, "%d", minn);
+      int_len = 0;
+    }
+    else {
+      sscanf (&str1[int_len - 2], "%d", minn);
+      str1[int_len] = '\0';
+      (void) strip_char (2, str1, &int_len);
+    }
+  }
+
+  /* Get hour. */
+  *hour = MISSING;
+  if (int_len > 0) {
+    if (int_len <= 2) {
+      sscanf (str1, "%d", hour);
+      int_len = 0;
+    }
+    else {
+      sscanf (&str1[int_len - 2], "%d", hour);
+      str1[int_len] = '\0';
+      (void) strip_char (2, str1, &int_len);
+    }
+  }
+  
+  /* Get day. */
+  *day = MISSING;
+  if (int_len > 0) {
+    if (int_len <= 2) {
+      sscanf (str1, "%d", day);
+      int_len = 0;
+    }
+    else {
+      sscanf (&str1[int_len - 2], "%d", day);
+      str1[int_len] = '\0';
+      (void) strip_char (2, str1, &int_len);
+    }
+  }
+  
+  /* Get month. */
+  *month = MISSING;
+  if (int_len > 0) {
+    if (int_len <= 2)	{
+      sscanf (str1, "%d", month);
+      int_len = 0;
+    }
+    else {
+      sscanf (&str1[int_len - 2], "%d", month);
+      str1[int_len] = '\0';
+      (void) strip_char (2, str1, &int_len);
+    }
+  }
+  
+  /* Get year.  A year of 0000 or 9999 defaults to missing. */
+  *year = MISSING;
+  if (int_len > 0) 
+    sscanf (str1, "%d", year);
+  if ((*year == 0) || (*year == 9999))
+    *year = MISSING;
+
+  /* All OK. */
+  return Success;
+}
+
+
+/* Free a netCDF attribute list. */
+gaint free_att_info (struct gafile *pfi) { 
+  struct gaattr *attrib, *nextattrib;
+
+  if (pfi->attr) {
+    for (attrib = pfi->attr; attrib != NULL; attrib = nextattrib) { 
+      nextattrib = attrib->next;
+      if (attrib->value) gree(attrib->value,"f18");
+      gree(attrib,"f19");
+    }
+    pfi->attr = NULL;
+  }
+  return Success;
+}
+
+/* open and read the metadata in a netCDF file */
+/* gafile structure should already be initialized */
+gaint read_metadata (struct gafile *pfi) {
+struct gavar *pvar;
+gaint rc,i,ii,j,len,ngatts,natts,ndims,nvars,status,oflg,dummy;
+size_t sz,size=0;
+char name[300];
+#if USEHDF ==1
+int32 ndsets,dimsize,sds_id,dim_id,dtype,ndatts;
+int32 dim_sizes[H4_MAX_VAR_DIMS],rank;
+char sdsname[H4_MAX_NC_NAME+1];
+char dimname[H4_MAX_NC_NAME+1];
+#endif
+
+  if ((pfi->name == NULL) || (strlen (pfi->name) == 0)) return Failure;
+
+  /* Open the file */
+  if (pfi->tmplat) {
+    i = gaopfn(1,1,&dummy,&oflg,pfi);   /* assume 1st ensemble member */
+    if (i==-99999) {
+      gaprnt(0,"read_metadata: gaopfn failed (rc=-99999)\n");
+      return Failure;
+    }
+    if (i==-88888) {
+      gaprnt(0,"read_metadata: gaopfn failed (rc=-88888)\n");
+      return Failure;
+    }
+  }
+  else {
+    if (pfi->ncflg==1) {
+      rc = gaopnc (pfi,0,1);
+      if (rc) return Failure;
+    }
+    if (pfi->ncflg==2) {
+      rc = gaophdf (pfi,0,1);
+      if (rc) return Failure;
+    }    
+  }
+
+  /* get general information. */
+#if USEHDF==1
+  if (pfi->ncflg==2) {
+    status = SDfileinfo(pfi->sdid, &ndsets, &ngatts);
+    if (status == -1) {
+      gaprnt(0,"read_metadata: SDfileinfo failed\n");
+      goto err1;
+    }
+    /* find out how many data sets are coordinate variables */
+    ndims=0;
+    for (i=0; i<ndsets; i++) {
+      /* get info about this data set */
+      sds_id = SDselect(pfi->sdid, i);
+      status = SDgetinfo(sds_id, sdsname, &rank, dim_sizes, &dtype, &natts);
+      if (status == -1) {
+	snprintf(pout,255,"read_metadata: SDgetinfo failed for sds_id=%d\n",sds_id);
+	gaprnt(0,pout);
+	goto err3;
+      }
+      /* coordinate variables must have only 1 dimension */
+      if (rank==1) {   
+	dim_id = SDgetdimid(sds_id,0);                                  
+	status = SDdiminfo(dim_id, dimname, &dimsize, &dtype, &ndatts); 
+	if (status == -1) {
+	  snprintf(pout,255,"read_metadata: SDdiminfo failed for sds_id=%d, dimid=%d\n",sds_id,dim_id);
+	  gaprnt(0,pout);
+	  goto err3;
+	}
+	/* name of dimension must match name of variable */
+	if (strcmp(dimname,sdsname)==0) {
+	  /* it's a coordinate variable */
+	  if (dimsize==0) {
+	    /* This is the unlimited dimension. 
+	       The first element of the dim_sizes array contains 
+	       the number of records in the unlimited dimension. */
+	    dimsize = dim_sizes[0]; 
+	  }
+	  pfi->sdfdimids[ndims] = (gaint)dim_id;
+	  strcpy(&pfi->sdfdimnam[ndims][0],dimname);
+	  pfi->sdfdimsiz[ndims] = (gaint)dimsize;
+	  ndims++;
+	}
+      }
+    }
+
+    if (ndims==0 && ndsets>0) {
+      /* file has data variables but no coordinate variables. 
+	 Get the dimension ids and names from the first data variable */
+      sds_id = SDselect(pfi->sdid, 0);
+      status = SDgetinfo(sds_id, sdsname, &rank, dim_sizes, &dtype, &natts);
+      for (j=0; j<rank; j++) {
+	dim_id = SDgetdimid(sds_id, j);
+	status = SDdiminfo(dim_id, dimname, &dimsize, &dtype, &ndatts);
+	pfi->sdfdimids[ndims] = (gaint)dim_id;
+	strcpy(&pfi->sdfdimnam[ndims][0],dimname);
+	pfi->sdfdimsiz[ndims] = (gaint)dimsize;
+	ndims++;
+      }
+    }
+    pfi->nsdfdims = ndims;
+    pfi->vnum = ndsets;
+
+  }
+#endif
+
+#if USENETCDF==1
+  if (pfi->ncflg==1) {
+    status = nc_inq(pfi->ncid, &ndims, &nvars, &ngatts, NULL);
+    if (status != NC_NOERR) {
+      handle_error(status);
+      goto err1;
+    }
+    pfi->nsdfdims = ndims;
+    pfi->vnum = nvars;
+    /* get NC coordinate information */
+    for (i=0; i<pfi->nsdfdims; i++) {
+      pfi->sdfdimids[i] = i;
+      status = nc_inq_dim (pfi->ncid, i, name, &size);
+      if (status != NC_NOERR) {
+	handle_error(status);
+	goto err1;
+      }
+      strcpy(&pfi->sdfdimnam[i][0],name);
+      pfi->sdfdimsiz[i] = (gaint)size;
+    }
+  }
+#endif
+  /* Retrieve global attributes */
+#if USEHDF==1
+  if (pfi->ncflg==2) {
+    read_hdfatts (pfi->sdid, "global", ngatts, pfi);
+  }
+#endif
+#if USENETCDF==1
+  if (pfi->ncflg==1) {
+    read_ncatts (pfi->ncid, NC_GLOBAL, NULL, ngatts, pfi); 
+  }
+#endif
+  /* Get variable info and attributes */
+  sz = pfi->vnum * sizeof(struct gavar);
+  if ((pvar = (struct gavar *)galloc(sz,"pvar")) == NULL) {
+    gaprnt(0,"read_metadata: memory allocation failed for pvar array \n");
+    goto err2;
+  }
+  pfi->pvar1 = pvar;
+  i = 0;
+  while (i<pfi->vnum)  {
+    /* initialize variables in the pvar structure */
+    pvar->offset = 0;
+    pvar->recoff = 0;
+    pvar->ncvid = -999;
+    pvar->sdvid = -999;
+    pvar->h5vid = -999;
+    pvar->levels = 0;
+    pvar->dfrm = 0;
+    pvar->var_t = 0;
+    pvar->scale = 1;
+    pvar->add = 0;
+    pvar->undef= -9.99E33;
+    pvar->vecpair = -999;
+    pvar->isu = 0;
+    pvar->isdvar = 0;
+    pvar->nvardims = 0;
+    for (ii=0; ii<16; ii++) pvar->units[ii]=-999;
+
+    /* get the variable info */
+    natts=0;
+#if USEHDF==1
+    if (pfi->ncflg==2) {
+      /* get info about the current data set */
+      sds_id = SDselect(pfi->sdid, i);
+      if (sds_id==FAIL) {
+	snprintf(pout,255,"read_metadata: SDselect failed for varid %d\n",i);
+	gaprnt(0,pout);
+	goto err3;
+      }
+      status = SDgetinfo(sds_id, name, &(pvar->nvardims), dim_sizes, &dtype, &natts);
+      if (status == -1) {
+	snprintf(pout,255,"read_metadata: SDgetinfo failed for varid %d\n",i);
+	gaprnt(0,pout);
+	goto err3;
+      }
+      status = SDnametoindex(pfi->sdid, name);
+      if (status == -1) {
+	snprintf(pout,255,"read_metadata: SDnametoindex failed for varid %d\n",i);
+	gaprnt(0,pout);
+	goto err3;
+      }
+      pvar->sdvid = status;
+      for (j=0; j<pvar->nvardims; j++) {
+	dim_id = SDgetdimid(sds_id,j);
+	pvar->vardimids[j] = (gaint)dim_id;
+      }
+    }
+#endif
+#if USENETCDF==1
+    if (pfi->ncflg==1) {
+      status = nc_inq_var(pfi->ncid, i, name, NULL, &(pvar->nvardims), pvar->vardimids, &natts);
+      if (status != NC_NOERR) {
+	snprintf(pout,255,"read_metadata: nc_inq_var failed to retrieve variable info for varid %d\n",i);
+	gaprnt(0,pout);
+	handle_error(status);
+	goto err3;
+      }
+      pvar->ncvid = i;
+    }
+#endif
+    len = strlen(name);
+    strncpy(pvar->longnm,name,len+1);
+
+    /* Retrieve variable attribute values */
+#if USEHDF==1
+    if (pfi->ncflg==2) {
+      read_hdfatts (pfi->sdid, pvar->longnm, natts, pfi);
+    }
+#endif
+#if USENETCDF==1
+    if (pfi->ncflg==1) {
+      read_ncatts (pfi->ncid, pvar->ncvid, pvar->longnm, natts, pfi);
+    }
+#endif
+
+    i++; pvar++;
+  }  
+  
+  /* determine if new or old units are being used */
+  set_time_type (pfi);
+  
+  /* set up standard tables according to time unit being used */
+  init_standard_arrays (pfi->time_type);
+  
+  return Success;
+
+err3:
+  if (pfi->pvar1) gree(pfi->pvar1,"f20");
+  goto err2;
+
+err2:
+  free_att_info (pfi);
+  goto err1;
+
+err1:
+  close_sdf (pfi);
+  return Failure;
+}
+
+/* Close a SDF file. */
+void close_sdf (struct gafile *pfi) { 
+#if USENETCDF==1
+  if (pfi->ncflg==1) gaclosenc(pfi);
+#endif
+#if USEHDF==1
+  if (pfi->ncflg==2) gaclosehdf(pfi); 
+#endif
+}
+		
+gaint set_time_type (struct gafile *pfi) {
+#if USENETCDF==1
+  struct gavar *time, *lclvar;
+  utUnit timeunit ;
+  struct gaattr *attr;
+  gaint i,flag;
+
+  time = NULL;
+  time = find_var (pfi, cdc_vars[TIME_IX]);
+  if (time == NULL) {
+    i=0; flag=1;
+    lclvar = pfi->pvar1;  
+    while (i<pfi->vnum && (flag) && (lclvar != NULL)) {
+      if (lclvar->nvardims == 1) {
+	attr = NULL;
+	attr = find_att(lclvar->longnm, pfi->attr, cdc_time_atts[T_UNITS_IX]);
+	if (attr != NULL) {
+	  if ((utScan((char*)attr->value, &timeunit)) == 0) { 
+	    if (utIsTime(&timeunit)) {
+	      time = lclvar ;
+	      flag=0;
+	    }
+	  }
+	}
+      }
+      i++; lclvar++;
+    } 
+  }
+  if (time == NULL) return Failure ;
+  attr = NULL;
+  attr = find_att(time->longnm, pfi->attr, cdc_time_atts[T_UNITS_IX]);
+  if ((attr!=NULL) && (!strncasecmp ("yyyy", (char*)attr->value, 4))) 
+    pfi->time_type = CDC;        /* it's the old style */
+  else 
+    pfi->time_type = COOP;
+#endif
+  return Success;
+}
+ 
+ 
+gaint init_standard_arrays (gaint time_type) {
+#if USENETCDF==1
+  if (time_type == CDC) {
+    dims = cdc_dims;
+    vars = cdc_vars;
+    var_type = cdc_var_type;
+    var_atts = cdc_var_atts;
+    var_atts_type = cdc_var_atts_type;
+    var_atts_val = cdc_var_atts_val;
+    obs_atts_val = cdc_obs_atts_val;
+    vatts_abbrev = cdc_vatts_abbrev;
+    time_atts = cdc_time_atts;
+    time_atts_val = cdc_time_atts_val;
+    latlon_atts = cdc_latlon_atts;
+    num_reqd_vatts = NUM_REQD_VATTS;
+    num_reqd_vars = NUM_REQD_VARS;
+    num_reqd_dims = NUM_REQD_DIMS;
+  }
+  else {
+    dims = coop_dims;
+    vars = coop_vars;
+    var_type = coop_var_type;
+    var_atts = coop_var_atts;
+    var_atts_type = coop_var_atts_type;
+    var_atts_val = coop_var_atts_val;
+    obs_atts_val = coop_obs_atts_val;
+    vatts_abbrev = coop_vatts_abbrev;
+    time_atts = coop_time_atts;
+    time_atts_val = coop_time_atts_val;
+    latlon_atts = coop_latlon_atts;
+    num_reqd_vatts = NUM_REQD_COOP_VATTS;
+    num_reqd_vars = NUM_REQD_COOP_VARS;
+    num_reqd_dims = NUM_REQD_COOP_DIMS;
+  }
+#endif
+  return Success;
+}
+
+
+/* Return an attribute structure, given the variable and attribute names.
+   The varname argument may be "global", "ALL", or a specific variable name. */
+
+struct gaattr *find_att (char *varname, struct gaattr *first_att, char *attname) {
+  static struct gaattr *attr = NULL;
+  
+  attr = first_att;
+  while (attr != NULL) {
+    if (!strcmp(varname,"ALL")) {
+      /* don't test if varnames match */
+      if (!strcasecmp(attname, attr->name)) { 
+	return (attr);
+      }
+    }
+    else {
+      /* do test if varnames match */
+      if (!strcmp(varname, attr->varname)) {
+	if (!strcasecmp(attname, attr->name)) {
+	  return (attr);
+	}
+      }    
+    }
+    attr = attr->next;
+  }
+  /* didn't find any match */
+  return(NULL);
+}
+
+
+/* read netcdf attribute information for a file or variable */
+gaint read_hdfatts (gaint sdid, char *vname, gaint natts, struct gafile *pfi) 
+{
+#if USEHDF ==1 
+struct gaattr *attrib=NULL,*newattrib=NULL;
+gaint   i,len=0,gotatt;
+int32   sds_id,attr_dtype,attr_count;
+char    *varname,*attname;
+char8   *cval=NULL;
+uchar8  *ucval=NULL;
+int8    *icval=NULL;
+uint8   *uicval=NULL;
+int16   *sval=NULL;
+uint16  *usval=NULL;
+int32   *ival=NULL;
+uint32  *uival=NULL;
+float32 *fval=NULL;
+float64 *dval=NULL;
+size_t sz;
+
+  if (cmpwrd("global",vname)) 
+    len=7;
+  else
+    len=strlen(vname)+2;
+  sz = len;
+  if ((varname=(char*)galloc(sz,"hdfvname"))==NULL) {
+    gaprnt(0,"read_hdfatts error: memory allocation failed for varname\n");
+    return(Failure);
+  }
+  if (cmpwrd("global",vname)) {
+    sds_id = sdid;
+    strncpy(varname,"global",len);
+  }
+  else {
+    strncpy(varname,vname,len);
+    sds_id = SDnametoindex(sdid, vname);
+    if (sds_id == -1) return (0);
+    sds_id = SDselect(sdid,sds_id);
+  }
+  
+  /* Loop through list of attributes */ 
+  for (i = 0 ; i < natts ; i++) {
+	 
+    /* Get info about the current attribute  */
+    attr_count = attr_dtype = 0;
+    sz = H4_MAX_NC_NAME+1;
+    if ((attname=(char*)galloc(sz,"hdatname"))==NULL) {
+      gaprnt(0,"read_hdfatts error: memory allocation failed for attname\n");
+      gree(varname,"f145a");
+      return(Failure);
+    }
+    if (SDattrinfo(sds_id, i, attname, &attr_dtype, &attr_count) == -1) {
+      snprintf(pout,255,"SDattrinfo failed for variable %s, attribute number %d\n", varname, i);
+      gaprnt(2,pout);
+    }
+    else {
+      if (attr_count > 0) {
+	len = attr_count;
+	gotatt = 0;
+	switch (attr_dtype) 
+	  {
+	  case (DFNT_CHAR8):    /* definition value 4 */
+	    len = len + 1; 
+	    sz = len * sizeof (char8);
+	    cval = (char8*) galloc(sz,"catval");
+	    if (SDreadattr(sds_id, i, cval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type CHAR8\n"); 
+	      gree(cval,"f145"); cval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	      cval[len-1]='\0';
+	    }
+	    break;
+	  case (DFNT_UCHAR8):   /* definition value 3 */
+	    sz = len * sizeof (uchar8);
+	    ucval = (uchar8*) galloc(sz,"ucatval");
+	    if (SDreadattr(sds_id, i, ucval) == -1) { 
+	      gaprnt(2,"SDreadattr failed for type UCHAR8\n"); 
+	      gree(ucval,"f146"); ucval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_INT8):     /* definition value 20 */
+	    sz = len * sizeof (int8);
+	    icval = (int8*) galloc(sz,"iatval");
+	    if (SDreadattr(sds_id, i, icval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type INT8\n"); 
+	      gree(icval,"f147"); icval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_UINT8):    /* definition value 21 */
+	    sz = len * sizeof (uint8);
+	    uicval = (uint8*) galloc(sz,"uiatval");
+	    if (SDreadattr(sds_id, i, uicval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type UINT8\n"); 
+	      gree(uicval,"f148"); uicval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_INT16):    /* definition value 22 */
+	    sz = len * sizeof (int16);
+	    sval = (int16*) galloc(sz,"satval");
+	    if (SDreadattr(sds_id, i, sval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type INT16\n"); 
+	      gree(sval,"f149"); sval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_UINT16):   /* definition value 23 */
+	    sz = len * sizeof (uint16);
+	    usval = (uint16*) galloc(sz,"usatval");
+	    if (SDreadattr(sds_id, i, usval) == -1) { 
+	      gaprnt(2,"SDreadattr failed for type UINT16\n"); 
+	      gree(usval,"f150"); usval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_INT32):    /* definition value 24 */
+	    sz = len * sizeof (int32);
+	    ival = (int32*) galloc(sz,"latval");
+	    if (SDreadattr(sds_id, i, ival) == -1) {
+	      gaprnt(2,"SDreadattr failed for type INT32\n"); 
+	      gree(ival,"f151"); ival=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_UINT32):   /* definition value 25 */
+	    sz = len * sizeof (uint32);
+	    uival = (uint32*) galloc(sz,"ulatval");
+	    if (SDreadattr(sds_id, i, uival) == -1) { 
+	      gaprnt(2,"SDreadattr failed for type UINT32\n"); 
+	      gree(uival,"f151"); uival=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_FLOAT32):  /* definition value  5 */
+	    sz = len * sizeof (float32);
+	    fval = (float32*) galloc(sz,"fatval");
+	    if (SDreadattr(sds_id, i, fval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type FLOAT32\n"); 
+	      gree(fval,"f153"); fval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  case (DFNT_FLOAT64):  /* definition value  6 */
+	    sz = len * sizeof (float64);
+	    dval = (float64*) galloc(sz,"datval");
+	    if (SDreadattr(sds_id, i, dval) == -1) {
+	      gaprnt(2,"SDreadattr failed for type FLOAT64\n"); 
+	      gree(dval,"f154"); dval=NULL;
+	    }
+	    else { 
+	      gotatt=1; 
+	    }
+	    break;
+	  default:
+	    snprintf(pout,255,"Failed to retrieve attribute %d of type %d \n", i, attr_dtype);
+	    gaprnt(2,pout);
+	  };
+	
+	if (gotatt) {
+	  /* Successfully extracted the attribute, so add a link to the list */
+	  sz = sizeof(struct gaattr);
+	  if ((newattrib = (struct gaattr *) galloc(sz,"newathdf")) == NULL) {
+	    snprintf(pout,255,"read_hdfatts error: memory allocation failed when adding attribute number %d\n",i);
+	    gaprnt(2,pout);
+	    if (cval)   { gree(cval,"f145");   cval=NULL;   }
+	    if (ucval)  { gree(ucval,"f146");  ucval=NULL;  }
+	    if (icval)  { gree(icval,"f147");  icval=NULL;  }
+	    if (uicval) { gree(uicval,"f148"); uicval=NULL; }
+	    if (sval)   { gree(sval,"f149");   sval=NULL;   }
+	    if (usval)  { gree(usval,"f150");  usval=NULL;  }
+	    if (ival)   { gree(ival,"f151");   ival=NULL;   }
+	    if (uival)  { gree(uival,"f151");  uival=NULL;  }
+	    if (fval)   { gree(fval,"f153");   fval=NULL;   }
+	    if (dval)   { gree(dval,"f154");   dval=NULL;   }
+	  }
+	  else {
+	    if (pfi->attr) { /* some attributes already exist */
+	      /* advance to end of chain */
+	      attrib = pfi->attr;
+	      while (attrib->next != NULL) attrib = attrib->next;
+	      /* hang new attribute on end of chain */
+	      attrib->next = newattrib;
+	    }
+	    else {
+	      /* new attribute is the chain anchor */
+	      pfi->attr = newattrib;
+	    }
+	    newattrib->next = NULL;
+	    strcpy(newattrib->varname,varname);      
+	    strcpy(newattrib->name,attname);      
+	    newattrib->len  = len;
+	    /* We're going to save HDF types as NC types */
+	    /*	NC_BYTE =	1,	 signed 1 byte integer */
+	    /*	NC_CHAR =	2,	 ISO/ASCII character */
+	    /*	NC_SHORT =	3,	 signed 2 byte integer */
+	    /*	NC_INT =	4,	 signed 4 byte integer */
+	    /*	NC_FLOAT =	5,	 single precision floating point number */
+	    /*	NC_DOUBLE =	6	 double precision floating point number */
+	    if      (attr_dtype == DFNT_CHAR8)   { 
+	      newattrib->value = cval;	
+	      newattrib->nctype = 1;
+	    }
+	    else if (attr_dtype == DFNT_UCHAR8)  { 
+	      newattrib->value = ucval;
+	      newattrib->nctype = 2;
+	    }
+	    else if (attr_dtype == DFNT_INT8)    { 
+	      newattrib->value = icval;
+	      newattrib->nctype = 2;
+	    }
+	    else if (attr_dtype == DFNT_UINT8)   { 
+	      newattrib->value = uicval; 
+	      newattrib->nctype = 2;
+	    }
+	    else if (attr_dtype == DFNT_INT16)   { 
+	      newattrib->value = sval;	
+	      newattrib->nctype = 3;
+	    }
+	    else if (attr_dtype == DFNT_UINT16)  { 
+	      newattrib->value = usval;
+	      newattrib->nctype = 3;
+	    }
+	    else if (attr_dtype == DFNT_INT32)   { 
+	      newattrib->value = ival;	
+	      newattrib->nctype = 4;
+	    }
+	    else if (attr_dtype == DFNT_UINT32)  { 
+	      newattrib->value = uival;
+	      newattrib->nctype = 4;
+	    }
+	    else if (attr_dtype == DFNT_FLOAT32) { 
+	      newattrib->value = fval;	
+	      newattrib->nctype = 5;
+	    } 
+	    else if (attr_dtype == DFNT_FLOAT64) { 
+	      newattrib->value = dval; 
+	      newattrib->nctype = 6;
+	    }
+	  }
+	}
+      } /* end of if statement for attr_count > 0 */
+    } /* end of if-else statement for getting attribute info */
+    gree(attname,"155b");
+  } /* end of for loop on i */
+  gree(varname,"f155a");
+  return (Success);
+#endif
+  return(Success);
+}
+
+
+/* read netcdf attribute information for a file or variable */
+/* gaint read_ncatts (gaint cdfid, gaint varid, char *vname, gaint natts, struct gafile *pfi)  */
+gaint read_ncatts (gaint cdfid, gaint varid, char *vname, gaint natts, struct gafile *pfi) 
+{
+#if USENETCDF == 1
+struct gaattr *attrib=NULL,*newattrib=NULL;
+gadouble *dval=NULL;
+gafloat  *fval=NULL;
+long   *ival=NULL;
+short  *sval=NULL;
+char   *bval=NULL;
+char   *cval=NULL;
+char   *attname,*varname=NULL;
+gaint   i,len,status,gotatt;
+size_t  sz,attlen;
+nc_type type;
+
+  /* Get the variable name */
+  if ((varid == NC_GLOBAL) && (vname == NULL)) 
+    len=8;
+  else 
+    len = strlen(vname)+2;
+  sz = len;
+  if ((varname=(char*)galloc(sz,"ncvname"))==NULL) {
+    gaprnt(0,"read_ncatts: memory allocation failed for varname\n");
+    return(Failure);
+  }
+  if ((varid == NC_GLOBAL) && (vname == NULL)) {
+    strncpy(varname,"global",7);
+  }
+  else {
+    strncpy(varname,vname,len);
+  }
+  
+  /* Loop through all attributes */
+  for (i=0 ; i<natts ; i++) {
+    /* Get current attribute's name */
+    sz = MAX_NC_NAME+2;
+    if ((attname=(char*)galloc(sz,"ncattname"))==NULL) {
+      gaprnt(0,"read_ncatts: memory allocation failed for attname\n");
+      gree(varname,"f55c");
+      return(Failure);
+    }
+    status = nc_inq_attname(cdfid, varid, i, attname);
+    if (status != NC_NOERR) { 
+      handle_error(status); 
+      snprintf(pout,255,"read_ncatts: ncattname failed for varid %d attribute number %d\n",varid,i);
+      gaprnt(2,pout);
+    }
+    else {
+      attlen=0; type=0;
+      /* Get current attribute's data type and length */
+      status = nc_inq_att(cdfid, varid, attname, &type, &attlen);
+      if (status != NC_NOERR) { 
+	handle_error(status); 
+	snprintf(pout,255,"read_ncatts: nc_inq_att failed for varid %d attribute number %d\n",varid,i);
+	gaprnt(2,pout);
+      }
+      else {
+        if (attlen > 0) {
+	  gotatt=0;
+	  /* Retrieve the attribute's value */
+	  switch (type) 
+	    {
+	    case (NC_BYTE):
+	      sz = attlen*sizeof(char);
+	      bval = (char *) galloc(sz,"bval");
+  	      status = nc_get_att_schar(cdfid, varid, attname, (signed char*)bval);
+              if (status != NC_NOERR) { 
+		gree(bval,"f22"); 
+		bval = NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type BYTE\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+	      }
+	      break;
+	    case (NC_CHAR):
+	      attlen = attlen + 1;
+	      sz = attlen*sizeof(char);
+	      cval = (char *) galloc(sz,"cval");
+	      status = nc_get_att_text(cdfid, varid, attname, cval);
+              if (status != NC_NOERR) { 
+		gree(cval,"f24");
+		cval = NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type CHAR\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+		cval[attlen-1]='\0';
+	      }
+	      break;
+	    case (NC_SHORT):
+	      sz = attlen * sizeof(short);
+	      sval = (short *) galloc(sz,"sval");
+	      status = nc_get_att_short(cdfid, varid, attname, sval);
+              if (status != NC_NOERR) { 
+		gree(sval,"f26");
+		sval=NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type SHORT\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+	      }
+	      break;
+	    case (NC_LONG):
+	      sz = attlen * sizeof(long);
+	      ival = (long *) galloc(sz,"ival");
+	      status = nc_get_att_long(cdfid, varid, attname, ival);
+              if (status != NC_NOERR) { 
+		gree(ival,"f28");
+		ival = NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type LONG\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+	      }
+	      break;
+	    case (NC_FLOAT):
+	      sz = attlen * sizeof(gafloat);
+	      fval = (gafloat *) galloc(sz,"fval");
+	      status = nc_get_att_float(cdfid, varid, attname, fval);
+              if (status != NC_NOERR) {
+		gree(fval,"f30");
+		fval = NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type FLOAT\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+	      }
+	      break;
+	    case (NC_DOUBLE): 
+	      sz = attlen * sizeof(gadouble);
+	      dval = (gadouble *) galloc(sz,"dval");
+	      status = nc_get_att_double(cdfid, varid, attname, dval);
+              if (status != NC_NOERR) { 
+		gree(dval,"f32");
+		dval = NULL;
+		handle_error(status); 
+		snprintf(pout,255,"read_ncatts: failed to get %s attribute %d type DOUBLE\n",varname,i);
+		gaprnt(2,pout);
+	      }
+	      else { 
+		gotatt=1; 
+	      }
+            break;
+	    default:
+	      snprintf(pout,255,"read_ncatts: %s attribute %d type %d not supported\n",varname,i,type);
+	      gaprnt(2,pout);
+	    };
+	  
+	  if (gotatt) {
+	    /* Successfully extracted the attribute, so add a link to the list */
+	    sz = sizeof(struct gaattr);
+	    if ((newattrib = (struct gaattr *) galloc(sz,"newattr")) == NULL) {
+	      snprintf(pout,255,"read_ncatts: memory allocation failed when adding attribute number %d\n",i);
+	      gaprnt(2,pout);
+	      if (bval) { gree(bval,"f33"); bval = NULL; }
+	      if (cval) { gree(cval,"f34"); cval = NULL; }
+	      if (sval) { gree(sval,"f35"); sval = NULL; }
+	      if (ival) { gree(ival,"f36"); ival = NULL; }
+	      if (fval) { gree(fval,"f37"); fval = NULL; }
+	      if (dval) { gree(dval,"f38"); dval = NULL; }
+	    }
+	    else { 
+	      if (pfi->attr) { /* some attributes already exist */
+		/* advance to end of chain */
+		attrib = pfi->attr;
+		while (attrib->next != NULL) attrib = attrib->next;
+		/* hang new attribute on end of chain */
+		attrib->next = newattrib;
+	      }
+	      else {
+		/* new attribute is first link in chain */
+		pfi->attr = newattrib;
+	      }
+	      newattrib->next = NULL;
+	      strcpy(newattrib->varname,varname);
+	      strcpy(newattrib->name,attname);
+	      newattrib->len  = attlen;
+	      newattrib->nctype = (gaint)type;
+	      if      (type == NC_BYTE)   newattrib->value = bval;
+	      else if (type == NC_CHAR)   newattrib->value = cval;
+	      else if (type == NC_SHORT)  newattrib->value = sval;
+	      else if (type == NC_LONG)   newattrib->value = ival;
+	      else if (type == NC_FLOAT)  newattrib->value = fval;
+	      else if (type == NC_DOUBLE) newattrib->value = dval;
+	    }
+	  } /* end of if (gotatt) statement */
+	} /* end of if statement for attlen > 0 */
+      } /* end of if-else statement for getting attribute type and length */
+    } /* end of if-else statement for getting attribute name */
+    gree(attname,"f39a");
+  } /* end of for loop on i */
+  gree(varname,"f39b");
+  return (Success);
+#endif 
+}
+
+
+/* find a dimension id, given the dimension name */
+gaint find_dim (struct gafile *pfi, char *name) {
+  gaint i;
+  for (i=0; i<pfi->nsdfdims; i++) {
+    if (!strcmp (pfi->sdfdimnam[i], name)) return(pfi->sdfdimids[i]);
+  }
+  return (-1);
+}
+
+
+/* Reads one dimension axis value. 
+   Used to determine start and increment for time axis setup. */
+gaint read_one_dimension (struct gafile *pfi, struct gavar *coord, 
+			gaint start, gaint count, gadouble *data) {
+  gaint rc;
+  gadouble ddata;
+  size_t st,cnt;
+
+#if USEHDF == 1 
+  int32 lst,lcnt,sds_id,dtype,rank,dim_sizes[H4_MAX_NC_DIMS],natts;
+  float32  fdata;
+  int32    idata;
+  uint32   uidata;
+ 
+
+  if (pfi->ncflg==2) {
+    lst=start;
+    lcnt=count;
+    /* get the data type */
+    if ((sds_id = SDselect(pfi->sdid,coord->sdvid))==FAIL) return Failure;
+    rc = SDgetinfo(sds_id, coord->longnm, &rank, dim_sizes, &dtype, &natts);
+    if (rc == -1) {
+      gaprnt(0,"sdfdeflev: unable to determine coordinate axis data type\n");
+      return Failure;
+    }
+    switch (dtype) {
+    case (DFNT_INT32):  
+      if ((SDreaddata (sds_id, &lst, NULL, &lcnt, (VOIDP *)&idata)) != 0) {
+	gaprnt(0,"SDF Error: SDreaddatda failed to read coordinate axis value \n");
+	return Failure;
+      }
+      *data = (gadouble)idata; 
+      break;
+    case (DFNT_UINT32):  
+      if ((SDreaddata (sds_id, &lst, NULL, &lcnt, (VOIDP *)&uidata)) != 0) {
+	gaprnt(0,"SDF Error: SDreaddatda failed to read coordinate axis value \n");
+	return Failure;
+      }
+      *data = (gadouble)uidata; 
+      break;
+    case (DFNT_FLOAT32):
+      if ((SDreaddata (sds_id, &lst, NULL, &lcnt, (VOIDP *)&fdata)) != 0) {
+	gaprnt(0,"SDF Error: SDreaddatda failed to read coordinate axis value \n");
+	return Failure;
+      }
+      *data = (gadouble)fdata; 
+      break;
+    case (DFNT_FLOAT64):
+      if ((SDreaddata (sds_id, &lst, NULL, &lcnt, (VOIDP *)&ddata)) != 0) {
+	gaprnt(0,"SDF Error: SDreaddatda failed to read coordinate axis value \n");
+	return Failure;
+      }
+      *data = ddata;
+      break;
+    default:
+      snprintf(pout,255,"SDF coordinate axis data type %d not handled\n",dtype);
+      gaprnt(0,pout);
+      return Failure;
+    };
+  }
+#endif
+
+#if USENETCDF == 1
+  if (pfi->ncflg==1) {
+    st=start;
+    cnt=count;
+    rc = nc_get_vara_double(pfi->ncid, coord->ncvid, &st, &cnt, &ddata);
+    if (rc != NC_NOERR) {
+      handle_error(rc);
+      gaprnt(0,"SDF Error: nc_get_vara_double failed to read coordinate axis value \n");
+      return Failure;
+    }
+    *data = ddata;
+  }
+#endif
+  return Success ;
+}
+
+
+/* find a variable pointer, given the variable name */
+struct gavar *find_var (struct gafile *pfi, char *varname) {
+  gaint i;
+  struct gavar *pvar;
+  i=0;
+  pvar = pfi->pvar1;
+  while (i < pfi->vnum) {
+    if (!strcmp(varname, pvar->longnm)) return (struct gavar *)pvar;
+    i++; pvar++;
+  }
+  return NULL;  
+}
+
+
+gaint decode_delta_t (char *delta_t_str, gaint *year, gaint *month, gaint *day, gaint *hour, gaint *minn, gaint *sec) {
+  char temp_str[100];
+  gaint delta_t_len;
+  gaint year_mark = 4, month_mark = 7, day_mark = 10;
+  gaint hour_mark = 13, minute_mark = 16, second_mark = 19;
+
+  *year = *month = *day = *hour = *minn = *sec = MISSING;
+
+  delta_t_len = strlen (delta_t_str);
+  if ((delta_t_len > day_mark)    && (delta_t_str[day_mark] != ' '))    return Failure;
+  if ((delta_t_len > hour_mark)   && (delta_t_str[hour_mark] != ':'))   return Failure;
+  if ((delta_t_len > minute_mark) && (delta_t_str[minute_mark] != ':')) return Failure;
+
+  /* Get year. */
+  strcpy (temp_str, delta_t_str);
+  temp_str[year_mark] = '\0';
+  sscanf (temp_str, "%d", year);
+
+  /* Get month. */
+  strcpy (temp_str, &delta_t_str[year_mark + 1]);
+  temp_str[month_mark - year_mark - 1] = '\0';
+  sscanf (temp_str, "%d", month);
+
+  /* Get day. */
+  strcpy (temp_str, &delta_t_str[month_mark + 1]);
+  temp_str[day_mark - month_mark - 1] = '\0';
+  sscanf (temp_str, "%d", day);
+
+  /* Get other fields if present. */
+  if (delta_t_len > day_mark) {
+
+    /* Get hour. */
+    strcpy (temp_str, &delta_t_str[day_mark + 1]);
+    temp_str[hour_mark - day_mark - 1] = '\0';
+    sscanf (temp_str, "%d", hour);
+    
+    /* Get minute. */
+    strcpy (temp_str, &delta_t_str[hour_mark + 1]);
+    temp_str[minute_mark - hour_mark - 1] = '\0';
+    sscanf (temp_str, "%d", minn);
+    
+    /* Get second. */
+    strcpy (temp_str, &delta_t_str[minute_mark + 1]);
+    temp_str[second_mark - minute_mark - 1] = '\0';
+    sscanf (temp_str, "%d", sec);
+    
+  }
+  else {
+    *hour = *minn = *sec = MISSING;
+  }
+  return Success;
+}
+
+
+/* Handle return codes */
+void handle_error(gaint status) {
+#if USENETCDF==1
+  snprintf(pout,255," %s\n",nc_strerror(status));
+  gaprnt(0,pout);
+#endif
+}
+
+gaint gadxdf(struct gafile *pfi, GASDFPARMS *parms) 
+{
+struct gaens *ens;
+struct gachsub *pchsub;
+struct sdfnames *varnames=NULL;
+struct dt tdef,tdefi,tdefe,dt1,dt2;
+gadouble *tvals,*evals,v1,v2,temp;
+gaint rc,len,ichar,tim1,tim2;
+gaint flgs[1],i,j,ii,jj,t,e,reclen,err,flag;
+char rec[512], mrec[512], *ch, *pos, *sname; 
+size_t sz;
+  
+  /* Initialize variables */
+  sname=NULL;
+  initparms(parms);
+  parms->isxdf = 1 ;
+  
+  /* Open descriptor file */
+  descr = fopen (pfi->dnam, "r");  
+  if (descr == NULL) {
+    /* Add default suffix of .ctl */
+    sz = strlen(pfi->dnam)+5;
+    sname = (char *)galloc(sz,"sname");
+    if (sname == NULL) {
+      gaprnt(0,"gadxdf: memory allocation error in creating data descriptor file name\n");
+      return Failure;
+    }
+    for(i=0;i<=strlen(pfi->dnam);i++) *(sname+i)=*(pfi->dnam+i);
+    strcat(sname,".ctl");
+    descr = fopen (sname, "r");
+  }
+  
+  if (descr == NULL) {
+    gaprnt (0,"gadxdf: Can't open description file\n");
+    if (sname) gree(sname,"f45");
+    return Failure;
+  }
+  
+  /* Copy modified descriptor file name into gafile structure */
+  if (sname != NULL) {
+    getwrd (pfi->dnam,sname,255);
+    if (sname) gree(sname,"f46");
+  } 
+  
+  /* initialize variables */
+  for (i=0;i<1;i++) flgs[i] = 1;
+  
+  /* Parse the descriptor file */
+  pfi->vnum = 0 ;
+  while (fgets(rec,512,descr)!=NULL) {
+    
+    /* Remove any leading blanks from rec */
+    reclen = strlen(rec);
+    jj = 0;
+    while (jj<reclen && rec[0]==' ') {
+      for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+      jj++;
+    }
+    /* replace newline with null at end of record */
+    for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+      if (rec[ichar] == '\n') {
+	rec[ichar] = '\0' ;
+	break ; 
+      }
+    }
+    /* Keep mixed case and lower case versions of rec handy */
+    strcpy (mrec,rec);
+    lowcas(rec);
+    
+    /* Parse comment -- check for attribute metadata */
+    if (!isalnum(*(mrec))) {
+      if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+      }
+    } 
+    
+    /* Parse OPTIONS */
+    else if (cmpwrd("options",rec)) {
+      if ((ch=nxtwrd(rec))!=NULL) {
+        while (ch != NULL) {
+          if (cmpwrd("yrev",ch)) pfi->yrflg = 1;
+          else if (cmpwrd("zrev",ch)) pfi->zrflg = 1;
+          else if (cmpwrd("template",ch)) pfi->tmplat = 1; 
+          else if (cmpwrd("365_day_calendar",ch)) {
+	    pfi->calendar=1;
+	    mfcmn.cal365=pfi->calendar;
+	  }
+	  else {
+	    gaprnt (0,"gadxdf error: invalid options keyword\n");
+	    goto err9;
+          }
+          ch = nxtwrd(ch);
+        }
+      }
+    } 
+    
+    /* Parse TITLE */
+    else if (cmpwrd("title",rec)) {
+      parms->needtitle = 0 ;
+      if ((ch=nxtwrd(mrec))==NULL) {
+        gaprnt (1,"gadxdf warning: missing title string\n");
+	pfi->title[0] = '\0' ;
+      } else {
+        getstr (pfi->title,ch,511);
+      }
+    }
+    
+    /* Parse DTYPE */
+    else if (cmpwrd("dtype",rec)) {
+      if ((ch=nxtwrd(rec))==NULL ) pfi->ncflg = 1;   /* default to netcdf */
+      else if (cmpwrd("netcdf",ch)) pfi->ncflg = 1;
+      else if (cmpwrd("hdfsds",ch) || cmpwrd("hdf4",ch)) pfi->ncflg = 2;
+      else {
+        gaprnt (0,"gadxdf Error:  Data file type invalid\n");
+        goto err9;
+      }
+    }
+
+    /* Parse DSET */
+    else if (cmpwrd("dset",rec)) {
+      ch = nxtwrd(mrec);
+      if (ch==NULL) {
+        gaprnt (0,"gadxdf error: data file name is missing\n");
+        goto err9;
+      }
+      if (*ch=='^' || *ch=='$') {
+        fnmexp (pfi->name,ch,pfi->dnam);
+      } else {
+        getwrd (pfi->name,ch,511);
+      }
+      flgs[0] = 0;
+    } 
+    
+    /* Parse CHSUB records.  time1, time2, then a string,  multiple times */
+    else if (cmpwrd("chsub",rec)) {
+      /* point to first block in chain */
+      pchsub = pfi->pchsub1;    
+      if (pchsub!=NULL) {
+        while (pchsub->forw!=NULL) {
+          pchsub = pchsub->forw;       /* advance to end of chain */
+        }
+      }
+      flag = 0;
+      ch = mrec;
+      while (1) {
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        flag = 1;
+        if ( (ch = intprs(ch,&tim1)) == NULL) break;
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        if (*ch=='*' && (*(ch+1)==' '||*(ch+1)=='\t')) tim2 = -99;
+        else if ( (ch = intprs(ch,&tim2)) == NULL) break;
+        if ( (ch=nxtwrd(ch)) == NULL ) break;
+        flag = 0;
+        if (pchsub) {   /* chain exists */
+	  sz = sizeof(struct gachsub);
+          pchsub->forw = (struct gachsub *)galloc(sz,"chsub2");
+          if (pchsub->forw==NULL) {
+	    gaprnt(0,"gadxdf error: memory allocation failed for pchsub\n");
+	    goto err8; 
+	  }
+          pchsub = pchsub->forw;
+	  pchsub->forw = NULL;
+        } else {        /* start a new chain */
+	  sz = sizeof(struct gachsub);
+          pfi->pchsub1 = (struct gachsub *)galloc(sz,"chsub3");
+          if (pfi->pchsub1==NULL)  {
+	    gaprnt(0,"gadxdf error: memory allocation failed for pchsub1\n");
+	    goto err8; 
+	  }
+          pchsub = pfi->pchsub1;
+	  pchsub->forw = NULL;
+        }
+        len = wrdlen(ch);
+	sz = len+1;
+        if ((pchsub->ch = (char *)galloc(sz,"chsub4")) == NULL) goto err8;
+        getwrd(pchsub->ch,ch,len);
+        pchsub->t1 = tim1;
+        pchsub->t2 = tim2;
+      }
+      if (flag) {
+        gaprnt (1,"gadxdf warning: Invalid chsub record; Ignored\n");
+      }
+    }
+
+    /* Parse UNDEF */
+    else if (cmpwrd("undef",rec)) {
+      ch = nxtwrd(mrec);
+      if (ch==NULL) {
+        gaprnt (0,"gadxdf error: missing undef value\n");
+        goto err9;
+      }
+      pos = getdbl(ch,&(pfi->undef));
+      if (pos==NULL) {
+        gaprnt (0,"gadxdf error: invalid undef value\n");
+        goto err9;
+      }
+      /* Get the undef attribute name, if it's there */
+      if ((ch=nxtwrd(ch))!=NULL) {
+	len = 0;
+	while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+	sz = len+1;
+	if ((pfi->undefattr = (char *)galloc(sz,"undefattr2")) == NULL) goto err8;
+	for (i=0; i<len; i++) *(pfi->undefattr+i) = *(ch+i);
+	*(pfi->undefattr+len) = '\0';
+	/* Set the undef attribute flag */
+	pfi->undefattrflg = 1;
+      }
+      pfi->ulow = fabs(pfi->undef/EPSILON);
+      pfi->uhi  = pfi->undef + pfi->ulow;
+      pfi->ulow = pfi->undef - pfi->ulow;
+      parms->needundef = 0 ;
+      parms->hasDDFundef = 1 ;
+    } 
+      
+    /* Parse XDEF */
+    else if (cmpwrd("xdef",rec)) {
+      if (pfi->type == 2) continue;
+      if ((ch = nxtwrd(mrec)) == NULL) goto err0;   /* xdimname must be mixed case version*/
+      parms->xsrch = 0 ;                    
+      /* Copy the X dimension name into parms structure*/
+      len = 0;
+      while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+      sz = len+1;
+      if ((parms->xdimname = (char *)galloc(sz,"xdimname")) == NULL) goto err8;
+      for (i=0; i<len; i++) *(parms->xdimname+i) = *(ch+i);
+      *(parms->xdimname+len) = '\0';
+      ch = nxtwrd(rec) ;                             /* skip over xdef in lowcase version */
+      if ((ch = nxtwrd(ch)) == NULL) {
+        parms->xsetup = 1 ;                    
+      } 
+      else {
+        if ((pos = intprs(ch,&(pfi->dnum[0])))==NULL) goto err1;
+	if (pfi->dnum[0]<1) {
+	  snprintf(pout,255,"Warning: Invalid XDEF syntax in %s -- Changing size of X axis from %d to 1 \n",
+		  pfi->dnam,pfi->dnum[0]);
+	  gaprnt (1,pout);
+	  pfi->dnum[0] = 1;
+	}
+        if (*pos != ' ') goto err1;
+        if ((ch = nxtwrd(ch))==NULL) goto err2;
+        if (cmpwrd("linear",ch)) {
+	  rc = deflin(ch, pfi, 0, 0);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+	  /* Check if grid wraps around the globe */
+	  v2 = *(pfi->grvals[0]);
+	  v1 = *(pfi->grvals[0]+1) + v2;
+	  temp = v1+(pfi->dnum[0])*v2;
+	  temp=temp-360.0;
+	  if (fabs(temp-v1)<0.01) pfi->wrap = 1;
+        } 
+	else if (cmpwrd("levels",ch)) {
+	  rc = deflev (ch, rec, pfi, 0);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+        } else goto err2;
+        parms->xsetup = 0 ;
+      }
+    } 
+
+    /* Parse YDEF */
+    else if (cmpwrd("ydef",rec)) {
+      if (pfi->type == 2) continue;
+      if ((ch = nxtwrd(mrec)) == NULL) goto err0;   /* ydimname must be mixed case version*/
+      parms->ysrch = 0 ;
+      /* Copy the Y dimension name into parms structure*/
+      len = 0;
+      while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+      sz = len+1;
+      if ((parms->ydimname = (char *)galloc(sz,"ydimname")) == NULL) goto err8;
+      for (i=0; i<len; i++) *(parms->ydimname+i) = *(ch+i);
+      *(parms->ydimname+len) = '\0';
+      ch = nxtwrd(rec) ;                             /* skip over ydef in lowcase version*/
+      if ((ch = nxtwrd(ch))  == NULL) { 
+        parms->ysetup = 1 ;
+      } 
+      else {
+        if ((pos = intprs(ch,&(pfi->dnum[1])))==NULL) goto err1 ;
+	if (pfi->dnum[1]<1) {
+	  snprintf(pout,255,"Warning: Invalid YDEF syntax in %s -- Changing size of Y axis from %d to 1 \n",
+		  pfi->dnam,pfi->dnum[1]);
+	  gaprnt (1,pout);
+	  pfi->dnum[1] = 1;
+	}
+        if (*pos!=' ') goto err1;
+        if ((ch = nxtwrd(ch))==NULL) goto err2;
+        if (cmpwrd("linear",ch)) {
+	  rc = deflin(ch, pfi, 1, 0);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+        } else if (cmpwrd("levels",ch)) {
+	  rc = deflev (ch, rec, pfi, 1);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+        } else if (cmpwrd("gausr40",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  if ((pos = intprs(ch,&i))==NULL) goto err3;
+	  pfi->grvals[1] = gagaus(i,pfi->dnum[1]);
+	  if (pfi->grvals[1]==NULL) goto err9;
+	  pfi->abvals[1] = pfi->grvals[1];
+	  pfi->ab2gr[1] = lev2gr;
+	  pfi->gr2ab[1] = gr2lev;
+	  pfi->linear[1] = 0;
+        } else if (cmpwrd("mom32",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  if ((pos = intprs(ch,&i))==NULL) goto err3;
+	  pfi->grvals[1] = gamo32(i,pfi->dnum[1]);
+	  if (pfi->grvals[1]==NULL) goto err9;
+	  pfi->abvals[1] = pfi->grvals[1];
+	  pfi->ab2gr[1] = lev2gr;
+	  pfi->gr2ab[1] = gr2lev;
+	  pfi->linear[1] = 0;
+        } else if (cmpwrd("gausr30",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  if ((pos = intprs(ch,&i))==NULL) goto err3;
+	  pfi->grvals[1] = gags30(i,pfi->dnum[1]);
+	  if (pfi->grvals[1]==NULL) goto err9;
+	  pfi->abvals[1] = pfi->grvals[1];
+	  pfi->ab2gr[1] = lev2gr;
+	  pfi->gr2ab[1] = gr2lev;
+	  pfi->linear[1] = 0;
+        } else if (cmpwrd("gausr20",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  if ((pos = intprs(ch,&i))==NULL) goto err3;
+	  pfi->grvals[1] = gags20(i,pfi->dnum[1]);
+	  if (pfi->grvals[1]==NULL) goto err9;
+	  pfi->abvals[1] = pfi->grvals[1];
+	  pfi->ab2gr[1] = lev2gr;
+	  pfi->gr2ab[1] = gr2lev;
+	  pfi->linear[1] = 0;
+        } else if (cmpwrd("gausr15",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  if ((pos = intprs(ch,&i))==NULL) goto err3;
+	  pfi->grvals[1] = gags15(i,pfi->dnum[1]);
+	  if (pfi->grvals[1]==NULL) goto err9;
+	  pfi->abvals[1] = pfi->grvals[1];
+	  pfi->ab2gr[1] = lev2gr;
+	  pfi->gr2ab[1] = gr2lev;
+	  pfi->linear[1] = 0;
+        } else goto err2;
+        parms->ysetup = 0 ;
+      }
+    } 
+
+    /* Parse ZDEF */
+    else if (cmpwrd("zdef",rec)) {
+      if ((ch = nxtwrd(mrec)) == NULL) goto err0; /* get mixed case version */
+      parms->zsrch = 0 ;
+      /* Copy the Z dimension name into parms structure*/
+      len = 0;
+      while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+      sz = len+1;
+      if ((parms->zdimname = (char *)galloc(sz,"zdimname")) == NULL) goto err8;
+      for (i=0; i<len; i++) *(parms->zdimname+i) = *(ch+i);
+      *(parms->zdimname+len) = '\0';
+      ch = nxtwrd(rec) ;                           /* point past zdef in lowcased version */
+      if ((ch = nxtwrd(ch))  == NULL) {
+        parms->zsetup = 1 ;
+      } 
+      else {
+        if ((pos = intprs(ch,&(pfi->dnum[2])))==NULL) goto err1 ;
+	if (pfi->dnum[2]<1) {
+	  snprintf(pout,255,"Warning: Invalid ZDEF syntax in %s -- Changing size of Z axis from %d to 1 \n",
+		  pfi->dnam,pfi->dnum[2]);
+	  gaprnt (1,pout);
+	  pfi->dnum[2] = 1;
+	}
+        if (*pos!=' ') goto err1;
+        if ((ch = nxtwrd(ch))==NULL) goto err2;
+        if (cmpwrd("linear",ch)) {
+	  rc = deflin(ch, pfi, 2, 0);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+        } else if (cmpwrd("levels",ch)) {
+	  rc = deflev (ch, rec, pfi, 2);
+	  if (rc==-1) goto err8;
+	  if (rc) goto err9;
+        } else goto err2;
+        parms->zsetup = 0 ;
+      }
+    } 
+
+    /* Parse TDEF */
+    else if (cmpwrd("tdef",rec)) {
+      if ((ch = nxtwrd(mrec)) == NULL) goto err0; /* get mixed case version */
+      parms->tsrch = 0 ;
+      if (!strncasecmp(ch, "%nodim%", 7)) {
+        parms->tdimname = NULL ;             /* we won't be using any tdimname */
+	pfi->dnum[TINDEX] = 1 ;              /* 1 time step ; be sure not to map any tdim */
+      } 
+      else {
+	/* Copy the T dimension name into parms structure*/
+	len = 0;
+	while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+	sz = len+1;
+	if ((parms->tdimname = (char *)galloc(sz,"tdimname")) == NULL) goto err8;
+	for (i=0; i<len; i++) *(parms->tdimname+i) = *(ch+i);
+	*(parms->tdimname+len) = '\0';
+      }
+      ch = nxtwrd(rec) ;                           /* skip over tdef in lowcased version */
+      if ((ch = nxtwrd(ch)) == NULL) {
+        if (parms->tdimname == NULL) {
+	  sz = sizeof(gadouble)*8;
+	  if ((tvals = (gadouble *)galloc(sz,"tvals3")) == NULL) goto err8;
+	  tvals[0] = 1.0 ;
+	  tvals[1] = 1.0 ;
+	  tvals[2] = 1.0 ;
+	  tvals[3] = 0.0 ; /* initial hours */
+	  tvals[4] = 0.0 ;
+	  tvals[5] = 0.0 ; /* step in months */
+	  tvals[6] = 1.0 ; /* step in minutes */
+	  tvals[7] = -999.9 ;
+	  pfi->grvals[TINDEX] = tvals ;
+	  pfi->abvals[TINDEX] = tvals ;
+	  pfi->linear[TINDEX] = 1 ;
+	  parms->tsetup = 0 ;
+        } 
+	else {
+	  parms->tsetup = 1 ;
+        }
+      } 
+      else { 
+        if ((pos = intprs(ch,&(pfi->dnum[3])))==NULL) goto err1 ;
+	if (parms->tdimname == NULL) {
+	  /*  %nodim% case can only have 1 timestep */
+	  if (pfi->dnum[3] != 1) {
+	    gaprnt(0, "TDEF with %nodim% has timestep count != 1; resetting to 1.\n") ;
+	    pfi->dnum[3] = 1 ;
+ 	  }
+	}
+	else if (pfi->dnum[3]<1) {
+	  snprintf(pout,255,"Warning: Invalid TDEF syntax in %s -- Changing size of T axis from %d to 1 \n",
+		  pfi->dnam,pfi->dnum[3]);
+	  gaprnt (1,pout);
+	  pfi->dnum[3] = 1;
+	}
+        if (*pos!=' ') goto err1;
+        if ((ch = nxtwrd(ch))==NULL) goto err2;
+        if (cmpwrd("linear",ch)) {
+	  if ((ch = nxtwrd(ch))==NULL) goto err3;
+	  tdef.yr = -1000;
+	  tdef.mo = -1000;
+	  tdef.dy = -1000;
+	  if ((pos = adtprs(ch,&tdef,&dt1))==NULL) goto err3;
+	  if (*pos!=' ' || dt1.yr == -1000 || dt1.mo == -1000.0 || dt1.dy == -1000) goto err3;
+	  if ((ch = nxtwrd(ch))==NULL) goto err4;
+	  if ((pos = rdtprs(ch,&dt2))==NULL) goto err4;
+	  v1 = (dt2.yr * 12) + dt2.mo;
+	  v2 = (dt2.dy * 1440) + (dt2.hr * 60) + dt2.mn;
+	  if (dequal(v1, 0.0, 1.0e-08)==0 && dequal(v2, 0.0, 1.0e-08)==0) goto err4a ;
+	  sz = sizeof(gadouble)*8;
+	  if ((tvals = (gadouble *)galloc(sz,"tvals4")) == NULL) goto err8;
+	  *(tvals) = dt1.yr;
+	  *(tvals+1) = dt1.mo;
+	  *(tvals+2) = dt1.dy;
+	  *(tvals+3) = dt1.hr;
+	  *(tvals+4) = dt1.mn;
+	  *(tvals+5) = v1;
+	  *(tvals+6) = v2;
+	  *(tvals+7) = -999.9;
+	  pfi->grvals[3] = tvals;
+	  pfi->abvals[3] = tvals;
+	  pfi->linear[3] = 1;
+        } else goto err2;
+        parms->tsetup = 0 ;
+      }
+    } 
+
+    /* Parse EDEF */
+    else if (cmpwrd("edef",rec)) {
+      if ((ch = nxtwrd(mrec)) == NULL) goto err1;   /* get mixed case version */
+      parms->esrch  = 0;  /* got the coordinate variable name */
+      /* copy the E dimension name into parms structure */
+      len = 0;
+      while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t') len++;
+      sz = len+1;
+      if ((parms->edimname = (char *)galloc(sz,"edimname")) == NULL) {
+	gaprnt(0,"Unable to allocate memory for E coordinate axis name\n");
+	goto err8;
+      }
+      for (i=0; i<len; i++) *(parms->edimname+i) = *(ch+i);
+      *(parms->edimname+len) = '\0';
+      parms->esetup = 3;       /* still need size, ensemble names, time metadata */
+      ch = nxtwrd(rec) ;                           /* point past edef in lowcased version */
+      if ((ch = nxtwrd(ch)) != NULL) {
+	if ((pos = intprs(ch,&(pfi->dnum[EINDEX]))) == NULL) goto err1;
+	if (pfi->dnum[EINDEX]<1) {
+	  snprintf(pout,255,"Warning: Invalid EDEF syntax in %s -- Changing size of E axis from %d to 1 \n",
+		  pfi->dnam,pfi->dnum[EINDEX]);
+	  gaprnt (1,pout);
+	  pfi->dnum[EINDEX] = 1;
+	}
+	/* set up linear scaling */
+	sz = sizeof(gadouble)*6;
+	if ((evals = (gadouble *)galloc(sz,"evals")) == NULL) {
+	  gaprnt(0,"gadxdf: memory allocation failed for ensemble dimension scaling values\n");
+	  goto err1;
+	}
+	v1=v2=1;
+	*(evals+1) = v1 - v2;
+	*(evals) = v2;
+	*(evals+2) = -999.9;
+	*(evals+4) = -1.0 * ( (v1-v2)/v2 );
+	*(evals+3) = 1.0/v2;
+	*(evals+5) = -999.9;
+	pfi->grvals[EINDEX] = evals;
+	pfi->abvals[EINDEX] = evals+3;
+	pfi->ab2gr[EINDEX] = liconv;
+	pfi->gr2ab[EINDEX] = liconv;
+	pfi->linear[EINDEX] = 1;
+	/* allocate an array of ensemble structures */
+	sz = pfi->dnum[EINDEX] * sizeof(struct gaens); 
+	if ((ens = (struct gaens *)galloc(sz,"ens3")) == NULL) {
+	  gaprnt(0,"Unable to allocate memory for E coordinate axis values\n");
+	  goto err8;
+	}
+	pfi->ens1 = ens;
+	parms->esetup = 2;    /* still need ensemble names, time metadata */
+	j = 0;
+	ch = nxtwrd(ch);
+	/* Check for keyword "names" followed by list of ensemble members.
+	   The option for separate lines containing names, lengths, and 
+	   initial times is not supported in xdfopen */
+	if ((ch!=NULL) && cmpwrd("names",ch)) {
+	  while (j<pfi->dnum[4]) {
+	    if ((ch=nxtwrd(ch))==NULL) goto err7b;
+	    /* get the ensemble name */
+	    if ((getenm(ens, ch))!=0) goto err7c;
+	    /* initialize remaining fields in ensemble structure */
+	    for (jj=0;jj<4;jj++) ens->grbcode[jj]=-999;
+	    ens->length=0;
+	    ens->gt=1;
+	    ens->tinit.yr=0;
+	    ens->tinit.mo=0;
+	    ens->tinit.dy=0;
+	    ens->tinit.hr=0;
+	    ens->tinit.mn=0;
+	    j++; ens++;
+	  }
+	  parms->esetup=1;  /* still need time metadata */
+	} 
+      }
+    } 
+
+    /* parse the variable declarations */
+    else if (cmpwrd("vars",rec)) {
+      if ((ch = nxtwrd(rec)) == NULL) goto err5;
+      if ((pos = intprs(ch,&(pfi->vnum)))==NULL) goto err5;
+      sz = pfi->vnum * sizeof(struct sdfnames) ;
+      if ((varnames = (struct sdfnames *) galloc(sz,"varnames")) == NULL) goto err8;
+      parms->names1 = varnames;
+      parms->dvsrch = 0 ;
+      parms->dvcount = pfi->vnum ;
+      i = 0;
+      while (i<pfi->vnum) {
+        if (fgets(rec,512,descr)==NULL) {
+          gaprnt (0,"gadxdf error: Unexpected EOF reading variables\n");
+          snprintf(pout,255, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+          gaprnt (2,pout);
+          goto retrn;
+        }
+	/* Remove any leading blanks from rec */
+	reclen = strlen(rec);
+	jj = 0;
+	while (jj<reclen && rec[0]==' ') {
+	  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+	  jj++;
+	}
+	/* replace newline with null at end of record */
+        for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+	  if (rec[ichar] == '\n') {
+	    rec[ichar] = '\0' ;
+	    break ; 
+	  }
+        }
+	/* Keep mixed case and lower case versions of rec handy */
+        strcpy (mrec,rec);
+        lowcas(rec);
+	/* Allow comments between VARS and ENDVARS */
+        if (!isalnum(*(mrec))) {
+	  /* Parse comment if it contains attribute metadata  */
+	  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	    if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	    else continue;
+	  }
+  	  else continue; 
+	}
+        if (cmpwrd("endvars",rec)) {
+          gaprnt (0,"gadxdf error: Unexpected ENDVARS record\n");
+          snprintf(pout,255, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+          gaprnt (2,pout);
+          goto err9;
+        }
+	/* Get the compound variable name (longnm=>abbrv). */
+	/* We'll extract # levels and other metadata later. */
+        if ((getncvnm(varnames, mrec))!=0) goto err6;
+        i++; varnames++;
+      }
+
+      /* Check for final record */
+      if (fgets(rec,512,descr)==NULL) {
+        gaprnt (0,"gadxdf error: Missing ENDVARS statement.\n");
+        goto retrn;
+      }
+
+      /* See if final record is an attribute comment or 'endvars'. If not, send error message */
+      strcpy (mrec,rec);
+      lowcas(rec);
+      while (!cmpwrd("endvars",rec)) {
+	if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+	  if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+	}
+        else {
+	  snprintf(pout,255,"gadxdf error: Looking for \"endvars\", found \"%s\" instead.\n",rec);
+	  gaprnt (0,pout);
+	  goto err9;
+	}
+  	if (fgets(rec,256,descr)==NULL) {
+	  gaprnt (0,"gadxdf error: Missing ENDVARS statement.\n");
+	  goto retrn;
+	}
+      }
+
+    } else {
+      /* Parse error of descriptor file */
+      gaprnt (0,"gadxdf error: Unknown keyword in description file\n");
+      goto err9;
+    }
+  }
+  
+  /* Check if required DSET entry is present */
+  err=0;
+  for (i=0; i<1; i++) {
+    if (flgs[i]) {
+      gaprnt (0,"gadxdf error: missing DSET record \n");
+      err=1;
+    }
+  }
+  if (err) goto retrn;
+  
+  /* Done scanning.  Check if scanned stuff makes sense, 
+     and then set things up correctly */
+
+  /* set the global calendar and check if we are trying to change with a new file... */
+  if(mfcmn.cal365<0) {
+    mfcmn.cal365=pfi->calendar;
+  } else {
+    if (pfi->calendar != mfcmn.cal365) {
+      gaprnt(0,"Attempt to change the global calendar...\n");
+      if(mfcmn.cal365) {
+	gaprnt(0,"The calendar is NOW 365 DAYS and you attempted to open a standard calendar file\n");
+      } else {
+	gaprnt(0,"The calendar is NOW STANDARD and you attempted to open a 365-day calendar file\n");
+      }
+      goto retrn;
+    }
+  }
+
+  /* if time series templating was specified, & the TDEF line was incomplete, ERROR! */
+  if (pfi->tmplat && parms->tsetup) {
+    gaprnt (0,"gadxdf error: Use of OPTIONS template requires a complete TDEF entry\n");
+    goto retrn ;
+  }
+
+  /* temporarily set the E dimension size to 1 until we can parse the rest of the metadata */
+  if (pfi->tmplat && parms->esetup==3) {
+    pfi->dnum[4]=1;
+    /* set up linear scaling */
+    sz = sizeof(gadouble)*6;
+    if ((evals = (gadouble *)galloc(sz,"evals")) == NULL) {
+      gaprnt(0,"gadsdf: memory allocation failed for default ensemble dimension scaling values\n");
+      goto err1;
+    }
+    v1=v2=1;
+    *(evals+1) = v1 - v2;
+    *(evals) = v2;
+    *(evals+2) = -999.9;
+    *(evals+4) = -1.0 * ( (v1-v2)/v2 );
+    *(evals+3) = 1.0/v2;
+    *(evals+5) = -999.9;
+    pfi->grvals[EINDEX] = evals;
+    pfi->abvals[EINDEX] = evals+3;
+    pfi->ab2gr[EINDEX] = liconv;
+    pfi->gr2ab[EINDEX] = liconv;
+    pfi->linear[EINDEX] = 1;
+    /* allocate a single ensemble structure */
+    sz = sizeof(struct gaens);
+    if ((ens = (struct gaens *)galloc(sz,"ens1")) == NULL) {
+      gaprnt(0,"gadsdf: memory allocation failed for default E axis values\n");
+      goto err1;
+    }
+    pfi->ens1 = ens;
+    snprintf(ens->name,15,"1");
+    ens->length = pfi->dnum[TINDEX];
+    ens->gt = 1;
+    gr2t(pfi->grvals[TINDEX],1.0,&ens->tinit);
+    /* set grib codes to default values */
+    for (j=0;j<4;j++) ens->grbcode[j]=-999;
+    parms->esetup=4; /* set this to 4 so we know there's a dummy E axis set up */
+  }
+
+
+  /* Create the fnums array. 
+     If the file name is a time series template, figure out
+     which times go with which files, so we don't waste a lot
+     of time later opening and closing files unnecessarily. */
+
+  if (pfi->tmplat) {
+    /* The fnums array is the size of the time axis multiplied by the size of the ensemble axis. 
+       It contains the t index which generates the filename that contains the data for each timestep 
+       If the ensemble has no data file for a given time, the fnums value will be -1 */
+    sz = sizeof(gaint)*pfi->dnum[3]*pfi->dnum[4];
+    pfi->fnums = (gaint *)galloc(sz,"fnums1");   
+    if (pfi->fnums==NULL) {
+      gaprnt(0,"Open Error: memory allocation failed for fnums\n");
+      goto err2;
+    }
+    /* get dt structure for t=1 */
+    gr2t(pfi->grvals[3],1.0,&tdefi);
+    /* loop over ensembles */
+    ens=pfi->ens1;
+    e=1;
+    while (e<=pfi->dnum[4]) {
+      j = -1; 
+      t=1;
+      /* set fnums value to -1 for time steps before ensemble initial time */
+      while (t<ens->gt) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      j = ens->gt;
+      /* get dt structure for ensemble initial time */
+      gr2t(pfi->grvals[3],ens->gt,&tdefe);
+      /* get filename for initial time of current ensemble member  */
+      ch = gafndt(pfi->name,&tdefe,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,ens->gt,e,&flag);   
+      if (ch==NULL) {
+	snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,ens->gt);
+	gaprnt(0,pout);
+	goto err2;
+      }
+      /* set the pfi->tmplat flag to the flag returned by gafndt */
+      if (flag==0) {
+	gaprnt(1,"Warning: OPTIONS keyword \"template\" is used, but the \n");
+	gaprnt(1,"   DSET entry contains no substitution templates.\n");
+	pfi->tmplat = 1;
+      } else {
+	pfi->tmplat = flag; 
+      }
+      pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      /* loop over remaining valid times for this ensemble */
+      for (t=ens->gt+1; t<ens->gt+ens->length; t++) {
+	/* get filename for time index=t ens=e */
+	gr2t(pfi->grvals[3],(gadouble)t,&tdef);
+	pos = gafndt(pfi->name,&tdef,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,t,e,&flag);  
+	if (pos==NULL) {
+	  snprintf(pout,255,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,t);
+	  gaprnt(0,pout);
+	  goto err2;
+	}
+	if (strcmp(ch,pos)!=0) {    /* filename has changed */
+	  j = t;   
+	  gree(ch,"f47");
+	  ch = pos;
+	}
+	else {
+	  gree(pos,"f48");
+	}
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+      }
+      gree(ch,"f48a");
+      /* set fnums value to -1 for time steps after ensemble final time */
+      j = -1;
+      while (t<=pfi->dnum[3]) {
+	pfi->fnums[(e-1)*pfi->dnum[3]+t-1] = j;                                                    
+	t++;
+      }
+      e++; ens++;
+    }
+    pfi->fnumc = 0;
+    pfi->fnume = 0;
+  }
+
+  fclose (descr);
+  return Success;
+  
+ err0:
+  gaprnt(0, "gadxdf error: Missing or invalid dimension name.\n") ;
+  goto err9;
+
+ err1:
+  gaprnt (0,"gadxdf error: Missing or invalid dimension size.\n");
+  goto err9;
+  
+ err2:
+  gaprnt (0,"gadxdf error: Missing or invalid dimension");
+  gaprnt (0," scaling type\n");
+  goto err9;
+  
+ err3:
+  gaprnt (0,"gadxdf error: Missing or invalid dimension");
+  gaprnt (0," starting value\n");
+  goto err9;
+  
+ err4:
+  gaprnt (0,"gadxdf error: Missing or invalid dimension");
+  gaprnt (0," increment value\n");
+  goto err9;
+
+ err4a:
+  gaprnt (0,"gadxdf error: 0 time increment in tdef\n");
+  gaprnt (0," use 1 for single time data\n");
+  goto err9;
+  
+ err5:
+  gaprnt (0,"gadxdf error: Missing or invalid variable");
+  gaprnt (0," count\n");
+  goto err9;
+  
+ err6:
+  gaprnt (0,"gadxdf error: Invalid variable record\n");
+  goto err9;
+  
+ err7b:
+  gaprnt (0,"gadxdf error: Invalid number of ensembles\n");
+  goto err9;
+
+ err7c:
+  gaprnt (0,"gadxdf error: Invalid ensemble name\n");
+  goto err9;
+
+ err8:
+  gaprnt (0,"gadxdf error: Memory allocation Error\n");
+  goto retrn;
+  
+ err9:
+  gaprnt (0,"  --> The invalid description file record is: \n");
+  gaprnt (0,"  --> ");
+  gaprnt (0,rec);
+  gaprnt (0,"\n");
+  
+ retrn:
+  gaprnt (0,"  The data file was not opened. \n");
+  fclose (descr);
+  return Failure;
+  
+}
+
+
+/*  handle var name of the form longnm=>abbrv
+    or just the abbrv with no long name */
+
+gaint getncvnm (struct sdfnames *var, char *mrec) {
+gaint ib,i,j,k,len,flag;
+
+  ib = 0;
+  while (*(mrec+ib)==' ') ib++;
+
+  if (*(mrec+ib)=='\0' || *(mrec+ib)=='\n') return(1);
+
+  /* Scan for the '=>' string */
+  len = 0;
+  i = ib;
+  flag = 0;
+
+  while (1) {
+    if (*(mrec+i)==' ' || *(mrec+i)=='\0' || *(mrec+i)=='\n') break;
+    if (*(mrec+i)=='=' && *(mrec+i+1)=='>') {
+      flag = 1;
+      break;
+    }
+    len++ ; i++; 
+  }
+
+  if (flag) {
+    for (j=ib; j<i; j++) {
+      k = j-ib;
+      var->longnm[k] = *(mrec+j); 
+    }
+    var->longnm[len] = '\0';
+    i+=2;
+  } else {
+    i = 0;
+    var->longnm[0] = '\0';
+  } 
+
+  if (*(mrec+i)=='\n' || *(mrec+i)=='\0') return (1);
+
+  getwrd(var->abbrv, mrec+i, 15);
+  lowcas(var->abbrv);
+
+  /* Check if 1st character is lower-case alphabetic */
+  if (islower(*(var->abbrv))) return(0);
+  else return (1);
+}
+
+/* Initialize parms structure */
+void initparms(GASDFPARMS *parms) {
+  parms->isxdf = 0;
+  parms->xsrch = 1;
+  parms->ysrch = 1;
+  parms->zsrch = 1;
+  parms->tsrch = 1;
+  parms->esrch = 1;
+  parms->dvsrch = 1;
+  parms->xsetup = 1;
+  parms->ysetup = 1;
+  parms->zsetup = 1;
+  parms->tsetup = 1;
+  parms->esetup = 3;
+  parms->needtitle = 1;
+  parms->needundef = 1;
+  parms->needunpack = 1;
+  parms->xdimname = NULL;
+  parms->ydimname = NULL;
+  parms->zdimname = NULL;
+  parms->tdimname = NULL;
+  parms->edimname = NULL;
+  parms->names1 = NULL;
+  parms->dvcount = -1;
+  parms->dvsetup = (gaint *) 0 ; 
+  parms->hasDDFundef = 0 ;
+  return;
+}
+
+/* Free memory for parms structure */
+void freeparms (GASDFPARMS *parms) {
+  if (parms->xdimname) gree(parms->xdimname,"f50");
+  if (parms->ydimname) gree(parms->ydimname,"f51");
+  if (parms->zdimname) gree(parms->zdimname,"f52");
+  if (parms->tdimname) gree(parms->tdimname,"f53");
+  if (parms->edimname) gree(parms->edimname,"f54");
+  if (parms->names1)   gree(parms->names1,"f55");
+  return;
+}
+
+#endif
diff --git a/src/gasdf.h b/src/gasdf.h
new file mode 100644
index 0000000..d8908c4
--- /dev/null
+++ b/src/gasdf.h
@@ -0,0 +1,58 @@
+/* gasdf.h - header info for SDF functionality */
+/* id: netcdf_io.h,v 1.2 1995/05/31 23:53:44 jac (Julia Collins) */
+/* Revision 1.3 1997/07/21 09:51:00 hoop */
+/* added gasdfparms struct */
+/* Revision 1.2  1995/05/31  23:53:44  jac  */
+/* add missing definition */
+/*  */
+/* Revision 1.1  1995/05/02  20:23:12  jac */
+/* Initial revision */
+/* */
+
+#define CALENDAR "calendar"
+#define CAL365 "365_day_year"
+#define ALTCAL365 "noleap"
+
+#define MISSING		-1
+
+/* Missing data definitions  */
+#define BFILL		FILL_BYTE
+#define BMISS		-BFILL
+#define SFILL		FILL_SHORT
+#define SMISS		-SFILL
+#define LFILL		FILL_LONG
+#define LMISS		-LFILL
+#define FFILL		FILL_FLOAT
+#define FMISS		-FFILL		
+#define DFILL		FILL_DOUBLE
+#define DMISS		-DFILL
+
+/* temporary flags to read time according to new or old standards */
+#define CDC			0
+#define COOP			1
+
+/* default scale and offset values for unpacked files */
+#define B_SCALE		(char) 	 1
+#define S_SCALE		(short)  1
+#define L_SCALE		(long) 	 1
+#define F_SCALE		(float)  1.0
+#define D_SCALE		(double) 1.0 
+#define B_OFFSET	(char) 	 0
+#define S_OFFSET	(short)  0
+#define L_OFFSET	(long) 	 0
+#define F_OFFSET	(float)  0.0
+#define D_OFFSET	(double) 0.0 
+
+/* Missing data definitions  */
+#define BFILL		FILL_BYTE
+#define BMISS		-BFILL
+#define SFILL		FILL_SHORT
+#define SMISS		-SFILL
+#define LFILL		FILL_LONG
+#define LMISS		-LFILL
+#define FFILL		FILL_FLOAT
+#define FMISS		-FFILL		
+#define DFILL		FILL_DOUBLE
+#define DMISS		-DFILL
+
+
diff --git a/src/gasdf_std_time.h b/src/gasdf_std_time.h
new file mode 100644
index 0000000..dfd5c05
--- /dev/null
+++ b/src/gasdf_std_time.h
@@ -0,0 +1,376 @@
+#ifndef NC_UNSPECIFIED
+#define NC_UNSPECIFIED 0
+#endif
+
+/* id: netcdf_std.h,v 1.1 1995/05/02 20:23:12 jac Exp $ */
+/* Revision 1.1  1995/05/02  20:23:12  jac */
+/* Initial revision */
+/* */
+
+/* 	=== Header file for standard netCDF format ===		*/
+
+#define NUM_REQD_DIMS		3
+#define NUM_REQD_VARS		3
+#define NUM_REQD_GATTS		3
+#define NUM_REQD_VATTS		13
+#define NUM_REQD_TATTS		7
+#define NUM_OPT_TATTS		2
+#define NUM_REQD_LLATTS		3
+#define NUM_OPT_ATTS		1
+#define NUM_FREQUENCY_VARS	5
+#define NUM_FREQUENCY_DIMS	1
+
+#define NUM_REQD_COOP_VATTS	14
+#define NUM_REQD_LEVEL_ATTS	4
+#define NUM_REQD_COOP_VARS	3
+#define NUM_REQD_COOP_DIMS	3
+
+int         num_reqd_vatts,
+            num_reqd_vars,
+            num_reqd_dims;
+
+/* this value should reflect the current max number of 		*/
+/* attributes that are required for any of the variables.	*/
+#define MAX_NUM_REQD_ATTS	14
+
+/* this value should reflect the current max number of 		*/
+/* dimensions that are required for any of the variables.	*/
+#define MAX_NUM_REQD_DIMS	4
+
+/* this value should reflect the max number of any sort of 	*/
+/* required netCDF file component, be it dimensions, variables, */
+/* or attributes.						*/
+#define MAX_REQD		13
+
+#define TIME_IX			0
+#define LAT_IX			1
+#define LON_IX			2
+#define T_UNITS_IX		1
+#define DELTA_T_IX		2
+#define AVG_PER_IX		3
+#define TIME_ARANGE		4
+#define LTM_RANGE_IX		5
+#define PREV_AVG_PER		6
+#define DATASET_IX		0
+#define DESC_IX			1
+#define LEVEL_IX		2
+#define STAT_IX			3
+#define PSTAT_IX		4
+#define VRANGE_IX		5
+#define ARANGE_IX		6
+#define PRECIS_IX		7
+#define UNITS_IX		8
+#define MISSING_IX		9
+#define VTITLE_IX		10
+#define OFFSET_IX		11
+#define SCALE_IX		12
+#define FILL_IX			0
+#define GTITLE_IX		1
+#define HISTORY_IX		2
+#define LL_UNITS_IX		1
+#define LL_ARANGE		2
+#define FREQUENCY_IX		0
+#define POWERX_IX		1
+#define POWERY_IX		2
+#define PHASE_IX		3
+#define COH2_IX			4
+
+char       **dims;
+static char *cdc_dims[NUM_REQD_DIMS] = {
+  "time",
+  "lat",
+  "lon"
+};
+
+static char *coop_dims[NUM_REQD_COOP_DIMS] = {
+  "time",
+  "lat",
+  "lon"
+};
+
+/* even though this duplicates the required dimensions (since these */
+/* are coordinate variables), define variables for readability.     */
+char       **vars;
+static char *cdc_vars[NUM_REQD_VARS] = {
+  "time",
+  "lat",
+  "lon"
+};
+
+static char *coop_vars[NUM_REQD_COOP_VARS] = {
+  "time",
+  "lat",
+  "lon"
+};
+
+nc_type     *var_type;
+static nc_type cdc_var_type[NUM_REQD_VARS] = {
+  NC_DOUBLE,
+  NC_FLOAT,
+  NC_FLOAT
+};
+
+static nc_type coop_var_type[NUM_REQD_COOP_VARS] = {
+  NC_DOUBLE,
+  NC_FLOAT,
+  NC_FLOAT
+};
+
+
+
+char       **var_atts;
+static char *cdc_var_atts[NUM_REQD_VATTS] = {
+  "dataset",
+  "var_desc",
+  "level_desc",
+  "statistic",
+  "parent_stat",
+  "valid_range",
+  "actual_range",
+  "precision",
+  "units",
+  "missing_value",
+  "title",
+  "add_offset",
+  "scale_factor"
+};
+
+static char *coop_var_atts[NUM_REQD_COOP_VATTS] = {
+  "dataset",
+  "var_desc",
+  "level_desc",
+  "statistic",
+  "parent_stat",
+  "valid_range",
+  "actual_range",
+  "precision",
+  "units",
+  "missing_value",
+  "long_name",
+  "add_offset",
+  "scale_factor",
+  "least_significant_digit"
+};
+
+nc_type     *var_atts_type;
+static nc_type cdc_var_atts_type[NUM_REQD_VATTS] = {
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_UNSPECIFIED,
+  NC_SHORT,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_UNSPECIFIED
+};
+
+static nc_type coop_var_atts_type[NUM_REQD_COOP_VATTS] = {
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_UNSPECIFIED,
+  NC_SHORT,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_CHAR,
+  NC_UNSPECIFIED,
+  NC_UNSPECIFIED,
+  NC_SHORT
+};
+
+char       **var_atts_val;
+static char *cdc_var_atts_val[NUM_REQD_VATTS] = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  "MISS",			/* lower valid range value only */
+  "MISS",			/* lower actual range value only */
+  "-9999",
+  NULL,
+  "MISS",
+  NULL,
+  "0",				/* use default offset for variable type */
+  "1"				/* use default scale for variable type */
+};
+
+static char *coop_var_atts_val[NUM_REQD_COOP_VATTS] = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  "MISS",			/* lower valid range value only */
+  "MISS",			/* lower actual range value only */
+  "-9999",
+  NULL,
+  "MISS",
+  NULL,
+  "0",				/* use default offset for variable type */
+  "1",				/* use default scale for variable type */
+  "2"
+};
+
+char       **obs_atts_val;
+static char *cdc_obs_atts_val[NUM_REQD_VATTS] = {
+  NULL,
+  NULL,
+  NULL,
+  "N",
+  "I",
+  "0",				/* lower valid range value only */
+  "0",				/* lower actual range value only */
+  "0",
+  "observations",
+  "MISS",
+  NULL,
+  "0",				/* use default offset for variable type */
+  "1"				/* use default scale for variable type */
+};
+
+static char *coop_obs_atts_val[NUM_REQD_COOP_VATTS] = {
+  NULL,
+  NULL,
+  NULL,
+  "N",
+  "I",
+  "0",				/* lower valid range value only */
+  "0",				/* lower actual range value only */
+  "0",
+  "observations",
+  "MISS",
+  NULL,
+  "0",				/* use default offset for variable type */
+  "1",				/* use default scale for variable type */
+  "2"
+};
+
+/* reserve X to indicate none */
+char       *vatts_abbrev;
+static char cdc_vatts_abbrev[NUM_REQD_VATTS] = {
+  'D',
+  'V',
+  'L',
+  'S',
+  'P',
+  'R',
+  'A',
+  'E',
+  'U',
+  'M',
+  'T',
+  'O',
+  'F'
+};
+
+/* reserve X to indicate none */
+static char coop_vatts_abbrev[NUM_REQD_COOP_VATTS] = {
+  'D',
+  'V',
+  'L',
+  'S',
+  'P',
+  'R',
+  'A',
+  'E',
+  'U',
+  'M',
+  'T',
+  'O',
+  'F',
+  'Q'
+};
+
+
+char       **time_atts;
+static char *cdc_time_atts[NUM_REQD_TATTS] = {
+  "title",
+  "units",
+  "delta_t",
+  "avg_period",
+  "valid_range",
+  "ltm_range",
+  "prev_avg_period"
+};
+
+static char *coop_time_atts[NUM_REQD_TATTS] = {
+  "long_name",
+  "units",
+  "delta_t",
+  "avg_period",
+  "actual_range",
+  "ltm_range",
+  "prev_avg_period"
+};
+
+
+char       **time_atts_val;
+static char *cdc_time_atts_val[NUM_REQD_TATTS] = {
+  "Time",
+  "yyyymmddhhmmss",
+  NULL,
+  "0000-00-00 00:00:00",
+  NULL,
+  "MISSING",			/* this is the default for both range values */
+  "0000-00-00 00:00:00"
+};
+
+static char *coop_time_atts_val[NUM_REQD_TATTS] = {
+  "Time",
+  "hours since 0001-01-01 00:00:00",
+  NULL,
+  "0000-00-00 00:00:00",
+  NULL,
+  "MISSING",			/* this is the default for both range values */
+  "0000-00-00 00:00:00"
+};
+
+
+char       **latlon_atts;
+static char *cdc_latlon_atts[NUM_REQD_LLATTS] = {
+  "title",
+  "units",
+  "valid_range"
+};
+
+static char *coop_latlon_atts[NUM_REQD_LLATTS] = {
+  "long_name",
+  "units",
+  "actual_range"
+};
+
+
+
+/* id: time.h,v 1.1 1995/05/31 23:56:27 jac Exp $ */
+/* Revision 1.1  1995/05/31  23:56:27  jac */
+/* Initial revision */
+/* */
+
+/* time definitions */
+#define HOURS_PER_DAY		24
+#define HOURS_PER_YR		8760
+#define HOURS_PER_LEAP_YR	8784
+#define DAYS_PER_PENTAD		5
+#define DAYS_PER_YR		365
+#define DAYS_PER_LEAP_YR	366
+#define MONTHS_PER_SEASON	3
+#define MONTHS_PER_YR		12
+#define PENTADS_PER_YR		73
+#define SEASONS_PER_YR		4
+
+#define PMONTHS		0
+#define PSEASONS	1
+#define PYEARS		2
+#define PDAYS		3
+#define PHOURS		4
+#define PPENTADS	5
+#define MAXPER		6
diff --git a/src/gatxt.c b/src/gatxt.c
new file mode 100644
index 0000000..1760caa
--- /dev/null
+++ b/src/gatxt.c
@@ -0,0 +1,189 @@
+/*
+    Copyright (C) 2009 by Arlindo da Silva <dasilva at opengrads.org>
+    All Rights Reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; using version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, please consult  
+              
+              http://www.gnu.org/licenses/licenses.html
+
+    or write to the Free Software Foundation, Inc., 59 Temple Place,
+    Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+/* Simple functions to produce color text using ANSI color sequences,
+   see:
+
+        http://en.wikipedia.org/wiki/ANSI_escape_code
+
+   The main function used from grads is gatxtl(string,level) which
+   colorizes a *string* given a "level" as in gaprnt(), except that
+   level=-1 means the prompt.
+
+   The actual colors used dependend on the color scheme specified
+   during initialization; see gatxtl() below for the specific colors.
+   Usually,
+
+   color scheme          works well with a
+   ------------          -----------------
+       0                 black background
+       1                 white background
+       2                 green background
+
+*/
+
+
+#include <stdio.h>
+#include "gatypes.h"
+
+static gaint color_on = 0; /* off by default */
+static gaint scheme   = 0;   /* color scheme */
+
+/* Normal colors */
+static char *black   = "";
+static char *red     = "";
+static char *green   = "";
+static char *yellow  = "";
+static char *blue    = "";
+static char *magenta = "";
+static char *cyan    = "";
+static char *white   = "";
+static char *reset   = "";
+
+static char *normal  = "";
+static char *bold    = "";
+
+/* Normal colors */
+/* static char *Black   = ""; */
+/* static char *Red     = ""; */
+/* static char *Green   = ""; */
+/* static char *Yellow  = ""; */
+/* static char *Blue    = ""; */
+/* static char *Magenta = ""; */
+/* static char *Cyan    = ""; */
+/* static char *White   = ""; */
+
+void gatxti(gaint on, gaint cs) {  /* Turn this feature ON/OFF */
+  color_on = on;
+  if ( cs < 0 ) cs = 0;
+  scheme = cs;
+}
+
+/* Print ANSI sequence associated with a color name.
+   Available options for *nomal* intensite colors are:
+
+          black  
+          red    
+          green  
+          yellow 
+          blue   
+          magenta
+          cyan   
+          white  
+
+    Bright colors are specified by capitalizing the first leter,
+    e.g., "Red". Specify color=NULL for a reset.
+
+*/
+
+void gatxt(char *color) {
+  if ( !color_on ) return;
+  if ( color==NULL ) {
+    printf("%s",reset);
+    return;
+  }
+
+  /* Normal */
+       if ( color[0]=='b' && 
+            color[2]=='a' ) printf("%s",black);
+  else if ( color[0]=='r' ) printf("%s",red);
+  else if ( color[0]=='g' ) printf("%s",green);
+  else if ( color[0]=='y' ) printf("%s",yellow);
+  else if ( color[0]=='b' ) printf("%s",blue);
+  else if ( color[0]=='m' ) printf("%s",magenta);
+  else if ( color[0]=='c' ) printf("%s",cyan);
+  else if ( color[0]=='w' ) printf("%s",white);
+
+  else if ( color[0]=='o' ) printf("%s",normal);
+  else if ( color[0]=='*' ) printf("%s",bold);
+
+  /* Bright colors */
+  else if ( color[0]=='B' && 
+            color[2]=='a' ) printf("%s",black);
+  else if ( color[0]=='R' ) printf("%s",red);
+  else if ( color[0]=='G' ) printf("%s",green);
+  else if ( color[0]=='Y' ) printf("%s",yellow);
+  else if ( color[0]=='B' ) printf("%s",blue);
+  else if ( color[0]=='M' ) printf("%s",magenta);
+  else if ( color[0]=='C' ) printf("%s",cyan);
+  else if ( color[0]=='W' ) printf("%s",white);
+
+}
+
+static char buffer[256];
+#define COLORIZE(c) snprintf(buffer,255,"%s%s%s",c,str,reset)
+
+char *gatxts(char *str, char *color) { /* colorize the string */
+
+
+  if ( !color_on ) return str;
+
+  /* Normal */
+       if ( color[0]=='b' && 
+            color[2]=='a' ) COLORIZE(black);
+  else if ( color[0]=='r' ) COLORIZE(red);
+  else if ( color[0]=='g' ) COLORIZE(green);
+  else if ( color[0]=='y' ) COLORIZE(yellow);
+  else if ( color[0]=='b' ) COLORIZE(blue);
+  else if ( color[0]=='m' ) COLORIZE(magenta);
+  else if ( color[0]=='c' ) COLORIZE(cyan);
+  else if ( color[0]=='w' ) COLORIZE(white);
+
+  /* Bright colors */
+  else if ( color[0]=='B' && 
+            color[2]=='a' ) COLORIZE(black);
+  else if ( color[0]=='R' ) COLORIZE(red);
+  else if ( color[0]=='G' ) COLORIZE(green);
+  else if ( color[0]=='Y' ) COLORIZE(yellow);
+  else if ( color[0]=='B' ) COLORIZE(blue);
+  else if ( color[0]=='M' ) COLORIZE(magenta);
+  else if ( color[0]=='C' ) COLORIZE(cyan);
+  else if ( color[0]=='W' ) COLORIZE(white);
+
+  buffer[255] = '\0';
+  return (char *) buffer;
+
+}
+
+char *gatxtl(char *str, gaint level) { /* colorize according to level */
+
+  if ( scheme==0 ) {
+    if (level==-1) return gatxts(str,"Green"); /* prompt */
+    if (level==0 ) return gatxts(str,"Red");
+    if (level==1 ) return gatxts(str,"magenta");
+    if (level==2 ) return gatxts(str,"yellow");
+  }
+  else if ( scheme==1 ) {
+    if (level==-1) return gatxts(str,"Green"); /* prompt */
+    if (level==0) return gatxts(str,"Red");
+    if (level==1) return gatxts(str,"magenta");
+    if (level==2) return gatxts(str,"blue");
+  }
+  else if ( scheme==2 ) {
+   if (level==-1) return gatxts(str,"Blue"); /* prompt */
+    if (level==0) return gatxts(str,"black");
+    if (level==1) return gatxts(str,"magenta");
+    if (level==2) return gatxts(str,"white");
+  } 
+  return (str);
+}
diff --git a/src/gatypes.h b/src/gatypes.h
new file mode 100644
index 0000000..9c53206
--- /dev/null
+++ b/src/gatypes.h
@@ -0,0 +1,10 @@
+ /************\
+ * Data Types * 
+ \************/
+typedef double        gadouble;
+typedef float         gafloat;
+typedef int           gaint;
+typedef unsigned long gaPixel;
+typedef unsigned int  gauint;
+typedef long int      galint;
+
diff --git a/src/gauser.c b/src/gauser.c
new file mode 100644
index 0000000..07671f5
--- /dev/null
+++ b/src/gauser.c
@@ -0,0 +1,8104 @@
+/*  copyright (C) 1988-2010 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+/* If autoconfed, only include malloc.h when it's present */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#if USESHP==1
+#include "shapefil.h"
+#endif
+
+#if USENETCDF == 1
+#include "netcdf.h"
+#endif 
+
+#if USEHDF == 1
+#include "mfhdf.h"
+#endif 
+#if USEHDF5 == 1
+#include "hdf5.h"
+#endif 
+
+#if USEGUI == 1
+#include "gagui.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include "grads.h"
+#include "gx.h"
+
+char *gatxtl(char *str, int level);
+
+extern struct gamfcmn mfcmn;
+static char *cdims[7] = {"None","Lon","Lat","Lev","Time","Ens","Val"};
+static char *ccdims[6] = {"Xdim","Ydim","Zdim","Tdim","Edim","Val"}; 
+static char pout[256];   /* Build error msgs here */
+static struct gacmn *savpcm;
+
+/*  Variables to handle message buffering for the script language */
+static gaint msgflg = 0;
+struct msgbuf {
+  struct msgbuf *forw;
+  gaint levl;
+  gaint len;
+  char *msg;
+};
+static struct msgbuf *msgstk, *msgcurr, *msgnew;
+
+
+/* Handle all user commands */
+gaint gacmd (char *com, struct gacmn *pcm, gaint exflg) {
+struct gafile *pfi,*pfi2;
+struct gadefn *pdf,*pdf2;
+struct gaclct *clct,*clct2;
+gaint rc,reinit,fnum,i,len,retcod,flag,xin,yin,bwin,gifflg,tcolor;
+char cc[260], bgImage[256], fgImage[256];
+char *cmd,*rslt,*ccc,*ch;
+size_t sz;
+
+  ccc = NULL;
+  gaiomg();   /* enable interpolation message */
+
+  len = 0;
+  while(*(com+len)) len++;
+  len++;
+  sz = len+1;
+  ccc = (char *)galloc(sz,"ccc");
+  if (ccc==NULL) {
+    gaprnt(0,"Memory allocation error: Command Proecessing\n");
+    return(1);
+  }
+  for (i=0; i<len; i++) *(ccc+i) = *(com+i);
+  *(ccc+len) = '\0';          /* Maintain mixed case version */
+  cmd = ccc;
+  lowcas (cmd);
+  while (*cmd==' ') cmd++;
+  while (*com==' ') com++;
+
+  retcod = 0;
+
+  /* Check for implied define */
+  flag = 0;
+  if (*cmd>='a' && *cmd<='z') {
+    i = 0;
+    ch = cmd;
+    while ( (*ch>='a' && *ch<='z') || (*ch>='0' && *ch<='9' ) ) {
+      i++;
+      if (i>16) break;
+      ch++;
+    }
+    if (i<17) {
+      while (*ch==' ') ch++;
+      if (*ch=='=') {
+        flag = 1;
+        ch++;
+        while (*ch==' ') ch++;
+      }
+    }
+    if (flag) {
+      if (pcm->pfid==NULL) {
+        gaprnt (0,"DEFINE error:  no file open yet\n");
+        retcod = 1;
+        goto retrn;
+      }
+      retcod = gadef (cmd, pcm, 1);
+      goto retrn;
+    }
+  }
+
+  if (!(cmpwrd("clear",cmd) || cmpwrd("c",cmd))) gxfrme (9);
+  if (*com=='\0' || *com=='\n') goto retrn; 
+
+  if (cmpwrd("quit",cmd)) {
+     retcod = -1;
+     goto retrn;
+  } 
+
+  else if (*cmd=='!') {
+    system(com+1);
+    goto retrn;
+
+#if READLINE == 1
+    /* print history or repeat commands from history  */
+  }  
+  else if (cmpwrd("history", cmd) ||
+	   cmpwrd("his",     cmd) ||
+	   cmpwrd("repeat",  cmd) ||
+	   cmpwrd("r",       cmd)    ) {
+    retcod = gahistory(cmd, com, pcm);
+    goto retrn;
+#endif
+#if USEGUI == 1
+  } 
+  else if (cmpwrd("gui",cmd)) {
+    char *tmp ;
+    if ((cmd=nxtwrd(com)) == NULL) {
+      gaprnt (0,"GUI error:  No file name specified\n");
+      retcod = 1;
+      goto retrn;
+    } else {
+      gaint lentmp ;
+
+      lentmp = (gaint) strlen(cmd) ;
+      sz = lentmp + 1;
+      tmp = (char *) galloc(sz,"gui") ;
+      getwrd(tmp, cmd, lentmp) ;
+      retcod = Custom_GUI(tmp);
+      if(tmp) gree(tmp,"f186");
+      goto retrn;
+    }
+#endif
+#if GRIB2
+  } else if (cmpwrd("flush",cmd)) {
+    g2clear();
+    gaprnt (1,"grib2 cache cleared\n");
+    goto retrn;
+#endif
+  } else if (cmpwrd("stack",cmd)) {
+    goto retrn;
+
+  } else if (cmpwrd("reset",cmd) || cmpwrd("reinit",cmd)) {
+    pcm->xsiz = pcm->pxsize;
+    pcm->ysiz = pcm->pysize;
+    gxvpag (pcm->xsiz, pcm->ysiz, 0.0, pcm->xsiz, 0.0, pcm->ysiz);
+    gainit();
+    gacln (pcm,1);
+    gacln (pcm,2);
+    gacln (pcm,3);
+    gacln (pcm,4);
+    reinit = 0;
+    if (cmpwrd("reinit",cmd)) {
+      reinit = 1;
+      mfcmn.cal365=-999;
+      mfcmn.warnflg=2;
+      /* release all define blocks */
+      pdf = pcm->pdf1;
+      while (pdf) {
+        pdf2 = pdf->pforw;
+        pfi = pdf->pfi;
+        if (pfi->rbuf) gree(pfi->rbuf,"f189a");
+        if (pfi->sbuf) gree(pfi->sbuf,"f189b");
+        if (pfi->ubuf) gree(pfi->ubuf,"f189c");
+	for (i=0; i<5; i++) {
+	  gree(pfi->grvals[i],"f189d");
+	  gree(pfi->abvals[i],"f189e");
+	}
+        gree(pfi,"f190");
+        gree(pdf,"f191");
+        pdf = pdf2;
+      }
+      /* release all collections */
+      for (i=0; i<32; i++) {
+	clct = pcm->clct[i];
+	while (clct) {
+	  gasfre(clct->stn);
+	  clct2 = clct->forw;
+	  gree(clct,"f218");
+	  clct = clct2;
+	}
+	pcm->clct[i] = NULL;
+	pcm->clctnm[i] = 0;
+      }
+      /* close all files */
+      pfi = pcm->pfi1;
+      while (pfi) {
+        if (pfi->infile) fclose(pfi->infile); 
+        if (pfi->mfile)  fclose(pfi->mfile);
+	if (pfi->ncflg==1) gaclosenc(pfi);
+	if (pfi->ncflg==2) gaclosehdf(pfi);
+	if (pfi->ncflg==3) gacloseh5(pfi);
+	if (pfi->bufrdset) {            /* bufr station data */
+	  gabufr_close(pfi->bufrdset);  /* free memory */
+	  pfi->bufrdset=NULL;           /* reset the pointer */
+	}
+#if USEGADAP
+        if (pfi->dhandle > -999) dapclo(pfi);  /* opendap station data */
+#endif
+        pfi2 = pfi->pforw;
+        frepfi(pfi,0);
+        pfi = pfi2;
+      }
+      pcm->pfi1 = NULL;
+      pcm->pfid = NULL;
+      pcm->fnum = 0;
+      pcm->dfnum = 0;
+      pcm->undef =  -9.99e8;         /* default undef value */
+      pcm->pdf1 = NULL;
+      pcm->grflg = 0;
+      pcm->devbck = 0;
+      if (pcm->ffile) fclose(pcm->ffile);
+      pcm->ffile = NULL;
+      if (pcm->sfile) fclose(pcm->sfile);
+      pcm->sfile = NULL;
+      if (pcm->fwname) gree(pcm->fwname,"f192");
+      pcm->fwname = NULL;
+#if USENETCDF == 1
+      if (pcm->ncwid != -999) nc_close(pcm->ncwid);
+#endif
+      pcm->fwenflg = BYTEORDER;
+      gxhend();
+      gxdbck(pcm->devbck);
+      gxgrey(pcm->grflg);
+#if GRIB2
+      g2clear();
+#endif
+      gaprnt (1,"All files closed; all defined objects released;\n");
+    }
+    if (pcm->fnum>0 && pcm->pfi1) {
+      pcm->pfid = pcm->pfi1;
+      pcm->dfnum = 1;
+      pfi = pcm->pfi1;
+      if (pfi->type==2 || pfi->wrap) gacmd ("set lon 0 360",pcm,0);
+      else {
+        snprintf(pout,255,"set x 1 %i",pfi->dnum[0]);
+        gacmd (pout,pcm,0);
+      }
+      if (pfi->type==2) {
+        gacmd ("set lat -90 90",pcm,0);
+        gacmd ("set lev 500",pcm,0);
+      } else {
+        snprintf(pout,255,"set y 1 %i",pfi->dnum[1]);
+        gacmd (pout,pcm,0);
+
+	/* set z to max if x or y = 1 */
+	if(pfi->type==1 && pfi->dnum[2] > 1
+	   && ( (pfi->dnum[0] == 1) || (pfi->dnum[1] == 1) ) ) {
+	  if(pfi->dnum[2] <= 1) {
+	    snprintf(pout,255,"set z 1");
+	  } else {
+	    snprintf(pout,255,"set z 1 %i",pfi->dnum[2]);
+	  }
+	  gacmd (pout,pcm,0);
+	} else {
+	  gacmd ("set z 1",pcm,0);
+	}
+      }
+      gacmd ("set t 1",pcm,0);
+      gacmd ("set e 1",pcm,0);
+    }
+    gxchdf(0);               /* set default font to 0 */ 
+    gxfrme (1);
+    if (reinit)
+      gaprnt (1,"All GrADS attributes have been reinitialized\n");
+    else gaprnt (1,"Most GrADS attributes have been reset\n");
+    goto retrn;
+  }
+  else if (cmpwrd("screen",cmd)) {
+    if ((cmd=nxtwrd(cmd)) == NULL) {
+      gaprnt (0,"Screen Error: Missing keyword\n");
+      retcod = 1;
+      goto retrn;
+    }
+    i = 0;
+    if (cmpwrd("save",cmd)) i = 1;
+    if (cmpwrd("show",cmd)) i = 2;
+    if (cmpwrd("free",cmd)) i = 3;
+    if (i) {
+      if ((cmd=nxtwrd(cmd)) == NULL) {
+        gaprnt (0,"Screen Error: Missing screen number\n");
+        retcod = 1;
+        goto retrn;
+      }
+      if (intprs(cmd,&(fnum)) == NULL ) {
+        gaprnt (0,"Screen Error: Invalid screen number\n");
+        retcod = 1;
+        goto retrn;
+      }
+      if (i==1) gxdssv(fnum);
+      if (i==2) gxdssh(fnum);
+      if (i==3) gxdsfr(fnum);
+      gxfrme(9);
+    } else {
+      gaprnt (0,"Screen Error: Unknown keyword\n");
+      retcod = 1;
+      goto retrn;
+    }
+    goto retrn;
+  }
+  else if (cmpwrd("close",cmd)) {
+    if ((cmd=nxtwrd(cmd)) == NULL) {
+      gaprnt (0,"Close Error: Missing file number\n");
+      retcod = 1;
+      goto retrn;
+    }
+    if (intprs(cmd,&(fnum)) == NULL ) {
+      gaprnt (0,"Close Error: Invalid file number\n");
+      retcod = 1;
+      goto retrn;
+    }
+    if (fnum != pcm->fnum) {
+      gaprnt (0,"Close Error: Only last file may be closed\n");
+      retcod = 1;
+      goto retrn;
+    }
+    /* advance to end of chain of open file structures */
+    pfi = pcm->pfi1;
+    for (i=0; i<fnum-1 && pfi; i++) pfi = pfi->pforw;
+    if (pfi==NULL || pfi->pforw!=NULL) {
+      gaprnt (0,"Logic Error 4 on Close.  No Action Taken\n");
+      retcod = 1;
+      goto retrn;
+    }
+    /* close any data and map files that are open */
+    if (pfi->infile) fclose (pfi->infile);
+    if (pfi->mfile) fclose(pfi->mfile);
+    if (pfi->ncflg==1) gaclosenc(pfi);
+    if (pfi->ncflg==2) gaclosehdf(pfi);
+    if (pfi->ncflg==3) gacloseh5(pfi);
+    if (pfi->bufrdset) {            /* bufr station data */
+      gabufr_close(pfi->bufrdset);  /* free memory */
+      pfi->bufrdset=NULL;           /* reset the pointer */
+    }
+#if USEGADAP
+    if (pfi->dhandle > -999) dapclo(pfi);  /* opendap station data */
+#endif
+    frepfi(pfi,0);
+    pcm->fnum--;                           /* decrease number of open files */
+    if (pcm->dfnum==fnum) {                /* if closed file was default ... */
+      pcm->dfnum = 1;                      /* ...reset default file number to 1  */
+      pcm->pfid = pcm->pfi1;               /* ...reset pointer to default gafile */
+    }
+    if (pcm->fnum==0) {                    /* no files open, so ... */
+      pcm->dfnum = 0;                      /*    set default file to zero */
+      pcm->pfi1 = NULL;                    /*    pointer to file chain is null */
+      pcm->pfid = NULL;                    /*    pointer to default file is null */
+    } else {
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-2 && pfi; i++) pfi = pfi->pforw;  /* move to end of chain */
+      pfi->pforw = NULL;                                 /* set last link to null */
+    }
+    snprintf(pout,255,"File %i has been closed\n",fnum);
+    gaprnt (2,pout);
+    goto retrn;
+  }
+  else if (cmpwrd("clear",cmd) || cmpwrd("c",cmd)) {
+    rc = 0;
+    if ((cmd=nxtwrd(cmd)) != NULL) {
+      rc=99;
+      if (cmpwrd("norset",cmd))   rc = 1;
+      if (cmpwrd("events",cmd))   rc = 2;
+      if (cmpwrd("graphics",cmd)) rc = 3;
+      if (cmpwrd("hbuff",cmd))    rc = 4;
+      if (cmpwrd("button",cmd))   rc = 5;
+      if (cmpwrd("rband",cmd))    rc = 6;
+      if (cmpwrd("dropmenu",cmd)) rc = 7;
+      if (cmpwrd("sdfwrite",cmd)) rc = 8;
+      if (cmpwrd("mask",cmd))     rc = 9;
+      if (cmpwrd("shp",cmd))      rc = 10;
+    }
+    if (rc==99) {
+      gaprnt (0,"Invalid option on clear command\n");
+      goto retrn;
+    }
+    if (rc<2) {
+      if (exflg) gxfrme (0);
+      else gxfrme (1);
+    }
+    else if (rc==2) gxfrme(8);
+    else if (rc==3) gxfrme(7);
+    else if (rc==4) gxhfrm(0);
+    else if (rc>4 && rc<8) {
+      if ((cmd=nxtwrd(cmd)) == NULL) {
+        gaprnt (0,"Invalid or missing widget number on clear command\n");
+        goto retrn;
+      }
+      if (intprs(cmd,&(fnum)) == NULL ) {
+        gaprnt (0,"Invalid or missing widget number on clear command\n");
+        goto retrn;
+      }
+      gxrs1wd (rc-4, fnum);
+    }
+    if (rc==1) gacln(pcm,0);
+    else if (rc==8) gacln(pcm,2);  /* clears sdfwrite file name and attributes */
+    else if (rc<5 || rc==99) {
+      gacln (pcm,1);
+      pcm->dbflg = 0;
+    }
+    else if (rc==9) gxmaskclear();
+    else if (rc==10) gacln(pcm,3);  /* clears user-provided shapefile attributes */
+    goto retrn;
+  }
+
+  else if (cmpwrd("swap",cmd)) {
+    if (pcm->dbflg) gxfrme(2);
+    gacln(pcm,1);
+    goto retrn;
+  } 
+
+  else if (cmpwrd("outxwd", cmd)) { 
+    if (pcm->batflg) {
+      gaprnt(0,"The outxwd command does not work in batch mode\n");
+      retcod = 1;
+      goto retrn;
+    }
+    char *fname, name_file_xwd[256] ; 
+    fname = nxtwrd(com) ; 
+    if (fname) { 
+      if (sscanf(fname, "%s", name_file_xwd) == 1) { 
+	if (pcm->dbflg) { 
+	  dump_back_buffer(name_file_xwd) ; 
+	} else { 
+	  dump_front_buffer(name_file_xwd) ; 
+	} 
+      } 
+    } else { 
+      gaprnt(0,"command outxwd: missing output filename\n") ; 
+    } 
+    gacln(pcm,1) ; 
+    goto retrn;
+  } 
+
+  else if (cmpwrd("q",cmd)||cmpwrd("query",cmd)) {
+    retcod = gaqury (cmd, com, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("help",cmd)) {
+    retcod = gahelp (cmd, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("exec",cmd)) {
+    retcod = gaexec (com, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("run",cmd)) {
+    if ((cmd=nxtwrd(com)) == NULL) {
+      gaprnt (0,"RUN error:  No file name specified\n");
+      retcod = 1;
+      goto retrn;
+    }
+    savpcm = pcm;
+    rslt = gsfile(cmd,&rc,0);
+    if (rc==0 && rslt!=NULL) gaprnt(2,rslt);
+    if (rslt!=NULL) gree(rslt,"f193");
+    retcod = rc;
+    goto retrn;
+  }
+  else if (cmpwrd("enable",cmd)) {
+    retcod = gaenab (com, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("disable",cmd)) {
+    if ((cmd=nxtwrd(com)) == NULL) 
+      gxhend();                                     /* without 2nd arg, assume 'disable print' */ 
+    else {
+      if (cmpwrd("print",cmd)) 
+	gxhend();                                   /* close the metafile output file  */
+      else if (cmpwrd("fwrite",cmd)) {
+	if (pcm->ffile) {                           /* don't close a file unless it's open  */ 
+	  if (pcm->ffile!=stdout) fclose(pcm->ffile);    /* don't close stdout */    
+	}
+        pcm->ffile = NULL;
+        if (pcm->fwname) gree(pcm->fwname,"f194");  /* reset fwrite file name on disable. */
+        pcm->fwname = NULL;                         
+        pcm->fwenflg = BYTEORDER;                   /* set fwrite to default state */
+        pcm->fwsqflg = 0;                           /* default is stream */
+        pcm->fwexflg = 0;                           /* default is not exact -- old bad way */
+      }
+      else if (cmpwrd("stnwrt",cmd)) {
+        if (pcm->sfile) fclose(pcm->sfile);
+        pcm->sfile = NULL;
+      }
+      else gaprnt (0,"DISABLE error: Invalid keyword\n");
+    }
+    goto retrn;
+  }
+  else if (cmpwrd("redraw",cmd)) {
+    gardrw(com,pcm);
+    gxfrme(9);
+    goto retrn;
+  }
+  else if (cmpwrd("draw",cmd)) {
+    gadraw(com,pcm);
+    gxfrme (9);          /* flush any buffers as needed */
+    goto retrn;
+  }
+  else if (cmpwrd("print",cmd)) {
+    gxhprt (com);
+    goto retrn;
+  }
+#if GXPNG==1
+  else if (cmpwrd("printim",cmd)) {
+    if ((ch=nxtwrd(com)) == NULL) {
+      gaprnt (0,"PRINTIM error:  missing output file name\n");
+      retcod = 1;
+      goto retrn;
+    }
+    getwrd (cc,ch,256);
+    if ((cmd=nxtwrd(cmd)) == NULL) {
+      gaprnt (0,"PRINTIM error:  logic error 64\n");
+      retcod = 1;
+      goto retrn;
+    }
+    xin = -999;
+    yin = -999;
+    bwin = -999;
+    gifflg = 9;
+    bgImage[0]='\0';
+    fgImage[0]='\0';
+    tcolor=-1;
+    while ((cmd=nxtwrd(cmd)) != NULL) {
+      if      (cmpwrd("black",cmd))  bwin = 0;
+      else if (cmpwrd("white",cmd))  bwin = 1;
+      else if (cmpwrd("png",cmd))  gifflg = 0;
+      else if (cmpwrd("gif",cmd))  gifflg = 1;
+      else if (cmpwrd("jpg",cmd))  gifflg = 3;
+      else if (cmpwrd("jpeg",cmd)) gifflg = 3;
+      else if (cmpwrd("-b",cmd)) {
+	/* get background image filename */
+        if((cmd=nxtwrd(cmd)) != NULL) {
+          if(strlen(cmd) < 256){
+            getwrd(bgImage,cmd, 255);
+            snprintf(pout,255,"Background image file: %s \n", bgImage);
+	    gaprnt(2,pout);
+          }
+        } else {
+          gaprnt(1,"PRINTIM warning: Background image file name not provided\n");
+	  if (cmd == NULL) break;
+	}
+      }
+      else if (cmpwrd("-f",cmd)) {
+	/* get foreground image filename */
+        if((cmd=nxtwrd(cmd)) != NULL) {
+          if(strlen(cmd) < 256){
+            getwrd(fgImage,cmd, 255);
+            snprintf(pout,255,"Foreground image file: %s \n", fgImage);
+	    gaprnt(2,pout);
+          }
+	} else {
+          gaprnt(1,"PRINTIM warning: Foreground image file name not provided\n");
+	  if (cmd == NULL) break;
+	}
+      }
+      else if (cmpwrd("-t",cmd)) {
+	/* set transparent color number */
+        if((cmd=nxtwrd(cmd)) != NULL) {
+	  if(sscanf(cmd, "%i", &tcolor) != 1) {
+	     gaprnt(1,"PRINTIM warning: Invalid transparent color number\n");
+	  } 
+	} else {
+	  gaprnt(1,"PRINTIM warning: Missing transparent color number\n");
+	  if (cmd == NULL) break;
+	}
+      }
+      else if (*cmd=='x') {
+	/* set horizontal image size */
+        if (intprs(cmd+1,&(xin)) == NULL ) {
+          gaprnt (0,"PRINTIM error:  Invalid x option; ignored\n");
+          xin = -999;
+        }
+      }
+      else if (*cmd=='y') {
+	/* set vertical image size */
+        if (intprs(cmd+1,&(yin)) == NULL ) {
+          gaprnt (0,"PRINTIM error: Invalid y option; ignored\n");
+          yin = -999;
+        }
+      } else {
+        gaprnt (0,"PRINTIM error: Invalid option; ignored\n");
+      }
+    }
+    if (gifflg == 9) {
+      len = 0;
+      while (*(cc+len)) len++;
+      len = len-4;
+      if (len>0) {
+	/* png */
+        if (*(cc+len)=='.' && *(cc+len+1)=='p' && *(cc+len+2)=='n' && *(cc+len+3)=='g' ) gifflg = 0;
+        if (*(cc+len)=='.' && *(cc+len+1)=='P' && *(cc+len+2)=='N' && *(cc+len+3)=='G' ) gifflg = 0;
+	/* gif */
+        if (*(cc+len)=='.' && *(cc+len+1)=='g' && *(cc+len+2)=='i' && *(cc+len+3)=='f' ) gifflg = 1;
+        if (*(cc+len)=='.' && *(cc+len+1)=='G' && *(cc+len+2)=='I' && *(cc+len+3)=='F' ) gifflg = 1;
+	/* jpg */
+        if (*(cc+len)=='.' && *(cc+len+1)=='j' && *(cc+len+2)=='p' && *(cc+len+3)=='g' ) gifflg = 3;
+        if (*(cc+len)=='.' && *(cc+len+1)=='J' && *(cc+len+2)=='P' && *(cc+len+3)=='G' ) gifflg = 3;
+      }
+      if (gifflg==9) gifflg = 0; /* png is default format */
+    }
+    rc = gxhpng (cc,xin,yin,bwin,gifflg,bgImage,fgImage,tcolor);
+    if (rc==1) gaprnt (0,"PRINTIM error: open error\n");
+    if (rc==2) gaprnt (0,"PRINTIM error: output error\n");
+    if (rc==3) gaprnt (0,"PRINTIM error: background image open error\n");
+    if (rc==4) gaprnt (0,"PRINTIM error: foreground image open error\n");
+    if (rc==5) gaprnt (0,"PRINTIM error: background image must be .png\n");
+    if (rc==6) gaprnt (0,"PRINTIM error: foreground image must be .png\n");
+    if (rc==7) gaprnt (0,"PRINTIM error: gdImageCreate failed for background image\n");
+    if (rc==8) gaprnt (0,"PRINTIM error: gdImageCreate failed for foreground image\n");
+    if (rc) retcod = 1;
+    else retcod = 0;
+    goto retrn;
+  }
+#else
+  else if (cmpwrd("printim",cmd)) {
+    gaprnt (0,"PRINTIM error: command not supported in this build\n");
+    retcod = 1;
+    goto retrn;
+  }
+#endif
+  else if (cmpwrd("set",cmd)) {
+    retcod = gaset (cmd, com, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("open",cmd)) {
+    if ((cmd=nxtwrd(com)) == NULL) {
+      gaprnt (0,"OPEN error:  missing data description file name\n");
+      retcod = 1;
+      goto retrn;
+    }
+    getwrd (cc,cmd,256);
+    retcod = gaopen (cc, pcm);
+    if (!retcod) mygreta(cc);   /* (for IGES only) keep track of user's opened files */
+
+    goto retrn;
+#if (USENETCDF==1 || USEHDF ==1)
+  } else if (cmpwrd("sdfopen", cmd)) {
+    if ((cmd = nxtwrd(com)) == NULL) {
+      gaprnt(0, "SDFOPEN error:  missing self-describing file pathname\n") ;
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gasdfopen(cmd, pcm) ;
+    if (!retcod) mygreta(cmd);  /* (for IGES only) keep track of user's opened files */
+    goto retrn;
+  }
+  else if (cmpwrd("xdfopen", cmd)) {
+    if ((cmd = nxtwrd(com)) == NULL) {
+        gaprnt(0, "XDFOPEN error:  missing data descriptor file name\n") ;
+        retcod = 1 ;
+        goto retrn ;
+    }
+    retcod = gaxdfopen(cmd, pcm) ;
+    if (!retcod) mygreta(cmd);  /* (for IGES only) keep track of user's opened files */
+    goto retrn ;
+#endif
+  } else if (cmpwrd("d",cmd) || cmpwrd("display",cmd)) {
+    if (pcm->pfid==NULL) {
+      gaprnt (0,"DISPLAY error:  no file open yet\n");
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gadspl (cmd, pcm);
+    gxfrme (9);          /* flush any buffers as needed */
+    goto retrn;
+  }
+  else if (cmpwrd("coll",cmd) || cmpwrd("collect",cmd)) {
+    if (pcm->pfid==NULL) {
+      gaprnt (0,"COLLECT error:  no file open yet\n");
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gacoll(cmd, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("define",cmd)) {
+    if (pcm->pfid==NULL) {
+      gaprnt (0,"DEFINE error:  no file open yet\n");
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gadef (cmd, pcm, 0);
+    goto retrn;
+  }
+  else if (cmpwrd("undefine",cmd)) {
+    if (pcm->pfid==NULL) {
+      gaprnt (0,"DEFINE error: no file open yet\n");
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gaudef (cmd, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("modify",cmd)) {
+    if (pcm->pfid==NULL) {
+      gaprnt (0,"MODIFY error: no file open yet\n");
+      retcod = 1;
+      goto retrn;
+    }
+    retcod = gamodf (cmd, pcm);
+    goto retrn;
+  }
+  else if (cmpwrd("sdfwrite",cmd)) {
+    if (pcm->pdf1==NULL) {
+      gaprnt (0,"SDFWRITE error: no defined variables\n");
+      retcod = 1;
+      goto retrn;
+    } 
+    retcod = ncwrite(cmd, pcm);
+    goto retrn;
+  }
+  else {
+    if (pcm->impcmd) {
+      savpcm = pcm;
+      rslt = gsfile(com,&rc,1);
+      if (rc==0 && rslt!=NULL) gaprnt(2,rslt);
+      if (rslt!=NULL) gree(rslt,"f195");
+      retcod = rc;
+      goto retrn;
+    }
+    gaprnt (0,"Unknown command: ");
+    gaprnt (0,cmd);
+    gaprnt (0,"\n");
+    retcod = 1;
+    goto retrn;
+  }
+
+retrn:
+  if (ccc) {
+    gree(ccc,"f196");
+  }
+  return (retcod);
+}
+
+void mygreta(char *path) {
+/* char mypath[1500],mymsg[1551],date[20]; */
+/*  if (strncmp(path,"http://",7)) { */
+/*   realpath(path,mypath); */
+/*   strcpy(date,"`date +%Y%m%d`"); */
+/*   snprintf(mymsg,1550,"echo %s %s >> $HOME/.mygreta",date,mypath); */
+/*   system(mymsg); */
+/*  } */
+}
+
+/* if flag is 0, clean without resetting user options. 
+   if flag is 1, clean and reset user options except sdfwrite & shapefile parameters
+   if flag is 2, clean and reset only sdfwrite parameters 
+   if flag is 3, clean and reset only shapefile fields
+   if flag is 4, clean and reset only KML and GeoTIFF options
+   The reset/reinit commands calls gacln four times, with flag=1 and flag=2, flag=3, and flag=4.
+
+*/
+
+void gacln (struct gacmn *pcm, gaint flg) {
+struct gaattr *attr,*nextattr;
+gaint i;
+#if USESHP==1
+struct dbfld *fld,*nextfld;
+#endif
+
+  /* The 'basic' clean */
+  pcm->pass = 0;
+  for (i=0; i<10; i++) pcm->gpass[i] = 0;
+  if (!pcm->ylpflg) pcm->yllow = 0.0;
+  pcm->xexflg = 0; 
+  pcm->yexflg = 0;
+  pcm->shdcnt = 0;
+  pcm->cntrcnt = 0;
+  pcm->lastgx = 0;
+  pcm->xdim = -1;
+  pcm->ydim = -1;
+  pcm->xgr2ab = NULL;
+  pcm->ygr2ab = NULL;
+  pcm->xab2gr = NULL;
+  pcm->yab2gr = NULL;
+
+  /* reset sdfwrite parameters */
+  if (flg==2) {
+    pcm->ncwid = -999;
+    pcm->sdfwtype = 1;
+    pcm->sdfwpad = 0;
+    pcm->sdfchunk = 0;
+    pcm->xchunk = 0;
+    pcm->ychunk = 0;
+    pcm->zchunk = 0;
+    pcm->tchunk = 0;
+    pcm->echunk = 0;
+    pcm->sdfzip = 0;
+    pcm->sdfprec = 8;
+    if (pcm->sdfwname) {
+      gree(pcm->sdfwname,"g225");
+      pcm->sdfwname = NULL;
+    }
+    while (pcm->attr != NULL) {
+      attr = pcm->attr;           /* point to first block in chain */
+      if (attr->next == NULL) {
+	pcm->attr = NULL;         /* first block is only block */
+      }
+      else {        /* move start of chain from 1st to 2nd block */
+	nextattr = attr->next;
+	pcm->attr = nextattr;
+      }
+      if (attr->value) gree(attr->value,"g85");  /* release memory from 1st block */
+      gree(attr,"g86");
+    }
+  } 
+
+  /* reset shapefile fields */ 
+  if (flg==3) {
+#if USESHP==1    
+    /* reset shapefile type to line */
+    pcm->shptype=2; 
+    /* release file name */
+    if (pcm->shpfname) {
+      gree (pcm->shpfname,"g89");
+      pcm->shpfname = NULL;
+    }
+    /* release chain of data base fields */
+    while (pcm->dbfld != NULL) {
+      /* point to first block in chain */
+      fld = pcm->dbfld;  
+      if (fld->next == NULL) {
+	/* first block is only block */
+	pcm->dbfld = NULL; 
+      } 
+      else { 
+	/* move start of chain from 1st to 2nd block */
+	nextfld = fld->next;
+	pcm->dbfld = nextfld;
+      }
+      /* release memory from 1st block */
+      if (fld->value != NULL) gree(fld->value,"g87");
+      gree(fld,"g88");
+    }
+#endif
+  }
+
+  /* reset KML and GeoTIFF options */
+  if (flg==4) {
+    pcm->gtifflg=1;               /* reset GeoTIFF output to float */
+    pcm->kmlflg=1;                /* reset KML output to img */
+    if (pcm->kmlname) {           /* release KML file name */
+      gree (pcm->kmlname,"g90");
+      pcm->kmlname = NULL;
+    }
+    if (pcm->tifname) {           /* release TIFF file name */
+      gree (pcm->tifname,"g91");
+      pcm->tifname = NULL;
+    }
+    if (pcm->gtifname) {          /* release GeoTIFF file name */
+      gree (pcm->gtifname,"g92");
+      pcm->gtifname = NULL;
+    }
+  }
+
+  /* reset user options */
+  if (flg==1) {
+    pcm->cstyle = -9;
+    pcm->ccolor = -9;
+    pcm->cthick = 3;
+    pcm->cmark = -9;
+    pcm->cint = 0;
+    pcm->cflag = 0;
+    pcm->ccflg = 0;
+    pcm->cmin = -9.99e33;
+    pcm->cmax = 9.99e33;
+    pcm->blkflg = 0;
+    pcm->aflag = 0;
+    pcm->aflag2 = 0;
+    pcm->axflg = 0;
+    pcm->ayflg = 0;
+    pcm->gridln = -9;
+    pcm->rainmn = pcm->rainmx = 0.0;
+    pcm->grdsflg = 1;
+    pcm->arrflg = 0;
+    pcm->hemflg = -1;
+    pcm->rotate = 0;
+    pcm->xflip = 0;
+    pcm->yflip = 0;
+    if (pcm->xlstr) gree(pcm->xlstr,"f197");
+    if (pcm->ylstr) gree(pcm->ylstr,"f198");
+    if (pcm->clstr) gree(pcm->clstr,"f199");
+    if (pcm->xlabs) gree(pcm->xlabs,"f200");
+    if (pcm->ylabs) gree(pcm->ylabs,"f201");
+    pcm->xlstr = NULL;
+    pcm->ylstr = NULL;
+    pcm->clstr = NULL;
+    pcm->xlabs = NULL;
+    pcm->ylabs = NULL;
+    pcm->xlint = 0.0;
+    pcm->ylint = 0.0;
+    pcm->xlflg = 0;
+    pcm->ylflg = 0;
+    pcm->xlpos = 0.0;
+    pcm->ylpos = 0.0;
+    pcm->ylpflg = 0;
+    pcm->yllow = 0.0;
+    pcm->xlside = 0;
+    pcm->ylside = 0;
+    pcm->tlsupp = 0;
+    pcm->ptflg = 0;
+    pcm->cachesf = 1.0; 
+    pcm->fillpoly = -1;
+    pcm->marktype = 3;
+    pcm->marksize = 0.05;
+  }
+}
+
+/* Handle redraw command */
+
+gaint gardrw (char *cmd, struct gacmn *pcm) {
+struct gbtn btn;
+char oper[12];
+gaint num,state,i,sflg;
+size_t sz;
+
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"REDRAW error: Missing operand\n");
+    return (1);
+  }
+  getwrd (oper,cmd,10);
+  lowcas (oper);
+
+  if (cmpwrd("button",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrbn;
+    if (intprs(cmd,&(num)) == NULL ) goto errrbn;
+    if (num<0 || num>255) goto errrbn;
+    state = -1;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrbn;
+    if (intprs(cmd,&(state)) == NULL ) goto errrbn;
+    btn.bc = pcm->btnbc;
+    btn.fc = pcm->btnfc;
+    btn.oc1 = pcm->btnoc;
+    btn.oc2 = pcm->btnoc2;
+    btn.btc = pcm->btnbtc;
+    btn.ftc = pcm->btnftc;
+    btn.otc1 = pcm->btnotc;
+    btn.otc2 = pcm->btnotc2;
+    btn.thk = pcm->btnthk;
+    btn.state = state;
+
+    sflg = 2;
+    if ((cmd = nxtwrd (cmd)) == NULL) {
+      btn.len = 0;
+      btn.ch = NULL;
+    } else {
+      if (intprs(cmd,&(i)) == NULL ) goto errrbn;
+      if (i) sflg = 3;
+      if ((cmd = nxtwrd (cmd)) == NULL) {
+        btn.len = 0;
+        btn.ch = NULL;
+      } else {
+        btn.len = 0;
+        while (*(cmd+btn.len)) btn.len++;
+	sz = btn.len+1;
+        btn.ch = (char *)galloc(sz,"btn1");
+        *(btn.ch+btn.len) = '\0';
+        if (btn.ch==NULL) {
+          gaprnt(0,"Memory allocation error; DRAW BUTTON cmd\n");
+          return(1);
+        }
+        for (i=0; i<btn.len; i++) *(btn.ch+i) = *(cmd+i);
+      }
+    }
+    gxdpbn(num, &btn, sflg, 0, state);
+  } else {
+    gaprnt (0,"REDRAW error:  Invalid operand\n");
+    return(1);
+  }
+  return (0);
+
+  errrbn:
+  gaprnt (0,"REDRAW error: Syntax is REDRAW BUTTON number state flag text\n");
+  return (1);
+}
+
+
+/* handle draw command */
+
+static gadouble justx[9] = {0.0,0.5,1.0,0.0,0.5,1.0,0.0,0.5,1.0};
+static gadouble justy[9] = {0.0,0.0,0.0,0.5,0.5,0.5,1.0,1.0,1.0};
+
+gaint gadraw (char *cmd, struct gacmn *pcm) {
+struct gbtn btn;
+struct gdmu dmu;
+gadouble *xy, *newxy, llinc;
+gadouble x,y,xlo,xhi,ylo,yhi,cs,swide,shite,ang;
+gaint i,cnt,newcnt,cflg,ipos,len,mk,wx,thk,col,ival;
+char oper[12],chars[250];
+char *c1,*c2,*ccmd;
+size_t sz;
+#if USESHP==1
+SHPHandle shpid=NULL;
+SHPObject *shp=NULL;
+gadouble *pxy,newx,newy,lnfact;
+int shape,begshp,endshp=0,shpcnt,shptype,j,v,begv,endv,p,haveinfo,numparts;
+char shparg[4096];
+#endif
+
+  /* Check initial operands */
+
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"DRAW error: Missing operand\n");
+    return (1);
+  }
+  getwrd (oper,cmd,10);
+  lowcas (oper);
+
+  if (cmpwrd("map",oper)) {
+    if (pcm->dmax[0]>pcm->dmin[0] && pcm->dmax[1]>pcm->dmin[1]) {
+      gamscl(pcm);
+      gawmap(pcm,0);
+    }
+    return (0);
+  }
+  if (cmpwrd("button",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    if (intprs(cmd,&(cnt))   == NULL) goto errbn;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    if (getdbl(cmd,&(btn.x)) == NULL) goto errbn;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    if (getdbl(cmd,&(btn.y)) == NULL) goto errbn;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    if (getdbl(cmd,&(btn.w)) == NULL) goto errbn;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    if (getdbl(cmd,&(btn.h)) == NULL) goto errbn;
+    btn.bc = pcm->btnbc;
+    btn.fc = pcm->btnfc;
+    btn.oc1 = pcm->btnoc;
+    btn.oc2 = pcm->btnoc2;
+    btn.btc = pcm->btnbtc;
+    btn.ftc = pcm->btnftc;
+    btn.otc1 = pcm->btnotc;
+    btn.otc2 = pcm->btnotc2;
+    btn.thk = pcm->btnthk;
+    btn.state = 0;
+
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errbn;
+    btn.len = 0;
+    while (*(cmd+btn.len)) btn.len++;
+    sz = btn.len+1;
+    btn.ch = (char *)galloc(sz,"btn2");
+    *(btn.ch+btn.len) = '\0';
+    if (btn.ch==NULL) {
+      gaprnt(0,"Memory allocation error; DRAW BUTTON cmd\n");
+      return(1);
+    }
+    for (i=0; i<btn.len; i++) *(btn.ch+i) = *(cmd+i);
+    gxdpbn(cnt, &btn, 0, 0, -1);
+    return (0);
+
+    errbn:
+    gaprnt (0,"DRAW error: Syntax is DRAW BUTTON number x y w h ");
+    gaprnt (0,"string\n");
+    return (1);
+  }
+
+  if (cmpwrd("dropmenu",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+    if (intprs(cmd,&(cnt)) == NULL ) goto errpm;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+    if (cmpwrd("cascade", cmd)) {
+      dmu.casc = 1;
+    } else {
+      dmu.casc = 0;
+      if (getdbl(cmd,&(dmu.x)) == NULL ) goto errpm;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+      if (getdbl(cmd,&(dmu.y)) == NULL ) goto errpm;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+      if (getdbl(cmd,&(dmu.w)) == NULL ) goto errpm;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+      if (getdbl(cmd,&(dmu.h)) == NULL ) goto errpm;
+    }
+    dmu.fc = pcm->drvals[0]; dmu.bc = pcm->drvals[1];
+    dmu.oc1 = pcm->drvals[2]; dmu.oc2 = pcm->drvals[3];
+    dmu.tfc = pcm->drvals[4]; dmu.tbc = pcm->drvals[5];
+    dmu.toc1 = pcm->drvals[6]; dmu.toc2 = pcm->drvals[7];
+    dmu.bfc = pcm->drvals[8]; dmu.bbc = pcm->drvals[9];
+    dmu.boc1 = pcm->drvals[10]; dmu.boc2 = pcm->drvals[11];
+    dmu.soc1 = pcm->drvals[12]; dmu.soc2 = pcm->drvals[13];
+    dmu.thk = pcm->drvals[14];
+
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errpm;
+    dmu.len = 0;
+    while (*(cmd+dmu.len)) dmu.len++;
+    sz = dmu.len+1;
+    dmu.ch = (char *)galloc(sz,"dmu1");
+    *(dmu.ch+dmu.len) = '\0';
+    if (dmu.ch==NULL) {
+      gaprnt(0,"Memory allocation error; DRAW DROPMENU cmd\n");
+      return(1);
+    }
+    for (i=0; i<dmu.len; i++) {
+      *(dmu.ch+i) = *(cmd+i);
+      if (*(dmu.ch+i)=='|') *(dmu.ch+i) = '\0';
+    }
+    gxdrmu (cnt,&dmu,0,-1);
+    return (0);
+
+    errpm:
+    gaprnt (0,"DRAW error: Syntax is DRAW DROPMENU number x y w h ");
+    gaprnt (0,"string | string | ...\n");
+    return (1);
+  }
+
+  if (cmpwrd("wxsym",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errwx;
+    if (intprs(cmd,&wx) == NULL ) goto errwx;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errwx;
+    if (getdbl(cmd,&x) == NULL ) goto errwx;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errwx;
+    if (getdbl(cmd,&y) == NULL ) goto errwx;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errwx;
+    if (getdbl(cmd,&cs) == NULL ) goto errwx;
+    thk = 3;
+    col = -1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&col) == NULL ) goto errwx;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&thk) == NULL ) goto errwx;
+      }
+    }
+    if (wx<1 || wx>43) goto errwx;
+    gxwide (thk);
+    gxstyl(1);
+    wxsym (wx,x,y,cs,col,pcm->wxcols);
+    return (0);
+
+    errwx:
+    gaprnt (0,"DRAW error: Syntax is DRAW WXSYM sym x y siz <color <thickness>>");
+    gaprnt (0,"<color <thick> >\n");
+    return (1);
+  }
+  if (cmpwrd("string",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errst;
+    if (getdbl(cmd,&x) == NULL ) goto errst;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errst;
+    if (getdbl(cmd,&y) == NULL ) goto errst;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errst;
+    c1 = cmd;
+    len=0;
+    while (*c1!='\0' && *c1!='\n') {len++; c1++;}
+    gxwide (pcm->strthk);
+    gxcolr (pcm->strcol);
+
+    swide = 0.2;
+    gxchln (cmd,len,pcm->strhsz,&swide);
+    shite = pcm->strvsz;
+
+    ang = pcm->strrot*M_PI/180;
+    x = x - justx[pcm->strjst] * swide * cos(ang);
+    y = y - justx[pcm->strjst] * swide * sin(ang);
+    x = x - justy[pcm->strjst] * shite * cos(ang+1.5708);
+    y = y - justy[pcm->strjst] * shite * sin(ang+1.5708);
+
+    gxchpl (cmd,len,x,y,pcm->strvsz,pcm->strhsz,pcm->strrot);
+    return (0);
+
+    errst:
+    gaprnt (0,"DRAW error: Syntax is DRAW STRING x y string\n");
+    return (1);
+  }
+  if (cmpwrd("rec",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrc;
+    if (getdbl(cmd,&xlo) == NULL ) goto errrc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrc;
+    if (getdbl(cmd,&ylo) == NULL ) goto errrc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrc;
+    if (getdbl(cmd,&xhi) == NULL ) goto errrc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errrc;
+    if (getdbl(cmd,&yhi) == NULL ) goto errrc;
+    if (xlo>=xhi || ylo>=yhi) goto errrc;
+    gxwide (pcm->linthk);
+    gxcolr (pcm->lincol);
+    gxstyl (pcm->linstl);
+    gxplot (xlo,ylo,3);
+    gxplot (xhi,ylo,2);
+    gxplot (xhi,yhi,2);
+    gxplot (xlo,yhi,2);
+    gxplot (xlo,ylo,2);
+    return (0);
+
+    errrc:
+    gaprnt (0,"DRAW error: Syntax is DRAW REC xlo ylo xhi yhi\n");
+    return (1);
+  }
+
+  /* The interface for drawing shapefiles is adapted from a design by Graziano Giuliani */
+  if (cmpwrd("shp",oper)) {
+#if USESHP==1
+    /* Shapefiles require an x/y varying environment, and input is lon/lat pairs.  
+       Interpolation along the sides is done to insure curvature along the map projection. 
+       Conversion from lon/lat to x/y is performed, then the polygon is plotted.  */
+    if (pcm->xdim<0 && pcm->ydim<0) {
+      gaprnt (2,"No scaling environment\n");
+      return (1);
+    }
+    if (pcm->xdim!=0 || pcm->ydim!=1) {
+      gaprnt (0,"DRAW SHP error: Invalid Dimension Environment\n");
+      gaprnt (0,"                X and Y must be varying\n");
+      return (1);
+    }
+
+    /* count the args */
+    i = 0;
+    ccmd = cmd;
+    while ( (ccmd = nxtwrd (ccmd)) != NULL) i++;
+    if (i<1) {
+      gaprnt(0,"DRAW error: Syntax is DRAW SHP filename ... \n"); return (1);
+    }
+    cmd=nxtwrd(cmd);
+
+    /* parse the shapefile name */
+    getwrd(shparg,cmd,4095);
+    begshp = -1;
+
+    /* parse user-specified range of shapes to draw */
+    if (i>1) {
+      cmd=nxtwrd(cmd);
+      if (intprs(cmd,&ival)==NULL) return(1);
+      begshp=ival;
+      if (i>2) {
+	cmd=nxtwrd(cmd);
+	if (intprs(cmd,&ival)==NULL) return(1);
+	endshp=ival;
+      }
+      else endshp = begshp;
+    }
+
+    /* open the shapefile */
+    shpid = gaopshp(shparg);
+    if (shpid==NULL) return(1);
+    SHPGetInfo (shpid, &shpcnt, &shptype, NULL, NULL);
+    if (begshp==-1) {  /* draw all shapes in file */
+      begshp=0; 
+      endshp=shpcnt-1; 
+    } 
+
+    /* Determine increment for interpolation */
+    llinc = hypot(pcm->dmax[0]-pcm->dmin[0], pcm->dmax[1]-pcm->dmin[1]);
+    llinc = llinc/200.0;
+    if (llinc<0.0001) llinc=0.0001;
+
+    /* set the clipping region */
+    gxclip (pcm->xsiz1, pcm->xsiz2, pcm->ysiz1, pcm->ysiz2);
+    /* loop over requested shapes */
+    for (i=begshp; i<=endshp; i++) {
+      if ((shp = SHPReadObject (shpid,i))==NULL) { 
+	gaprnt(0,"SHPReadObject failed\n"); 
+	SHPClose (shpid);
+	return(1); 
+      }
+      /* skip shapes of a certain kind ... */
+      if ((shp->nSHPType==0) ||             /* type is NULL */
+	  (shp->nSHPType!=shptype) ||       /* type is different from file header */
+	  (shp->nParts<0) ||                /* shape has no parts */
+	  (shp->nVertices<=0) ||            /* shape has no vertices */
+	  (shp->dfYMax < pcm->dmin[1]) ||   /* shape is below dim env lat range */
+	  (shp->dfYMin > pcm->dmax[1]) ) {  /* shape is above dim env lat range */
+	SHPDestroyObject (shp); shp=NULL;
+	continue;
+      }
+      /* determine shape type */
+      shape=0;
+      if ((shp->nSHPType==SHPT_POINT) || 
+	  (shp->nSHPType==SHPT_MULTIPOINT) || 
+	  (shp->nSHPType==SHPT_POINTZ) || 
+	  (shp->nSHPType==SHPT_MULTIPOINTZ) || 
+	  (shp->nSHPType==SHPT_POINTM) || 
+	  (shp->nSHPType==SHPT_MULTIPOINTM)) 
+	shape=1;  /* points */
+      if ((shp->nSHPType==SHPT_ARC)  || 
+	  (shp->nSHPType==SHPT_ARCZ) ||
+	  (shp->nSHPType==SHPT_ARCM)) 
+	shape=2;  /* lines */
+      if ((shp->nSHPType==SHPT_POLYGON)  || 
+	  (shp->nSHPType==SHPT_POLYGONZ) ||
+	  (shp->nSHPType==SHPT_POLYGONM)) 
+	shape=3;  /* polygons */
+      
+      if (shape>0) {
+	/* get the number of parts in this shape */
+	haveinfo=1;
+	if (shp->nParts==0) {	/* implies single part with no info */
+	  numparts=1;
+	  haveinfo=0;
+	} 
+	else {
+	  numparts=shp->nParts;
+	}
+	/* loop over all parts  */
+	for (p=0; p<numparts; p++) {
+	  if (haveinfo) {
+	    begv = shp->panPartStart[p];         /* starting vertex for this part */
+	    if (p==shp->nParts-1) 
+	      endv = shp->nVertices-1;           /* final vertex */
+	    else
+	      endv = shp->panPartStart[p+1]-1;   /* vertex preceding start of next part */
+	  } 
+	  else {
+	    begv = 0;
+	    endv = shp->nVertices-1;
+	  }  
+	  cnt = endv - begv + 1;                 /* number of vertices in this part */
+
+
+	  /* ensure shapes will wrap the globe and be drawn within the entire dim env lon range */
+	  lnfact = 0.0;
+	  while (shp->dfXMax+lnfact > pcm->dmin[0]) lnfact -= 360.0;
+	  lnfact += 360.0; 
+	  
+	  while (shp->dfXMin+lnfact < pcm->dmax[0]) { 
+	    if (shp->dfXMax+lnfact < pcm->dmin[0]) {
+	      lnfact += 360.0;
+	      continue;
+	    }
+
+	    /* allocate memory for x/y coordinates */
+	    if ((pxy = (gadouble *)galloc(2*(cnt+1)*sizeof(gadouble),"shpxy"))==NULL) {
+	      gaprnt (0,"DRAW error: Memory allocation failed for shp vertices\n");
+	      SHPDestroyObject (shp); shp=NULL;
+	      SHPClose (shpid);
+	      return (1);
+	    }
+	    
+	    /* copy the lat/lon pairs for this part into the pxy array */
+	    j=0;
+	    for (v=begv; v<=endv; v++) {
+	      *(pxy+j+0) = shp->padfX[v]+lnfact;
+	      *(pxy+j+1) = shp->padfY[v];
+	      j+=2;
+	    }
+	    /* Make sure the polygon is closed. It should be, 
+	       if shapefile conforms to ESRI specs, but just in case ... */
+	    if (shape==3) {
+	      if (*pxy != *(pxy+(cnt-1)*2) || *(pxy+1) != *(pxy+(cnt-1)*2+1)) {
+		*(pxy+cnt*2) = *pxy;
+		*(pxy+cnt*2+1) = *(pxy+1);
+		cnt++;
+	      }
+	    }
+	    /* Draw the shape */	  
+	    if (shape==1) {   
+	      /* shape is a point */
+	      gxcolr (pcm->lincol);
+	      j=0;
+	      for (v=begv; v<=endv; v++) {
+		/* convert lon,lat to x,y */
+		gxconv (*(pxy+j+0),*(pxy+j+1),&newx,&newy,2);
+		gxmark (pcm->marktype,newx,newy,pcm->marksize);
+		j+=2;
+	      }
+	      gree(pxy,"f204a");
+	    }
+	    else {     
+	      /* shape is a line or polygon  */
+	      /* gxmpoly routine converts lon,lat to x,y and interpolates to smaller 
+		 line segments so that shapes drawn on curved projections look right. */
+	      newxy = gxmpoly(pxy,cnt,llinc,&newcnt); 
+	      gree(pxy,"f204a");
+	      if (newxy==NULL) { 
+		gaprnt (0,"DRAW SHP error: Memory allocation in gxmpoly\n");
+		SHPDestroyObject (shp); shp=NULL;
+		SHPClose (shpid);
+		return (1);
+	      }
+	      /* Make sure the new polygon is closed, then draw it */
+	      if (shape==3) {
+		if (*newxy != *(newxy+(newcnt-1)*2) || *(newxy+1) != *(newxy+(newcnt-1)*2+1)) {
+		  *(newxy+newcnt*2) = *newxy;
+		  *(newxy+newcnt*2+1) = *(newxy+1);
+		  newcnt++;
+		}
+		/* fill in the polygon */
+		if (pcm->fillpoly!=-1) {
+		  gxcolr (pcm->fillpoly);
+		  gxfill (newxy,newcnt);
+		}
+	      }
+	      
+	      /* draw the line, or draw border around the polygon */
+	      gxwide (pcm->linthk);            
+	      gxstyl(pcm->linstl); 
+	      gxcolr (pcm->lincol);
+	      gxplot (*(newxy),*(newxy+1),3);
+	      for (j=1; j<newcnt; j++) {
+		gxplot (*(newxy+j*2),*(newxy+j*2+1),2);
+	      }
+	      /* release memory holding the x,y coordinates for this part */
+	      gree(newxy,"f204a");
+	    }
+
+	    lnfact += 360.0;
+	  }
+	}
+      }
+      /* The only type that should get trapped here is a MultiPatch (value 31) */
+      else {
+	snprintf(pout,255,"Warning: shape type %d is not supported \n",shp->nSHPType);
+	gaprnt(2,pout);
+      }
+      
+      /* release memory for this shape */
+      SHPDestroyObject (shp); shp=NULL;
+    }
+    SHPClose (shpid);
+    /* redraw the frame around the plot */
+    gafram(pcm);
+    /* reset the clipping area */
+    gxclip (0.0, pcm->xsiz, 0.0, pcm->ysiz);
+
+    return(0);
+#else
+    gaprnt(0,"This build does not support drawing shapefiles\n");
+    return(1);
+#endif
+  }
+  if (cmpwrd("polyf",oper) || cmpwrd("mappoly",oper)) {
+    i = 0;
+    ccmd = cmd;
+    while ( (ccmd = nxtwrd (ccmd)) != NULL) i++;
+    if (i<6) {
+      gaprnt (0,"DRAW error: Syntax is DRAW POLYF x1 y1 x2 y2 ...\n");
+      return (1);
+    }
+    sz = sizeof(gadouble)*(i+2);
+    xy = (gadouble *)galloc(sz,"xy");
+    if (xy==NULL) {
+      gaprnt (0,"DRAW error: Memory allocation error\n");
+      return (1);
+    }
+    i = 0;
+    while ( (cmd = nxtwrd(cmd)) != NULL) {
+      if (getdbl(cmd,xy+i) == NULL ) {
+        gaprnt (0,"DRAW error: Invalid polyf coordinate\n");
+        gree(xy,"f202");
+        return(1);
+      }
+      i++;
+    }
+    cnt = i/2;
+    if (*xy != *(xy+(cnt-1)*2) || *(xy+1) != *(xy+(cnt-1)*2+1)) {
+      *(xy+cnt*2) = *xy;
+      *(xy+cnt*2+1) = *(xy+1);
+      cnt++;
+    }
+
+    /*  Mappoly requires an x/y varying environment, and assumes
+        input is lon/lat pairs.  Interpolation along the side
+        is done to insure curvature along the map projection, 
+        then conversion from lon/lat to x/y is performed, then
+        the polygon is plotted.  */
+
+    if (cmpwrd("mappoly",oper)) {
+
+      /* Check for x/y varying -- not really required, but 
+         cannot think of any reason to allow for other dimension
+         environments. */
+
+      if (pcm->xdim!=0 && pcm->ydim!=1) {
+        gree(xy,"f203");
+        gaprnt (0,"DRAW MAPPOLY error: Invalid Dimension Environment\n");
+        gaprnt (0,"                    X and Y must be varying\n");
+        return (1);
+      }
+
+      /* Determine increment for interpolation */
+
+      llinc = hypot(pcm->dmax[0]-pcm->dmin[0], pcm->dmax[1]-pcm->dmin[1]);
+      llinc = llinc/200.0;
+      if (llinc<0.0001) llinc=0.0001;
+  
+      /* Do the interpolation and convert to x,y -- 
+         the gxmpoly routine does this and is located in
+         gxwmap */
+
+      newxy = gxmpoly(xy,cnt,llinc,&newcnt); 
+      gree(xy,"f204");
+      if (newxy==NULL) { 
+        gaprnt (0,"DRAW MAPPOLY error: Memory allocation\n");
+        return (1);
+      }
+      xy = newxy;
+      cnt = newcnt;
+      gxcolr (pcm->lincol);
+      /*  draw border to avoid gaps */
+      gxwide (1);
+      gxstyl(1);
+      gxcolr (pcm->lincol);
+      gxplot (*(xy),*(xy+1),3);
+      for (i=1; i<cnt; i++) {
+        gxplot (*(xy+i*2),*(xy+i*2+1),2);
+      }
+    }
+    gxcolr (pcm->lincol);
+    if (pcm->ptflg) gxptrn (pcm->ptopt,pcm->ptden,pcm->ptang);
+    gxfill (xy,cnt);
+    if (pcm->ptflg) gxptrn (1,1,0);
+    gree(xy,"f205");
+    return (0);
+  }
+  if (cmpwrd("recf",oper) || cmpwrd("maskrec",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errfc;
+    if (getdbl(cmd,&xlo) == NULL ) goto errfc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errfc;
+    if (getdbl(cmd,&ylo) == NULL ) goto errfc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errfc;
+    if (getdbl(cmd,&xhi) == NULL ) goto errfc;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errfc;
+    if (getdbl(cmd,&yhi) == NULL ) goto errfc;
+    if (xlo>=xhi || ylo>=yhi) goto errfc;
+    if (cmpwrd("maskrec",oper)) {
+      gxmaskrec (xlo,xhi,ylo,yhi);
+      return(0);
+    }
+    gxcolr (pcm->lincol);
+    if (pcm->ptflg) gxptrn (pcm->ptopt,pcm->ptden,pcm->ptang);
+    gxrecf (xlo,xhi,ylo,yhi);
+    if (pcm->ptflg) gxptrn (1,1,0);
+    return (0);
+
+    errfc:
+    gaprnt (0,"DRAW error: Syntax is DRAW RECF xlo ylo xhi yhi\n");
+    return (1);
+  }
+  if (cmpwrd("line",oper)) {
+    gxwide (pcm->linthk);
+    gxcolr (pcm->lincol);
+    gxstyl (pcm->linstl);
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errln;
+    if (getdbl(cmd,&xlo) == NULL ) goto errln2;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errln;
+    if (getdbl(cmd,&ylo) == NULL ) goto errln2;
+    gxplot (xlo,ylo,3);
+    while ( (cmd = nxtwrd(cmd)) != NULL) {
+      if (getdbl(cmd,&xlo) == NULL ) goto errln2;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto errln3;
+      if (getdbl(cmd,&ylo) == NULL ) goto errln2;
+      gxplot (xlo,ylo,2);
+    }
+    return (0);
+
+    errln:
+    gaprnt (0,"DRAW error: Syntax is DRAW LINE x1 y1 x2 y2\n");
+    return (1);
+    errln2:
+    gaprnt (0,"DRAW error: Invalid LINE coordinate\n");
+    return (1);
+    errln3:
+    gaprnt (0,"DRAW LINE error: Missing Y coordinate\n");
+    return (1);
+  }
+  if (cmpwrd("mark",oper)) {
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errmk;
+    if (intprs(cmd,&mk) == NULL ) goto errmk;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errmk;
+    if (getdbl(cmd,&x) == NULL ) goto errmk;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errmk;
+    if (getdbl(cmd,&y) == NULL ) goto errmk;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto errmk;
+    if (getdbl(cmd,&cs) == NULL ) goto errmk;
+    gxwide (pcm->linthk);
+    gxcolr (pcm->lincol);
+    gxstyl (1);
+    gxmark (mk,x,y,cs);
+    return (0);
+
+    errmk:
+    gaprnt (0,"DRAW error: Syntax is DRAW MARK marktype x y size\n");
+    return (1);
+  }
+  if (cmpwrd("title",oper) || cmpwrd("xlab",oper) ||
+      cmpwrd("ylab",oper)) {
+
+    /* Count number of strings, delete leading blanks, change string
+       delimeter (the backslash) to nulls. */
+
+    if ((cmd=nxtwrd(cmd)) == NULL) {
+      gaprnt (0,"DRAW error: Missing character string \n");
+      return (1);
+    }
+
+    cnt = 1;
+    c1 = cmd;
+    c2 = chars;
+    cflg = 1;
+    while (*c1!='\0' && *c1!='\n') {
+      if (cflg && *c1==' ') c1++;
+      else {
+        *c2 = *c1;
+        cflg = 0;
+        if (*c2=='\\') {
+          *c2 = '\0';
+          cnt++;
+          cflg = 1;
+        }
+        c1++; c2++;
+      }
+    }
+    *c2 = '\0';
+
+    if (cmpwrd("title",oper)) {
+      gxcolr (pcm->anncol);
+      gxwide (pcm->annthk);
+      cs = 0.2;
+      if (cnt==2) cs=0.175;
+      if (cnt==3) cs=0.15;
+      if (cnt>3) cs=0.125;
+      x = pcm->xsiz1 + (pcm->xsiz2-pcm->xsiz1)/2.0;
+      y = pcm->ysiz2 + cs*(gadouble)(cnt-1)*1.7 + cs*0.4 + 0.1;
+      ipos = 0;
+      for (i=0; i<cnt; i++) {
+        swide = 1.0;
+        gxchln (&(chars[ipos]),500,cs,&swide);
+        gxchpl (&(chars[ipos]),500,x-swide*0.5,y,cs*1.2,cs,0.0);
+        y = y - cs*1.7;
+        while (chars[ipos]) ipos++;
+        ipos++;
+      }
+    }
+    else if (cmpwrd("xlab",oper)) {
+      gxcolr (pcm->anncol);
+      gxwide (pcm->annthk);
+      cs = 0.16;
+      if (cnt==2) cs=0.14;
+      if (cnt>2)  cs=0.12;
+      x = pcm->xsiz1 + (pcm->xsiz2-pcm->xsiz1)/2.0;
+      y = pcm->ysiz1 - cs*1.7 - 0.3;
+      ipos = 0;
+      for (i=0; i<cnt; i++) {
+        swide = 1.0;
+        gxchln (&(chars[ipos]),500,cs,&swide);
+        gxchpl (&(chars[ipos]),500,x-swide*0.5,y,cs*1.2,cs,0.0);
+        y = y - cs*1.7;
+        while (chars[ipos]) ipos++;
+        ipos++;
+      }
+    }
+    else if (cmpwrd("ylab",oper)) {
+      gxcolr (pcm->anncol);
+      gxwide (pcm->annthk);
+      cs = 0.16;
+      if (cnt==2) cs=0.14;
+      if (cnt>2)  cs=0.12;
+      y = pcm->ysiz1 + (pcm->ysiz2-pcm->ysiz1)/2.0;
+      x = pcm->xsiz1 - pcm->yllow - cs*1.7*(gadouble)(cnt-1) - cs;
+      ipos = 0;
+      for (i=0; i<cnt; i++) {
+        swide = 1.0;
+        gxchln (&(chars[ipos]),500,cs,&swide);
+        gxchpl (&(chars[ipos]),500,x,y-swide*0.5,cs*1.2,cs,90.0);
+        x = x + cs*1.7;
+        while (chars[ipos]) ipos++;
+        ipos++;
+      }
+    }
+    return (0);
+  }
+  gaprnt (0,"DRAW error:  Invalid operand\n");
+  return (1);
+}
+
+/* handle enable command */
+
+gaint gaenab (char *cmd, struct gacmn *pcm) {
+gaint rc;
+char cc[256], *ch;
+
+  for (rc=0; rc<190; rc++) cc[rc] = *(cmd+rc);
+  cc[40]='\0';
+  lowcas (cc);
+  if ((ch=nxtwrd(cc)) == NULL) {
+    gaprnt (0,"ENABLE error: Missing operand\n");
+    return (1);
+  }
+  if (!cmpwrd("print",ch)) {
+    gaprnt (0,"ENABLE error: Invalid operand \n");
+    return (1);
+  }
+  if ((ch=nxtwrd(ch)) == NULL) {
+    gaprnt (0,"ENABLE error: Missing file name \n");
+    return (1);
+  }
+  cmd = nxtwrd(cmd);
+  cmd = nxtwrd(cmd);
+  getwrd (cc,cmd,256);
+  rc = gxhbgn(cc);
+  return (rc);
+}
+
+/* Execute command on behalf of the scripting language.
+   Return the result in a dynamically allocated buffer */
+
+char *gagsdo (char *cmd, gaint *rc) {
+gaint savflg,tlen,i;
+struct gacmn *pcm;
+char *mbuf, *ch;
+
+   savflg = msgflg;
+   msgflg = 1;          /* Buffer messages */
+   pcm = savpcm;        /* Get common pointer */
+   msgstk = NULL;
+
+   *rc = gacmd(cmd, pcm, 0);
+
+   /* Set up output buffer */
+
+   if (msgstk==NULL) {
+     msgflg = savflg;
+     return(NULL);
+   }
+
+   tlen = 0;
+   msgcurr = msgstk;
+   while (msgcurr) {
+     tlen += msgcurr->len;
+     msgcurr = msgcurr->forw;
+   }
+
+   mbuf = (char *)malloc(tlen+1);
+   if (mbuf==NULL) {
+     printf ("Memory allocation error: Message Return Buffer\n");
+     msgflg = savflg;
+     return (NULL);
+   }
+
+   msgcurr = msgstk;
+   ch = mbuf;
+   while (msgcurr!=NULL) {
+     for (i=0; i<msgcurr->len; i++) {
+       *ch = *(msgcurr->msg+i);
+       ch++;
+     }
+     msgcurr = msgcurr->forw;
+   }
+   msgcurr = msgstk;
+   while (msgcurr!=NULL) {
+     if (msgcurr->msg) free(msgcurr->msg);
+     msgstk = msgcurr->forw;
+     free(msgcurr);
+     msgcurr = msgstk;
+   }
+
+   *(mbuf+tlen) = '\0';
+   msgflg = savflg;
+   return (mbuf);
+}
+
+/* Handle exec command.  Read exec file, then recursively
+   call gacmd.  */
+
+gaint gaexec (char *cmd, struct gacmn *pcm) {
+FILE *efile;
+gaint i,j,n,flag,iarg;
+char ename[50];
+char ccc[500],cout[500];
+char *args[10],*ptr;
+gaint rc, savflg, ret;
+
+  efile = NULL;
+  savflg = msgflg;
+  msgflg = 0;         /* Don't buffer messages */
+
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"EXEC error:  missing file name \n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Get file name and open file.  If we cannot open file, exit */
+
+  getwrd (ename,cmd,49);
+  efile = fopen(ename,"r");
+  if (efile==NULL) {
+    gaprnt (0,"EXEC error:  Can't open file\n");
+    snprintf(pout,255,"  File name is: %s\n",ename);
+    gaprnt (0,pout);
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Locate any arguments, save pointers to them, and terminate them
+     with a null.  We modify the cmd line at this point.  */
+
+  for (i=0;i<10;i++) args[i]=NULL;
+  i = 0;
+  cmd = nxtwrd(cmd);
+  while (cmd != NULL && i<10) {
+    args[i] = cmd;
+    ptr = cmd;
+    if (*ptr == '~') {
+      ptr++;
+      args[i] = ptr;
+      while (*ptr != '~') ptr++;
+      cmd = nxtwrd(ptr);
+      *ptr = '\0';
+    } else {
+      cmd = nxtwrd(cmd);
+      while (*ptr!=' ' && *ptr!='\0' && *ptr!='\n') ptr++;
+      *ptr = '\0';
+    }
+    i++;
+  }
+
+
+  /* Read and execute the commands in the file.  Scan each command for
+     any arg tokens and replace them with the arg strings */
+
+  while ( (fgets(ccc,300,efile))!=NULL) {
+    if (*ccc=='*') continue;
+    /* Remove cr for PC/cygwin version */
+    n=strlen(ccc);
+    if ( n > 1 ) {
+      if ((gaint)ccc[n-2] == 13) ccc[n-2] = ' ';
+    }
+    i = 0; j = 0;
+    while (ccc[i]!='\n') {
+      flag = 1;
+      if (ccc[i] == '&' && ccc[i+1]>='0' && ccc[i+1]<='9') {
+        iarg = (gaint)(ccc[i+1]) - 48;
+        ptr = args[iarg];
+        if (ptr!=NULL) {
+          while (*ptr!='\0') {
+            cout[j] = *ptr;
+            j++; ptr++;
+          }
+          i+=2;
+          flag = 0;
+        }
+      }
+      if (flag) {
+        cout[j] = ccc[i];
+        i++; j++;
+      }
+    }
+    cout[j] = ccc[i];
+    cout[j+1] = '\0';
+    gaprnt (0,cout);
+    rc = gacmd(cout,pcm,1);
+    if (rc) {
+      snprintf(pout,255,"EXEC error:  error in %s.  EXEC stopped.\n",ename);
+      gaprnt (0,pout);
+      ret = rc;
+      goto retrn;
+    }
+  }
+  snprintf(pout,255,"EOF EXECuting %s \n",ename);
+  gaprnt (0,pout);
+  ret = 0;
+
+retrn:
+  if (efile) fclose(efile);
+  msgflg = savflg;
+  return (ret);
+}
+
+/* Handle undefine command */
+
+gaint gaudef (char *cmd, struct gacmn *pcm) {
+struct gafile *pfi;
+struct gadefn *pdf, *opdf;
+char name[20];
+gaint i;
+
+  /* Get the define name */
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"UNDEFINE error:  name is missing \n");
+    return(1);
+  }
+  i=0;
+  while (*cmd!='\0' && *cmd!='\n') {
+    name[i] = *cmd;
+    cmd++; i++;
+    if (i>16) break;
+  }
+  name[i] = '\0';
+
+  pdf = pcm->pdf1;
+  opdf = NULL;
+  while (pdf!=NULL) {
+    if (cmpwrd(name,pdf->abbrv)) break;
+    opdf = pdf;
+    pdf = pdf->pforw;
+  }
+  if (pdf==NULL) {
+    gaprnt (1,"UNDEFINE Warning:  name not found\n");
+    return (0);
+  } else {
+    if (opdf==NULL) pcm->pdf1 = pdf->pforw;
+    else opdf->pforw = pdf->pforw;
+    pfi = pdf->pfi;
+    gree(pfi->rbuf,"f160");
+    gree(pfi->ubuf,"f160a");
+    for (i=0; i<5; i++) {
+      gree(pfi->grvals[i],"f161");
+      gree(pfi->abvals[i],"f162");
+    }
+    gree(pfi,"f163");
+    gree(pdf,"f164");
+    snprintf(pout,255,"%s UNDEFINEd and storage released\n",name);
+    gaprnt (2,pout);
+  }
+  return (0);
+}
+
+/* Query or modify define data value -- modify if flag = 1 */
+
+gaint gaqdef (char *cmd, struct gacmn *pcm, gaint flag) {
+struct gafile *pfi;
+struct gadefn *pdf;
+gadouble grval,*gr;
+gaint i,gri,grj;
+char name[20];
+char *ch;
+char *gru;
+
+  /* Get the defined variable name */
+  if ((cmd=nxtwrd(cmd)) == NULL) goto err;
+  i=0;
+  ch = cmd;
+  while (*ch!='\0' && *ch!='\n') {
+    name[i] = *ch;
+    ch++; i++;
+    if (i>16) break;
+  }
+  name[i] = '\0';
+
+  /* Get i, j, and value */
+  if ((cmd=nxtwrd(cmd)) == NULL) goto err;
+  if (intprs(cmd,&gri)  == NULL) goto err;
+  if ((cmd=nxtwrd(cmd)) == NULL) goto err;
+  if (intprs(cmd,&grj)  == NULL) goto err;
+  if (flag) {
+    if ((cmd=nxtwrd(cmd))  == NULL) goto err;
+    if ((strncmp(cmd,"missing",7)) == 0) flag=2;
+    else if (getdbl(cmd,&grval) == NULL) goto err;
+  }
+
+  /* Locate defined object in link list */
+  pdf = pcm->pdf1;
+  while (pdf!=NULL) {
+    if (cmpwrd(name,pdf->abbrv)) break;
+    pdf = pdf->pforw;
+  }
+  if (pdf==NULL) {
+    gaprnt (1,"Warning:  defined name not found\n");
+    return (0);
+  }
+
+  /* Locate desired value in defined object */
+  pfi = pdf->pfi;
+  gri = gri - (pfi->dimoff[0]+1);
+  grj = grj - (pfi->dimoff[1]+1);
+
+  if (flag) {
+    /* Modify existing data point */
+    if (gri<0 || gri>=pfi->dnum[0] || grj<0 || grj>=pfi->dnum[1]) {
+      gaprnt (0,"SET DEFVAL Error:  Out of Range\n");
+      return (1);
+    }
+    gru = pfi->ubuf;
+    gru = gru + (grj*pfi->dnum[0]+gri);    
+    if (flag==2) {
+      /* set value to be undefined */
+      *gru = 0;
+     }
+    else {
+      /* set new value */
+      gr = pfi->rbuf;
+      gr = gr + (grj*pfi->dnum[0]+gri);
+      *gr = grval;
+      *gru = 1;
+    }
+  } 
+  else {
+    /* Print defined value */
+    if (gri<0 || gri>=pfi->dnum[0] || grj<0 || grj>=pfi->dnum[1]) {
+      gaprnt(2,"DEFVAL is out of range\n");
+    } 
+    else {
+      gr = pfi->rbuf;
+      gr = gr + (grj*pfi->dnum[0]+gri);
+      gru = pfi->ubuf;
+      gru = gru + (grj*pfi->dnum[0]+gri);
+      if (*gru == 1) {
+	snprintf(pout,255,"DEFVAL is %g\n",*gr);
+	gaprnt (2,pout);
+      }
+      else {
+	gaprnt(2,"DEFVAL is missing\n");
+      }
+    }
+  }
+  return(0);
+
+err:
+  if (flag) {
+    gaprnt(0,"SET DEFVAL Error: Syntax is: ");
+    gaprnt(0,"set defval name i j value (value may be \"missing\")\n");
+  } else {
+    gaprnt(0,"QUERY DEFVAL Error: Syntax is: ");
+    gaprnt(0,"query defval name i j\n");
+  }
+  return(1);
+}
+
+/* Modify attributes or contents of a defined grid */
+
+gaint gamodf (char *cmd, struct gacmn *pcm) {
+struct gadefn *pdf;
+struct gafile *pfi;
+struct dt dtim,otim;
+gadouble t1,t2,d1;
+gaint i,flg;
+char name[20];
+
+  /* Get the name of the defined grid (2nd arg) */
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"MODIFY error:  name is missing \n");
+    return (1);
+  }
+
+  i=0;
+  while (*(cmd+i)!=' ' && *(cmd+i)!='\n' && *(cmd+i)!='\0' && i<17) {
+    name[i] = *(cmd+i);
+    i++;
+  }
+  name[i] = '\0';
+
+  /* See if the name is a defined grid */
+  pdf = pcm->pdf1;
+  while (pdf!=NULL && !cmpwrd(name,pdf->abbrv)) pdf = pdf->pforw;
+  if (pdf==NULL) {
+    snprintf(pout,255,"MODIFY Error: Defined grid %s not found\n",name);
+    gaprnt (0,pout);
+    return (1);
+  }
+
+  /* Take action based on 3rd argument */
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"MODIFY error:  Action keyword is missing\n");
+    return (1);
+  }
+  else if (cmpwrd("seasonal",cmd) || cmpwrd("diurnal",cmd)) {
+    pfi = pdf->pfi;
+    if (pfi->dnum[3]==1) {
+      gaprnt(0,"MODIFY Error:  ");
+      gaprnt(0,"Time not varying for this defined variable\n");
+      return(1);
+    }
+
+    /* Convert starting grid time to world time, add appropriate
+       increment, and convert back to grid */
+    t1 = (gadouble)(pfi->dimoff[3]+1);
+    gr2t (pfi->grvals[3], t1, &dtim);
+    otim.yr=0; otim.mo=0; otim.dy=0; otim.hr=0; otim.mn=0;
+    if (cmpwrd("seasonal",cmd)) {
+      otim.yr = 1;
+      flg = 1;
+    } else {
+      otim.dy = 1;
+      flg = 2;
+    }
+    timadd (&dtim, &otim);
+    t2 = t2gr(pfi->abvals[3],&otim);
+
+    /* Check that the final time is integral -- otherwise ... a serious problem */
+    if (t2<0.0) i = (gaint)(t2-0.1);
+    else i = (gaint)(t2+0.1);
+    d1 = (gadouble)i;
+    if (fabs(t2-d1)>0.001 || (flg==1 && (t2-t1>12.5))) { 
+      gaprnt (0,"MODIFY Error:  Invalid time scaling in defined variable\n");
+      return (1);
+    }
+
+    /* Calculate cyclic time in grid units, set up pfi block, return */
+    pfi->cysiz = (gaint)(0.1 + t2 - t1);
+    pfi->climo = flg;
+    gaprnt (0,"Defined variable is now climatological\n");
+    return (0);
+  }
+  else {
+    gaprnt (0,"MODIFY error: Invalid operand\n");
+    gaprnt (0,"  Operand = ");
+    gaprnt (0,cmd);
+    gaprnt (0,"\n");
+    return (1);
+  }
+
+}
+
+
+/* Handle define command */
+
+gaint gadef (char *cmd, struct gacmn *pcm, gaint impf) {
+struct gagrid *pgr,*pgr1;
+struct gastat *pst;
+struct gafile *pfi,*pfiv,*pfic;
+struct gadefn *pdf,*pcurr,*psave;
+struct gadefn **prev;
+struct dt tmin,tmax;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble vmin,vmax,zmin,zmax,emin,emax,*res,*gr;
+gaint itmin,itmax,it,izmin,izmax,iz,iemin,iemax,ie;
+gaint i,rc,gsiz,vdz,vdt,vde;
+size_t sz,siz;
+char *resu,*gru;
+char name[20];
+
+  pdf = NULL;
+  pst = NULL;
+  pgr1 = NULL;
+  pfiv = NULL;
+
+  /* Save user dim limits */
+  zmin = pcm->dmin[2];
+  zmax = pcm->dmax[2];
+  tmin = pcm->tmin;
+  tmax = pcm->tmax;                    
+  emin = pcm->dmin[4];
+  emax = pcm->dmax[4];
+  vdz  = pcm->vdim[2];
+  vdt  = pcm->vdim[3];
+  vde  = pcm->vdim[4];
+
+  /* Get the define name */
+  if (!impf) {
+    if ((cmd=nxtwrd(cmd)) == NULL) {
+      gaprnt (0,"DEFINE error:  name is missing \n");
+      goto retrn;
+    }
+  }
+  garemb (cmd);
+  i=0;
+  while ( (*cmd>='a' && *cmd<='z') || (*cmd>='0' && *cmd<='9' ) ) {
+    name[i] = *cmd;
+    cmd++; i++;
+    if (i>16) break;
+  }
+  name[i] = '\0';
+  if (*cmd!='=') {
+    gaprnt (0,"DEFINE error:  Name too long; missing '='\n");
+    goto retrn;
+  }
+  cmd++;
+  if (*cmd=='\0') {
+    gaprnt (0,"DEFINE error:  expression missing\n");
+    goto retrn;
+  }
+
+  /* We are now pointing to the expression.  We need to set up
+     our looping environment -- we are going to always loop
+     through Z and T and E.                                */
+
+  pfi = pcm->pfid;
+  if (pfi->type==2 || pfi->type==3) {
+    gaprnt (0,"Define error:  Define not yet valid for station data\n");
+    gaprnt (0,"    Default file is a station data file\n");
+    goto retrn;
+  }
+
+  conv = pfi->ab2gr[2];                /* Get Z grid limits */
+  vmin = conv(pfi->abvals[2],zmin);
+  vmax = conv(pfi->abvals[2],zmax);
+  if (dequal(vmin,vmax,1.0e-08)==0) {
+    if (vmin<0.0) izmin = (gaint)(vmin-0.5);
+    else izmin = (gaint)(vmin+0.5);
+    izmax = izmin;
+  } else {
+    izmin = (gaint)(floor(vmin+0.001));
+    izmax = (gaint)(ceil(vmax-0.001));
+  }
+  
+
+  vmin = t2gr(pfi->abvals[3],&tmin);   /* Get T grid limits */
+  vmax = t2gr(pfi->abvals[3],&tmax);
+  if (dequal(vmin,vmax,1.0e-08)==0) {
+    if (vmin<0.0) itmin = (gaint)(vmin-0.5);
+    else itmin = (gaint)(vmin+0.5);
+    itmax = itmin;
+  } else {
+    itmin = (gaint)(floor(vmin+0.001));
+    itmax = (gaint)(ceil(vmax-0.001));
+  }
+
+  conv = pfi->ab2gr[4];                /* Get E grid limits */
+  vmin = conv(pfi->abvals[4],emin);
+  vmax = conv(pfi->abvals[4],emax);
+  if (dequal(vmin,vmax,1.0e-08)==0) {
+    if (vmin<0.0) iemin = (gaint)(vmin-0.5);
+    else iemin = (gaint)(vmin+0.5);
+    iemax = iemin;
+  } else {
+    iemin = (gaint)(floor(vmin+0.001));
+    iemax = (gaint)(ceil(vmax-0.001));
+  }
+ 
+  /* Fix Z and T and E dimensions */
+  pcm->dmax[2] = pcm->dmin[2];
+  pcm->tmax    = pcm->tmin;               
+  pcm->dmax[4] = pcm->dmin[4];               
+  pcm->vdim[2] = 0;
+  pcm->vdim[3] = 0;
+  pcm->vdim[4] = 0;
+
+  /* Get the first grid */
+  pst = getpst(pcm);
+  if (pst==NULL) goto retrn;
+
+  conv = pfi->gr2ab[2];
+  pst->dmin[2] = conv(pfi->grvals[2],(gadouble)izmin);
+  pst->dmax[2] = pst->dmin[2];
+  gr2t (pfi->grvals[3], (gadouble)itmin, &(pst->tmin));
+  pst->tmax = pst->tmin;
+  conv = pfi->gr2ab[4];
+  pst->dmin[4] = conv(pfi->grvals[4],(gadouble)iemin);
+  pst->dmax[4] = pst->dmin[4];
+
+  rc = gaexpr(cmd, pst);
+  if (!rc) rc = gaqsig();
+  if (rc) {
+    gaprnt (0,"DEFINE error:  Invalid expression. \n");
+    goto retrn;
+  }
+  if (pst->type!=1) {
+    gaprnt (0,"DEFINE Error:  Define does not yet support station data\n");
+    gaprnt (0,"    Expression results in station data object\n");
+    goto retrn;
+  }
+
+  /* Based on the grid we just got, we can now figure out the size of
+     the final defined grid and fill in the gafile structure for the
+     defined grid.  Allocate all the necessary stuff and fill it all
+     in.  */
+
+  /* Allocate the pdf and pfi blocks */
+  sz = sizeof(struct gadefn);
+  pdf = (struct gadefn *)galloc(sz,"pdfdef");
+  if (pdf==NULL) {
+    gaprnt (0,"Memory Allocation Error:  DEFINE operation\n");
+    goto retrn;
+  }
+  sz = sizeof(struct gafile);
+  pfiv = (struct gafile *)galloc(sz,"pfiv");
+  if (pfiv==NULL) {
+    gaprnt (0,"Memory Allocation Error:  DEFINE operation\n");
+    goto retrn;
+  }
+  pdf->pfi = pfiv;
+  pfiv->rbuf = NULL;
+  pfiv->sbuf = NULL;
+  pfiv->ubuf = NULL;
+
+  /* Fill in the pfi block */
+  pgr1 = pst->result.pgr;
+  pfiv->type = 4;
+  pfiv->climo = 0;
+  pfiv->calendar = pfi->calendar;
+  pfiv->undef = pgr1->undef;
+  pfiv->dnum[2] = 1 + izmax - izmin;
+  pfiv->dnum[3] = 1 + itmax - itmin;
+  pfiv->dnum[4] = 1 + iemax - iemin;
+  pfiv->gr2ab[2] = pfi->gr2ab[2];
+  pfiv->ab2gr[2] = pfi->ab2gr[2];
+  pfiv->gr2ab[4] = pfi->gr2ab[4];
+  pfiv->ab2gr[4] = pfi->ab2gr[4];
+
+  if ((pfiv->grvals[2] = cpscal (pfi->grvals[2], pfi->linear[2], 0, 2))==NULL) goto etrn;
+  if ((pfiv->abvals[2] = cpscal (pfi->abvals[2], pfi->linear[2], 1, 2))==NULL) goto etrn;
+
+  if ((pfiv->grvals[3] = cpscal (pfi->grvals[3], pfi->linear[3], 0, 3))==NULL) goto etrn;
+  if ((pfiv->abvals[3] = cpscal (pfi->abvals[3], pfi->linear[3], 1, 3))==NULL) goto etrn;
+
+  if ((pfiv->grvals[4] = cpscal (pfi->grvals[4], pfi->linear[4], 0, 4))==NULL) goto etrn;
+  if ((pfiv->abvals[4] = cpscal (pfi->abvals[4], pfi->linear[4], 1, 4))==NULL) goto etrn;
+
+  pfiv->linear[2] = pfi->linear[2];
+  pfiv->linear[3] = pfi->linear[3];
+  pfiv->linear[4] = pfi->linear[4];
+  pfiv->dimoff[2] = izmin-1;
+  pfiv->dimoff[3] = itmin-1;
+  pfiv->dimoff[4] = iemin-1;
+  pfiv->ppflag = 0;
+
+  if (pgr1->idim>-1 && pgr1->jdim>-1) {             /* I and J are varying */
+    pfiv->gr2ab[0] = pgr1->igrab;
+    pfiv->ab2gr[0] = pgr1->iabgr;
+    if ((pfiv->grvals[0] = cpscal (pgr1->ivals,  pgr1->ilinr, 0, pgr1->idim))==NULL) goto etrn;
+    if ((pfiv->abvals[0] = cpscal (pgr1->iavals, pgr1->ilinr, 1, pgr1->idim))==NULL) goto etrn;
+    pfiv->linear[0] = pgr1->ilinr;
+    pfiv->dimoff[0] = pgr1->dimmin[0]-1;
+    pfiv->dnum[0]   = pgr1->isiz;
+
+    pfiv->gr2ab[1] = pgr1->jgrab;
+    pfiv->ab2gr[1] = pgr1->jabgr;
+    if ((pfiv->grvals[1] = cpscal (pgr1->jvals,  pgr1->jlinr, 0, pgr1->jdim))==NULL) goto etrn;
+    if ((pfiv->abvals[1] = cpscal (pgr1->javals, pgr1->jlinr, 1, pgr1->jdim))==NULL) goto etrn;
+    pfiv->linear[1] = pgr1->jlinr;
+    pfiv->dimoff[1] = pgr1->dimmin[1]-1;
+    pfiv->dnum[1]   = pgr1->jsiz;
+  }
+  else if (pgr1->idim > -1 && pgr1->jdim == -1) {   /* I is varying, J is fixed */
+    if (pgr1->idim == 0) {           /* I is X */
+      pfiv->gr2ab[0] = pgr1->igrab;
+      pfiv->ab2gr[0] = pgr1->iabgr;
+      if ((pfiv->grvals[0] = cpscal (pgr1->ivals,  pgr1->ilinr, 0, pgr1->idim))==NULL) goto etrn;
+      if ((pfiv->abvals[0] = cpscal (pgr1->iavals, pgr1->ilinr, 1, pgr1->idim))==NULL) goto etrn;
+      pfiv->linear[0] = pgr1->ilinr;
+      pfiv->dimoff[0] = pgr1->dimmin[0]-1;
+      pfiv->dnum[0]   = pgr1->isiz;
+
+      pfiv->gr2ab[1] = pfi->gr2ab[1];
+      pfiv->ab2gr[1] = pfi->ab2gr[1];
+      if ((pfiv->grvals[1] = cpscal (pfi->grvals[1], pfi->linear[1], 0, 1))==NULL) goto etrn;
+      if ((pfiv->abvals[1] = cpscal (pfi->abvals[1], pfi->linear[1], 1, 1))==NULL) goto etrn;
+      pfiv->linear[1] = pfi->linear[1];
+      pfiv->dimoff[1] = 0;
+      pfiv->dnum[1]   = 1;
+    } 
+    else {                           /* I is Y */
+      pfiv->gr2ab[1] = pgr1->igrab;
+      pfiv->ab2gr[1] = pgr1->iabgr;
+      if ((pfiv->grvals[1] = cpscal (pgr1->ivals,  pgr1->ilinr, 0, pgr1->idim))==NULL) goto etrn;
+      if ((pfiv->abvals[1] = cpscal (pgr1->iavals, pgr1->ilinr, 1, pgr1->idim))==NULL) goto etrn;
+      pfiv->linear[1] = pgr1->ilinr;
+      pfiv->dimoff[1] = pgr1->dimmin[1]-1;
+      pfiv->dnum[1]   = pgr1->isiz;
+
+      pfiv->gr2ab[0] = pfi->gr2ab[0];
+      pfiv->ab2gr[0] = pfi->ab2gr[0];
+      if ((pfiv->grvals[0] = cpscal (pfi->grvals[0], pfi->linear[0], 0, 0))==NULL) goto etrn;
+      if ((pfiv->abvals[0] = cpscal (pfi->abvals[0], pfi->linear[0], 1, 0))==NULL) goto etrn;
+      pfiv->linear[0] = pfi->linear[0];
+      pfiv->dimoff[0] = 0;
+      pfiv->dnum[0]   = 1;
+    }
+  }
+  else {                             /* I and J are fixed */
+    pfiv->gr2ab[0] = pfi->gr2ab[0];
+    pfiv->ab2gr[0] = pfi->ab2gr[0];
+    if ((pfiv->grvals[0] = cpscal (pfi->grvals[0], pfi->linear[0], 0, 0))==NULL) goto etrn;
+    if ((pfiv->abvals[0] = cpscal (pfi->abvals[0], pfi->linear[0], 1, 0))==NULL) goto etrn;
+    pfiv->linear[0] = pfi->linear[0];
+    pfiv->dimoff[0] = 0;
+    pfiv->dnum[0]   = 1;
+    
+    pfiv->gr2ab[1] = pfi->gr2ab[1];
+    pfiv->ab2gr[1] = pfi->ab2gr[1];
+    if ((pfiv->grvals[1] = cpscal (pfi->grvals[1], pfi->linear[1], 0, 1))==NULL) goto etrn;
+    if ((pfiv->abvals[1] = cpscal (pfi->abvals[1], pfi->linear[1], 1, 1))==NULL) goto etrn;
+    pfiv->linear[1] = pfi->linear[1];
+    pfiv->dimoff[1] = 0;
+    pfiv->dnum[1]   = 1;
+  }
+
+  /* If the first grid is all the data we need, then we are pretty much done.  */
+
+  if (izmin==izmax && itmin==itmax && iemin==iemax) {
+    if (pgr1->idim<0) {   /* grid is a single data value */
+      sz = sizeof(gadouble);
+      pfiv->rbuf = (gadouble *)galloc(sz,"pfivrbuf");
+      if (pfiv->rbuf==NULL) {
+        gaprnt (0,"Define Error:  Unable to allocate data memory\n");
+        goto retrn;
+      }
+      sz = sizeof(char);
+      pfiv->ubuf = (char *)galloc(sz,"pfivubuf");
+      if (pfiv->ubuf==NULL) {
+        gaprnt (0,"Define Error:  Unable to allocate undef mask memory\n");
+        goto retrn;
+      }
+      *(pfiv->rbuf) = *(pgr1->grid);
+      *(pfiv->ubuf) = *(pgr1->umask);
+    } else {
+      pfiv->rbuf = pgr1->grid;
+      pfiv->ubuf = pgr1->umask;
+    }
+    pgr1->grid = NULL;
+    pgr1->umask = NULL;  
+    siz = pgr1->isiz;
+    siz = siz * pgr1->jsiz;
+  } 
+  else {
+    /* We need to get multiple grids.  Set this up.  */
+
+    /* Calculate size and then allocate the storage for the defined object */
+    gsiz = pgr1->isiz*pgr1->jsiz;
+    siz = (size_t)gsiz * (size_t)pfiv->dnum[2] * (size_t)pfiv->dnum[3] * (size_t)pfiv->dnum[4];
+    sz = siz * sizeof(gadouble);
+    pfiv->rbuf = (gadouble *)galloc(sz,"defnrbuf");
+    if (pfiv->rbuf==NULL) {
+      gaprnt (0,"Define Error:  Unable to allocate data memory\n");
+      snprintf(pout,255,"  Size of request was %ld grid elements\n",siz);
+      gaprnt (0,pout);
+      goto retrn;
+    }
+    sz = siz * sizeof(char);
+    pfiv->ubuf = (char *)galloc(sz,"defnubuf");
+    if (pfiv->ubuf==NULL) {
+      gaprnt (0,"Define Error:  Unable to allocate memory for undef mask\n");
+      snprintf(pout,255,"  Size of request was %ld grid elements\n",siz);
+      gaprnt (0,pout);
+      goto retrn;
+    }
+
+    /* Now we can loop and get all the data */
+
+    res  = pfiv->rbuf;
+    resu = pfiv->ubuf;
+    for (ie=iemin; ie<=iemax; ie++) {
+      for (it=itmin; it<=itmax; it++) {
+	for (iz=izmin; iz<=izmax; iz++) {
+
+	  /* fix dmin and dmax values for Z, T, E dimensions */
+	  conv = pfi->gr2ab[2];
+	  pst->dmin[2] = conv(pfi->grvals[2],(gadouble)iz);
+	  pst->dmax[2] = pst->dmin[2];
+	  gr2t (pfi->grvals[3], (gadouble)it, &(pst->tmin));
+	  pst->tmax = pst->tmin;
+	  conv = pfi->gr2ab[4];
+	  pst->dmin[4] = conv(pfi->grvals[4],(gadouble)ie);
+	  pst->dmax[4] = pst->dmin[4]; 
+
+	  /* reuse first grid evaluated above */
+	  if (ie==iemin && it==itmin && iz==izmin ) {
+	    gr  = pgr1->grid; 
+	    gru = pgr1->umask;
+	  }
+	  else {
+	    /* evaluate the expression again */
+	    rc = gaexpr(cmd, pst);
+	    if (!rc) rc = gaqsig();
+	    if (rc) {
+	      gaprnt (0,"DEFINE error:  Invalid expression. \n");
+	      goto retrn;
+	    }
+	    pgr = pst->result.pgr;
+	    if (pgr->idim!=pgr1->idim || pgr->jdim!=pgr1->jdim ||
+		gagchk(pgr,pgr1,pgr1->idim) ||
+		gagchk(pgr,pgr1,pgr1->jdim) ) {
+	      gaprnt (0,"Define Error: Internal Logic Check 4\n");
+	      goto retrn;
+	    }
+	    gr  = pgr->grid;
+	    gru = pgr->umask;
+	  }
+
+	  /* copy the grid into defined variable space */
+	  for (i=0; i<gsiz; i++) {
+	    *res  = *gr;
+	    *resu = *gru;
+	    /* make sure defined vars have undef values, use pcm->undef */
+	    if (*gru == 0) *res = pcm->undef; 
+	    res++; resu++; 
+	    gr++;  gru++;
+	  }
+
+	  /* free the result grid  */
+	  if (ie==iemin && it==itmin && iz==izmin ) {
+	    if (pgr1->idim>-1) {
+	      gree(pgr1->grid,"f86a");
+	      gree(pgr1->umask,"f87a");
+	    }
+	    pgr1->grid = NULL;
+	    pgr1->umask = NULL;
+	    pst->result.pgr = NULL;
+	  }
+	  else {
+	    gafree (pst);
+	  }
+	}
+      }
+    }
+  }
+
+  siz = siz * sizeof(gadouble);
+  snprintf(pout,255,"Define memory allocation size = %ld bytes\n",siz);
+  gaprnt (2,pout);
+
+  /* Now we will chain our new object to the chain of define blocks
+     hung off the common area */
+
+  pcurr = pcm->pdf1;
+  prev = &(pcm->pdf1);
+  while (pcurr!=NULL) {
+    if (cmpwrd(name,pcurr->abbrv)) {
+      gaprnt (2,"Name already DEFINEd:  ");
+      gaprnt (2,name);
+      gaprnt (2,".   Will be deleted and replaced.\n");
+      pfic = pcurr->pfi;
+      gree(pfic->rbuf,"f93");
+      gree(pfic->ubuf,"f93a");
+      for (i=0; i<5; i++) {
+	gree(pfic->grvals[i],"f93b");
+	gree(pfic->abvals[i],"f93c");
+      }
+      gree(pfic,"f94");
+      *prev = pcurr->pforw;
+      psave = pcurr;
+      pcurr = pcurr->pforw;
+      gree(psave,"f95");
+      continue;
+    }
+    prev = &(pcurr->pforw);
+    pcurr = pcurr->pforw;
+  }
+
+  *prev = pdf;          /* Chain it up */
+  pdf->pforw = NULL;
+  getwrd(pdf->abbrv,name,19);
+  gree(pgr1,"f96");
+  gree(pst,"f97");
+  /* Restore user dim limits*/
+  pcm->dmax[2] = zmax;
+  pcm->tmax    = tmax;                    
+  pcm->dmax[4] = emax;
+  pcm->vdim[2] = vdz;
+  pcm->vdim[3] = vdt;
+  pcm->vdim[4] = vde;
+  return (0);
+
+etrn:
+  gaprnt(0,"Memory allocation error for Define\n");
+
+retrn:
+  if (pst!=NULL) {
+    gafree(pst);
+    gree(pst,"f98");
+  }
+  if (pgr1!=NULL) {
+    if (pgr1->grid!=NULL && pgr1->idim>-1) gree(pgr1->grid,"f208");
+    gree(pgr1,"f99");
+  }
+  if (pdf!=NULL) gree(pdf,"f209");
+  if (pfiv!=NULL) {
+    if (pfiv->rbuf!=NULL) gree(pfiv->rbuf,"f210a");
+    if (pfiv->ubuf!=NULL) gree(pfiv->ubuf,"f210b");
+    gree(pfiv,"f100");
+  }
+  pcm->tmax = tmax;                    /* Restore user dim limits*/
+  pcm->dmax[2] = zmax;
+  pcm->vdim[2] = vdz;
+  pcm->vdim[3] = vdt;
+  return(1);
+}
+
+/* Handle query command */
+
+char *gxnms[29] = {"Clear","Contour","Shaded","Vector","Grid","Fgrid",
+		   "Line","Scatter","Bar","Stream","Value","Model","Wxsym","Line",
+		   "StnMark","Barb","GrFill","LineFill","","","Fwrite","Findstn","Stat",
+                   "GeoTIFF", "KML", "Shapefile","ImageMap","Shaded2","Shaded2b"};
+/* messages for query gxout */
+static char *gxout0D[3]   = {"Display", "Stat", "Print"};
+static char *gxout1D[5]   = {"0", "Line", "Bar", "Errbar", "Linefill"};
+static char *gxout1Da[3]  = {"0", "Vector", "Barb"};
+static char *gxout2Da[20] = {"0", "Contour", "Shaded","Grid", "4", "5", "Fgrid",
+			     "Fwrite", "8", "9", "Grfill", "Pgrid", "GeoTIFF", "KML",
+			     "ImageMap","Shapefile","16","17","18","19"};
+static char *gxout2Db[10] = {"0", "1", "2", "Grid", "Vector", "Scatter", "6", "7", "Stream", "Barb"};
+static char *gxoutStn[10]  = {"0", "Value", "Barb", "Findstn", "Model", 
+			      "Wxsym", "6", "Stnmark", "Stnwrite", "Shapefile"};
+
+char *dweek[8] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat","???"};
+
+gaint gaqury (char *cmd, char *ccc, struct gacmn *pcm) {
+struct gafile *pfi;
+struct gavar *pvar;
+struct gadefn *pdf;
+struct gaens *ens;
+struct dt dtim;
+struct xinfo xinf;
+struct gdlg dlg; 
+struct gaattr *attr;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble x, y, v, v1, v2, lon, lat, rinfo[10];
+gaint i, j, cnt, fnum, flag, etype, info[10], ival;
+gaint closethisfilelater=0, hdrflg, hdrflgd;
+char *arg, lab[20], lab2[20], *ch, *name, *name2;
+char *varnam;
+short *sptr=NULL;
+long *lptr=NULL;
+gafloat *fptr=NULL;
+gadouble *dptr=NULL,dval;
+size_t sz;
+#if (USENETCDF == 1 || USEHDF == 1)
+struct dt tdef, tdefi;
+char *tfile, *tfile2;
+gaint ncid=0, rc, error, n_atts, n_gatts;
+gaint sdid=0;
+char dimname[256];
+#endif
+#if USEHDF5 == 1
+gaint h5id=-999;
+hid_t fid=0;
+#endif
+#if USESHP==1
+SHPHandle shpid=NULL;
+SHPObject *shp=NULL;
+DBFHandle dbfid=NULL;
+struct dbfld *fld,*fld1;
+char shparg[4096];
+int fcnt,rcnt,shptype,shpcnt;
+gadouble minvals[4], maxvals[4];
+
+#endif
+
+  arg = nxtwrd(cmd);
+  if (arg == NULL) {
+    gaprnt (2,"query or q Options: \n");
+    gaprnt (2,"  q attr     Returns global and variable attributes for an open file\n");
+    gaprnt (2,"  q cache    Returns netcdf4/hdf5 cache size for a particular file \n");
+    gaprnt (2,"  q cachesf  Returns global cache scale factor\n");
+    gaprnt (2,"  q config   Returns GrADS configuration information\n");
+    gaprnt (2,"  q ctlinfo  Returns contents of data descriptor file\n");
+    gaprnt (2,"  q contours Returns colors and levels of line contours\n");
+    gaprnt (2,"  q dbf      Lists contents of a shapefile attribute database\n");
+    gaprnt (2,"  q define   Lists currently defined variables\n");
+    gaprnt (2,"  q defval   Returns value of a defined variable at a point\n");
+    gaprnt (2,"  q dialog   Launches a dialog box\n");
+    gaprnt (2,"  q dims     Returns current dimension environment\n");
+    gaprnt (2,"  q ens      Returns a list of ensemble members\n");
+    gaprnt (2,"  q file     Returns info on a particular file\n");
+    gaprnt (2,"  q files    Lists all open files\n");
+    gaprnt (2,"  q fwrite   Returns status of fwrite output file\n");
+    gaprnt (2,"  q gxinfo   Returns graphics environment info\n");
+    gaprnt (2,"  q gxout    Gives current gxout settings\n");
+    gaprnt (2,"  q pos      Waits for mouse click, returns position and widget info\n");
+    gaprnt (2,"  q sdfwrite Returns status of self-describing fwrite options\n");
+    gaprnt (2,"  q shades   Returns colors and levels of shaded contours\n");
+    gaprnt (2,"  q shp      Lists the contents of a shapefile\n");
+    gaprnt (2,"  q shpopts  Returns settings for drawing and writing shapefiles\n");
+    gaprnt (2,"  q string   Returns width of a string\n");
+    gaprnt (2,"  q time     Returns info about time settings\n");
+    gaprnt (2,"  q undef    Returns output undef value \n");
+    gaprnt (2,"  q xinfo    Returns characteristics of graphics display window\n");
+    gaprnt (2,"  q xy2w     Converst XY screen to world coordinates\n");
+    gaprnt (2,"  q xy2gr    Converts XY screen to grid coordinates\n");
+    gaprnt (2,"  q w2xy     Converts world to XY screen coordinates\n");
+    gaprnt (2,"  q w2gr     Converts world to grid coordinates\n");
+    gaprnt (2,"  q gr2w     Converts grid to world coordinates\n");
+    gaprnt (2,"  q gr2xy    Converts grid to XY screen coordinates\n");
+    gaprnt (2,"  q pp2xy    Converts virtual page XY to real page XY coordinates\n");
+    gaprnt (2,"Details about argument syntax for some of these options are in the \n");
+    gaprnt (2,"online documentation: http://www.iges.org/grads/gadoc/gradcomdquery.html\n");
+  }
+  else if (cmpwrd(arg,"mem")) {
+    glook();
+  }
+  else if (cmpwrd(arg,"undef")) {
+    snprintf(pout,255,"Output undef value is set to %12f\n",pcm->undef);
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"dbuff")) {
+    if (pcm->dbflg) snprintf(pout,255,"double buffering is on\n");
+    else snprintf(pout,255,"double buffering is off\n");
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"calendar")) {
+    if (mfcmn.cal365==-999) snprintf(pout,255,"calendar mode not yet set\n");
+    else if (mfcmn.cal365==1) snprintf(pout,255,"365-day calendar in effect\n");
+    else snprintf(pout,255,"standard calendar in effect\n");
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"cachesf")) {
+    snprintf(pout,255,"Global cache scale factor is %g\n",qcachesf());
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"cache")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      /* no file number given, use the default file */
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      /* get the file number */
+      if (intprs(arg,&fnum) == NULL ) {
+        gaprnt(0,"QUERY CACHE Error: invalid argument \n");
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY CACHE Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    snprintf(pout,255,"File %i cache size in bytes: %ld \n",fnum,pfi->cachesize);
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"dialog")) {
+    if ((arg = nxtwrd (arg)) == NULL) goto errdl;
+    if (getdbl(arg,&(dlg.x)) == NULL ) goto dialog;
+    if ((arg = nxtwrd (arg)) == NULL) goto errdl;
+    if (getdbl(arg,&(dlg.y)) == NULL ) goto errdl;
+    if ((arg = nxtwrd (arg)) == NULL) goto errdl;
+    if (getdbl(arg,&(dlg.w)) == NULL ) goto errdl;
+    if ((arg = nxtwrd (arg)) == NULL) goto errdl;
+    if (getdbl(arg,&(dlg.h)) == NULL ) goto errdl;
+    dlg.pc = pcm->dlgpc;
+    dlg.fc = pcm->dlgfc;
+    dlg.bc = pcm->dlgbc;
+    dlg.oc = pcm->dlgoc;
+    dlg.th = pcm->dlgth;
+    dlg.nu = pcm->dlgnu;
+
+    if ((arg = nxtwrd (arg)) == NULL) goto errdl;
+    dlg.len = 0;
+    while (*(arg+dlg.len)) dlg.len++;
+    sz = dlg.len+1;
+    dlg.ch = (char *)galloc(sz,"dlg1");
+    *(dlg.ch+dlg.len) = '\0';
+    if (dlg.ch==NULL) {
+      gaprnt(0,"Memory allocation error; QUERY DIALOG cmd\n");
+     return(1);
+    }
+    for (i=0; i<dlg.len; i++) *(dlg.ch+i) = *(ccc+(arg-cmd)+i);
+    ch = gxdlg(&dlg);
+    gaprnt (2,ch);
+    gree(ch,"f211");
+    return (0);
+
+    errdl:
+    gaprnt (0,"QUERY error: Syntax is QUERY DIALOG x y w h ");
+    gaprnt (0,"string\n");
+    return (1);
+    
+    dialog:
+    dlg.x = -1;
+    dlg.y = -1;
+    dlg.w = -1;
+    dlg.h = -1;
+    dlg.pc = pcm->dlgpc;
+    dlg.fc = pcm->dlgfc;
+    dlg.bc = pcm->dlgbc;
+    dlg.oc = pcm->dlgoc;
+    dlg.th = pcm->dlgth;
+    dlg.nu = pcm->dlgnu;
+
+    dlg.len = 0;
+    while (*(arg+dlg.len)) dlg.len++;
+    sz = dlg.len+1;
+    dlg.ch = (char *)galloc(sz,"dlg2");
+    *(dlg.ch+dlg.len) = '\0';
+    if (dlg.ch==NULL) {
+      gaprnt(0,"Memory allocation error; QUERY DIALOG cmd\n");
+      return(1);
+    }
+    for (i=0; i<dlg.len; i++) *(dlg.ch+i) = *(ccc+(arg-cmd)+i);
+    ch = gxdlg(&dlg);
+    gaprnt (2,ch);
+    gree(ch,"f212");
+    return (0);
+  }
+  else if (cmpwrd(arg,"ens")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY ENS argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY ENS Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    ens = pfi->ens1;
+    i=0;
+    while (i<pfi->dnum[4]) {
+      gat2ch(&(ens->tinit),4,lab,20);
+      snprintf(pout,255,"Ensemble %d named %s has %d timesteps and begins at %s (t=%d) ",
+	     i+1, ens->name, ens->length, lab, ens->gt );
+      gaprnt(2,pout);
+      if (ens->grbcode[0]>-900) {
+	if (ens->grbcode[1]>-900) 
+	  snprintf(pout,255,"grbcode=%d,%d",ens->grbcode[0],ens->grbcode[1]);
+	else
+	  snprintf(pout,255,"grbcode=%d",ens->grbcode[0]);
+	gaprnt(2,pout);
+      }
+      gaprnt(2,"\n");
+      
+      i++; ens++;
+    }
+  }
+  /* this command is used by the GDS -- formatted specifically */
+  else if (cmpwrd(arg,"ens_name")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY ENS_NAME argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY ENS_NAME Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    ens = pfi->ens1;
+    i=0;
+    gaprnt(2,"ens String grads_name ");
+    while (i<pfi->dnum[4]) {
+      snprintf(pout,255,"%s",ens->name);
+      gaprnt(2,pout);
+      if (i<pfi->dnum[4]-1) gaprnt(2,",");
+      i++; ens++;
+    }
+    gaprnt(2,"\n");
+  }
+  /* this command is used by the GDS -- formatted specifically */
+  else if (cmpwrd(arg,"ens_length")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY ENS_LENGTH argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY ENS_LENGTH Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    ens = pfi->ens1;
+    i=0;
+    gaprnt(2,"ens String grads_length ");
+    while (i<pfi->dnum[4]) {
+      snprintf(pout,255,"%d",ens->length);
+      gaprnt(2,pout);
+      if (i<pfi->dnum[4]-1) gaprnt(2,",");
+      i++; ens++;
+    }
+    gaprnt(2,"\n");
+  }
+  /* this command is used by the GDS -- formatted specifically */
+  else if (cmpwrd(arg,"ens_tinit")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY ENS_TINIT argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY ENS_TINIT Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    ens = pfi->ens1;
+    i=0;
+    gaprnt(2,"ens String grads_tinit ");
+    while (i<pfi->dnum[4]) {
+      snprintf(pout,255,"%d",ens->gt);
+      gaprnt(2,pout);
+      if (i<pfi->dnum[4]-1) gaprnt(2,",");
+      i++; ens++;
+    }
+    gaprnt(2,"\n");
+  }
+  else if (cmpwrd(arg,"vars")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY VARS argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY VARS Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    pvar = pfi->pvar1;
+    j = 0;
+    while (j<pfi->vnum) {
+      printf("%s\n",pvar->abbrv);
+      printf(" description: %s\n",pvar->varnm);
+      printf(" levels: %d ",pvar->levels); printf("\n");
+      printf(" units: "); for (i=0;i<16;i++) printf("%-4g ",pvar->units[i]); printf("\n");
+      printf(" vecpair=%d \n", pvar->vecpair);
+      printf(" isu=%d \n", pvar->isu);
+      printf(" offset=%d \n",pvar->offset);
+      printf(" recoff=%d \n",pvar->recoff);
+      printf(" dfrm=%d \n",pvar->dfrm);
+      printf(" var_t=%d \n",pvar->var_t);
+      if (pfi->ncflg) {
+	printf(" %d dimids: ",pvar->nvardims);
+        for (i=0;i<pvar->nvardims;i++) printf("%-4d ",pvar->vardimids[i]); printf("\n");
+	if (pfi->ncflg==1) printf(" ncvid=%d \n",pvar->ncvid);
+	if (pfi->ncflg==2) printf(" sdvid=%d \n",pvar->sdvid);
+	if (pfi->ncflg==3) printf(" h5vid=%d \n",pvar->h5vid);
+	printf(" scale=%f \n",pvar->scale);
+	printf(" add=%f \n",pvar->add);
+      }
+      printf("\n");
+      pvar++; j++;
+    }	
+  }
+  else if (cmpwrd(arg,"shpopts"))  {
+#if USESHP==1
+    snprintf(pout,255,"Settings for drawing shapefiles:\n polygon fill color: %i \n",pcm->fillpoly);
+    gaprnt (2,pout);
+    snprintf(pout,255," mark type: %i \n",pcm->marktype);
+    gaprnt (2,pout);
+    snprintf(pout,255," mark size: %g \n",pcm->marksize);
+    gaprnt (2,pout);
+    snprintf(pout,255,"Settings for writing shapefiles:\n");
+    gaprnt (2,pout);
+    if (pcm->shpfname)
+      snprintf(pout,255," output filename root: %s\n",pcm->shpfname);
+    else 
+      snprintf(pout,255," output filename root: grads\n");
+    gaprnt (2,pout);
+    if (pcm->shptype==1) gaprnt(2," output type: point\n");
+    if (pcm->shptype==2) gaprnt(2," output type: line\n");
+    snprintf(pout,255," format string: \%%%d.%df\n",pcm->dblen,pcm->dbprec);
+    gaprnt(2,pout);
+    /* print the user-provided fields that are linked off of gacmn  */
+    if (pcm->dbfld) { 
+      gaprnt(2," attributes:\n");
+      fld = pcm->dbfld;  
+      while (fld) {
+	snprintf(pout,255,"  %s: ",fld->name);
+	gaprnt(2,pout);
+	if (fld->type == FTInteger) {
+	  intprs(fld->value,&ival);
+	  snprintf(pout,255,"%d \n",ival); 
+	} 
+	else if (fld->type == FTDouble) {
+	  getdbl(fld->value,&dval);
+          snprintf(lab,20,"\%%-%d.%df\n",pcm->dblen,pcm->dbprec);
+	  snprintf(pout,255,lab,dval); 
+	} 
+	else {
+	  snprintf(pout,255,"%s\n",(char*)fld->value); 
+	}
+	gaprnt(2,pout);
+	fld = fld->next;
+      } 
+    }
+#else
+  gaprnt(0,"This build does not support shapefiles\n");
+#endif
+  }
+  else if (cmpwrd(arg,"shp"))  {
+#if USESHP==1
+    if ((arg = nxtwrd (arg)) == NULL) {
+      gaprnt(0,"Query Error: Missing shapefile name \n");
+    } 
+    else {
+      getwrd(shparg,ccc+(arg-cmd),4095);      /* use mixed-case version */
+      shpid = gaopshp(shparg);
+      if (shpid) {
+	SHPGetInfo (shpid, &shpcnt, &shptype, minvals, maxvals);
+	snprintf(pout,255,"Shapefile Type=%s #Shapes=%d XBounds=%g:%g YBounds=%g:%g\n", 
+		SHPTypeName(shptype),shpcnt,minvals[0],maxvals[0],minvals[1],maxvals[1]);
+	gaprnt(2,pout);
+	for (i=0; i<shpcnt; i++) {
+	  shp = NULL;
+	  if ((shp = SHPReadObject (shpid,i))!=NULL) { 
+	    snprintf(pout,255,"%d:  %s  parts=%d  vertices=%d  ",
+		    shp->nShapeId,SHPTypeName(shp->nSHPType),shp->nParts,shp->nVertices);
+	    gaprnt(2,pout);
+	    snprintf(pout,255,"XBounds=%g:%g  ",shp->dfXMin,shp->dfXMax); gaprnt(2,pout);
+	    snprintf(pout,255,"YBounds=%g:%g  ",shp->dfYMin,shp->dfYMax); gaprnt(2,pout);
+	    snprintf(pout,255,"ZBounds=%g:%g  ",shp->dfZMin,shp->dfZMax); gaprnt(2,pout);
+	    snprintf(pout,255,"MBounds=%g:%g \n",shp->dfMMin,shp->dfMMax); gaprnt(2,pout);
+	    SHPDestroyObject (shp);
+	  }
+	}
+	SHPClose(shpid);
+      }
+    }
+#else
+  gaprnt(0,"This build does not support querying shapefiles\n");
+#endif
+  }
+  else if (cmpwrd(arg,"dbf")) {
+#if USESHP==1
+    if ((arg = nxtwrd (arg)) == NULL) {
+      gaprnt(0,"Query Error: Missing shapefile name \n");
+    } 
+    else {
+      getwrd(shparg,ccc+(arg-cmd),4095);   /* use mixed-case version */
+      dbfid = gaopdbf(shparg);
+      if (dbfid) {
+	fcnt = DBFGetFieldCount (dbfid);
+	rcnt = DBFGetRecordCount (dbfid);
+	snprintf(pout,255,"RECORD#,");
+	gaprnt(2,pout);
+	fld = NULL;
+	if ((fld = (struct dbfld *)galloc(fcnt*sizeof(struct dbfld),"dbfld"))==NULL) {
+	  gaprnt(0,"failed to allocate memory for dbf fields \n");
+	}
+	else {
+	  fld1 = fld; 
+	  i=0;
+	  /* print out the attribute names */
+	  while (i<fcnt) {
+	    fld->type = DBFGetFieldInfo (dbfid, i, fld->name, &fld->len, &fld->prec);
+	    snprintf(pout,255,"%s",fld->name);
+	    gaprnt(2,pout);
+	    if (i<fcnt-1) gaprnt(2,",");
+	    i++; fld++;
+	  }
+	  gaprnt(2,"\n");
+	  gree(fld1,"aa1");
+	  /* print out the attribute values for each record */
+	  for (i=0; i<rcnt; i++) {
+	    snprintf(pout,255,"%d,",i);
+	    gaprnt(2,pout);
+	    for (j=0; j<fcnt; j++) {
+	      if (DBFIsAttributeNULL(dbfid,i,j)) {
+		gaprnt(2,"(NULL)");
+	      }
+	      else {
+		snprintf(pout,255,"%s",DBFReadStringAttribute(dbfid,i,j));
+		gaprnt(2,pout);
+	      }
+	      if (j<fcnt-1) gaprnt(2,",");
+	    }
+	    gaprnt(2,"\n");
+	  }
+	}
+	DBFClose(dbfid);
+      }
+    }
+#else
+  gaprnt(0,"This build does not support querying shapefiles\n");
+#endif
+  }
+  else if (cmpwrd(arg,"string")) {
+    if ((arg = nxtwrd (arg)) == NULL) {
+      gaprnt(0,"Query String Error: Missing String\n");
+    } else {
+      i = 0;
+      while (*(arg+i)!='\0' && *(arg+i)!='\n') i++;
+      v = 0.2;
+      gxchln (ccc+(arg-cmd),i,pcm->strhsz,&v);
+      snprintf(pout,255,"String Width = %g\n",v);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd(arg,"fwrite")) {
+    if (pcm->ffile) gaprnt(2,"FWrite file is open\n");
+    else gaprnt(2,"FWrite file is closed\n");
+    if (pcm->fwname) {
+      gaprnt (2,"FWrite file name is: ");
+      gaprnt (2,pcm->fwname);
+      gaprnt (2,"\n");
+    } else gaprnt (2,"FWrite file name is: grads.fwrite\n");
+    if (pcm->fwenflg==0) {
+      gaprnt (2,"FWrite byte order is little_endian ");
+    } else {
+      gaprnt (2,"FWrite byte order is big_endian ");
+    }
+    if (BYTEORDER==0) {
+      gaprnt (2,"; machine byte order is little_endian\n");
+    } else {
+      gaprnt (2,"; machine byte order is big_endian\n");
+    }
+    snprintf(pout,255,"Fwrite output undef value is set to %12f\n",pcm->undef);
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd(arg,"sdfwrite")) {
+    if (pcm->sdfwname) {
+      gaprnt (2,"SDFwrite file name is: ");
+      gaprnt (2,pcm->sdfwname);
+      gaprnt (2,"\n");
+    } else gaprnt (2,"SDFwrite file name is: grads.sdfwrite.nc\n");
+    gaprnt(2,"SDFwrite format is ");
+    if (pcm->sdfzip==1) gaprnt (2,"compressed ");
+    if (pcm->sdfwtype==1) gaprnt (2,"NetCDF ");
+    else if (pcm->sdfwtype==2) gaprnt (2,"NetCDF-4 ");
+    if (pcm->sdfprec==8) gaprnt (2,"double precision ");
+    else if (pcm->sdfprec==4) gaprnt (2,"floating point precision ");
+    gaprnt(2,"\n");
+    if (pcm->sdfchunk || pcm->sdfzip) {
+      gaprnt(2,"SDFWrite output chunk dimensions: ");
+      if (pcm->xchunk) snprintf(pout,255,"%d ",pcm->xchunk);
+      else snprintf(pout,255,"Xsize ");
+      gaprnt(2,pout);
+      if (pcm->ychunk) snprintf(pout,255,"%d ",pcm->ychunk);
+      else snprintf(pout,255,"Ysize ");
+      gaprnt(2,pout);
+      snprintf(pout,255,"%d ",pcm->zchunk ? pcm->zchunk : 1 );
+      gaprnt(2,pout);
+      snprintf(pout,255,"%d ",pcm->tchunk ? pcm->echunk : 1 );
+      gaprnt(2,pout);
+      snprintf(pout,255,"%d\n",pcm->echunk ? pcm->echunk : 1 );
+      gaprnt(2,pout);
+    }
+    snprintf(pout,255,"SDFwrite output undef value is set to %12f\n",pcm->undef);
+    gaprnt(2,pout);
+    if (pcm->sdfwpad==0) {
+      gaprnt (2,"SDFwrite file will have same number of dimensions as defined variable\n");
+    }
+    if (pcm->sdfwpad==1) {
+      gaprnt (2,"SDFwrite file will have at least 4 dimensions\n");
+    }
+    if (pcm->sdfwpad==2) {
+      gaprnt (2,"SDFwrite file will have 5 dimensions\n");
+    }
+    if (pcm->attr) {
+      attr=pcm->attr;
+      gaprnt (2,"SDFwrite attribute metadata:\n");
+      while (attr) {
+	/* print strings */
+	if (attr->nctype <= 2) {
+	  snprintf(pout,255,"  %s %s %s %s\n",
+		  attr->varname,attr->type,attr->name,(char*)attr->value);
+	    gaprnt(2,pout);
+	} 
+	else {
+	  snprintf(pout,255,"  %s %s %s ",attr->varname,attr->type,attr->name);
+	  gaprnt(2,pout);
+	  if      (attr->nctype == 3) sptr = (short*)attr->value;
+	  else if (attr->nctype == 4) lptr = (long*)attr->value;
+	  else if (attr->nctype == 5) fptr = (gafloat*)attr->value;
+	  else if (attr->nctype == 6) dptr = (gadouble*)attr->value;
+	  for (i=0; i<attr->len; i++) {
+	    /* print numbers */
+	    if (attr->nctype == 3) {
+	      snprintf(pout,255,"%i",(gaint)*(sptr));
+	      gaprnt(2,pout);
+	      sptr++;
+	    } else if (attr->nctype == 4) {
+	      snprintf(pout,255,"%li",*(lptr));
+	      gaprnt(2,pout);
+	      lptr++;
+	    } else if (attr->nctype == 5) {
+	      snprintf(pout,255,"%f",*(fptr));
+	      gaprnt(2,pout);
+	      fptr++;
+	    } else { 
+	      snprintf(pout,255,"%g",*(dptr));
+	      gaprnt(2,pout);
+	      dptr++;
+	    }
+	    if (i != attr->len-1) {
+	      snprintf(pout,255,",");
+	      gaprnt(2,pout);
+	    }
+	  }
+	  snprintf(pout,255,"\n");
+	  gaprnt(2,pout);
+	}
+	attr=attr->next;
+      }
+    }
+  }
+
+  /* Configuration options */
+  else if (cmpwrd(arg,"config")) {
+      gacfg(2);
+  }
+
+  else if (cmpwrd(arg,"dims")||cmpwrd(arg,"dim")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No files open\n");
+      return (1);
+    }
+    pfi = pcm->pfid;
+    snprintf(pout,255,"Default file number is: %i \n",pcm->dfnum);
+    gaprnt (2,pout);
+    /* Longitude */
+    if (pfi->type==2) {
+      v1 = pcm->dmin[0];
+      v2 = pcm->dmax[0];
+    } else {
+      conv = pfi->ab2gr[0];
+      v1 = conv(pfi->abvals[0],pcm->dmin[0]);
+      v2 = conv(pfi->abvals[0],pcm->dmax[0]);
+    }
+    if (pcm->dmin[0]==pcm->dmax[0]) {
+      snprintf(pout,255,"X is fixed     Lon = %g  X = %g\n",pcm->dmin[0],v1);
+    } else {
+      snprintf(pout,255,"X is varying   Lon = %g to %g   X = %g to %g\n",
+           pcm->dmin[0],pcm->dmax[0],v1,v2);
+    }
+    gaprnt (2,pout);
+    /* Latitude  */
+    if (pfi->type==2) {
+      v1 = pcm->dmin[1];
+      v2 = pcm->dmax[1];
+    } else {
+      conv = pfi->ab2gr[1];
+      v1 = conv(pfi->abvals[1],pcm->dmin[1]);
+      v2 = conv(pfi->abvals[1],pcm->dmax[1]);
+    }
+    if (pcm->dmin[1]==pcm->dmax[1]) {
+      snprintf(pout,255,"Y is fixed     Lat = %g  Y = %g\n",pcm->dmin[1],v1);
+    } else {
+      snprintf(pout,255,"Y is varying   Lat = %g to %g   Y = %g to %g\n",
+           pcm->dmin[1],pcm->dmax[1],v1,v2);
+    }
+    gaprnt (2,pout);
+    /* Level */
+    if (pfi->type==2) {
+      v1 = pcm->dmin[2];
+      v2 = pcm->dmax[2];
+    } else {
+      conv = pfi->ab2gr[2];
+      v1 = conv(pfi->abvals[2],pcm->dmin[2]);
+      v2 = conv(pfi->abvals[2],pcm->dmax[2]);
+    }
+    if (pcm->dmin[2]==pcm->dmax[2]) {
+      snprintf(pout,255,"Z is fixed     Lev = %g  Z = %g\n",pcm->dmin[2],v1);
+    } else {
+      snprintf(pout,255,"Z is varying   Lev = %g to %g   Z = %g to %g\n",
+           pcm->dmin[2],pcm->dmax[2],v1,v2);
+    }
+    gaprnt (2,pout);
+    /* Time */
+    v1 = t2gr(pfi->abvals[3],&(pcm->tmin));
+    v2 = t2gr(pfi->abvals[3],&(pcm->tmax));
+    if (pcm->tmin.mn==0) gat2ch(&(pcm->tmin),4,lab,20);
+    else gat2ch (&(pcm->tmin),5,lab,20);
+    if (pcm->tmax.mn==0) gat2ch(&(pcm->tmax),4,lab2,20);
+    else gat2ch (&(pcm->tmax),5,lab2,20);
+    if (v1==v2) {
+      snprintf(pout,255,"T is fixed     Time = %s  T = %g\n",lab,v1);
+    } else {
+      snprintf(pout,255,"T is varying   Time = %s to %s  T = %g to %g\n",
+                  lab,lab2,v1,v2);
+    }
+    gaprnt (2,pout);
+    /* Ensemble */
+    v1=pcm->dmin[4];
+    v2=pcm->dmax[4];
+    if (v1==v2) {
+      name = e2ens(pfi,v1);
+      snprintf(pout,255,"E is fixed     Ens = %s  E = %g\n",name,v1);
+    } else {
+      name = e2ens(pfi,v1);
+      name2 = e2ens(pfi,v2);
+      snprintf(pout,255,"E is varying   Ens = %s to %s  E = %g to %g\n",name,name2,v1,v2);
+    }
+    gaprnt (2,pout);
+  }
+
+  else if (cmpwrd(arg,"w2xy") || cmpwrd(arg,"w2gr")) {
+    if (pcm->xdim<0 || pcm->ydim<0) {
+      gaprnt (2,"No scaling environment\n");
+      return (0);
+    }
+    flag = 0;
+    if (cmpwrd(arg,"w2gr")) flag = 1;
+    if ((arg = nxtwrd (arg)) == NULL) goto errw;
+    if (pcm->xdim == 3) {
+      if (adtprs(arg,&(pcm->tmin),&dtim) == NULL) goto errw;
+      lon = t2gr(pcm->xgrval,&dtim);
+    } else {
+      if (getdbl(arg,&lon) == NULL ) goto errw;
+    }
+    if ((arg = nxtwrd (arg)) == NULL) goto errw;
+    if (pcm->ydim == 3) {
+      if (adtprs(arg,&(pcm->tmin),&dtim) == NULL) goto errw;
+      lat = t2gr(pcm->ygrval,&dtim);
+    } else {
+      if (getdbl(arg,&lat) == NULL ) goto errw;
+    }
+    if (flag) {
+      conv = pcm->xab2gr;
+      x = lon;
+      if (conv && pcm->xdim!=3) x = conv(pcm->xabval, lon);
+      conv = pcm->yab2gr;
+      y = lat;
+      if (conv && pcm->ydim!=3) y = conv(pcm->yabval, lat);
+      snprintf(pout,255,"%s = %g  %s = %g\n", ccdims[pcm->xdim], x, ccdims[pcm->ydim], y);
+      gaprnt(2,pout);
+    } else {
+      gxconv (lon,lat,&x,&y,2);
+      snprintf(pout,255,"X = %g  Y = %g\n",x,y);
+      gaprnt(2,pout);
+    }
+    return (0);
+    errw:
+    if (flag) snprintf(pout,255,"Query Error: Syntax is QUERY W2GR %s %s\n",
+             cdims[pcm->xdim+1],cdims[pcm->ydim+1]);
+    else snprintf(pout,255,"Query Error: Syntax is QUERY W2XY %s %s\n",
+             cdims[pcm->xdim+1],cdims[pcm->ydim+1]);
+    gaprnt (0,pout);
+    return (1);
+  }
+
+  else if (cmpwrd(arg,"gr2w") || cmpwrd(arg,"gr2xy")) {
+    if (pcm->xdim<0 || pcm->ydim<0) {
+      gaprnt (2,"No scaling environment\n");
+      return (0);
+    }
+    flag = 0;
+    if (cmpwrd(arg,"gr2w")) flag = 1;
+    if ((arg = nxtwrd (arg)) == NULL) goto errgr;
+    if (getdbl(arg,&x) == NULL ) goto errgr;
+    if ((arg = nxtwrd (arg)) == NULL) goto errgr;
+    if (getdbl(arg,&y) == NULL ) goto errgr;
+    conv = pcm->xgr2ab;
+    lon = x;
+    if (conv && pcm->xdim!=3) lon = conv(pcm->xgrval, x);
+    conv = pcm->ygr2ab;
+    lat = y;
+    if (conv && pcm->ydim!=3) lat = conv(pcm->ygrval, y);
+    if (flag) {
+      if (pcm->xdim==3) {
+        gr2t (pcm->xgrval, lon, &dtim);
+        gat2ch (&dtim, 5, lab, 20);
+        snprintf(pout,255,"%s = %s  %s = %g\n",cdims[pcm->xdim+1],lab,
+                    cdims[pcm->ydim+1],lat);
+        gaprnt(2,pout);
+      } else if (pcm->ydim==3) {
+        gr2t (pcm->ygrval, lat, &dtim);
+        gat2ch (&dtim, 5, lab, 20);
+        snprintf(pout,255,"%s = %g  %s = %s\n",cdims[pcm->xdim+1],lon,
+                    cdims[pcm->ydim+1],lab);
+        gaprnt(2,pout);
+      } else {
+        snprintf(pout,255,"%s = %g  %s = %g\n",cdims[pcm->xdim+1],lon,
+                    cdims[pcm->ydim+1],lat);
+        gaprnt(2,pout);
+      }
+    } else {
+      gxconv (lon,lat,&x,&y,2);
+      snprintf(pout,255,"X = %g  Y = %g\n",x,y);
+      gaprnt(2,pout);
+    }
+    return (0);
+    errgr:
+    if (flag) snprintf(pout,255,"Query Error: Syntax is QUERY GR2W %s %s\n",
+             ccdims[pcm->xdim],ccdims[pcm->ydim]);
+    else snprintf(pout,255,"Query Error: Syntax is QUERY GR2XY %s %s\n",
+             ccdims[pcm->xdim],ccdims[pcm->ydim]);
+    gaprnt (0,pout);
+    return (1);
+  }
+
+  else if (cmpwrd(arg,"pp2xy")) {
+    if ((arg = nxtwrd (arg)) == NULL) goto errpp;
+    if (getdbl(arg,&x) == NULL ) goto errpp;
+    if ((arg = nxtwrd (arg)) == NULL) goto errpp;
+    if (getdbl(arg,&y) == NULL ) goto errpp;
+    gxppvp (x, y, &x, &y);
+    snprintf(pout,255,"X = %g  Y = %g\n",x,y);
+    gaprnt(2,pout);
+    return (0);
+    errpp:
+    gaprnt (0,"Query Error: Syntax is QUERY PP2XY ppx ppy\n");
+    return (1);
+  }
+
+  else if (cmpwrd(arg,"xy2w") || cmpwrd(arg,"xy2gr")) {
+    flag = 0;
+    if (cmpwrd(arg,"xy2gr")) flag = 1;
+    if ((arg = nxtwrd (arg)) == NULL) goto errxy;
+    if (getdbl(arg,&x) == NULL ) goto errxy;
+    if ((arg = nxtwrd (arg)) == NULL) goto errxy;
+    if (getdbl(arg,&y) == NULL ) goto errxy;
+    if (pcm->xdim<0 || pcm->ydim<0) {
+      gaprnt (2,"No scaling environment\n");
+    } else {
+      gxxy2w (x,y,&lon,&lat);
+      if (flag) {
+        conv = pcm->xab2gr;
+        x = lon;
+        if (lon>-999.0) {
+          if (conv && pcm->xdim!=3) x = conv(pcm->xabval, lon);
+        }
+        conv = pcm->yab2gr;
+        y = lat;
+        if (lat>-999.0) {
+          if (conv && pcm->ydim!=3) y = conv(pcm->yabval, lat);
+        }
+        snprintf(pout,255,"%s = %g  %s = %g\n",ccdims[pcm->xdim],x,ccdims[pcm->ydim],y);
+        gaprnt(2,pout);
+      } else {
+        if (pcm->xdim==3) {
+          gr2t (pcm->xgrval, lon, &dtim);
+          gat2ch (&dtim, 5, lab, 20);
+          snprintf(pout,255,"%s = %s  %s = %g\n",cdims[pcm->xdim+1],lab,cdims[pcm->ydim+1],lat);
+          gaprnt(2,pout);
+        } else if (pcm->ydim==3) {
+          gr2t (pcm->ygrval, lat, &dtim);
+          gat2ch (&dtim, 5, lab, 20);
+          snprintf(pout,255,"%s = %g  %s = %s\n",cdims[pcm->xdim+1],lon,cdims[pcm->ydim+1],lab);
+          gaprnt(2,pout);
+        } else {
+          snprintf(pout,255,"%s = %g  %s = %g\n",cdims[pcm->xdim+1],lon,cdims[pcm->ydim+1],lat);
+          gaprnt(2,pout);
+        }
+      }
+    }
+    return (0);
+    errxy:
+    if (flag) gaprnt (0,"Query Error: Syntax is QUERY XY2GR x y\n");
+    else gaprnt (0,"QUERY error: Syntax is QUERY XY2W x y\n");
+    return (1);
+  }
+
+  else if (cmpwrd(arg,"ll2xy")) {
+    if ((arg = nxtwrd (arg)) == NULL) goto errll;
+    if (getdbl(arg,&lon) == NULL ) goto errll;
+    if ((arg = nxtwrd (arg)) == NULL) goto errll;
+    if (getdbl(arg,&lat) == NULL ) goto errll;
+    gxconv (lon,lat,&x,&y,2);
+    snprintf(pout,255,"%g %g\n",x,y);
+    gaprnt (2,pout);
+    return (0);
+    errll:
+    gaprnt (0,"QUERY error: Syntax is QUERY LL2XY lon lat\n");
+    return (1);
+  }
+
+  else if (cmpwrd(arg,"defval")) {
+    i = gaqdef (arg, pcm, 0);
+    return (i);
+  }
+
+  else if (cmpwrd(arg,"udft")) {
+    gaprnt(2,"Warning: User Defined Functions have been disabled in this version of GrADS\n");
+    return (0);
+  }
+
+  else if (cmpwrd(arg,"ctlinfo")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' '&&*arg!='\0'&&*arg!='\n'&&i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY CTLINFO argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY CTLINFO Error:  file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+
+    snprintf(pout,255,"dset %s\n",pfi->name);
+    gaprnt (2,pout);
+    snprintf(pout,255,"title %s\n",pfi->title);
+    gaprnt (2,pout);
+    snprintf(pout,255,"undef %g\n",pfi->undef);
+    gaprnt (2,pout);
+
+    if (pfi->ncflg==1) gaprnt(2,"dtype netcdf\n");
+    if (pfi->ncflg==2) gaprnt(2,"dtype hdfsds\n");
+    if (pfi->type==2) {
+      gaprnt (2,"dtype station\n");
+      snprintf(pout,255,"  Tsize = %i\n",pfi->dnum[3]);
+      gaprnt(2,pout);
+    } 
+    else {
+      snprintf(pout,255,"xdef %i",pfi->dnum[0]);
+      gaprnt(2,pout);
+      if (pfi->linear[0]) {
+        conv = pfi->gr2ab[0];
+        snprintf(pout,255," linear %g %g\n",conv(pfi->grvals[0],1.0),*(pfi->grvals[0]));
+        gaprnt (2,pout);
+      } 
+      else {
+        gaprnt(2," levels");
+        conv = pfi->gr2ab[0];
+        cnt = 3;
+        for (i=1; i<=pfi->dnum[0]; i++) {
+          snprintf(pout,255," %g",conv(pfi->grvals[0],(gadouble)i));
+          gaprnt (2,pout);
+          cnt++;
+          if (cnt>10 && i!=pfi->dnum[0]) {
+            gaprnt (2,"\n"); cnt = 1;
+          }
+        }
+        gaprnt (2,"\n");
+      }
+
+      snprintf(pout,255,"ydef %i",pfi->dnum[1]);
+      gaprnt(2,pout);
+      if (pfi->linear[1]) {
+        conv = pfi->gr2ab[1];
+        snprintf(pout,255," linear %g %g\n",conv(pfi->grvals[1],1.0),*(pfi->grvals[1]));
+        gaprnt (2,pout);
+      } else {
+        gaprnt(2," levels");
+        conv = pfi->gr2ab[1];
+        cnt = 3;
+        for (i=1; i<=pfi->dnum[1]; i++) {
+          snprintf(pout,255," %g",conv(pfi->grvals[1],(gadouble)i));
+          gaprnt (2,pout);
+          cnt++;
+          if (cnt>10 && i!=pfi->dnum[1]) {
+            gaprnt (2,"\n"); cnt = 1;
+          }
+        }
+        gaprnt (2,"\n");
+      }
+
+      snprintf(pout,255,"zdef %i",pfi->dnum[2]);
+      gaprnt(2,pout);
+      if (pfi->linear[2]) {
+        conv = pfi->gr2ab[2];
+        snprintf(pout,255," linear %g %g\n",conv(pfi->grvals[2],1.0),*(pfi->grvals[2]));
+        gaprnt (2,pout);
+      } else {
+        gaprnt(2," levels");
+        conv = pfi->gr2ab[2];
+        cnt = 3;
+        for (i=1; i<=pfi->dnum[2]; i++) {
+          snprintf(pout,255," %g",conv(pfi->grvals[2],(gadouble)i));
+          gaprnt (2,pout);
+          cnt++;
+          if (cnt>10 && i!=pfi->dnum[2]) {
+            gaprnt (2,"\n"); cnt = 1;
+          }
+        }
+        gaprnt (2,"\n");
+      }
+
+      gr2t (pfi->grvals[3],1.0,&dtim);
+      if (dtim.mn==0) gat2ch (&dtim,4,lab,20);
+      else gat2ch (&dtim,5,lab,20);
+      if (*(pfi->grvals[3]+5)!=0) {
+        snprintf(pout,255,"tdef %i linear %s %gmo\n",pfi->dnum[3],lab,*(pfi->grvals[3]+5));
+      } else {
+        snprintf(pout,255,"tdef %i linear %s %gmn\n",pfi->dnum[3],lab,*(pfi->grvals[3]+6));
+      }
+      gaprnt (2,pout);
+
+      /* only write out EDEF if esize > 1*/
+      if (pfi->dnum[4]>1) {
+	if (pfi->ens1) {
+	  /* write out a multi-line EDEF entry with all metadata */
+	  snprintf(pout,255,"edef %i \n",pfi->dnum[4]);
+	  gaprnt(2,pout);
+	  for (i=0; i<pfi->dnum[4]; i++) {
+	    gat2ch(&(pfi->ens1[i].tinit),4,lab,20);
+	    snprintf(pout,255,"%s %d %s\n", pfi->ens1[i].name, pfi->ens1[i].length, lab);
+	    gaprnt(2,pout);
+	  }
+	  gaprnt(2,"endedef\n");
+	}
+      }
+	
+      snprintf(pout,255,"vars %i\n",pfi->vnum);
+      gaprnt (2,pout);
+      pvar = pfi->pvar1;
+      for (i=0;i<pfi->vnum;i++) {
+	/* print out the variable name and the number of levels */
+	if (pvar->longnm[0] != '\0')
+	  snprintf(pout,255,"%s=>%s  %i  ",pvar->longnm,pvar->abbrv,pvar->levels);
+	else
+	  snprintf(pout,255,"%s  %i  ",pvar->abbrv,pvar->levels);
+	gaprnt(2,pout);
+	/* print out the values in the units field */
+	for (j=0; j<5; j++) {
+	  if (pvar->units[j] != -999) {
+	    if      (pvar->units[j] == -100) gaprnt(2,"x");
+	    else if (pvar->units[j] == -101) gaprnt(2,"y");
+	    else if (pvar->units[j] == -102) gaprnt(2,"z");
+	    else if (pvar->units[j] == -103) gaprnt(2,"t");
+	    else if (pvar->units[j] == -104) gaprnt(2,"e");
+	    else {
+	      snprintf(pout,255,"%g",pvar->units[j]);
+	      gaprnt(2,pout);
+	    }
+	    if (pvar->units[j+1] != -999) gaprnt(2,",");    /* add a comma if we've got more */
+	  }
+	}
+	/* print out the description */
+	snprintf(pout,255,"  %s\n",pvar->varnm);
+        gaprnt(2,pout);
+        pvar++;
+      }
+      gaprnt (2,"endvars\n");
+    }
+  }
+  else if (cmpwrd(arg,"file")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' '&&*arg!='\0'&&*arg!='\n'&&i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY FILE argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY FILE Error:  file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+    snprintf(pout,255,"File %i : %s\n",fnum,pfi->title);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  Descriptor: %s\n",pfi->dnam);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  Binary: %s\n",pfi->name);
+    gaprnt (2,pout);
+    if (pfi->type==2) {
+      if (pfi->bufrflg) {
+	gaprnt (2,"  Type = BUFR Station Data\n");
+      } else {
+	gaprnt (2,"  Type = Station Data\n");
+      }
+      snprintf(pout,255,"  Tsize = %i\n",pfi->dnum[3]);
+      gaprnt(2,pout);
+    } else {
+      gaprnt (2,"  Type = Gridded\n");
+      snprintf(pout,255,"  Xsize = %i  Ysize = %i  Zsize = %i  Tsize = %i  Esize = %i\n",
+         pfi->dnum[0],pfi->dnum[1],pfi->dnum[2],pfi->dnum[3],pfi->dnum[4]);
+      gaprnt(2,pout);
+    }
+    snprintf(pout,255,"  Number of Variables = %i\n",pfi->vnum);
+    gaprnt (2,pout);
+
+    pvar = pfi->pvar1;
+    for (i=0;i<pfi->vnum;i++) {
+      /* print out the variable name and the number of levels */
+      snprintf(pout,255,"     %s  %i  ",pvar->abbrv,pvar->levels);
+      gaprnt(2,pout);
+      /* print out the values in the units field */
+      for (j=0; j<5; j++) {
+	if (pvar->units[j] != -999) {
+	  if      (pvar->units[j] == -100) gaprnt(2,"x");
+	  else if (pvar->units[j] == -101) gaprnt(2,"y");
+	  else if (pvar->units[j] == -102) gaprnt(2,"z");
+	  else if (pvar->units[j] == -103) gaprnt(2,"t");
+	  else if (pvar->units[j] == -104) gaprnt(2,"e");
+	  else {
+	    snprintf(pout,255,"%g",pvar->units[j]);
+	    gaprnt(2,pout);
+	  }
+	  if (pvar->units[j+1] != -999) gaprnt(2,",");    /* add a comma if we've got more */
+	}
+      }
+      /* print out the description */
+      snprintf(pout,255,"  %s\n",pvar->varnm);
+      gaprnt(2,pout);
+      pvar++;
+    }
+  }
+
+  else if (cmpwrd(arg,"gxout")) {
+    snprintf(pout,255,"General = %s\n",gxout0D[pcm->gout1]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"1D Graphic, 1 expr = %s\n",gxout1D[pcm->gout1]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"1D Graphic, 2 expr = %s\n",gxout1Da[pcm->gout1a]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"2D Graphic, 1 expr = %s\n",gxout2Da[pcm->gout2a]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"2D Graphic, 2 expr = %s\n",gxout2Db[pcm->gout2b]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Station data = %s\n",gxoutStn[pcm->goutstn]);
+    gaprnt(2,pout);
+  }
+
+  else if (cmpwrd(arg,"gxinfo")) {
+    snprintf(pout,255,"Last Graphic = %s\n",gxnms[pcm->lastgx]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Page Size = %g by %g\n",pcm->xsiz,pcm->ysiz);
+    gaprnt(2,pout);
+    snprintf(pout,255,"X Limits = %g to %g\n",pcm->xsiz1,pcm->xsiz2);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Y Limits = %g to %g\n",pcm->ysiz1,pcm->ysiz2);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Xaxis = %s  Yaxis = %s\n",cdims[pcm->xdim+1],
+                  cdims[pcm->ydim+1]);
+    gaprnt(2,pout);
+    snprintf(pout,255,"Mproj = %d\n",pcm->mproj);
+    gaprnt(2,pout);
+  }
+
+  else if (cmpwrd(arg,"xinfo")) {
+    if (pcm->batflg) {
+      gaprnt(2,"Batch Mode\n");
+    } else {
+      if (win_data (&xinf) ) {
+        snprintf(pout,255,"Window ID = %d\n",xinf.winid);
+        gaprnt(2,pout);
+        snprintf(pout,255,"Window X = %d\n",xinf.winx);
+        gaprnt(2,pout);
+        snprintf(pout,255,"Window Y = %d\n",xinf.winy);
+        gaprnt(2,pout);
+        snprintf(pout,255,"Window Width = %d\n",xinf.winw);
+        gaprnt(2,pout);
+        snprintf(pout,255,"Window Height = %d\n",xinf.winh);
+        gaprnt(2,pout);
+        snprintf(pout,255,"Window Border = %d\n",xinf.winb);
+        gaprnt(2,pout);
+      } else {
+        gaprnt(2,"Error\n");
+      }
+    }
+  }
+
+  else if (cmpwrd(arg,"shades")) {
+    if (pcm->shdcnt<1) {
+      gaprnt(2,"None\n");
+    } else {
+      snprintf(pout,255,"Number of levels = %i\n",pcm->shdcnt);
+      gaprnt(2,pout);
+      for (i=0; i<pcm->shdcnt; i++) {
+        if (i==0) 
+	  snprintf(pout,255,"%i <= %g\n",pcm->shdcls[i],pcm->shdlvs[1]);
+        else if (i==pcm->shdcnt-1) 
+	  snprintf(pout,255,"%i %g >\n",pcm->shdcls[i],pcm->shdlvs[i]);
+        else 
+	  snprintf(pout,255,"%i %g %g\n",pcm->shdcls[i],pcm->shdlvs[i],pcm->shdlvs[i+1]);
+        gaprnt(2,pout);
+      }
+    }
+  }
+
+  else if (cmpwrd(arg,"contours")) {
+    if (pcm->cntrcnt < 1) {
+      gaprnt(2,"None\n");
+    } else {
+      snprintf(pout,255,"Number of levels = %i\n",pcm->cntrcnt);
+      gaprnt(2,pout);
+      for (i=0; i<pcm->cntrcnt; i++) {
+        snprintf(pout,255,"%i %g\n",pcm->cntrcols[i],pcm->cntrlevs[i]);
+        gaprnt(2,pout);
+      }
+    }
+  }
+
+  else if (cmpwrd(arg,"time")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if (pcm->tmin.mn==0) gat2ch(&(pcm->tmin),4,lab,20);
+    else gat2ch (&(pcm->tmin),5,lab,20);
+    if (pcm->tmax.mn==0) gat2ch(&(pcm->tmax),4,lab2,20);
+    else gat2ch (&(pcm->tmax),5,lab2,20);
+    snprintf(pout,255,"Time = %s to %s",lab,lab2);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  %s to %s\n",dweek[dayweek(&(pcm->tmin))],dweek[dayweek(&(pcm->tmax))]);
+    gaprnt (2,pout);
+  }
+
+  else if (cmpwrd(arg,"bpos") || cmpwrd(arg,"pos")) {
+    i = 1;
+    if ((arg = nxtwrd (arg)) != NULL) {
+      if (cmpwrd(arg,"nowait")) i = 0;
+    }
+    gxdbtn (i, &x, &y, &i, &etype, info, rinfo);
+    if (etype<1) {
+      snprintf(pout,255,"Position = %g %g %i %i\n",
+	       x,y,i,etype);
+    } else if (etype==1) {
+      snprintf(pout,255,"Position = %g %g %i %i %i %i\n",
+	       x,y,i,etype,*info,*(info+1));
+    } else if (etype==2) {
+      snprintf(pout,255,"Position = %g %g %i %i %i %g %g\n",
+	       x,y,i,etype,*info,*rinfo,*(rinfo+1));
+    } else if (etype==3) {
+      snprintf(pout,255,"Position = %g %g %i %i %i %i %i %i %i %i %i %i\n",
+         x,y,i,etype,*info,*(info+1),*(info+2),*(info+3),*(info+4),*(info+5),*(info+6),*(info+7));
+    }
+    gaprnt (2,pout);
+  }
+
+  else if (cmpwrd(arg,"define")) {
+    if (pcm->pdf1==NULL) {
+      gaprnt (1,"No Defined Variables\n");
+      return(0);
+    } else {
+      pdf = pcm->pdf1;
+      while (pdf) {
+        pfi = pdf->pfi;
+        snprintf(pout,255,"%s %g\n",pdf->abbrv,*(pfi->rbuf));
+	gaprnt(2,pout);
+        pdf = pdf->pforw;
+      }
+    }
+    return(0);
+  }
+
+  else if (cmpwrd(arg,"files")) {
+    pfi = pcm->pfi1;
+    if (pfi==NULL) {
+      gaprnt (2,"No files open\n");
+    } else {
+      j = 1;
+      while (pfi!=NULL) {
+        snprintf(pout,255,"File %i : %s\n",j,pfi->title);
+        gaprnt (2,pout);
+        snprintf(pout,255,"  Descriptor: %s\n",pfi->dnam);
+        gaprnt (2,pout);
+        snprintf(pout,255,"  Binary: %s\n",pfi->name);
+        gaprnt (2,pout);
+        pfi = pfi->pforw;
+        j++;
+      }
+    }
+  }
+
+  else if (cmpwrd(arg,"attr")) {
+    if (pcm->pfi1==NULL) {
+      gaprnt (0,"No Files Open\n");
+      return(1);
+    }
+    if ((arg = nxtwrd (arg)) == NULL) {
+      pfi = pcm->pfid;
+      fnum = pcm->dfnum;
+    } else {
+      if (intprs(arg,&fnum) == NULL ) {
+        i = 0;
+        while (*arg!=' ' && *arg!='\0' && *arg!='\n' && i<19) {
+          lab[i] = *arg;
+          arg++;
+          i++;
+        }
+        lab[i] = '\0';
+        snprintf(pout,255,"Invalid QUERY ATTR argument: %s \n",lab);
+        gaprnt (0,pout);
+        return (1);
+      }
+      pfi = pcm->pfi1;
+      for (i=0; i<fnum-1; i++) {
+        pfi = pfi->pforw;
+        if (pfi==NULL) {
+          snprintf(pout,255,"QUERY ATTR Error: file %i not open\n",fnum);
+          gaprnt (0,pout);
+          return(1);
+        }
+      }
+    }
+  
+    /* Print attributes from the descriptor file */
+    hdrflgd=1;
+    if (pfi->attr) { 
+      /* Print global and coordinate attributes */
+      hdrflgd = prntgaattr (pfi, "global", hdrflgd, fnum);
+      hdrflgd = prntgaattr (pfi, "lon",  hdrflgd, fnum);
+      hdrflgd = prntgaattr (pfi, "lat",  hdrflgd, fnum);
+      hdrflgd = prntgaattr (pfi, "lev",  hdrflgd, fnum);
+      hdrflgd = prntgaattr (pfi, "time", hdrflgd, fnum);
+      hdrflgd = prntgaattr (pfi, "ens",  hdrflgd, fnum);
+      /* Print variable attributes associated with the GrADS variable name, pvar->abbrv */
+      pvar = pfi->pvar1;           
+      for (i=0; i<pfi->vnum; i++) {
+	hdrflgd = prntgaattr (pfi, pvar->abbrv, hdrflgd, fnum);
+	pvar++;
+      }  
+      /* Print a blank line between descriptor attrbutes and native attributes for GDS parsing */
+      if (!hdrflgd) gaprnt(2,"\n");
+    } 
+    if (hdrflgd) {
+      /* Always include the following text, even if there are no descriptor attributes */
+      snprintf(pout,255,"No Descriptor Attributes for File %i : %s \n\n",fnum,pfi->title);
+      gaprnt(2,pout);
+    }
+
+
+    /* Print native attributes for NetCDF, HDFSDS, HDF5 data sets */
+    hdrflg=1; 
+
+    /* Global attributes for netcdf */
+    if (pfi->ncflg==1) {  
+#if USENETCDF == 1
+      /* open each data file in template set until we find one that exists */
+      if (pfi->tmplat) {
+	ncid=-999; rc=0; error=0;
+	gr2t(pfi->grvals[3], 1.0, &tdefi);
+	tfile = gafndt(pfi->name, &tdefi, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	rc = nc_open(tfile, NC_NOWRITE, &ncid);
+	if (rc != NC_NOERR) error=1;
+	if (!error) {
+	  closethisfilelater=1;
+	} else {
+	  for (i=2; i<=pfi->dnum[3]; i++) {
+	    ncid=-999; rc=0; error=0;
+	    gr2t(pfi->grvals[3], (gadouble)i, &tdef);
+	    tfile2 = gafndt(pfi->name, &tdef, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	    if (strcmp(tfile,tfile2)!=0) {
+	      gree(tfile,"f213");
+	      tfile = tfile2;
+	      rc = nc_open(tfile2, NC_NOWRITE, &ncid);
+	      if (rc != NC_NOERR) error=1;
+	      if (!error) {
+		closethisfilelater=1;
+		break;
+	      }
+	    }
+	  }
+	}
+	gree(tfile,"f214");
+      } 
+      else {
+	/* Copy the netcdf file id from the file structure to the local variable ncid */
+	if (pfi->ncflg == 1) {
+	  ncid = pfi->ncid;
+	}
+	closethisfilelater=0;
+      }
+      /* Retrieve netcdf global attributes */
+      n_gatts = ncpattrs(ncid, "NC_GLOBAL", "global", hdrflg, fnum, pfi->title);
+      if (hdrflg && n_gatts>0) hdrflg=0;
+#endif
+    }
+    
+    /* Global attributes for DTYPE HDFSDS */
+    else if (pfi->ncflg == 2) {
+#if USEHDF==1
+      /* open each data file in template set until we find one that exists */
+      if (pfi->tmplat) {
+	sdid=-999;
+	gr2t(pfi->grvals[3], 1.0, &tdefi);
+	tfile = gafndt(pfi->name, &tdefi, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	sdid = SDstart(tfile,1);
+	if (sdid != -1) {
+	  closethisfilelater=1;
+	} else {
+	  for (i=2; i<=pfi->dnum[3]; i++) {
+	    sdid=-999;
+	    gr2t(pfi->grvals[3], (gadouble)i, &tdef);
+	    tfile2 = gafndt(pfi->name, &tdef, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	    if (strcmp(tfile,tfile2)!=0) {
+	      gree(tfile,"f215");
+	      tfile = tfile2;
+	      sdid = SDstart(tfile2,1); 
+	      if (sdid != -1) {
+		closethisfilelater=1;
+		break;
+	      }
+	    }
+	  }
+	}
+	gree(tfile,"f216");
+      } 
+      else {
+	/* Copy the hdf file id from the file structure to the local variable sdid */
+	sdid = pfi->sdid;
+	closethisfilelater=0;
+      }
+      
+      /* Retrieve HDF global attributes */
+      n_gatts = hdfpattrs(sdid, "foo", "global", hdrflg, fnum, pfi->title);
+      if (hdrflg && n_gatts>0) hdrflg=0;
+#endif
+    }
+    /* Global attributes for DTYPE HDF5 */
+    else if (pfi->ncflg == 3) {
+#if USEHDF5==1
+      /* open each data file in template set until we find one that exists */
+      if (pfi->tmplat) {
+	h5id=-999;
+	gr2t(pfi->grvals[3], 1.0, &tdefi);
+	tfile = gafndt(pfi->name, &tdefi, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	fid = H5Fopen(tfile,H5F_ACC_RDONLY, H5P_DEFAULT);
+	if (fid>0) {
+	  h5id = (gaint)fid;
+	  closethisfilelater=1;
+	} else {
+	  for (i=2; i<=pfi->dnum[3]; i++) {
+	    h5id=-999;
+	    gr2t(pfi->grvals[3], (gadouble)i, &tdef);
+	    tfile2 = gafndt(pfi->name, &tdef, &tdefi, pfi->abvals[3], pfi->pchsub1, pfi->ens1,1,1,&flag);
+	    if (strcmp(tfile,tfile2)!=0) {
+	      gree(tfile,"f215");
+	      tfile = tfile2;
+	      fid = H5Fopen(tfile2,H5F_ACC_RDONLY, H5P_DEFAULT); 
+	      if (fid>0) {
+		h5id = (gaint)fid;
+		closethisfilelater=1;
+		break;
+	      }
+	    }
+	  }
+	}
+	gree(tfile,"f216");
+      } 
+      else {
+	/* Copy the hdf5 file id from the file structure to the local variable h5id */
+	h5id = pfi->h5id;
+	closethisfilelater=0;
+      }
+      
+      /* Retrieve HDF5 global attributes (nothing to do yet) */
+/*       n_gatts = h5pattrs(h5id, "foo", "global", hdrflg, fnum, pfi->title); */
+/*       if (hdrflg && n_gatts>0) hdrflg=0; */
+#endif
+    }
+
+    /* Print netcdf coordinate attributes */
+#if USENETCDF == 1
+    if (pfi->ncflg == 1) {
+      for (i=0;i<pfi->nsdfdims;i++) {
+        n_atts = ncpattrs(pfi->ncid, pfi->sdfdimnam[i], pfi->sdfdimnam[i], hdrflg, fnum, pfi->title);
+        if (hdrflg && n_atts>0) hdrflg=0;
+      }
+    }
+#endif    
+    /* Print Variable attributes for dtype netcdf and dtype hdf. */
+    if ((pfi->ncflg == 1) || (pfi->ncflg == 2) || (pfi->ncflg == 3)) {  
+      pvar = pfi->pvar1;                  
+      for (i=0; i<pfi->vnum; i++) {
+	if (pvar->longnm[0] != '\0') {
+	  varnam = pvar->longnm;
+	}
+	else {
+	  varnam = pvar->abbrv;
+	}
+#if USENETCDF == 1
+	/* Print NetCDF variable attributes */
+	if (pfi->ncflg==1) {
+	  n_atts = ncpattrs(ncid, varnam, pvar->abbrv, hdrflg, fnum, pfi->title);
+	  if (hdrflg && n_atts>0) hdrflg=0; 
+	}
+#endif
+#if USEHDF ==1
+	/* Print HDF variable attributes */
+	if (pfi->ncflg==2) {
+	  n_atts = hdfpattrs(sdid, varnam, pvar->abbrv, hdrflg, fnum, pfi->title); 
+	  if (hdrflg && n_atts>0) hdrflg=0; 
+	}
+#endif
+#if USEHDF5 ==1
+	/* Print HDF5 variable attributes */
+	if (pfi->ncflg==3) {
+	  n_atts = h5pattrs(h5id, varnam, pvar->abbrv, hdrflg, fnum, pfi->title); 
+	  if (hdrflg && n_atts>0) hdrflg=0; 
+	}
+#endif
+	pvar++;
+      }  
+    }
+    
+    /* close the file we opened to get the attributes*/
+    if (closethisfilelater) {
+#if USENETCDF==1
+      if (pfi->ncflg==1) nc_close(ncid);
+#endif
+#if USEHDF==1
+      if (pfi->ncflg == 2)  SDend(sdid);
+#endif
+#if USEHDF5==1
+      if (pfi->ncflg == 3)  H5Fclose(fid);
+#endif
+    }
+    
+    if (hdrflg) {
+      snprintf(pout,255,"No Native Attributes for File %i : %s \n",fnum,pfi->title);
+      gaprnt(2,pout);
+    }
+    
+  } /* Matches  else if (cmpwrd(arg,"attr")) { */
+  
+  else {
+    i = 0;
+    while (*arg!=' '&&*arg!='\0'&&*arg!='\n'&&i<19) {
+      lab[i] = *arg;
+      arg++;
+      i++;
+    }
+    lab[i] = '\0';
+    snprintf(pout,255,"Invalid QUERY argument: %s \n",lab);
+    gaprnt(0,pout);
+  }
+  return (0);
+}
+
+
+/* Handle help command */
+
+gaint gahelp (char *cmd, struct gacmn *pcm) {
+
+  printf ("\nFor Complete Information See:  http://grads.iges.org/grads\n\n");
+  printf ("Basic Commands:\n");
+  printf (" OPEN <descr>      opens a data file \n");
+  printf (" Query             shows current status \n");
+  printf (" Clear             clears graphics window \n");
+  printf (" SET <args>        sets options \n");
+  printf (" Display expr      displays a variable graphically \n");
+  printf (" QUIT              exits the program \n");
+  return (0);
+}
+
+/* Handle collect command */
+
+gaint gacoll (char *cmd, struct gacmn *pcm) {
+struct gastat *pst;
+struct gaclct *clct,*clct2;
+gaint rc,i,flag,clnm;
+size_t sz;
+
+  if ((cmd=nxtwrd(cmd)) == NULL) goto collerr1;
+  if (intprs(cmd,&clnm) == NULL) goto collerr1;
+  if (clnm<0 || clnm>31) goto collerr1;
+  if ((cmd=nxtwrd(cmd)) == NULL) goto collerr1;
+
+  if (cmpwrd("free",cmd)) {
+    clct = pcm->clct[clnm];
+    while (clct) {
+      gasfre(clct->stn);
+      clct2 = clct->forw;
+      gree(clct,"f218");
+      clct = clct2;
+    }
+    pcm->clct[clnm] = NULL;
+    return (0);
+  }
+
+  /* Check environment */
+
+  if (pcm->vdim[0]!=0 || pcm->vdim[1]!=0 || (pcm->vdim[2]==1 &&
+     pcm->vdim[3]==1) || (pcm->vdim[2] == 0 && pcm->vdim[3] == 0)) {
+    gaprnt (0,"Collect Error: Z or T must be the only varying dimension\n");
+    return (1);
+  }
+
+  /* Evaluate expression(s)  */
+
+  garemb (cmd);
+  pst = getpst(pcm);
+  if (pst==NULL) return(1);
+  rc = gapars(cmd, pst, pcm);
+  if (rc) goto collerr2;
+
+  /* Make sure returned objects are station data */
+
+  flag = 0;
+  if (pcm->type[0]!=0) flag = 1;
+  if (pcm->numgrd>1 && pcm->type[1]!=0) flag = 1;
+  if (flag) {
+    gaprnt(0,"Collect Error: Station Data Required\n");
+    rc = 1;
+    goto collerr2;
+  }
+
+  /* Chain up what we have collected */
+
+  sz = sizeof(struct gaclct);
+  snprintf(pout,255,"%dclct%d",clnm,pcm->clctnm[clnm]);
+  clct = (struct gaclct *)galloc(sz,pout);
+  if (clct==NULL) {
+    gaprnt (0,"Memory allocation error in collect\n");
+    rc = 1;
+    goto collerr2;
+  }
+  clct->forw = NULL;
+  if (pcm->clct[clnm]==NULL) pcm->clct[clnm] = clct;
+  else {
+    /* add new collection to end of chain */
+    clct2 = pcm->clct[clnm];            
+    while (clct2->forw) clct2 = clct2->forw;
+    clct2->forw = clct;
+  }
+  clct->stn = pcm->result[0].stn;
+  pcm->clctnm[clnm]++;
+
+  /* Free any possible extra stuff */
+
+  if (pcm->numgrd > 1) {
+    for (i=1; i<pcm->numgrd; i++) {
+      if (pcm->type[i]==1) 
+	gagfre (pcm->result[i].pgr);
+      else 
+	gasfre (pcm->result[i].stn);
+    }
+  }
+  pcm->numgrd = 0;
+  pcm->relnum = 0;
+
+  gree(pst,"f219");
+  return (0);
+
+collerr1:
+
+  gaprnt (0,"Collect command error:  Invalid Syntax\n");
+  gaprnt (0,"  Format is:  collect n expr\n");
+  return (1);
+
+collerr2:
+  gagrel(pcm);
+  gree(pst,"f220");
+  return(rc);
+
+}
+
+/* Handle display command */
+
+gaint gadspl (char *cmd, struct gacmn *pcm) {
+struct gastat *pst;
+struct gafile *pfi;
+gadouble (*conv) (gadouble *, gadouble) = NULL;
+gadouble *vals,v;
+gadouble xl,yl,s1,s2;
+gaint llen, rcode, labsv;
+gaint l,l1,l2,vcnt,i,lflg,ldim,rc;
+char lab[30];
+static gaint dcolor[10] = {-1, 1, 3, 7, 2, 6, 9, 10, 11, 12 };
+
+  if (pcm->impflg) gacmd (pcm->impnam, pcm, 0);
+  rcode = 1;
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"Display command error:  No expression provided\n");
+    return (1);
+  }
+  garemb (cmd);
+
+  pst = getpst(pcm);
+  if (pst==NULL) return(1);
+
+  vcnt = 0;
+  for (i=0; i<5; i++) if (pcm->vdim[i]) vcnt++;
+  lflg = pcm->loopflg;
+  if (vcnt>2) lflg = 1;
+  pcm->pass = pcm->pass%INT_MAX;
+  if (!lflg) {            /* not looping */
+    pcm->mcolor = 8;
+    if (pcm->ccolor==-9) {
+      if (vcnt==2 && pcm->grflg==0) 
+	pcm->ccolor = dcolor[pcm->pass%10];
+      else 
+	pcm->ccolor = dcolor[(pcm->pass+1)%10];
+    }
+    if (pcm->cmark==-9) {
+      pcm->cmark = pcm->pass+2;
+      while (pcm->cmark>5) pcm->cmark-=5;
+    }
+    if (pcm->ccolor<0 || pcm->grflg) pcm->mcolor = 15;
+    rc = gapars(cmd, pst, pcm);
+    if (rc) goto retrn;
+    gaplot (pcm); 
+    gagrel (pcm);
+    pcm->pass++;
+    pcm->ccolor = -9;
+    pcm->cstyle = -9;
+    pcm->cmark = -9;
+    pcm->cint = 0.0;
+    pcm->cflag = 0;
+    pcm->ccflg = 0;
+    pcm->cmin = -9.99e33;
+    pcm->cmax = 9.99e33;
+    pcm->blkflg = 0;
+    pcm->rainmn = 0.0;
+    pcm->rainmx = 0.0;
+    pcm->arrflg = 0;
+    pcm->ptflg = 0;
+    pcm->xexflg = 0;  
+    pcm->yexflg = 0;
+  } else {               /* looping */
+    pcm->mcolor = 15; 
+    if (pcm->ccolor==-9) {
+      pcm->ccolor = -1;
+      if (vcnt<2 || pcm->grflg) pcm->ccolor = 1;
+    }
+    if (pcm->cmark==-9) {
+      pcm->cmark = pcm->pass+2;
+      while (pcm->cmark>5) pcm->cmark-=5;
+    }
+    pfi = pcm->pfid;
+    ldim = pcm->loopdim;
+    if (pfi->type > 1 && ldim < 3) {
+      gaprnt (0,"Display command error:  Invalid looping environment\n");
+      gaprnt (0,"  Cannot loop on stn data through X, Y, or Z\n");
+      return (1);
+    }
+    if (ldim==3) {                    /* loop on T */
+      vals = pfi->abvals[3];
+      v = t2gr(vals,&(pcm->tmin));
+      l1 = (gaint)v;
+      v = t2gr(vals,&(pcm->tmax));
+      l2 = (gaint)(v+0.999);
+    } 
+    else {                         /* loop on X, Y, Z or E */
+      conv = pfi->ab2gr[ldim];
+      vals = pfi->abvals[ldim];
+      v = conv(vals,pcm->dmin[ldim]);
+      l1 = (gaint)v;
+      v = conv(vals,pcm->dmax[ldim]);
+      l2 = (gaint)(v+0.999);
+    }
+    vals = pfi->grvals[ldim];
+    if (ldim!=3) conv = pfi->gr2ab[ldim];
+    gxfrme (2);
+    pcm->pass = 0;
+    labsv = pcm->clab;
+    for (l=l1;l<=l2;l++) {
+      if (ldim==3) {
+        gr2t (vals, (gadouble)l, &(pst->tmin));
+        pst->tmax = pst->tmin;
+      } 
+      else {
+        pst->dmin[ldim] = conv(vals,(gadouble)l);
+        pst->dmax[ldim] = pst->dmin[ldim];
+      }
+      rc = gapars(cmd, pst, pcm);
+      if (rc) goto retrn;
+      pcm->clab = 0;
+      if (l==l2) pcm->clab = labsv;
+      gaplot (pcm);
+      if (ldim==3) {
+	snprintf(lab,29,"%i:%i:%i:%i",pst->tmin.yr,pst->tmin.mo,pst->tmin.dy,pst->tmin.hr);
+      }
+      else {
+	snprintf(lab,29,"%g",pst->dmin[ldim]);
+      }
+      llen=0; while (lab[llen]) llen++;
+      xl = pcm->xsiz - (0.11*(gadouble)(llen));
+      xl -= 0.02;
+      yl = 0.02;
+      s1 = 0.13;
+      s2 = 0.11;
+      gxwide(1);
+      gxchpl (lab,llen,xl,yl,s1,s2,0.0);
+      gxfrme (2);
+      gagrel (pcm);
+      pcm->aflag = -1;
+      pcm->aflag2 = -1;
+    }
+    pcm->dbflg = 0;
+    pcm->pass = 0;
+    pcm->ccolor = -9;
+    pcm->cstyle = -9;
+    pcm->cmark = -9;
+    pcm->cint = 0.0;
+    pcm->cflag = 0;
+    pcm->ccflg = 0;
+    pcm->cmin = -9.99e33;
+    pcm->cmax = 9.99e33;
+    pcm->blkflg = 0;
+    pcm->rainmn = pcm->rainmx = 0.0;
+    pcm->aflag = 0;
+    pcm->aflag2 = 0;
+    pcm->axflg = 0;
+    pcm->ayflg = 0;
+    pcm->grdsflg = 1;
+    pcm->arrflg = 0;
+    pcm->ptflg = 0;
+    pcm->xexflg = 0; pcm->yexflg = 0;
+  }
+  gree(pst,"f103");
+  return (0);
+
+retrn:
+  gree(pst,"f104");
+  return(1);
+
+}
+
+/* Parse compound expression (multiple expressions seperated
+   by ;'s), get data, hand data off pcm, return */
+
+gaint gapars (char *cmd, struct gastat *pst, struct gacmn *pcm) {
+char *pos;
+char *expr;
+gaint num, i, rc;
+size_t sz;
+
+  sz = (strlen(cmd) + 5) * sizeof(char);
+  expr = (char *)galloc(sz,"gapars");
+  strcpy (expr, cmd);
+
+  /* Convert all the ;'s to nulls and count the number of
+     sub-expressions.                                           */
+
+  num  = 0;
+  pos = expr;
+  while (*pos!='\0') {
+    if (*pos==';') {
+      *pos = '\0';
+      num++;
+    }
+    pos++;
+  }
+  num++;
+
+  /* Evaluate all the subexpressions */
+  pos = expr;
+  for (i=0; i<num; i++) {
+    rc = gaexpr (pos, pst);
+    if (!rc) rc = gaqsig();
+    if (rc) goto err;
+    pcm->type[i] = pst->type;
+    pcm->result[i] = pst->result;
+    while (*pos!='\0') pos++;
+    pos++;
+  }
+  pcm->numgrd = num;
+  pcm->relnum = num;
+  gree(expr,"f221");
+  return (0);
+
+err:
+  gaprnt (0,"DISPLAY error:  Invalid expression \n");
+  gaprnt (0,"  Expression = ");
+  gaprnt (0,pos);
+  gaprnt (0,"\n");
+  pcm->numgrd = i;
+  pcm->relnum = i;
+  gagrel (pcm);
+  gree(expr,"f222");
+  return (1);
+}
+
+void gagrel (struct gacmn *pcm) {
+gaint i;
+
+  for (i=0; i<pcm->relnum; i++) {
+    if (pcm->type[i]==1) {
+      gagfre (pcm->result[i].pgr);
+    }
+    else gasfre (pcm->result[i].stn);
+  }
+  pcm->numgrd = 0;
+  pcm->relnum = 0;
+}
+
+/* Handle set command */
+
+char *justs[9] = {"bl","bc","br","l","c","r","tl","tc","tr"};
+
+gaint gaset (char *cmd, char *com, struct gacmn *pcm) {
+struct dt tdef;
+struct gawgds *wgds;
+struct gafile *pfi;
+struct gaens *ens;
+struct gaattr *attr,*newattr=NULL;
+struct dbfld *fld, *newfld=NULL;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble v1,v2,*vals,tt;
+gadouble val1,val2,xlo,xhi,ylo,yhi;
+gaint kwrd,i,i1,i2,num,id,itt,itt1,itt2,itmp[5];
+gaint enum1,enum2;
+gaint xx,yy,red,green,blue;
+char *ch=NULL,*ch2=NULL,*strng,*pat,*cmd1;
+char ename1[16],ename2[16];
+size_t sz;
+static char *kwds[125] = {"X","Y","Z","T","LON","LAT","LEV","TIME",
+			  "CINT","CSTYLE","CCOLOR","LOOPDIM",
+			  "LOOPING","LOOPINCR","DFILE","VRANGE",
+			  "CSMOOTH","GRID","CMARK","XAXIS","YAXIS",
+			  "GXOUT","BLACK","DIGNUM","DIGSIZ","CMIN",
+			  "CMAX","ARRSCL","ARRSIZ","CLEVS","STID",
+			  "GRADS","CLAB","MPROJ","CTERP","XSIZE",
+			  "CCOLS","MPVALS","MPDSET","VPAGE","PAREA",
+			  "LINE","STRING","STRSIZ","RGB","FGVALS",
+			  "MAP","BARBASE","BARGAP","CTHICK","MPDRAW",
+			  "POLI","DBUFF","XYREV","XFLIP","YFLIP",
+			  "ANNOT","DISPLAY","BACKGROUND","RBCOLS",
+			  "RBRANGE","MISSCONN","IMPRUN","ZLOG","STRMDEN",
+			  "FRAME","CLIP","VRANGE2","ARROWHEAD","MDLOPTS",
+			  "XLOPTS","YLOPTS","CLOPTS","XLAB","YLAB",
+			  "XLEVS","YLEVS","XLINT","YLINT","MISSWARN",
+			  "BUTTON","DEFVAL","BAROPTS","LFCOLS","WXCOLS",
+			  "FONT","FWRITE","XLPOS","YLPOS","CLSKIP","RBAND",
+			  "ARRLAB","MPT","WXOPT","XLABS","YLABS","FILL",
+			  "DROPMENU","LATS","TIMELAB","WARN","STNPRINT",
+			  "STAT","TLSUPP","GRIDLN","HEMPREF","PRNOPTS",
+			  "DATAWARN","DIALOG","WRITEGDS","COSLAT",
+			  "E","ENS","SDFWRITE","SDFATTR","GEOTIFF","KML",
+			  "UNDEF","CHUNKSIZE","CACHESF","SHPOPTS",
+			  "SHP","SHPATTR","LOG1D","STRMOPTS"};
+
+  strng = NULL;
+  kwrd=-1;
+  tt=0;
+  pfi = pcm->pfid;
+  cmd1 = cmd;
+  if ((cmd = nxtwrd (cmd))==NULL) {
+    gaprnt (0,"SET error:  missing operand\n");
+    return (1);
+  }
+  else if (cmpwrd("defval",cmd)) {
+    i1 = gaqdef (cmd, pcm, 1);
+    return (i1);
+  }
+  else if (cmpwrd("hempref",cmd)) {
+    kwrd=105;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("auto",cmd))  pcm->hemflg = -1; 
+    else if (cmpwrd("shem",cmd))  pcm->hemflg = 1; 
+    else if (cmpwrd("nhem",cmd))  pcm->hemflg = 0; 
+    else goto err;
+  }
+  else if (cmpwrd("gridln",cmd)) {
+    kwrd=104;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    i = 1;
+    if (cmpwrd("auto",cmd)) { pcm->gridln = -9; i=0; }
+    if (cmpwrd("off",cmd)) { pcm->gridln = -1; i=0; }
+    if (i) {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      pcm->gridln = itt;
+    }
+    return(0);
+  }
+  else if (cmpwrd("tlsupp",cmd)) {
+   kwrd=103;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("yr",cmd)) pcm->tlsupp = 1;
+    if (cmpwrd("year",cmd)) pcm->tlsupp = 1;
+    if (cmpwrd("mo",cmd)) pcm->tlsupp = 2;
+    if (cmpwrd("month",cmd)) pcm->tlsupp = 2;
+    return(0);
+  }
+  else if (cmpwrd("baropts",cmd)) {
+    kwrd=82;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("outline",cmd)) pcm->barolin = 1;
+    if (cmpwrd("filled",cmd)) pcm->barolin = 0;
+    return(0);
+  }
+  else if (cmpwrd("barbase",cmd)) {
+    kwrd = 47;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("bottom",cmd)) {
+      pcm->barflg = 0;
+      return (0);
+    }
+    if (cmpwrd("top",cmd)) {
+      pcm->barflg = -1;
+      return (0);
+    }
+    if (getdbl(cmd,&pcm->barbase) == NULL) goto err;
+    pcm->barflg = 1;
+  }
+  else if (cmpwrd("mdlopts",cmd)) {
+    kwrd = 69;
+    while ( (cmd = nxtwrd (cmd)) != NULL) {
+      i1 = 0;
+      if (cmpwrd("noblank",cmd)) {pcm->mdlblnk = 0; i1 = 1;}
+      if (cmpwrd("blank",cmd)) {pcm->mdlblnk = 1; i1 = 1;}
+      if (cmpwrd("dig3",cmd)) {pcm->mdldig3 = 1; i1 = 1;}
+      if (cmpwrd("nodig3",cmd)) {pcm->mdldig3 = 0; i1 = 1;}
+      if (i1==0) goto err;
+    }
+  }
+  else if (cmpwrd("bargap",cmd)) {
+    kwrd = 48;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if (itt<0 || itt>100) {
+      gaprnt(0,"SET BARGAP Error: gap must be 0 to 99\n");
+      return(1);
+    }
+    pcm->bargap = itt;
+  }
+  else if (cmpwrd("font",cmd)) {
+    kwrd = 85;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if (itt<0 || itt>9) {
+      gaprnt(0,"SET FONT Error: font must be 0 to 9\n");
+      return(1);
+    }
+    gxchdf(itt);
+  }
+  else if (cmpwrd("clip",cmd)) {
+    kwrd = 66;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&xlo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&xhi) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&ylo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&yhi) == NULL ) goto err;
+    if (xlo<0.0 || ylo<0.0) goto err;
+    if (xhi>pcm->pxsize || yhi>pcm->pysize) goto err;
+    if (yhi<=ylo || xhi<=xlo) goto err;
+    gxclip(xlo,xhi,ylo,yhi);
+  }
+  else if (cmpwrd("vpage",cmd)) {
+    kwrd = 39;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) {
+      pcm->xsiz = pcm->pxsize;
+      pcm->ysiz = pcm->pysize;
+      gxvpag (pcm->xsiz, pcm->ysiz, 0.0, pcm->xsiz, 0.0, pcm->ysiz);
+      gacln(pcm,1);
+      return (0);
+    }
+    if (getdbl(cmd,&xlo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&xhi) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&ylo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&yhi) == NULL ) goto err;
+    if (xlo<0.0 || ylo<0.0 || xhi>pcm->pxsize || yhi>pcm->pysize) {
+      gaprnt (0,"SET Error: vpage values beyond real page limits\n");
+      return(1);
+    }
+    if (yhi<=ylo || xhi<=xlo) goto err;
+    if ((yhi-ylo)/(xhi-xlo) > pcm->pysize/pcm->pxsize) {
+      pcm->ysiz = pcm->pysize;
+      pcm->xsiz = pcm->pysize * (xhi-xlo)/(yhi-ylo);
+    } else {
+      pcm->xsiz = pcm->pxsize;
+      pcm->ysiz = pcm->pxsize * (yhi-ylo)/(xhi-xlo);
+    }
+    gxvpag (pcm->xsiz, pcm->ysiz, xlo, xhi, ylo, yhi);
+    snprintf(pout,255,"Virtual page size = %g %g \n",pcm->xsiz,pcm->ysiz);
+    gaprnt (2,pout);
+    gacln(pcm,1);
+  }
+  else if (cmpwrd("mpt",cmd)) {
+    kwrd = 92;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("*",cmd))  itt = -999;
+    else {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      if (itt < 0) itt = 0;
+      if (itt>255) itt = 255;
+    }
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    green = -999;
+    blue = -999;
+    if (cmpwrd("off",cmd))  red = -9;
+    else {
+      if (intprs(cmd,&red) == NULL ) goto err;
+      if (red < -1) red = -1;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&green) == NULL ) goto err;
+        if (green < 1) green = 1;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (intprs(cmd,&blue) == NULL ) goto err;
+          if (blue < 1) blue = 1;
+        }
+      }
+    }
+    if (itt == -999) {
+      itt1 = 0; itt2 = 256;
+    } else {
+      itt1 = itt; itt2 = itt+1;
+    }
+    for (i=itt1; i<itt2; i++) {
+      pcm->mpcols[i] = red;
+      if (green != -999) pcm->mpstls[i] = green;
+      if (blue != -999) pcm->mpthks[i] = blue;
+    }
+  }
+  else if (cmpwrd("rgb",cmd)) {
+    kwrd = 44;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&red) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&green) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&blue) == NULL ) goto err;
+    if (itt<16 || itt>255 || 
+	red<0 || red>255 ||  
+        green<0 || green>255 || 
+	blue<0 || blue>255) {
+      gaprnt (0,"SET RGB Error:  Invalid color number or rgb value\n");
+      gaprnt (0,"  Color number must be 16-255, rgb value 0-255\n");
+      return(1);
+    }
+    if (!gxacol (itt,red,green,blue) ) {
+      snprintf(pout,255,"Color R:%i G:%i B:%i Unavailable: closest color assigned\n",red,green,blue);
+      gaprnt (2,pout);
+    } 
+  }
+  else if (cmpwrd("stat",cmd)) {
+    kwrd = 102;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->statflg = 0;
+    else if (cmpwrd("on",cmd)) pcm->statflg = 1;
+    else goto err;
+  }
+  else if (cmpwrd("arrlab",cmd)) {
+    kwrd = 91;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->arlflg = 0;
+    else if (cmpwrd("on",cmd)) pcm->arlflg = 1;
+    else goto err;
+  }
+  else if (cmpwrd("parea",cmd)) {
+    kwrd = 40;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) {
+      pcm->paflg = 0;
+      return (0);
+    }
+    if (getdbl(cmd,&xlo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&xhi) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&ylo) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&yhi) == NULL ) goto err;
+    if (xlo<0.0 || ylo<0.0 || xhi>pcm->xsiz || yhi>pcm->ysiz) {
+      gaprnt (0,"SET Error: parea values beyond page limits\n");
+      return(1);
+    }
+    if (yhi<=ylo || xhi<=xlo) goto err;
+    pcm->pxmin = xlo;
+    pcm->pxmax = xhi;
+    pcm->pymin = ylo;
+    pcm->pymax = yhi;
+    pcm->paflg = 1;
+  }
+  else if (cmpwrd("arrowhead",cmd)) {
+    kwrd = 68;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->ahdsiz)) == NULL ) goto err;
+    snprintf(pout,255,"Arrowhead = %g \n",pcm->ahdsiz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("cint",cmd)) {
+    kwrd = 8;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL ) goto err;
+    if (val1<=0) {
+      gaprnt (0,"SET Error: cint must be greater than 0.0\n");
+    }
+    else {
+      pcm->cint = val1;
+      snprintf(pout,255,"cint = %g \n",pcm->cint);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("xlint",cmd)) {
+    kwrd = 77;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->xlint)) == NULL ) goto err;
+    snprintf(pout,255,"xlint = %g \n",pcm->xlint);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("ylint",cmd)) {
+    kwrd = 78;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->ylint)) == NULL ) goto err;
+    snprintf(pout,255,"ylint = %g \n",pcm->ylint);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("xsize",cmd)) {
+    kwrd = 35;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&xx) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&yy) == NULL ) goto err;
+    gxdxsz(xx,yy);
+    gxfrme (9);
+  }
+  else if (cmpwrd("mpvals",cmd)) {
+    kwrd = 37;
+    i1 = 0;
+    if ((ch = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",ch)) {
+      pcm->mpflg = 0;
+      gaprnt (2,"mpvals have been turned off\n");
+    } else {
+      while ((cmd = nxtwrd (cmd)) != NULL) {
+        if (getdbl(cmd,&(pcm->mpvals[i1])) == NULL ) goto err;
+        i1++;
+        if (i1>9) goto err;
+      }
+      pcm->mpflg = i1;
+      gaprnt (2,"mpvals have been set\n");
+    }
+  }
+  else if (cmpwrd("fgvals",cmd)) {
+    kwrd = 45;
+    i1 = 0;
+    while ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&(pcm->fgvals[i1])) == NULL ) goto err;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (intprs(cmd,&(pcm->fgcols[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>48) goto err;
+    }
+    pcm->fgcnt = i1;
+    gaprnt (2,"fgvals set\n");
+  }
+  else if (cmpwrd("clevs",cmd)) {
+    kwrd = 29;
+    i1 = 0;
+    while ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&(pcm->clevs[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>254) goto err; 
+    }
+    pcm->cflag = i1;
+    snprintf(pout,255,"Number of clevs = %i \n",i1);
+    gaprnt (2,pout);
+    for (i=1; i<pcm->cflag; i++) {
+      if (pcm->clevs[i] <= pcm->clevs[i-1]) {
+	gaprnt(1,"Warning: Contour levels are not strictly increasing\n");
+	gaprnt(1,"         This may lead to errors or undesired results\n");
+      }
+    }
+  }
+  else if (cmpwrd("xlevs",cmd)) {
+    kwrd = 75;
+    i1 = 0;
+    while ( (cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&(pcm->xlevs[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>49) goto err;
+    }
+    pcm->xlflg = i1;
+    snprintf(pout,255,"Number of xlevs = %i \n",i1);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("ylevs",cmd)) {
+    kwrd = 76;
+    i1 = 0;
+    while ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&(pcm->ylevs[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>49) goto err;
+    }
+    pcm->ylflg = i1;
+    snprintf(pout,255,"Number of ylevs = %i \n",i1);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("rbcols",cmd)) {
+    kwrd = 59;
+    i1 = 0;
+    while ((cmd = nxtwrd (cmd)) != NULL) {
+      if (i1==0 && cmpwrd("auto",cmd)) break;
+      if (intprs(cmd,&(pcm->rbcols[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>255) goto err; 
+    }
+    pcm->rbflg = i1;
+    if (i1==0) gaprnt(2,"Rainbow colors set to auto\n");
+    else {
+      snprintf(pout,255,"Number of rainbow colors = %i\n",i1);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("dropmenu",cmd)) {
+    kwrd = 97;
+    i1 = 0;
+    while ( (cmd = nxtwrd (cmd)) != NULL) {
+      if (i1>14) goto drerr;
+      if (intprs(cmd,&(pcm->drvals[i1])) == NULL ) goto drerr;
+      i1++;
+    }
+    if (i1 == 0) goto drerr;
+  }
+  else if (cmpwrd("ccols",cmd)) {
+    kwrd = 36;
+    i1 = 0;
+    while ( (cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&(pcm->ccols[i1])) == NULL ) goto err;
+      i1++;
+      if (i1>255) goto err; 
+    }
+    pcm->ccflg = i1;
+    snprintf(pout,255,"Number of ccols = %i\n",i1);
+    gaprnt (2,pout);
+    if (pcm->cflag==0) {
+      gaprnt (2,"ccols won't take effect unless clevs are set.\n");
+    }
+  }
+  else if (cmpwrd("cmin",cmd)) {
+    kwrd = 25;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->cmin)) == NULL ) goto err;
+    snprintf(pout,255,"cmin = %g \n",pcm->cmin);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("cmax",cmd)) {
+    kwrd = 26;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->cmax)) == NULL ) goto err;
+    snprintf(pout,255,"cmax = %g \n",pcm->cmax);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("cmark",cmd)) {
+    kwrd = 18;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&(pcm->cmark)) == NULL ) goto err;
+    snprintf(pout,255,"cmark = %i \n",pcm->cmark);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("mproj",cmd)) {
+    kwrd = 33;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->mproj = 0;
+    else if (cmpwrd("scaled",cmd))       pcm->mproj = 1;
+    else if (cmpwrd("latlon",cmd))       pcm->mproj = 2;
+    else if (cmpwrd("nps",cmd))          pcm->mproj = 3;
+    else if (cmpwrd("sps",cmd))          pcm->mproj = 4;
+    else if (cmpwrd("robinson",cmd))     pcm->mproj = 5;
+    else if (cmpwrd("mollweide",cmd))    pcm->mproj = 6;
+    else if (cmpwrd("orthogr",cmd))      pcm->mproj = 7;
+    else if (cmpwrd("orthographic",cmd)) pcm->mproj = 7;
+    else if (cmpwrd("ortho",cmd))        pcm->mproj = 7;
+    else if (cmpwrd("lambert",cmd))      pcm->mproj = 13;
+    else goto err;
+  }
+  else if (cmpwrd("xyrev",cmd)) {
+    kwrd = 53;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->rotate = 0;
+    else if (cmpwrd("on",cmd)) pcm->rotate = 1;
+    else goto err;
+  }
+  else if (cmpwrd("xflip",cmd)) {
+    kwrd = 54;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->xflip = 0;
+    else if (cmpwrd("on",cmd)) pcm->xflip = 1;
+    else goto err;
+ }
+  else if (cmpwrd("yflip",cmd)) {
+    kwrd = 55;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->yflip = 0;
+    else if (cmpwrd("on",cmd)) pcm->yflip = 1;
+    else goto err;
+  }
+  else if (cmpwrd("writegds",cmd)) {
+    wgds = pcm->wgds;
+    kwrd = 109;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (*cmd=='-') {
+      itt = 0;
+      while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+      sz = itt+2;
+      ch = (char *)galloc(sz,"writegds");
+      if (ch==NULL) {
+        gaprnt (0,"Memory allocation Error\n");
+        goto err;
+      }
+      i2 = cmd - cmd1;
+      for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+      *(ch+i1) = '\0';
+      if (wgds->opts) gree(wgds->opts,"f223");
+      wgds->opts = ch;
+    }
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    itt = 0;
+    while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+    sz = itt+2;
+    ch = (char *)galloc(sz,"writegds2");
+    if (ch==NULL) {
+      gaprnt (0,"Memory allocation Error\n");
+      goto err;
+    }
+    i2 = cmd - cmd1;
+    for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+    *(ch+i1) = '\0';
+    if (wgds->fname) gree(wgds->fname,"f224");
+    wgds->fname = ch;
+    if (wgds->opts) {
+      snprintf(pout,255,"WRITEGDS file name = %s  Opts = %s\n",ch,wgds->opts);
+    } else {
+      snprintf(pout,255,"WRITEGDS file name = %s\n",ch);
+    }
+    gaprnt (2,pout);
+  }
+
+  else if (cmpwrd("shp",cmd)) {
+    kwrd = 121;
+#if USESHP==1
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    /* parse arguments to 'set shp' command */
+    while (cmpwrd("-pt",cmd) || cmpwrd("-point",cmd) || 
+	   cmpwrd("-ln",cmd) || cmpwrd("-line",cmd)  || 
+           cmpwrd("-poly",cmd) || cmpwrd("-fmt",cmd)) {
+      if (cmpwrd("-pt",cmd) || cmpwrd("-point",cmd)) pcm->shptype = 1;
+      if (cmpwrd("-ln",cmd) || cmpwrd("-line",cmd))  pcm->shptype = 2; 
+      if (cmpwrd("-poly",cmd)) pcm->shptype = 3; 
+      if (cmpwrd("-fmt",cmd)) {
+	if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+	if (intprs(cmd,&itt) == NULL ) goto err;
+	pcm->dblen = itt;
+	if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+	if (intprs(cmd,&itt) == NULL ) goto err;
+	pcm->dbprec = itt;
+      }
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    }
+    /* Parse the shapefile output filename root */
+    itt = 0;
+    while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+    sz = itt+1;
+    ch = (char *)galloc(sz,"shpname");
+    if (ch==NULL) {
+      gaprnt (0,"Memory allocation error for shapefile name\n");
+      goto err;
+    }
+
+    i2 = cmd - cmd1;
+    for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+    *(ch+itt) ='\0';
+
+    /* release previously set filenames for shapefile output */
+    if (pcm->shpfname) gree(pcm->shpfname,"f225e");
+    pcm->shpfname = ch;
+
+    snprintf(pout,255,"Shapefile output file name root: %s\n",pcm->shpfname);
+    gaprnt (2,pout);
+    if (pcm->shptype==1) gaprnt(2,"Shapefile output type: point\n");
+    if (pcm->shptype==2) gaprnt(2,"Shapefile output type: line\n");
+    if (pcm->shptype==3) gaprnt(2,"Shapefile output type: polygon\n");
+    snprintf(pout,255,"Shapefile format string is \%%%d.%df\n",pcm->dblen,pcm->dbprec);
+    gaprnt(2,pout);
+#else
+    gaprnt(0,"Error: This version of GrADS does not support shapefile output\n");
+    return (1);
+#endif
+  }
+
+  else if (cmpwrd("kml",cmd)) {
+    kwrd = 116;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    pcm->kmlflg = 1;                               /* set default value to image output */
+    while (cmpwrd("-img",cmd) || cmpwrd("-image",cmd) || 
+	   cmpwrd("-ln",cmd) || cmpwrd("-line",cmd) || 
+	   cmpwrd("-poly",cmd)) {
+      if (cmpwrd("-img",cmd) || cmpwrd("-image",cmd)) pcm->kmlflg = 1;     /* image output */
+      if (cmpwrd("-ln",cmd) || cmpwrd("-line",cmd))   pcm->kmlflg = 2;     /* contour output */
+      if (cmpwrd("-poly",cmd)) pcm->kmlflg = 3;     /* polygon output */
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    }
+    /* make sure TIFF output is enabled */
+#if GEOTIFF!=1
+    if (pcm->kmlflg==1) {
+      gaprnt(0,"Error: Creating TIFF images for KML output is not supported in this build.\n");
+      gaprnt(0,"  Try the \'-line\' option with \'set kml\' to output contour lines in KML format instead\n");  
+      return(1);
+    }
+#endif
+    /* Parse the KML output filename root */
+
+    /* get the length of the user-supplied filename */
+    itt = 0;
+    while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+    /* allocate memory for KML filename */
+    sz = itt+6;
+    ch = NULL;
+    ch = (char *)galloc(sz,"kmlname");
+    if (ch==NULL) {
+      gaprnt (0,"Memory allocation error for KML file name\n"); goto err;
+    }
+    /* copy the user-supplied filename to ch */
+    i2 = cmd - cmd1;
+    for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+    /* check if user already put ".kml" onto the filename */
+    if (*(ch+itt-4)=='.' &&  *(ch+itt-3)=='k' &&  *(ch+itt-2)=='m' &&  *(ch+itt-1)=='l') {
+      *(ch+itt)='\0';      /* make sure it is null-terminated */
+      itt = itt-4;         /* shorten the length in case we need the file root for TIFF image */
+    }
+    else {
+      /* add ".kml" to the end of the filename */
+      *(ch+i1+0)='.';
+      *(ch+i1+1)='k';
+      *(ch+i1+2)='m';
+      *(ch+i1+3)='l';
+      *(ch+i1+4)='\0';           
+    }
+    if (pcm->kmlflg==1) {
+      /* A second file will be created by GrADS containing the TIFF image */
+      ch2 = (char *)galloc(sz,"tifname");
+      if (ch2==NULL) {
+	gaprnt (0,"Memory allocation error for KML image file name\n");	goto err;
+      }
+      /* copy the user-supplied filename root to ch2 and add ".tif" */
+      for (i1=0; i1<itt; i1++) *(ch2+i1) = *(com+i1+i2);
+      *(ch2+i1+0) ='.';
+      *(ch2+i1+1) ='t';
+      *(ch2+i1+2) ='i';
+      *(ch2+i1+3) ='f';
+      *(ch2+i1+4) ='\0';           
+    }
+    /* release previously set filenames for KML output */
+    if (pcm->kmlname) gree(pcm->kmlname,"f225d");
+    pcm->kmlname = ch;
+    if (pcm->kmlflg==1) {
+      if (pcm->tifname) gree(pcm->tifname,"f225c");
+      pcm->tifname = ch2;
+      gaprnt (2,"KML output file names: \n");
+      snprintf(pout,255,"%s (TIFF image) \n",pcm->tifname);
+      gaprnt (2,pout);
+      snprintf(pout,255,"%s (KML text file) \n",pcm->kmlname);
+      gaprnt (2,pout);
+      gaprnt (2,"KML output type: image\n");
+    }
+    else {
+      gaprnt(2,"KML output file name: \n");
+      snprintf(pout,255,"%s (KML text file)\n",pcm->kmlname);
+      gaprnt (2,pout);
+      if (pcm->kmlflg==2)
+	gaprnt (2,"KML output type: contour lines\n");
+      else
+	gaprnt (2,"KML output type: polygons\n");
+    }
+  }
+  else if (cmpwrd("geotiff",cmd)) {
+    kwrd = 115;
+#if GEOTIFF==1
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    pcm->gtifflg = 1;                             /* set default value to 4-byte depth */
+    while (cmpwrd("-dbl",cmd) || cmpwrd("-flt",cmd)) {
+      if (cmpwrd("-flt",cmd) ) pcm->gtifflg = 1;  /* 4-byte depth in GeoTIFF output file */
+      if (cmpwrd("-dbl",cmd) ) pcm->gtifflg = 2;  /* 8-byte depth in GeoTIFF output file */
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    }
+    /* parse the geotiff output filename root -- .tif will be added by GrADS */
+    /* get the length of the user-supplied filename */
+    itt = 0;
+    while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+    /* allocate memory for GeoTIFF filename */
+    sz = itt+6;
+    ch = (char *)galloc(sz,"gtifname");
+    if (ch==NULL) {
+      gaprnt (0,"Memory allocation error for GeoTIFF file name\n"); goto err;
+    }
+    /* copy the user-supplied filename to ch */
+    i2 = cmd - cmd1;
+    for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+    /* check if user already put ".tif" onto the filename */
+    if (*(ch+itt-4)=='.' &&  *(ch+itt-3)=='t' &&  *(ch+itt-2)=='i' &&  *(ch+itt-1)=='f') {
+      *(ch+itt)='\0';      /* make sure it is null-terminated */
+    }
+    else {
+      /* add ".tif" to the end of the filename */
+      *(ch+i1+0)='.';
+      *(ch+i1+1)='t';
+      *(ch+i1+2)='i';
+      *(ch+i1+3)='f';
+      *(ch+i1+4)='\0';           
+    }
+    /* reset geotiff filename */
+    if (pcm->gtifname) gree(pcm->gtifname,"f225b");
+    pcm->gtifname = ch;
+    snprintf(pout,255,"GeoTIFF file name = %s\n",pcm->gtifname);
+    gaprnt (2,pout);
+    if (pcm->gtifflg==1) gaprnt(2,"GeoTIFF format is float  \n");
+    if (pcm->gtifflg==2) gaprnt(2,"GeoTIFF format is double \n");
+#else
+    gaprnt(0,"Error: This version of GrADS does not support GeoTIFF output\n");
+    return (1);
+#endif
+  }
+
+  /* Following is for the so-called 'exact fwrite' to
+     workaround the bug with scaling for hires files */
+  else if (cmpwrd("fwex",cmd)) {
+    pcm->fwexflg = 1;
+  }
+  else if (cmpwrd("fwrite",cmd)) {
+    kwrd = 86;
+    if (pcm->ffile) {
+      gaprnt (0,"SET FWrite Error:  fwrite file is open\n");
+      gaprnt (0,"Use DISABLE FWRITE command to close file\n");
+    } else {
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      while ( cmpwrd("-be",cmd) || cmpwrd("-le",cmd) ||
+	      cmpwrd("-ap",cmd) || cmpwrd("-cl",cmd) ||
+              cmpwrd("-sq",cmd) || cmpwrd("-st",cmd) ||
+              cmpwrd("-ex",cmd) ) {
+        if (cmpwrd("-be",cmd) ) pcm->fwenflg = 1;
+        if (cmpwrd("-le",cmd) ) pcm->fwenflg = 0;
+        if (cmpwrd("-sq",cmd) ) pcm->fwsqflg = 1;
+        if (cmpwrd("-st",cmd) ) pcm->fwsqflg = 0;
+        if (cmpwrd("-ap",cmd) ) pcm->fwappend = 1;
+        if (cmpwrd("-cl",cmd) ) pcm->fwappend = 0;
+        if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      }
+      itt = 0;
+      while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+      sz = itt+2;
+      ch = (char *)galloc(sz,"fwrite1");
+      if (ch==NULL) {
+        gaprnt (0,"Memory allocation Error\n");
+        goto err;
+      }
+      i2 = cmd - cmd1;
+      for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+      *(ch+i1) = '\0';
+      if (pcm->fwname) gree(pcm->fwname,"f225");
+      pcm->fwname = ch;
+      snprintf(pout,255,"FWrite file name = %s\n",ch);
+      gaprnt (2,pout);
+      if (pcm->fwenflg == 0) {
+        gaprnt (2,"FWwrite byte order is little_endian; format is ");
+      } else {
+        gaprnt (2,"FWwrite byte order is big_endian; format is ");
+      }
+      if (pcm->fwsqflg == 1) gaprnt (2,"sequential\n");
+      else gaprnt (2,"stream\n");
+      if (pcm->fwappend) {
+	gaprnt (2,"Fwrite appending to an existing file\n");
+      } else {
+	gaprnt (2,"Fwrite replacing an existing file\n");
+      }
+    }
+  }
+  else if (cmpwrd("sdfwrite",cmd)) {
+    kwrd = 113;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;  
+    /* parse any arguments to 'set sdfwrite' command */
+    pcm->sdfwpad = 0;  
+    while (cmpwrd("-4d",cmd)  || cmpwrd("-5d",cmd) || 
+	   cmpwrd("-flt",cmd) || cmpwrd("-dbl",cmd) ||
+	   cmpwrd("-nc3",cmd) || cmpwrd("-nc4",cmd) ||
+	   cmpwrd("-zip",cmd) || cmpwrd("-chunk",cmd)) {
+      if (cmpwrd("-4d",cmd))    pcm->sdfwpad = 1;   
+      if (cmpwrd("-5d",cmd))    pcm->sdfwpad = 2;
+      if (cmpwrd("-dbl",cmd))   pcm->sdfprec = 8;
+      if (cmpwrd("-flt",cmd))   pcm->sdfprec = 4;
+      if (cmpwrd("-nc3",cmd))   pcm->sdfwtype = 1;
+      if (cmpwrd("-nc4",cmd))   pcm->sdfwtype = 2;
+      if (cmpwrd("-zip",cmd))   pcm->sdfzip = 1;
+      if (cmpwrd("-chunk",cmd)) pcm->sdfchunk = 1;
+
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    }
+    /* parse the sdfwrite output filename */
+    itt = 0;
+    while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+    sz = itt+2;
+    ch = (char *)galloc(sz,"sdfwname");
+    if (ch==NULL) {
+      gaprnt (0,"Memory allocation error for sdfwrite file name\n");
+      goto err;
+    }
+    i2 = cmd - cmd1;
+    for (i1=0; i1<itt; i1++) *(ch+i1) = *(com+i1+i2);
+    *(ch+i1) = '\0';
+    /* release previously set sdfwrite filename */
+    if (pcm->sdfwname) gree(pcm->sdfwname,"f225a");
+    pcm->sdfwname = ch;
+    snprintf(pout,255,"SDFWrite file name = %s\n",ch);
+    gaprnt (2,pout);
+    gaprnt (2,"SDFWrite will replace an existing file\n");
+    if (pcm->sdfwpad==0) {
+      gaprnt (2,"SDFwrite file will have same number of dimensions as defined variable\n");
+    }
+    if (pcm->sdfwpad==1) {
+      gaprnt (2,"SDFwrite file will have at least 4 dimensions\n");
+    }
+    if (pcm->sdfwpad==2) {
+      gaprnt (2,"SDFwrite file will have 5 dimensions\n");
+    }
+#if HAVENETCDF4 != 1
+    /* reset flags if we dont' have netcdf-4 */
+    if (pcm->sdfwtype == 2) {
+      gaprnt(2,"Warning: This build is not enabled to write netCDF-4 format\n");
+      gaprnt(2,"         sdfwrite output will be netCDF classic format instead\n");
+      pcm->sdfwtype = 1;
+      if (pcm->sdfchunk==1) {
+	gaprnt(2,"         without chunking ");
+	pcm->sdfchunk = 0;
+      }
+      if (pcm->sdfzip==1) {
+	gaprnt(2,"or compression");
+	pcm->sdfzip = 0;
+      }
+      gaprnt(2,"\n");
+    }
+#endif
+    /* If -zip, make sure we have -nc4 and -chunk */
+    if (pcm->sdfzip) {
+      pcm->sdfwtype = 2;
+      pcm->sdfchunk = 1;
+    }
+
+  }
+  else if (cmpwrd("sdfattr",cmd)) {
+    kwrd = 114;
+    com=nxtwrd(com); /* advance past the 'sdfattr' in the mixed case version */
+    if ((com = nxtwrd (com)) == NULL) goto err;
+    /* parse the sdf attribute */
+    newattr = parseattr(com);
+    if (newattr==NULL) goto err;
+    /* hang the new attribute off the gacmn structure */
+    if (pcm->attr) {
+      attr=pcm->attr;
+      while (attr->next) attr = attr->next;      /* advance to end of chain */
+      attr->next = newattr;                      /* add new link */
+    }
+    else {
+      pcm->attr = newattr;                       /* set first link */
+    } 
+  }
+#if USESHP==1
+  else if (cmpwrd("shpattr",cmd)) {
+    kwrd = 122;
+    /* advance past the 'set shpattr' in the mixed case version */
+    com=nxtwrd(com); 
+    if ((com = nxtwrd (com)) == NULL) goto err;
+    /* parse the attribute (data base field) */
+    newfld = parsedbfld(com);
+    if (newfld==NULL) goto err;
+    /* hang the new field off the gacmn structure */
+    if (pcm->dbfld) {
+      fld=pcm->dbfld;
+      while (fld->next) fld = fld->next;      /* advance to end of chain */
+      fld->next = newfld;                     /* add new link */
+    }
+    else {
+      pcm->dbfld = newfld;                       /* set first link */
+    } 
+  }
+#endif
+#if HAVENETCDF4 == 1
+  else if (cmpwrd("chunksize",cmd)) {
+    kwrd = 118;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL) goto err;
+    pcm->xchunk = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL) goto err;
+      pcm->ychunk = itt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+	if (intprs(cmd,&itt) == NULL) goto err;
+	pcm->zchunk = itt;
+	if ((cmd = nxtwrd (cmd)) != NULL) {
+	  if (intprs(cmd,&itt) == NULL) goto err;
+	  pcm->tchunk = itt;
+	  if ((cmd = nxtwrd (cmd)) != NULL) {
+	    if (intprs(cmd,&itt) == NULL) goto err;
+	    pcm->echunk = itt;
+	  }
+	}
+      }
+    }
+  }
+#endif
+  else if (cmpwrd("cachesf",cmd)) {
+    kwrd = 119;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL) goto err;
+    pcm->cachesf = val1;
+    snprintf(pout,255,"Global cache scale factor is %g\n",pcm->cachesf);
+    gaprnt(2,pout);
+  }
+  else if (cmpwrd("imprun",cmd)) {
+    kwrd = 62;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) {
+      if (pcm->impflg) gree(pcm->impnam,"f226");
+      pcm->impflg = 0;
+      gaprnt (2,"IMPrun is off\n");
+    } else {
+      itt = 0;
+      while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+      sz = itt+6;
+      ch = (char *)galloc(sz,"imprun");
+      if (ch==NULL) {
+        gaprnt (0,"Memory allocation Error\n");
+        goto err;
+      }
+      for (i1=0; i1<itt; i1++) *(ch+i1+4) = *(cmd+i1);
+      *(ch+i1+4) = '\0';
+      *ch='r'; *(ch+1)='u'; *(ch+2)='n'; *(ch+3)=' ';
+      if (pcm->impflg) gree(pcm->impnam,"f227");
+      pcm->impflg = 1;
+      pcm->impnam = ch;
+      snprintf(pout,255,"Imprun file name = %s\n",ch);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("log1d",cmd)) {
+    kwrd = 123;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("loglog",cmd)) pcm->log1d = 3;
+    else if (cmpwrd("logh",cmd)) pcm->log1d = 1;
+    else if (cmpwrd("logv",cmd)) pcm->log1d = 2;
+    else if (cmpwrd("off",cmd)) pcm->log1d = 0;
+    else goto err;
+  }
+  else if (cmpwrd("zlog",cmd)) {
+    kwrd = 63;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->zlog = 1;
+    else if (cmpwrd("off",cmd)) pcm->zlog = 0;
+    else goto err;
+  }
+  else if (cmpwrd("coslat",cmd)) {
+    kwrd = 110;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->coslat = 1;
+    else if (cmpwrd("off",cmd)) pcm->coslat = 0;
+    else goto err;
+  }
+  else if (cmpwrd("missconn",cmd)) {
+    kwrd = 61;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->miconn = 1;
+    else if (cmpwrd("off",cmd)) pcm->miconn = 0;
+    else goto err;
+  }
+  else if (cmpwrd("mpdraw",cmd)) {
+    kwrd = 50;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->mpdraw = 1;
+    else if (cmpwrd("off",cmd)) pcm->mpdraw = 0;
+    else goto err;
+  }
+  else if (cmpwrd("dbuff",cmd)) {
+    kwrd = 52;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) {
+      pcm->dbflg = 1;
+      gxfrme(2);
+      gacln(pcm,1);
+    }
+    else if (cmpwrd("off",cmd)) {
+      if (pcm->dbflg) {
+        pcm->dbflg = 0;
+        gxfrme(1);
+        gacln (pcm,1);
+      }
+    }
+    else goto err;
+  }
+  else if (cmpwrd("poli",cmd)) {
+    kwrd = 51;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) {
+      if (pcm->mpcols[1] == -9) pcm->mpcols[1] = -1;
+      if (pcm->mpcols[2] == -9) pcm->mpcols[2] = -1;
+    }
+    else if (cmpwrd("off",cmd)) {
+      pcm->mpcols[1] = -9;
+      pcm->mpcols[2] = -9;
+    }
+    else goto err;
+  }
+  else if (cmpwrd("mpdset",cmd)) {
+    kwrd = 38;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    for (xx=0; xx<8; xx++) {
+      if (pcm->mpdset[xx]) gree(pcm->mpdset[xx],"f228");
+      pcm->mpdset[xx] = NULL;
+    }
+    xx = 0;
+    itt = 0;
+    while (xx<8) {
+      itt2 = itt;
+      while (*(cmd+itt)!=' '&&*(cmd+itt)!='\n'&&*(cmd+itt)!='\0') itt++;
+      sz = itt+2-itt2;
+      ch = (char *)galloc(sz,"setmpdset");
+      if (ch==NULL) {
+        gaprnt (0,"Memory allocation Error\n");
+        goto err;
+      }
+      for (i1=itt2; i1<itt; i1++) *(ch+i1-itt2) = *(cmd+i1);
+      *(ch+i1-itt2) = '\0';
+      pcm->mpdset[xx] = ch;
+      snprintf(pout,255,"MPDSET file name = %s\n",ch);
+      gaprnt (2,pout);
+      while (*(cmd+itt)==' ') itt++;
+      if (*(cmd+itt)=='\n'||*(cmd+itt)=='\0') break;
+      xx++;
+    }
+  }
+  else if (cmpwrd("rbrange",cmd)) {
+    kwrd = 60;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val2) == NULL ) goto err;
+    if (val1>=val2) goto err;
+    pcm->rainmn = val1;
+    pcm->rainmx = val2;
+  }
+  else if (cmpwrd("black",cmd)) {
+    kwrd = 22;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("off",cmd)) pcm->blkflg = 0;
+    else {
+      if (getdbl(cmd,&(pcm->blkmin)) == NULL ) goto err;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (getdbl(cmd,&(pcm->blkmax)) == NULL ) goto err;
+      pcm->blkflg = 1;
+    }
+  }
+  else if (cmpwrd("display",cmd)) {
+    kwrd = 57;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("color",cmd)) pcm->grflg=0;
+    else if (cmpwrd("grey",cmd)) pcm->grflg=1;
+    else if (cmpwrd("greyscale",cmd)) pcm->grflg=1;
+    else goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (cmpwrd("white",cmd)) pcm->devbck = 1;
+      else if (cmpwrd("black",cmd)) pcm->devbck = 0;
+      else goto err;
+    }
+    gxdbck(pcm->devbck);
+    gxgrey(pcm->grflg);
+  }
+  else if (cmpwrd("gxout",cmd)) {
+    kwrd = 21;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    pcm->gout0 = 9;
+    if      (cmpwrd("contour",cmd))  pcm->gout2a = 1;
+    else if (cmpwrd("shaded",cmd))   pcm->gout2a = 2;
+    else if (cmpwrd("shade1",cmd))   pcm->gout2a = 2;
+    else if (cmpwrd("shade2",cmd))   pcm->gout2a = 16;
+    else if (cmpwrd("shade2b",cmd))  pcm->gout2a = 17;
+    else if (cmpwrd("grid",cmd))    {pcm->gout2a = 3; pcm->gout2b = 3;}
+    else if (cmpwrd("vector",cmd))  {pcm->gout2b = 4; pcm->goutstn = 6; pcm->gout1a = 1;}
+    else if (cmpwrd("scatter",cmd))  pcm->gout2b = 5;
+    else if (cmpwrd("fgrid",cmd))    pcm->gout2a = 6;
+    else if (cmpwrd("fwrite",cmd))   pcm->gout2a = 7;
+    else if (cmpwrd("stream",cmd))   pcm->gout2b = 8;
+    else if (cmpwrd("grfill",cmd))   pcm->gout2a = 10;
+    else if (cmpwrd("geotiff",cmd)) {
+#if GEOTIFF==1
+      pcm->gout2a = 12; 
+#else
+      gaprnt(0,"Creating GeoTIFF files is not supported in this build\n");
+      goto err;
+#endif
+    }
+    else if (cmpwrd("kml",cmd))      pcm->gout2a = 13; 
+    else if (cmpwrd("imap",cmd))     pcm->gout2a = 14; 
+    else if (cmpwrd("shp",cmd)) {
+#if USESHP==1
+      pcm->gout2a = 15; pcm->goutstn = 9;}
+#else
+      gaprnt(0,"Creating shapefiles is not supported in this build\n");
+      goto err;}
+#endif
+    else if (cmpwrd("value",cmd))    pcm->goutstn = 1;
+    else if (cmpwrd("barb",cmd))    {pcm->goutstn = 2; pcm->gout2b = 9; pcm->gout1a = 2;}
+    else if (cmpwrd("findstn",cmd))  pcm->goutstn = 3;
+    else if (cmpwrd("model",cmd))    pcm->goutstn = 4;
+    else if (cmpwrd("wxsym",cmd))    pcm->goutstn = 5;
+    else if (cmpwrd("stnmark",cmd))  pcm->goutstn = 7;
+    else if (cmpwrd("stnwrt",cmd))   pcm->goutstn = 8;  /* undocumented */
+    else if (cmpwrd("line",cmd))    {pcm->gout1 = 1; pcm->tser = 0;}
+    else if (cmpwrd("bar",cmd))      pcm->gout1 = 2;
+    else if (cmpwrd("errbar",cmd))   pcm->gout1 = 3;
+    else if (cmpwrd("linefill",cmd)) pcm->gout1 = 4;
+    else if (cmpwrd("stat",cmd))     pcm->gout0 = 1;
+    else if (cmpwrd("print",cmd))    pcm->gout0 = 2;
+    else if (cmpwrd("writegds",cmd)) pcm->gout0 = 3;    /* only for internal use */
+    else if (cmpwrd("tserwx",cmd))   pcm->tser = 1;
+    else if (cmpwrd("tserbarb",cmd)) pcm->tser = 2;
+    else goto err;
+    if (pcm->gout0==9) pcm->gout0 = 0;
+  }
+  else if (cmpwrd("arrscl",cmd)) {
+    kwrd = 27;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->arrsiz)) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) {
+      pcm->arrmag = -999.0;
+    } else {
+      if (getdbl(cmd,&(pcm->arrmag)) == NULL ) goto err;
+    }
+    pcm->arrflg = 1;
+  }
+  else if (cmpwrd("xlabs",cmd)||cmpwrd("ylabs",cmd)) {
+    if (cmpwrd("xlabs",cmd)) {kwrd=94; strng=pcm->xlabs;}
+    if (cmpwrd("ylabs",cmd)) {kwrd=95; strng=pcm->ylabs;}
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    i1 = 0;
+    if (cmpwrd("off",cmd)) {
+      if (strng) gree(strng,"f229");
+      strng = NULL;
+    } else {
+      com = nxtwrd(com);
+      com = nxtwrd(com);
+      num = 0;
+      while(*(com+num)!='\0' && *(com+num)!='\n') num++;
+      if (strng) gree(strng,"f230");
+      sz = num+2;
+      strng = (char *)galloc(sz,"xlabs");
+      if (strng==NULL) {
+        gaprnt(0,"Memory Allocation Error: Set XLABS/YLABS\n");
+        goto err;
+      }
+      num = 0;
+      while(*(com+num)!='\0' && *(com+num)!='\n') {
+        *(strng+num) = *(com+num);
+        if (*(strng+num)=='|') {
+          *(strng+num) = '\0';
+          i1++;
+        }
+        num++;
+      }
+      *(strng+num) = '\0';
+      i1++;
+    }
+    if (kwrd==94) { pcm->xlabs=strng; pcm->ixlabs = i1; }
+    if (kwrd==95) { pcm->ylabs=strng; pcm->iylabs = i1; }
+  }
+  else if (cmpwrd("clab",cmd)||cmpwrd("xlab",cmd)||cmpwrd("ylab",cmd)) {
+    if (cmpwrd("clab",cmd)) {kwrd=32; strng=pcm->clstr; i1=pcm->clab;}
+    if (cmpwrd("xlab",cmd)) {kwrd=73; strng=pcm->xlstr; i1=pcm->xlab;}
+    if (cmpwrd("ylab",cmd)) {kwrd=74; strng=pcm->ylstr; i1=pcm->ylab;}
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) i1 = 1;
+    else if (cmpwrd("off",cmd)) i1 = 0;
+    else if (cmpwrd("forced",cmd)) i1 = 2;
+    else if (cmpwrd("masked",cmd)) i1 = 3;
+    else if (cmpwrd("auto",cmd)) {
+      if (strng) gree(strng,"f231");
+      strng = NULL;
+    }
+    else {
+      com = nxtwrd(com);
+      com = nxtwrd(com);
+      num = 0;
+      while(*(com+num)!='\0' && *(com+num)!='\n') num++;
+      if (strng) gree(strng,"f232");
+      sz = num+2;
+      strng = (char *)galloc(sz,"clab1");
+      if (strng==NULL) {
+        gaprnt(0,"Memory Allocation Error: Set ?LAB\n");
+        goto err;
+      }
+      num = 0;
+      while(*(com+num)!='\0' && *(com+num)!='\n') {
+        *(strng+num) = *(com+num);
+        num++;
+      }
+      *(strng+num) = '\0';
+      gaprnt (2,"Substitution string is: ");
+      gaprnt (2,strng);
+      gaprnt (2,"\n");
+    }
+    if (kwrd==32) {pcm->clstr=strng; pcm->clab=i1;}
+    if (kwrd==73) {pcm->xlstr=strng; pcm->xlab=i1;}
+    if (kwrd==74) {pcm->ylstr=strng; pcm->ylab=i1;}
+  }
+  else if (cmpwrd("prnopts",cmd)) {
+    kwrd = 106;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    com = nxtwrd(com);
+    com = nxtwrd(com);
+    num = 0;
+    while(*(com+num)!='\0' && *(com+num)!='\n' && *(com+num)!=' ') num++;
+    if (pcm->prstr) gree(pcm->prstr,"f233");
+    sz = num+2;
+    strng = (char *)galloc(sz,"prnopts");
+    if (strng==NULL) {
+      gaprnt(0,"Memory Allocation Error: Set PRNOPTS\n");
+      goto err;
+    }
+    num = 0;
+    while(*(com+num)!='\0' && *(com+num)!='\n' && *(com+num)!=' ') {
+      *(strng+num) = *(com+num);
+      num++;
+    }
+    *(strng+num) = '\0';
+    pcm->prstr = strng;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      pcm->prlnum = itt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&itt) == NULL ) goto err;
+        pcm->prbnum = itt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          pcm->prudef = 0;
+          if (*cmd=='u') pcm->prudef = 1;
+        }
+      }
+    }
+  }
+  else if (cmpwrd("frame",cmd)) {
+    kwrd = 65;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->frame = 1;
+    else if (cmpwrd("off",cmd)) pcm->frame = 0;
+    else if (cmpwrd("circle",cmd)) pcm->frame = 2;
+    else goto err;
+  }
+  else if (cmpwrd("grid",cmd)) {
+    kwrd = 17;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->grflag = 1;
+    else if (cmpwrd("off",cmd)) pcm->grflag = 0;
+    else if (cmpwrd("horizontal",cmd)) pcm->grflag = 2;
+    else if (cmpwrd("vertical",cmd)) pcm->grflag = 3;
+    else goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      else pcm->grstyl = itt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&itt) == NULL ) goto err;
+        else pcm->grcolr = itt;
+      }
+    }
+    if (pcm->grflag) {
+      snprintf(pout,255,"grid is on, style %i color %i \n",
+         pcm->grstyl, pcm->grcolr);
+      gaprnt (2,pout);
+    } else {
+      gaprnt (2,"grid is off\n");
+    }
+  }
+  else if (cmpwrd("clskip",cmd)) {
+    kwrd = 89;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if (itt<1) goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&val1) == NULL ) goto err;  
+      gxclmn(val1);
+    }
+    pcm->clskip = itt;
+  }
+  else if (cmpwrd("clopts",cmd)) {
+    kwrd = 72;
+    itt = pcm->clcol;
+    itt1 = pcm->clthck;
+    val1 = pcm->clsiz;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt1) == NULL ) goto xlerr;
+      else {
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (getdbl(cmd,&val1) == NULL ) goto xlerr;
+        }
+      }
+    }
+    pcm->clcol = itt;
+    pcm->clthck = itt1;
+    pcm->clsiz = val1;
+    snprintf(pout,255,"SET CLOPTS values:  Color = %i Thickness = %i", pcm->clcol, pcm->clthck);
+    gaprnt (2,pout);
+    snprintf(pout,255," Size = %g\n",pcm->clsiz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("shpopts",cmd)) {
+    kwrd=120;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->fillpoly = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ){
+        gaprnt(0,"SET SHPOPTS Error: Invalid mark type\n");
+      } else {
+        pcm->marktype = itt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (getdbl(cmd,&val1) == NULL ){
+            gaprnt(0,"SET SHPOPTS Error: Invalid mark size\n");
+          } else {
+            pcm->marksize = val1;
+          }
+        }
+      }
+    }
+    snprintf(pout,255,"SET SHPOPTS values:  polygon fill color = %i  ",pcm->fillpoly);
+    gaprnt (2,pout);
+    snprintf(pout,255,"mark type = %i  ",pcm->marktype);
+    gaprnt (2,pout);
+    snprintf(pout,255,"mark size = %g \n",pcm->marksize);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("wxopt",cmd)) {
+    kwrd = 93;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    else if (cmpwrd("wxsym",cmd)) pcm->wxopt = 1;
+    else if (cmpwrd("mark",cmd)) pcm->wxopt = 2;
+    else if (cmpwrd("char",cmd)) pcm->wxopt = 3;
+    else goto err;
+  }
+  else if (cmpwrd("wxcols",cmd)) {
+    kwrd = 84;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,itmp) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,itmp+1) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,itmp+2) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,itmp+3) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,itmp+4) == NULL ) goto err;
+    for (i1=0; i1<5; i1++) pcm->wxcols[i1] = itmp[i1];
+    gaprnt (2,"New WXCOLS have been set\n");
+  }
+  else if (cmpwrd("lfcols",cmd)) {
+    kwrd = 83;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt1) == NULL ) goto err;
+    pcm->lfc1 = itt;
+    pcm->lfc2 = itt1;
+    snprintf(pout,255,"LineFill Colors: Above = %i  Below = %i\n",
+      pcm->lfc1, pcm->lfc2);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("rband",cmd)) {
+    kwrd = 90;
+    itt = -1;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (intprs(cmd,&i1) == NULL ) goto rbberr;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (*cmd=='m' && *(cmd+1)=='b') {
+      cmd += 2;
+      if (intprs(cmd,&(itt)) == NULL ) goto rbberr;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+      if (itt>3) itt = 3;
+    }
+    if (cmpwrd("box",cmd)) i2 = 1;
+    else if (cmpwrd("line",cmd)) i2 = 2;
+    else goto rbberr;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (getdbl(cmd,&xlo) == NULL ) goto rbberr;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (getdbl(cmd,&ylo) == NULL ) goto rbberr;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (getdbl(cmd,&xhi) == NULL ) goto rbberr;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto rbberr;
+    if (getdbl(cmd,&yhi) == NULL ) goto rbberr;
+    gxdrbb (i1,i2,xlo,ylo,xhi,yhi,itt);
+  }
+  else if (cmpwrd("button",cmd)) {
+    kwrd = 80;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->btnfc = itt;
+    pcm->btnftc = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+     if (intprs(cmd,&itt) == NULL ) goto err;
+     pcm->btnbc = itt;
+     pcm->btnbtc = itt;
+     if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      pcm->btnoc = itt;
+      pcm->btnoc2 = itt;
+      pcm->btnotc = itt;
+      pcm->btnotc2 = itt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+       if (intprs(cmd,&itt) == NULL ) goto err;
+       pcm->btnoc2 = itt;
+       pcm->btnotc2 = itt;
+       if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&itt) == NULL ) goto err;
+        pcm->btnftc = itt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+         if (intprs(cmd,&itt) == NULL ) goto err;
+         pcm->btnbtc = itt;
+         if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (intprs(cmd,&itt) == NULL ) goto err;
+          pcm->btnotc = itt;
+          pcm->btnotc2 = itt;
+          if ((cmd = nxtwrd (cmd)) != NULL) {
+           if (intprs(cmd,&itt) == NULL ) goto err;
+           pcm->btnotc2 = itt;
+           if ((cmd = nxtwrd (cmd)) != NULL) {
+            if (intprs(cmd,&itt) == NULL ) goto err;
+            pcm->btnthk = itt;
+           }
+          }
+         }
+        }
+       }
+      }
+     }
+    }
+    snprintf(pout,255,"SET BUTTON values:  Fc, Bc, Oc, Oc2 = %i %i %i %i ",
+      pcm->btnfc,pcm->btnbc,pcm->btnoc,pcm->btnoc2);
+    gaprnt (2,pout);
+    snprintf(pout,255,"Toggle Fc, Bc, Oc, Oc2 = %i %i %i %i ",
+      pcm->btnftc,pcm->btnbtc,pcm->btnotc,pcm->btnotc2);
+    snprintf(pout,255,"Thick = %i\n",pcm->btnthk);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("dialog",cmd)) {
+    kwrd = 108;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->dlgpc = itt;    
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+     if (intprs(cmd,&itt) == NULL ) goto err;
+     pcm->dlgfc = itt;     
+     if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      pcm->dlgbc = itt;      
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+       if (intprs(cmd,&itt) == NULL ) goto err;
+       pcm->dlgoc = itt;       
+       if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&itt) == NULL ) goto err;
+        pcm->dlgth = itt;        
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+         if (cmpwrd("n",cmd)||cmpwrd("numeric",cmd)) pcm->dlgnu = 1;       
+        } else pcm->dlgnu = 0;
+       }
+      }
+     }
+    }
+    snprintf(pout,255,"SET DIALOG values:  Pc, Fc, Bc, Oc = %i %i %i %i ",
+      pcm->dlgpc,pcm->dlgfc,pcm->dlgbc,pcm->dlgoc);
+    gaprnt (2,pout);
+    if (pcm->dlgnu) {
+      snprintf(pout,255,"Thick = %i ",pcm->dlgth);
+      gaprnt (2,pout);
+      snprintf(pout,255,"Args = numeric\n ");
+      gaprnt (2,pout);
+    } else {
+      snprintf(pout,255,"Thick = %i\n",pcm->dlgth);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("xlpos",cmd)) {
+    kwrd = 87;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL ) goto xlerr2;
+    pcm->xlpos = val1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (cmpwrd("b",cmd)||cmpwrd("bottom",cmd)) pcm->xlside = 0;
+      if (cmpwrd("t",cmd)||cmpwrd("top",cmd)) pcm->xlside = 1;
+    }
+    if (pcm->xlside)
+      snprintf(pout,255,"SET XLPOS values:  Offset = %g  Side = Top\n",pcm->xlpos);
+    else
+      snprintf(pout,255,"SET XLPOS values:  Offset = %g  Side = Bottom\n",pcm->xlpos);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("ylpos",cmd)) {
+    kwrd = 88;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL ) goto xlerr2;
+    pcm->ylpos = val1;
+    pcm->ylpflg = 1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (cmpwrd("r",cmd)||cmpwrd("right",cmd)) pcm->ylside = 1;
+      if (cmpwrd("l",cmd)||cmpwrd("left",cmd)) pcm->ylside = 0;
+    }
+    snprintf(pout,255,"SET YLPOS values:  Offset = %g  Side = ",tt);
+    gaprnt (2,pout);
+    if (pcm->ylside) gaprnt(2,"Right\n");
+    else gaprnt(2,"Left\n");
+  }
+  else if (cmpwrd("xlopts",cmd)) {
+    kwrd = 70;
+    itt  = pcm->xlcol;
+    itt1 = pcm->xlthck;
+    val1 = pcm->xlsiz;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt1) == NULL ) goto xlerr;
+      else {
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (getdbl(cmd,&val1) == NULL ) goto xlerr;
+        }
+      }
+    }
+    pcm->xlcol  = itt;
+    pcm->xlthck = itt1;
+    pcm->xlsiz  = val1;
+    snprintf(pout,255,"SET XLOPTS values:  Color = %i  Thickness = %i  Size = %g \n",
+	     pcm->xlcol, pcm->xlthck, pcm->xlsiz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("ylopts",cmd)) {
+    kwrd = 71;
+    itt  = pcm->ylcol;
+    itt1 = pcm->ylthck;
+    val1 = pcm->ylsiz;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt1) == NULL ) goto xlerr;
+      else {
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (getdbl(cmd,&val1) == NULL ) goto xlerr;
+        }
+      }
+    }
+    pcm->ylcol  = itt;
+    pcm->ylthck = itt1;
+    pcm->ylsiz  = val1;
+    snprintf(pout,255,"SET YLOPTS values:  Color = %i  Thickness = %i   Size = %g \n",
+	     pcm->ylcol, pcm->ylthck, pcm->ylsiz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("annot",cmd)) {
+    kwrd = 56;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->anncol = itt;
+    pcm->xlcol  = itt;  /* set annot should change color of tic labels too */
+    pcm->ylcol  = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ) {
+        gaprnt(0,"SET ANNOT Error: Invalid thickness value\n");
+      } else {
+        pcm->annthk = itt;
+      }
+    }
+    snprintf(pout,255,"SET ANNOT values:  Color = %i  Thickness = %i\n",
+	     pcm->anncol, pcm->annthk);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("line",cmd)) {
+    kwrd = 41;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->lincol = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (intprs(cmd,&itt) == NULL ){
+        gaprnt(0,"SET LINE Error: Invalid linestyle value\n");
+      } else {
+        pcm->linstl = itt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (intprs(cmd,&itt) == NULL ){
+            gaprnt(0,"SET LINE Error: Invalid thickness value\n");
+          } else {
+            pcm->linthk = itt;
+          }
+        }
+      }
+    }
+    snprintf(pout,255,"SET LINE values:  color = %i  style = %i",
+      pcm->lincol, pcm->linstl);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  thickness = %i\n",pcm->linthk);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("map",cmd)) {
+    kwrd = 46;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("auto",cmd)) {
+      pcm->mapcol = -9;
+    } else {
+      if (intprs(cmd,&itt) == NULL ) goto err;
+      pcm->mapcol = itt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (intprs(cmd,&itt) == NULL ){
+          gaprnt(0,"SET MAP Error: Invalid linestyle value\n");
+        } else {
+          pcm->mapstl = itt;
+          if ((cmd = nxtwrd (cmd)) != NULL) {
+            if (intprs(cmd,&itt) == NULL ){
+              gaprnt(0,"SET MAP Error: Invalid thickness value\n");
+            } else {
+              pcm->mapthk = itt;
+            }
+          }
+        }
+      }
+    }
+    if (pcm->mapcol < 0 ) {
+      gaprnt (2,"SET MAP values:  auto\n");
+    } else {
+      snprintf(pout,255,"SET MAP values:  color = %i  style = %i",
+        pcm->mapcol, pcm->mapstl);
+      gaprnt (2,pout);
+      snprintf(pout,255,"  thickness = %i\n",pcm->mapthk);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("string",cmd)) {
+    kwrd = 42;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    pcm->strcol = itt;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      itt = -1;
+      for (i1=0; i1<9; i1++) if (cmpwrd(justs[i1],cmd)) itt=i1;
+      if (itt<0) {
+        gaprnt(0,"SET STRING Error: Invalid justification value\n");
+      } else {
+        pcm->strjst = itt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (intprs(cmd,&itt) == NULL ){
+            gaprnt(0,"SET STRING Error: Invalid thickness value\n");
+          } else {
+            pcm->strthk = itt;
+            if ((cmd = nxtwrd (cmd)) != NULL) {
+              if (getdbl(cmd,&val1) == NULL ){
+                gaprnt(0,"SET STRING Error: Invalid rotation value\n");
+              } else {
+                pcm->strrot = val1;
+              }
+            }
+          }
+        }
+      }
+    }
+    snprintf(pout,255,"SET STRING values:  color = %i  just = %s",
+      pcm->strcol, justs[pcm->strjst]);
+    gaprnt (2,pout);
+    snprintf(pout,255,"  thickness = %i  rotation = %g\n",
+      pcm->strthk, pcm->strrot);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("strsiz",cmd)) {
+    kwrd = 43;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&val1) == NULL ) goto err;
+    pcm->strhsz = val1;
+    i1 = 1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&val1) == NULL ){
+        gaprnt(0,"SET STRSIZ Error:  Invalid vsize value\n");
+      } else {pcm->strvsz = val1; i1 = 0;}
+    }
+    if (i1) pcm->strvsz = pcm->strhsz;
+    snprintf(pout,255,"SET STRSIZ values:  hsize = %g  vsize = %g\n",
+      pcm->strhsz, pcm->strvsz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("xaxis",cmd)) {
+    kwrd = 19;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->axmin)) == NULL) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->axmax)) == NULL) goto err;
+    pcm->axflg = 1;
+    pcm->axint = 0.0;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&v1) == NULL) goto err;
+      else pcm->axint = v1;
+    }
+    snprintf(pout,255,"xaxis labels range %g %g incr %g \n",pcm->axmin,pcm->axmax,pcm->axint);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("yaxis",cmd)) {
+    kwrd = 20;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->aymin)) == NULL) goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->aymax)) == NULL) goto err;
+    pcm->ayflg = 1;
+    pcm->ayint = 0.0;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&v1) == NULL) goto err;
+      else pcm->ayint = v1;
+    }
+    snprintf(pout,255,"yaxis labels range %g %g incr %g \n",pcm->aymin,pcm->aymax,pcm->ayint);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("misswarn",cmd)) {
+    kwrd = 79;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) itt = 1;
+    else if (cmpwrd("off",cmd)) itt=0;
+    else goto err;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&id) == NULL ) goto err;
+    for (i1=0; i1<id-1; i1++) {
+      pfi = pfi->pforw;
+      if (pfi==NULL) {
+        snprintf(pout,255,"SET MISSWARN error:  file %i not open\n",id);
+        gaprnt (0,pout);
+        return(1);
+      }
+    }
+    pfi->errflg = itt;
+  }
+  else if (cmpwrd("undef",cmd)) {
+    kwrd = 117;
+    if ((cmd = nxtwrd (cmd)) == NULL) {
+      gaprnt (2,"Warning: SET UNDEF argument is missing; output undef value is unchanged.\n");
+    }
+    else if (cmpwrd("file",cmd)) {    
+      if ((cmd = nxtwrd (cmd)) == NULL) {
+	gaprnt (2,"Warning: SET UNDEF FILE argument is missing; output undef value is unchanged.\n");
+      } 
+      else if (intprs(cmd,&id) == NULL ) {
+	gaprnt (2,"Warning: SET UNDEF FILE argument is invalid; output undef value is unchanged.\n");
+      }
+      else {
+	pfi = pcm->pfi1;
+	if (pfi!=NULL) {
+	  for (i1=0; i1<id-1; i1++) {
+	    pfi = pfi->pforw;
+	    if (pfi==NULL) {
+	      break;
+	    }
+	  }
+	}
+	if (pfi==NULL) {
+	  snprintf(pout,255,"Warning: SET UNDEF FILE -- file %d not open, output undef value is unchanged.\n",id);
+	  gaprnt (2,pout);
+	} else {
+	  pcm->undef = pfi->undef;
+	  snprintf(pout,255,"Output undef value copied from file %d : %s \n",id,pfi->dnam);
+	  gaprnt (2,pout);
+	}
+      }
+    }
+    else if (cmpwrd("dfile",cmd)) {    
+      id = pcm->dfnum;
+      pfi = pcm->pfi1;
+      for (i1=0; i1<id-1; i1++) {
+	pfi = pfi->pforw;
+	if (pfi==NULL) {
+	  break;
+	}
+      }
+      if (pfi==NULL) {
+	snprintf(pout,255,"Warning: SET UNDEF DFILE -- default file %i not open, output undef value is unchanged\n",id);
+	gaprnt (2,pout);
+      } else {
+	pcm->undef = pfi->undef;
+	snprintf(pout,255,"Output undef value copied from default file %d : %s \n",id,pfi->dnam);
+	gaprnt (2,pout);
+      }
+    }
+    else {
+      if (getdbl(cmd,&v1) == NULL) {
+	gaprnt(2,"Warning: SET UNDEF argument is invalid, output undef value is unchanged\n");
+      }
+      else {
+	pcm->undef = v1;
+      }
+    }
+    snprintf(pout,255,"Output undef value is set to %12f \n",pcm->undef);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("dfile",cmd)) {
+    kwrd = 14;
+    if (pcm->pfid==NULL) goto errf;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&id) == NULL ) goto err;
+    pfi = pcm->pfi1;
+    for (i1=0; i1<id-1; i1++) {
+      pfi = pfi->pforw;
+      if (pfi==NULL) {
+        snprintf(pout,255,"SET DFILE error:  file %i not open\n",id);
+        gaprnt (0,pout);
+        return(1);
+      }
+    }
+    snprintf(pout,255,"Default file set to: %s \n",pfi->name);
+    gaprnt (2,pout);
+    pcm->pfid = pfi;
+    pcm->dfnum = id;
+  }
+  else if (cmpwrd("background",cmd)) {
+    kwrd = 58;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    snprintf(pout,255,"background = %i \n",itt);
+    gaprnt (2,pout);
+    gxbckg(itt);
+  }
+  else if (cmpwrd("cthick",cmd)) {
+    kwrd = 49;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&(pcm->cthick)) == NULL ) goto err;
+    snprintf(pout,255,"cthick = %i \n",pcm->cthick);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("cstyle",cmd)) {
+    kwrd = 9;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&(pcm->cstyle)) == NULL ) goto err;
+    if(pcm->cstyle==0) {
+      snprintf(pout,255,"WARNING: cstyle=0; no lines will be plotted; try using 1 instead\n");
+    } else {
+      snprintf(pout,255,"cstyle = %i \n",pcm->cstyle);
+    }
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("digsiz",cmd) || cmpwrd("digsize",cmd)) {
+    kwrd = 24;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->digsiz)) == NULL ) goto err;
+    snprintf(pout,255,"digsiz = %g \n",pcm->digsiz);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("dignum",cmd)) {
+    kwrd = 23;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&itt) == NULL ) goto err;
+    if (itt<0 || itt>8) {
+      gaprnt (0,"Invalid dignum value:  must be 0 to 8\n");
+    } else {
+      pcm->dignum = itt;
+      snprintf(pout,255,"dignum = %i \n",pcm->dignum);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("axlim",cmd)||cmpwrd("vrange",cmd)) {
+    kwrd = 15;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("auto",cmd)) pcm->aflag = 0;
+    else {
+      if (getdbl(cmd,&(pcm->rmin)) == NULL ) goto err;
+      pcm->aflag = 0;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (getdbl(cmd,&(pcm->rmax)) == NULL ) goto err;
+      pcm->aflag = -1;
+      snprintf(pout,255, "1-D axis limits set: %g to %g \n", pcm->rmin, pcm->rmax);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("vrange2",cmd)) {
+    kwrd = 67;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->rmin2)) == NULL ) goto err;
+    pcm->aflag2 = 0;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (getdbl(cmd,&(pcm->rmax2)) == NULL ) goto err;
+    pcm->aflag2 = -1;
+    snprintf(pout,255, "Scatter Y axis limits set: %g to %g \n", pcm->rmin2, pcm->rmax2);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("strmden",cmd) || cmpwrd("strmopts",cmd)) {
+    kwrd = 124;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (intprs(cmd,&(pcm->strmden)) == NULL ) goto err;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      if (getdbl(cmd,&tt) == NULL ) goto err;
+      if (tt>0.001) pcm->strmarrd = tt;
+      if ((cmd = nxtwrd (cmd)) != NULL) {
+        if (getdbl(cmd,&tt) == NULL ) goto err;
+        if (tt>=0.0) pcm->strmarrsz = tt;
+        if ((cmd = nxtwrd (cmd)) != NULL) {
+          if (intprs(cmd,&i) == NULL ) goto err;
+          if (i>0 && i<3) pcm->strmarrt = i;
+        }
+      }
+    }
+    snprintf (pout, 255, "Streamline options set to: Density %i Spacing %g Size %g Type %i\n",
+        pcm->strmden, pcm->strmarrd, pcm->strmarrsz, pcm->strmarrt) ;
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("ccolor",cmd)) {
+    kwrd = 10;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("rainbow",cmd)) {
+      pcm->ccolor = -1;
+      gaprnt (2,"ccolor = rainbow \n");
+    } else if (cmpwrd("revrain",cmd)) {
+      pcm->ccolor = -2;
+      gaprnt (2,"ccolor = reverse rainbow \n");
+    } else {
+      if (intprs(cmd,&(pcm->ccolor)) == NULL ) goto err;
+      snprintf(pout,255,"ccolor = %i \n",pcm->ccolor);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("stid",cmd)) {
+    kwrd = 30;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->stidflg = 1;
+    else if (cmpwrd("off",cmd)) pcm->stidflg = 0;
+    else goto err;
+  }
+  else if (cmpwrd("csmooth",cmd)) {
+    kwrd = 16;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->csmth = 1;
+    else if (cmpwrd("off",cmd)) pcm->csmth = 0;
+    else if (cmpwrd("linear",cmd)) pcm->csmth = 2;
+    else goto err;
+  }
+  else if (cmpwrd("cterp",cmd)) {
+    kwrd = 34;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->cterp = 1;
+    else if (cmpwrd("off",cmd)) pcm->cterp = 0;
+    else goto err;
+  }
+  else if (cmpwrd("loopdim",cmd)) {
+    kwrd = 11;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("x",cmd)) pcm->loopdim=0;
+    else if (cmpwrd("y",cmd)) pcm->loopdim=1;
+    else if (cmpwrd("z",cmd)) pcm->loopdim=2;
+    else if (cmpwrd("t",cmd)) pcm->loopdim=3;
+    else if (cmpwrd("e",cmd)) pcm->loopdim=4;
+    else goto err;
+  }
+  else if (cmpwrd("grads",cmd)) {
+    kwrd = 31;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) {
+      pcm->grdsflg = 1;
+    }
+    else if (cmpwrd("off",cmd)) {
+      pcm->grdsflg = 0;
+      pcm->timelabflg = 0;
+    }
+    else goto err;
+  }
+  else if (cmpwrd("timelab",cmd)) {
+    kwrd = 100;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd)) pcm->timelabflg = 1;
+    else if (cmpwrd("off",cmd)) pcm->timelabflg = 0;
+    else goto err;
+  }
+  else if (cmpwrd("stnprint",cmd)) {
+    kwrd = 102;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd) ) pcm->stnprintflg = 1;
+    else if (cmpwrd("off",cmd) ) pcm->stnprintflg = 0;
+    else goto err;
+  }
+  else if (cmpwrd("warn",cmd)) {
+    kwrd = 101;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd) ) mfcmn.warnflg = 1;
+    else if (cmpwrd("off",cmd) ) mfcmn.warnflg = 0;
+    else goto err;
+  }
+  else if (cmpwrd("looping",cmd)) {
+    kwrd = 12;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd) ) {
+      pcm->loopflg = 1;
+      gaprnt (2,"Looping is on \n");
+    } else if (cmpwrd("off",cmd) ) {
+      pcm->loopflg = 0;
+      gaprnt (2,"Looping is off \n");
+    } else goto err;
+  }
+  else if (cmpwrd("ens",cmd)) {
+    kwrd=112;
+    if (pcm->pfid==NULL) goto errf;
+    pfi = pcm->pfid;
+    /* get the first ensemble name */
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    num = 1;
+    getwrd(ename1,cmd,16);
+    /* get the second ensemble name */
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      num = 2;
+      getwrd(ename2,cmd,16);
+      if (strcmp(ename1,ename2) == 0) num=1;
+    }
+    ens = pfi->ens1;
+    i=0;
+    enum1=enum2=-1;
+    while (i<pfi->dnum[4]) {
+      if (strcmp(ename1,ens->name) == 0) {
+	enum1=i;
+      }
+      if (num>1) {
+	if (strcmp(ename2,ens->name) == 0) enum2=i;
+      }
+      i++; ens++;
+    }
+    if (enum1<0) goto err;
+    if ((num>1) && (enum2<0)) goto err; 
+    if (num==1) enum2=enum1;
+    pcm->vdim[4] = num-1;
+    pcm->dmin[4] = enum1+1;  
+    pcm->dmax[4] = enum2+1;
+    snprintf(pout,255,"E set to %g %g \n", pcm->dmin[4], pcm->dmax[4]);
+    gaprnt (2,pout);    
+  }
+  else if (cmpwrd("e",cmd)) {
+    kwrd = 111;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (pcm->pfid==NULL) goto errf;
+    pfi = pcm->pfid;
+    num = 1;
+    if (cmpwrd("last",cmd)) {
+      v1 = pfi->dnum[4];
+    } else {
+      if (getdbl(cmd,&v1) == NULL) goto err;
+    }
+    v2 = v1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      num = 2;
+      if (cmpwrd("last",cmd)) {
+        v2 = pfi->dnum[4];
+      } else {
+        if (getdbl(cmd,&v2) == NULL) goto err;
+      }
+      if (v1==v2) num = 1;
+    } 
+    pcm->vdim[4] = num-1;
+    pcm->dmin[4] = v1;  
+    pcm->dmax[4] = v2;
+    snprintf(pout,255,"E set to %g %g \n", pcm->dmin[4], pcm->dmax[4]);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("x",cmd) || cmpwrd("y",cmd) ||
+           cmpwrd("z",cmd) || cmpwrd("t",cmd) ) {
+    if (*cmd=='x') kwrd=0;
+    if (*cmd=='y') kwrd=1;
+    if (*cmd=='z') kwrd=2;
+    if (*cmd=='t') kwrd=3;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (pcm->pfid==NULL) goto errf;
+    pfi = pcm->pfid;
+    num = 1;
+    if (kwrd==3 && cmpwrd("last",cmd)) {
+      v1 = pfi->dnum[3];
+    } else {
+      if (getdbl(cmd,&v1) == NULL) goto err;
+    }
+    v2 = v1;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      num = 2;
+      if (kwrd==3 && cmpwrd("last",cmd)) {
+        v2 = pfi->dnum[3];
+      } else {
+        if (getdbl(cmd,&v2) == NULL) goto err;
+      }
+      if (dequal(v1,v2,1.0e-8)==0) num=1;
+    }
+    pcm->vdim[kwrd] = num-1;
+
+    /* Try to save grid dims for write flag -ex */
+
+    if (pfi->type==1 && num==2) {
+      if (kwrd==0) {
+        pcm->xexflg = 1;
+        pcm->x1ex = (gaint)(v1+0.001);
+        pcm->x2ex = (gaint)(v2+0.001);
+      }
+      if (kwrd==1) {
+        pcm->yexflg = 1;
+        pcm->y1ex = (gaint)(v1+0.001);
+        pcm->y2ex = (gaint)(v2+0.001);
+      }
+    }
+
+    if (pfi->type==1 && num==1) {
+      v1 = floor(v1+0.5);
+      pcm->vdim[kwrd] = 0;
+    }
+    if (kwrd==3) {
+      vals = pfi->grvals[3];
+      gr2t (vals,v1,&(pcm->tmin));
+      if (num==1) pcm->tmax = pcm->tmin;
+      else gr2t(vals,v2,&(pcm->tmax));
+      gaprnt (2,"Time values set: ");
+      snprintf(pout,255,"%i:%i:%i:%i ",pcm->tmin.yr,pcm->tmin.mo,
+        pcm->tmin.dy,pcm->tmin.hr);
+      gaprnt (2,pout);
+      snprintf(pout,255,"%i:%i:%i:%i \n",pcm->tmax.yr,pcm->tmax.mo,
+        pcm->tmax.dy,pcm->tmax.hr);
+      gaprnt (2,pout);
+    } else {
+      if (pfi->type==1) {
+        conv = pfi->gr2ab[kwrd];
+        vals = pfi->grvals[kwrd];
+        pcm->dmin[kwrd] = conv(vals,v1);
+        if (num==1) 
+	  pcm->dmax[kwrd] = pcm->dmin[kwrd];
+        else 
+	  pcm->dmax[kwrd] = conv(vals,v2);
+      } else {
+        pcm->dmin[kwrd] = v1;
+        if (num==1) 
+	  pcm->dmax[kwrd] = pcm->dmin[kwrd];
+        else 
+	  pcm->dmax[kwrd] = v2;
+      }
+      snprintf(pout,255,"%s set to %g %g \n",kwds[kwrd+4], pcm->dmin[kwrd], pcm->dmax[kwrd]);
+      gaprnt (2,pout);
+    }
+  }
+  else if (cmpwrd("lon",cmd) || cmpwrd("lat",cmd) || cmpwrd("lev",cmd)) {
+    if (cmpwrd("lon",cmd)) {kwrd=4; id=0;}
+    if (cmpwrd("lat",cmd)) {kwrd=5; id=1;}
+    if (cmpwrd("lev",cmd)) {kwrd=6; id=2;}
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (pcm->pfid==NULL) goto errf;
+    num = 1;
+    if (getdbl(cmd,&(pcm->dmin[id])) == NULL) goto err;
+    pcm->dmax[id] = pcm->dmin[id];
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      num = 2;
+      if (getdbl(cmd,&(pcm->dmax[id])) == NULL) goto err;
+      if (dequal(pcm->dmin[id],pcm->dmax[id],1.0e-8)==0) num=1;
+    }
+    pcm->vdim[id] = num-1;
+    pfi = pcm->pfid;
+    if (pfi->type==1 && num==1) {
+      pcm->vdim[id] = 0;
+      conv = pfi->ab2gr[id];
+      vals = pfi->abvals[id];
+      v1 = conv(vals,pcm->dmin[id]);
+      v1 = floor(v1+0.5);
+      conv = pfi->gr2ab[id];
+      vals = pfi->grvals[id];
+      pcm->dmin[id] = conv(vals,v1);
+      pcm->dmax[id] = pcm->dmin[id];
+    }
+    snprintf(pout,255,"%s set to %g %g \n",kwds[id+4],pcm->dmin[id],pcm->dmax[id]);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("time",cmd)) {
+    kwrd=7; id=3;
+    if (pcm->pfid==NULL) goto errf;
+    if ((cmd = nxtwrd(cmd)) == NULL) goto err;
+    num = 1;
+    tdef = pcm->tmin;
+    if (adtprs(cmd,&tdef,&(pcm->tmin)) == NULL ) goto err;
+    pcm->tmax = pcm->tmin;
+    if ((cmd = nxtwrd (cmd)) != NULL) {
+      num = 2;
+      if (adtprs(cmd,&tdef,&(pcm->tmax)) == NULL ) goto err;
+    }
+    pcm->vdim[3] = 1;
+    if (num==1) {
+      pcm->vdim[3] = 0;
+      pfi = pcm->pfid;
+      vals = pfi->abvals[3];
+      v1 = t2gr(vals,&(pcm->tmin));
+      v1 = floor(v1+0.5);
+      vals = pfi->grvals[3];
+      gr2t (vals,v1,&(pcm->tmin));
+      pcm->tmax = pcm->tmin;
+    }
+    gaprnt (2,"Time values set: ");
+    snprintf(pout,255,"%i:%i:%i:%i ",pcm->tmin.yr,pcm->tmin.mo,
+      pcm->tmin.dy,pcm->tmin.hr);
+    gaprnt (2,pout);
+    snprintf(pout,255,"%i:%i:%i:%i \n",pcm->tmax.yr,pcm->tmax.mo,
+      pcm->tmax.dy,pcm->tmax.hr);
+    gaprnt (2,pout);
+  }
+  else if (cmpwrd("datawarn",cmd)) {
+    kwrd = 107;
+    if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+    if (cmpwrd("on",cmd) ) pcm->dwrnflg = 1;
+    else if (cmpwrd("off",cmd) ) pcm->dwrnflg = 0;
+    else goto err;
+  }
+  else if (cmpwrd("fill",cmd)) {
+    kwrd = 96;
+    pat = (char *)galloc(6,"fillpat");
+    if ((cmd = nxtwrd (cmd)) == NULL) goto pterr;
+    if (cmpwrd("on",cmd) ) {
+      snprintf(pat,5,"%s","on");
+      pcm->ptflg = 1;
+    }
+    else if (cmpwrd("off",cmd) ) {
+      snprintf(pat,5,"%s","off");
+      pcm->ptflg = 0;
+    }
+    else if (cmpwrd("open",cmd)) {
+      pcm->ptflg = 1;
+      pcm->ptopt = 0;
+      snprintf(pat,5,"%s","open");
+    }
+    else if (cmpwrd("solid",cmd)) {
+      snprintf(pat,5,"%s","solid");
+      pcm->ptflg = 1;
+      pcm->ptopt = 1;
+    }
+    else if (cmpwrd("dot",cmd)) {
+      snprintf(pat,5,"%s","dot");
+      pcm->ptflg = 1;
+      pcm->ptopt = 2;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (intprs(cmd,&num) == NULL ) goto err;
+      if (num<1 || num>6)
+        gaprnt (0,"Invalid ptrnden value:  must be integer 1 to 6\n");
+      else
+        pcm->ptden=num;
+    }
+    else if (cmpwrd("line",cmd)) {
+      snprintf(pat,5,"%s","line");
+      pcm->ptflg = 1;
+      pcm->ptopt = 3;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (intprs(cmd,&num) == NULL ) goto err;
+      if (num<1 || num>5)
+        gaprnt (0,"Invalid ptrnden value:  must be integer 1 to 5\n");
+      else
+        pcm->ptden=num;
+      if ((cmd = nxtwrd (cmd)) == NULL) goto err;
+      if (intprs(cmd,&num) == NULL ) goto err;
+      if (num!=-90&&num!=90&&num!=-60&&num!=60&&num!=-30&&num!=30
+	  &&num!=-45&&num!=45&&num!=0) {
+        gaprnt (0,"Invalid ptrnang value:  must be -90, -60, -45 -30\n");
+        gaprnt (0," 	                        0, 30. 45, 60, or 90\n");
+      }
+      else
+        pcm->ptang=num;
+    }
+    else goto err;
+
+    if (cmpwrd("line",pat) )
+      snprintf(pout,255,"SET FILL values: %s %d %d\n",pat,pcm->ptden,pcm->ptang);
+    else if (cmpwrd("dot",pat) )
+      snprintf(pout,255,"SET FILL values: %s %d\n",pat,pcm->ptden);
+    else
+      snprintf(pout,255,"SET FILL values: %s\n",pat);
+    gaprnt (2,pout);
+    gree(pat,"f234");
+  }
+
+  else {
+    gaprnt (0,"SET error: Invalid operand\n");
+    gaprnt (0,"  Operand = ");
+    gaprnt (0,cmd);
+    gaprnt (0,"\n");
+    return (1);
+  }
+  return (0);
+
+err:
+  gaprnt (0,"SET error:  Missing or invalid arguments ");
+  snprintf(pout,255,"for %s option\n",kwds[kwrd]);
+  gaprnt (0,pout);
+  return (1);
+
+errf:
+  gaprnt (0,"SET Error:  No files open yet\n");
+  return (1);
+
+xlerr:
+  gaprnt (0,"SET XLOPTS(YLOPTS,CLOPTS) Syntax Error");
+  gaprnt (0,"  Syntax is: SET XLOPTS color thickness size");
+  return (1);
+
+xlerr2:
+  gaprnt (0,"SET XLPOS(YLPOS) Syntax Error");
+  gaprnt (0,"  Syntax is: SET XLPOS offset side\n");
+  return (1);
+
+rbberr:
+  gaprnt (0,"SET RBAND Syntax Error.");
+  gaprnt (0,"  Syntax is: SET RBAND num type xlo ylo xhi yhi\n");
+  return (1);
+
+pterr:
+  gaprnt (0,"SET FILL Syntax Error.");
+  gaprnt (0,"  Syntax is: SET FILL type [density] [angle]\n");
+  return (1);
+
+drerr:
+  gaprnt (0,"SET DROPMENU Syntax Error.");
+  gaprnt (0,"  Syntax is: SET DROPMENU fc bc oc1 oc2 tfc tbc toc1 toc2\n");
+  gaprnt (0,"      bfc bbc boc1 boc2 soc1 soc2 thick\n");
+  return (1);
+}
+
+/* Open a data set by reading the descriptor file for that
+   data set, and create a gafile structure.  Chain the gafile
+   structure on to the list anchored in the gastat.                   */
+
+gaint  gaopen (char *name, struct gacmn *pcm) {
+struct gafile *pfi, *pfio;
+gaint rc;
+
+  pfi = getpfi();
+  if (pfi==NULL) {
+    gaprnt (0,"Memory Allocation Error: On File Open\n");
+    return (1);
+  }
+
+#if USEGADAP
+  /* if name starts with http:// then it's a URL */
+  if (*name=='h' && *(name+1)=='t' && *(name+2)=='t' &&
+      *(name+3)=='p' && *(name+4)==':' && *(name+5)=='/' &&
+      *(name+6)=='/' ) {    
+    rc = dappfi (name,pfi); 
+  } else {
+    gaprnt (2,"Scanning description file:  ");
+    gaprnt (2,name);
+    gaprnt (2,"\n");
+    rc = gaddes(name, pfi, 1);
+  }       
+#else 
+  gaprnt (2,"Scanning description file:  ");
+  gaprnt (2,name);
+  gaprnt (2,"\n");
+  rc = gaddes(name, pfi, 1);
+#endif
+
+  if (rc) {
+    frepfi (pfi,0);
+    return (rc);
+  }
+  pcm->fseq = pcm->fseq + 1;
+  pfi->fseq = pcm->fseq;       /* opened files get unique sequence number */
+
+  if (pfi->tmplat==0 && pfi->dhandle == -999) {
+    if (pfi->ncflg) {
+      if (pfi->ncflg==1) {    /* dtype netcdf */
+#if USENETCDF == 1
+	rc = gaopnc(pfi,0,1);
+	if (rc) {
+	  frepfi (pfi,0);
+	  return (1);
+	}
+#endif
+      }  
+      else if (pfi->ncflg==2) {    /* dtype hdfsds */
+#if USEHDF == 1
+	rc = gaophdf(pfi,0,1);
+	if (rc) {
+	  frepfi (pfi,0);
+	  return (1);
+	}
+#endif
+      }
+      else if (pfi->ncflg==3) {    /* dtype hdf5 */
+#if USEHDF5 == 1
+	rc = gaoph5(pfi,0,1);
+	if (rc) {
+	  frepfi (pfi,0);
+	  return (1);
+	}
+#endif
+      }
+
+    } else if (!pfi->bufrflg) {   
+      pfi->infile = fopen (pfi->name, "rb");
+      if (pfi->infile==NULL) {
+	gaprnt (0,"Open Error:  Can't open binary data file\n");
+	gaprnt (0,"  File name = ");
+	gaprnt (0,pfi->name);
+	gaprnt (0,"\n");
+	frepfi (pfi,0);
+	return (1);
+      }
+    }
+  }
+  
+  if (pcm->pfi1==NULL) {
+    pcm->pfi1 = pfi;
+  } else {
+    pfio = pcm->pfi1;
+    while (pfio->pforw!=NULL) pfio = pfio->pforw;
+    pfio->pforw = pfi;
+  }
+  pfi->pforw = NULL;
+  pcm->fnum++;
+
+  if (pcm->fnum==1) {pcm->pfid = pcm->pfi1; pcm->dfnum = 1;}
+  snprintf(pout,255,"Data file %s is open as file %i\n",pfi->name,pcm->fnum);
+  gaprnt (2,pout);
+
+  /* If first file open, set up some default dimension ranges for the user */
+  if (pcm->fnum==1) {
+    if (pfi->type==2 || pfi->wrap ) gacmd ("set lon 0 360",pcm,0);
+    else {
+      snprintf(pout,255,"set x 1 %i",pfi->dnum[0]);
+      gacmd (pout,pcm,0);
+    }
+    if (pfi->type==2) {
+      gacmd ("set lat -90 90",pcm,0);
+      gacmd ("set lev 500",pcm,0);
+    } else {
+      snprintf(pout,255,"set y 1 %i",pfi->dnum[1]);
+      gacmd (pout,pcm,0);
+      
+      /* set z to max if x or y = 1 */
+      if ((pfi->type==1 && pfi->dnum[2] >= 1)
+	  && ((pfi->dnum[0] == 1) || (pfi->dnum[1] == 1))) {
+	snprintf(pout,255,"set z 1 %i",pfi->dnum[2]);
+	gacmd (pout,pcm,0);
+      } else {
+	gacmd ("set z 1",pcm,0);
+      }
+    }
+    gacmd ("set t 1",pcm,0);
+    gacmd ("set e 1",pcm,0);
+  }
+
+  if (pfi->ppflag) {
+    snprintf(pout,255,"Notice: Implied interpolation for file %s\n",name);
+    gaprnt (1,pout);
+    gaprnt (1," Interpolation will be performed on any data ");
+    gaprnt (1,"displayed from this file\n");
+
+    if (pfi->ppflag==8 && pfi->pdefgnrl==0) {
+      snprintf(pout,255,"WARNING: The use of PDEF FILE in %s \n",pfi->dnam);
+      gaprnt (1,pout);
+      gaprnt (1," may be incorrect. Please make sure you are using it properly.\n");
+      gaprnt (1," Updated documentation is at http://iges.org/grads/gadoc/pdef.html\n");
+    }
+  }
+  return (0);
+}
+
+struct gastat *getpst (struct gacmn *pcm) {
+struct gastat *pst;
+gaint i,vcnt,lflg,ll;
+size_t sz;
+
+  sz = sizeof(struct gastat);
+  if ((pst = (struct gastat *)galloc(sz,"pst")) == NULL) {
+    gaprnt(0,"Memory allocation error in getpst\n");
+    return(NULL);
+  }
+  pst->pfi1 = pcm->pfi1;
+  pst->pfid = pcm->pfid;
+  pst->fnum = pcm->fnum;
+  pst->pclct = (struct gaclct **)&(pcm->clct);
+  for (i=0;i<5;i++) {
+    if (i==3) {
+      pst->tmin = pcm->tmin;
+      pst->tmax = pcm->tmax;
+    } 
+    else {
+      pst->dmin[i] = pcm->dmin[i];
+      pst->dmax[i] = pcm->dmax[i];
+    }
+  }
+  pst->type = 1;
+  pst->result.pgr = NULL;
+  pst->pdf1 = pcm->pdf1;
+
+  vcnt = 0;
+  for (i=0; i<5; i++) if (pcm->vdim[i]) vcnt++;
+  lflg = pcm->loopflg;
+  if (vcnt>2) lflg = 1;
+
+  ll=0;
+  pst->idim = -1;
+  pst->jdim = -1;
+  if (pcm->vdim[0]) {                    /* X is varying */
+    if (pcm->dmin[0]>pcm->dmax[0]) {
+      gaprnt (0,"Operation error:  Invalid dimension environment\n");
+      snprintf(pout,255,"  Min longitude > max longitude: %g %g \n",
+	       pcm->dmin[0],pcm->dmax[0]);
+      gaprnt (0,pout);
+      goto err;
+    }
+    if (pcm->loopdim!=0 || !lflg) {
+      pst->idim=0;
+      ll++;
+    }
+  }
+  if (pcm->vdim[1]) {                    /* Y is varying */
+    if (pcm->dmin[1]>pcm->dmax[1]) {
+      gaprnt (0,"Operation error:  Invalid dimension environment\n");
+      snprintf(pout,255,"  Min latitude > max latitude: %g %g \n",
+	       pcm->dmin[1],pcm->dmax[1]);
+      gaprnt (0, pout);
+      goto err;
+    }
+    if (pcm->loopdim!=1 || !lflg) {
+      if (ll>0) 
+	pst->jdim = 1;
+      else 
+	pst->idim = 1;
+      ll++;
+    }
+  }
+  if (pcm->vdim[2]) {                    /* Z is varying */
+    if (pcm->loopdim!=2 || !lflg) {
+      if (ll>0) 
+	pst->jdim = 2;
+      else 
+	pst->idim = 2;
+      ll++;
+    }
+  }
+  if (pcm->vdim[3]) {                    /* T is varying */
+    if (pcm->loopdim!=3 || !lflg) {
+      if (ll>0) 
+	pst->jdim = 3;
+      else 
+	pst->idim = 3;
+      ll++;
+    }
+  }
+  if (pcm->vdim[4]) {                    /* E is varying */
+    if (pcm->loopdim!=4||!lflg) {
+      if (ll>0) 
+	pst->jdim = 4;
+      else 
+	pst->idim = 4;
+      ll++;
+    }
+  }
+  if (lflg && (vcnt==ll) ) {
+    gaprnt (0,"Operation error:  Invalid dimension environment\n");
+    gaprnt (0,"  Looping dimension does not vary\n");
+    goto err;
+  }
+  if (ll>2) {
+    gaprnt (0,"Operation error:  Invalid dimension environment\n");
+    gaprnt (0,"  Too many varying dimensions \n");
+    goto err;
+  }
+
+  return (pst);
+
+err:
+  gree(pst,"f101");
+  return(NULL);
+
+}
+
+
+void gaprnt (gaint level, char *msg) {
+gaint len;
+
+  if (msgflg) {
+    len = 0;
+    while (*(msg+len)) len++;
+    len++;
+    msgnew = (struct msgbuf *)malloc(sizeof(struct msgbuf));
+    if (msgnew==NULL) {
+      msgflg = 0;
+      printf ("Memory allocation error:  msg buffers\n");
+      return;
+    }
+    msgnew->msg = (char *)malloc(len);
+    if (msgnew->msg==NULL) {
+      msgflg = 0;
+      printf ("Memory allocation error:  msg buffers\n");
+      gree(msgnew,"f102");
+      return;
+    }
+    len = 0;
+    while (*(msg+len)) {
+      *(msgnew->msg+len) = *(msg+len);
+      len++;
+    }
+    *(msgnew->msg+len) = '\0';
+    msgnew->len = len;
+    msgnew->forw = NULL;
+    if (msgstk==NULL) msgstk = msgnew;
+    else msgcurr->forw = msgnew;
+    msgcurr = msgnew;
+  }
+  if (!msgflg || level<2) {
+    printf ("%s",gatxtl(msg,level));
+  }
+}
+
+gaint prntgaattr (struct gafile *pfi, char *name, gaint hdrflg, gaint fnum) {
+  struct gaattr *attr;
+  short *sptr=NULL;
+  long *lptr=NULL;
+  gafloat *fptr=NULL;
+  gadouble *dptr=NULL;
+  gaint i;
+
+  if (pfi->attr) {
+    attr=pfi->attr;
+    while (attr) {
+      if (strcmp(attr->varname,name)==0) {
+	if (attr->fromddf == 1) {   /* only print those that were in a descriptor file */
+	  if (hdrflg) {
+	    snprintf(pout,255,"Descriptor Attributes for File %i : %s \n",fnum,pfi->title);
+	    gaprnt(2,pout);
+	    hdrflg=0;
+	  }
+	  /* print strings */
+	  if (attr->nctype <= 2) {
+	    snprintf(pout,255,"%s %s %s %s\n",
+		    attr->varname,attr->type,attr->name,(char*)attr->value);
+	    gaprnt(2,pout);
+	  } 
+	  else {
+	    snprintf(pout,255,"%s %s %s ",attr->varname,attr->type,attr->name);
+	    gaprnt(2,pout);
+	    if      (attr->nctype == 3) sptr = (short*)attr->value;
+	    else if (attr->nctype == 4) lptr = (long*)attr->value;
+	    else if (attr->nctype == 5) fptr = (gafloat*)attr->value;
+	    else if (attr->nctype == 6) dptr = (gadouble*)attr->value;
+	    for (i=0; i<attr->len; i++) {
+	      /* print numbers */
+	      if (attr->nctype == 3) {
+		snprintf(pout,255,"%i",(gaint)*(sptr));
+		gaprnt(2,pout);
+		sptr++;
+	      } else if (attr->nctype == 4) {
+		snprintf(pout,255,"%li",*(lptr));
+		gaprnt(2,pout);
+		lptr++;
+	      } else if (attr->nctype == 5) {
+		snprintf(pout,255,"%f",*(fptr));
+		gaprnt(2,pout);
+		fptr++;
+	      } else { 
+		snprintf(pout,255,"%g",*(dptr));
+		gaprnt(2,pout);
+		dptr++;
+	      }
+	      if (i != attr->len-1) {
+		snprintf(pout,255,",");
+		gaprnt(2,pout);
+	      }
+	    }
+	    snprintf(pout,255,"\n");
+	    gaprnt(2,pout);
+	  }
+	}
+      }
+      attr=attr->next;
+    }
+  }
+  return (hdrflg);
+}
+
+
+#if READLINE == 1
+/* print history or repeat commands from history  */
+gaint gahistory(char*cmd, char *com, struct gacmn *pcm) {
+
+#include <readline/history.h>
+
+  extern gaint history_length; 
+  HIST_ENTRY **his_cmd;
+  FILE *logid;        /* history file id */
+  char *logfile;      /* history filename */
+  gaint pformat=0;    /* format for printing */
+  gaint i,is,ie,in=0; /* counter, history boundaries, # boundary argument */
+  gaint nerror=0;     /* count error in repeated commands */
+  gaint fileout=0;    /* flag: output to a file? */
+  gaint retcod=0;     /* return code */
+  gaint verbose=1;    /* Give feetback */
+  gaint readhis=0;    /* Read history */
+
+  is=1;
+  ie=history_length;
+  com=nxtwrd(com);
+  if (com) {
+    if (cmpwrd("-s",com) ) { /* script style: quote commands */
+      pformat=1;
+      com=nxtwrd(com);
+    } else if (cmpwrd("-x",com) ) { /* exec style: no command number */
+      pformat=2;
+      com=nxtwrd(com);
+    } else if (cmpwrd("-q",com) ) {
+      verbose=0;
+      com=nxtwrd(com);
+    } else if (cmpwrd("-r",com) ) {
+      readhis=1;
+      com=nxtwrd(com);
+    }
+  }
+
+  if(readhis) { /* read history from file */
+    if(com)
+      if(verbose)
+	printf("Adding content of file '%s' to history.\n",com);
+      if(read_history(com)) {
+	printf("Error reading history from file '%s'.\n",com);
+	return(1);
+      }
+    return(0);
+  }
+  if (com) {
+    /* try to read requested history boundaries */
+    in=sscanf(com,"%d%d",&is,&ie);
+    if (in==1) { 
+      if(is<0) {
+	is=history_length+1+is;
+	ie=is;
+      } else if (is==0) {
+	is=history_search_pos("quit # (End of session: ", -1,history_length)+2;
+	ie=history_length;
+      } else {
+	ie=is;
+      }
+    }
+    if(in==2) {
+      /* look backward if is, ie < 0 */
+      if(is<0) is=history_length+1+is;
+      if(ie<0) ie=history_length+1+ie;
+      else if(ie==0) ie=history_length;
+    }
+  }
+  if(is>ie) {i=is;is=ie;ie=i;}
+  if (ie>history_length) ie=history_length;
+  for (i=1;i<=in;i++) com=nxtwrd(com);
+  if(com){
+   if(verbose) printf("Writing command history to file '%s'.\n",com);
+    fileout=1;
+    logfile=strtok(com," ");
+    logid=fopen(logfile,"a");
+    /* write only commands from current session to file */
+    if(in==0) is=history_search_pos("quit # (End of session: ", -1,history_length)+2;
+    if(in<2) ie=history_length-1;
+    if (strcmp(".gs",com+strlen(com)-3)==0) {
+      pformat=1;
+    } else if (strcmp(".eps",com+strlen(com)-4)==0 ||
+              strcmp(".EPS",com+strlen(com)-4)==0    ) {
+      pformat=3;
+   
+    } else {
+      pformat=2;
+    }
+  } else
+    logid=stdout;
+  his_cmd=history_list();
+  if (cmpwrd("history",cmd) || cmpwrd("his",cmd) ) {
+    /* print history */
+    if (pformat==1) 
+      for(i=is;i<=ie;i++) 
+	fprintf(logid,"'%s'\n",his_cmd[i-1]->line);
+    else if(pformat==2)
+      for(i=is;i<=ie;i++) 
+	fprintf(logid,"%s\n",his_cmd[i-1]->line);
+    else if(pformat==3) 
+      for(i=is;i<=ie;i++) 
+        fprintf(logid,"%%ga> %s\n",his_cmd[i-1]->line);
+    else 
+      for(i=is;i<=ie;i++) 
+	fprintf(logid,"  [%d] %s\n",i,his_cmd[i-1]->line);
+    if (fileout) fclose(logid);
+  } else {
+    /* repeat history commands */
+    if(ie==history_length) ie--;
+    if(is==ie) {
+      printf("  %s\n",his_cmd[is-1]->line);
+    }
+    else {
+      printf("  Repeating commands\n    [%d] \"%s\" ...\n    [%d] \"%s\"\n",
+	   is, his_cmd[is-1]->line, ie,his_cmd[ie-1]->line);
+    }
+    for(i=is;i<=ie;i++) {
+      if (cmpwrdl(his_cmd[i-1]->line, "his") || 
+           cmpwrdl(his_cmd[i-1]->line, "history") || 
+           cmpwrdl(his_cmd[i-1]->line, "r") || 
+           cmpwrdl(his_cmd[i-1]->line,"repeat" ) ) {
+	printf(" [%d] \"%s\" not repeated.\n",i,his_cmd[is-1]->line);
+	continue; /* skip repeat commands */
+      }
+      retcod = gacmd(his_cmd[i-1]->line,pcm,1);
+      if (retcod) {
+	++nerror;
+	snprintf(pout,255,"  Repeat:  Error in command [%d] \"%s\".\n",i,his_cmd[i-1]->line);
+	gaprnt (0,pout);
+	if (nerror>50) {
+	  snprintf(pout,255,"  Repeat:  Too many errors (>50 ). Repeat stopped.\n");
+	  gaprnt (0,pout);
+	  retcod = 1;
+	  return (retcod);
+	}
+      }
+    }
+  }
+  return (retcod);
+}
+#endif /* READLINE == 1 */
+
+/* Routine to write out attribute metadata for self-describing output file */
+gaint sdfwatt (struct gacmn *pcm, gaint varid, char *varname, char *attname, char *attval) {
+#if USENETCDF == 1
+  gaint rc;
+  struct gaattr *attr=NULL;
+
+   /* Default attributes have name and value provided in the function call */ 
+  if (attname != NULL) {
+    rc = nc_put_att_text(pcm->ncwid, varid, attname, strlen(attval), attval);
+    if (rc) {
+      snprintf(pout,255,"sdfwatt error from nc_put_att_text (%s %s): \n ",
+	       varname, attname); 
+      gaprnt (0,pout);
+      handle_error(rc);
+      return(1);
+    }
+  }
+  else {
+    /* Non-default user-defined attributes are chained off the gacmn structure */
+    attr = pcm->attr;
+    while (attr) {
+      if (!strcmp(attr->varname, varname)) {       /* varname must match */
+	/* NetCDF library calls depend on attribute type */
+	if (attr->nctype <= 2) { 
+	  rc = nc_put_att_text (pcm->ncwid, varid, attr->name, 
+				attr->len, (char*)attr->value);
+	  if (rc) {
+	    snprintf(pout,255,"sdfwatt error from nc_put_att_text (%s %s): \n ",
+		     attr->varname, attr->name); 
+	    gaprnt(0,pout);
+	    handle_error(rc);
+	    return(1);
+	  }
+	} else if (attr->nctype == 3) {
+	  rc = nc_put_att_short (pcm->ncwid, varid, attr->name, 
+				 attr->nctype, attr->len, (short*)attr->value);
+	  if (rc) {
+	    snprintf(pout,255,"sdfwatt error from nc_put_att_short (%s %s): \n ",
+		     attr->varname, attr->name); 
+	    gaprnt(0,pout);
+	    handle_error(rc);
+	    return(1);
+	  }
+	} else if (attr->nctype == 4) {
+	  rc = nc_put_att_long (pcm->ncwid, varid, attr->name, 
+				attr->nctype, attr->len, (long*)attr->value);
+	  if (rc) {
+	    snprintf(pout,255,"sdfwatt error from nc_put_att_long (%s %s): \n ",
+		     attr->varname, attr->name); 
+	    gaprnt(0,pout);
+	    handle_error(rc);
+	    return(1);
+	  }
+	} else if (attr->nctype == 5) {
+	  rc = nc_put_att_float (pcm->ncwid, varid, attr->name, 
+				 attr->nctype, attr->len, (gafloat*)attr->value);
+	  if (rc) {
+	    snprintf(pout,255,"sdfwatt error from nc_put_att_float (%s %s): \n ",
+		     attr->varname, attr->name); 
+	    gaprnt(0,pout);
+	    handle_error(rc);
+	    return(1);
+	  }
+	} else if (attr->nctype == 6) {
+	  rc = nc_put_att_double (pcm->ncwid, varid, attr->name, 
+				  attr->nctype, attr->len, (gadouble*)attr->value);
+	  if (rc) {
+	    snprintf(pout,255,"sdfwatt error from nc_put_att_double (%s %s): \n ",
+		     attr->varname, attr->name); 
+	    gaprnt(0,pout);
+	    handle_error(rc);
+	    return(1);
+	  }
+	}
+      }
+      attr = attr->next;
+    }
+  }
+  return (0);
+#endif
+ return (0);
+}
+
+/* Routine to write out coordinate values for self-describing output file */
+gaint sdfwdim (struct gafile *pfi, struct gacmn *pcm, gaint dim, gaint varid) {
+#if USENETCDF == 1
+struct dt tinit,time;
+gadouble *axis, *axis0;
+gadouble (*conv) (gadouble *, gadouble);
+gaint i, rc;
+size_t sz;
+ 
+ axis = NULL;
+ sz = sizeof(gadouble)*pfi->dnum[dim];
+ axis = (gadouble *)galloc(sz,"sdfaxis");
+ if (axis==NULL) { 
+   gaprnt(0,"sdfwdim error: unable to allocate memory for coordinate values\n"); 
+   return (1);
+ }
+ axis0 = axis; 
+ if (dim == 3) {
+   /* For T coordinate */
+   gr2t (pfi->grvals[dim],1.0+pfi->dimoff[dim],&tinit);
+   for (i=1; i<=pfi->dnum[dim]; i++) {
+     gr2t (pfi->grvals[dim],(gadouble)(i+pfi->dimoff[dim]),&time);
+     *(axis+i-1) = timdif(&tinit,&time);   
+   }
+ }
+ else {
+   /* For X, Y, Z and E coordinates */
+   conv = pfi->gr2ab[dim];
+   for (i=1; i<=pfi->dnum[dim]; i++) {
+     *axis = conv(pfi->grvals[dim],(gadouble)(i+pfi->dimoff[dim]));
+     axis++;
+   }
+ }
+ axis = axis0;
+ rc = nc_put_var_double(pcm->ncwid, varid, axis0);
+ if (rc) {
+   snprintf(pout,255,"sdfwdim error from nc_put_var_double (dim=%d): \n ",dim);
+   gaprnt(0,pout);
+   handle_error(rc);
+   return (1);
+ }
+ gree(axis,"g0");
+ return (0);
+#endif
+ return (0);
+}
+
+/* Routine to set up a coordinate dimension and variable in a self-describing output file */
+gaint sdfdefdim (gaint fileid, char *dimname, gaint dimsize, gaint *dimid, gaint *varid) {
+#if USENETCDF == 1
+gaint rc;
+ /* define the dimension */
+ rc = nc_def_dim(fileid, dimname, dimsize, dimid);
+ if (rc) {
+   snprintf(pout,255,"sdfdefdim error from nc_def_dim (%s): \n ",dimname);
+   gaprnt (0,pout);
+   handle_error(rc); 
+   return (1);
+ }
+ /* define the coordinate variable */
+ rc = nc_def_var(fileid, dimname, NC_DOUBLE, 1, dimid, varid);
+ if (rc) {
+   snprintf(pout,255,"sdfdefdim error from nc_def_var (%s): \n ",dimname);
+   gaprnt (0,pout);
+   handle_error(rc); 
+   return (1);
+ }
+ return (0);
+#endif
+ return(0);
+}
+
+
+/* Routine to write out a defined grid in netcdf format */
+gaint ncwrite (char *cmd, struct gacmn *pcm) {
+#if USENETCDF == 1
+struct gadefn *pdf;
+struct gafile *pfi;
+struct dt tinit;
+off_t pos,nelems;
+gaint i,rc,nvdims=0,vdims[5],dimids[5];
+size_t start[5],count[5],*chunksize=NULL;
+gaint xdimid,ydimid,zdimid,tdimid,edimid;
+gaint xvarid,yvarid,zvarid,tvarid,evarid,varid;
+char name[20],tunit[256];
+gafloat flundef,*flbuf=NULL;
+char *filename={"grads.sdfwrite.nc"};
+
+
+  /* Get the name of the defined grid */
+  if ((cmd=nxtwrd(cmd)) == NULL) {
+    gaprnt (0,"ncwrite error: name of defined grid is missing \n");
+    goto err;
+  }
+  /* copy defined variable name */
+  i=0;
+  while (*(cmd+i)!=' ' && *(cmd+i)!='\n' && *(cmd+i)!='\0' && i<17) {
+    name[i] = *(cmd+i);
+    i++;
+  }
+  name[i] = '\0';
+
+  /* See if the name is a defined grid */
+  pdf = pcm->pdf1;
+  while (pdf!=NULL && !cmpwrd(name,pdf->abbrv)) pdf = pdf->pforw;
+  if (pdf==NULL) {
+    snprintf(pout,255,"ncwrite error: defined grid %s not found\n",name);
+    gaprnt (0,pout);
+    goto err;
+  }
+  pfi = pdf->pfi;
+
+  /* Create the file. */
+  if (pcm->sdfwname) filename = pcm->sdfwname;    /* override default filename */
+  if (pcm->sdfwtype == 2) 
+#if HAVENETCDF4==1
+    rc = nc_create(filename, NC_CLOBBER|NC_NETCDF4, &i);
+#else
+    rc = nc_create(filename, NC_CLOBBER, &i);
+#endif
+  else
+    rc = nc_create(filename, NC_CLOBBER, &i);
+  if (rc) {
+    gaprnt (0,"ncwrite error from nc_create: \n ");
+    handle_error(rc);
+    goto err;
+  }
+  pcm->ncwid = i;
+
+  /* initialize the vdims array */
+  vdims[0] = vdims[1] = vdims[2] = vdims[3] = vdims[4] = -999;
+
+  /* Set up the dimensions and the coordinate variables. 
+     For now, no record dimension is defined.  */
+  
+  /* X is varying or user wants to pad the output with non-varying dims */
+  if (pcm->vdim[0] || pcm->sdfwpad) {
+    /* define the dimension */
+    if (sdfdefdim (pcm->ncwid, "lon", pfi->dnum[0], &xdimid, &xvarid)) goto err;
+    /* assign default and user-defined attributes */
+    if (sdfwatt(pcm, xvarid, "lon", "units", "degrees_east")) goto err;
+    if (sdfwatt(pcm, xvarid, "lon", "long_name", "Longitude")) goto err;
+    if (sdfwatt(pcm, xvarid, "lon", NULL, NULL)) goto err;
+    /* increment the number of varying dimensions */
+    vdims[nvdims] = 0;
+    nvdims++;
+  }
+  else {
+    xdimid = -999;
+    xvarid = -999;
+  }
+
+  /* Y is varying or user wants to pad the output with non-varying dims  */
+  if (pcm->vdim[1] || pcm->sdfwpad) {                    
+    /* define the dimension */
+    if (sdfdefdim (pcm->ncwid, "lat", pfi->dnum[1], &ydimid, &yvarid)) goto err;
+    /* assign default and user-defined attributes */
+    if (sdfwatt(pcm, yvarid, "lat", "units", "degrees_north")) goto err;
+    if (sdfwatt(pcm, yvarid, "lat", "long_name", "Latitude")) goto err;
+    if (sdfwatt(pcm, yvarid, "lat", NULL, NULL)) goto err;
+    /* increment the number of varying dimensions */
+    vdims[nvdims] = 1;
+    nvdims++;
+  }
+  else {
+    ydimid = -999;
+    yvarid = -999;
+  }
+
+  /* Z is varying or user wants to pad the output with non-varying dims */
+  if (pcm->vdim[2] || pcm->sdfwpad) {                    
+    /* define the dimension */
+    if (sdfdefdim (pcm->ncwid, "lev", pfi->dnum[2], &zdimid, &zvarid)) goto err;
+    /* assign default and user-defined attributes */
+    if (sdfwatt(pcm, zvarid, "lev", "units", "millibar")) goto err;
+    if (sdfwatt(pcm, zvarid, "lev", "long_name", "Level")) goto err;
+    if (sdfwatt(pcm, zvarid, "lev", NULL, NULL)) goto err;
+    /* increment the number of varying dimensions */
+    vdims[nvdims] = 2;
+    nvdims++;
+  }
+  else {
+    zdimid = -999;
+    zvarid = -999;
+  }
+
+  /* T is varying or user wants to pad the output with non-varying dims */
+  if (pcm->vdim[3] || pcm->sdfwpad) {                    
+    /* define the dimension */
+    if (sdfdefdim (pcm->ncwid, "time", pfi->dnum[3], &tdimid, &tvarid)) goto err;
+    /* assign default and user-defined attributes */
+    if (sdfwatt(pcm, tvarid, "time", "long_name", "Time")) goto err;
+    if (sdfwatt(pcm, tvarid, "time", NULL, NULL)) goto err;
+    /* write out the time axis units and calendar attributes after the 
+       user-defined attributes. This guarantees that they will be correct */
+    gr2t (pfi->grvals[3],1.0+pfi->dimoff[3],&tinit);
+    snprintf(tunit,255,"minutes since %04d-%02d-%02d %02d:%02d",
+	    tinit.yr,tinit.mo,tinit.dy,tinit.hr,tinit.mn);
+    if (sdfwatt(pcm, tvarid, "time", "units", tunit)) goto err;
+    /* if necessary, assign 365_day_calendar attribute */
+    if ((*(pfi->grvals[3]+6) != 0) && (pfi->calendar==1)) {
+      if (sdfwatt(pcm, tvarid, "time", "calendar", "noleap")) goto err;
+    }
+    /* increment the number of varying dimensions */
+    vdims[nvdims] = 3;
+    nvdims++;
+  }
+  else {
+    tdimid = -999;
+    tvarid = -999;
+  }
+
+  /* E is varying or user wants to pad the output with non-varying dims */
+  if (pcm->vdim[4] || pcm->sdfwpad==2) {                    
+    /* define the dimension */
+    if (sdfdefdim (pcm->ncwid, "ens", pfi->dnum[4], &edimid, &evarid)) goto err;
+    /* assign default and user-defined attributes */
+    if (sdfwatt(pcm, evarid, "ens", "grads_dim", "e")) goto err;
+    if (sdfwatt(pcm, evarid, "ens", "long_name", "Ensemble member")) goto err;
+    if (sdfwatt(pcm, evarid, "ens", NULL, NULL)) goto err;
+    /* increment the number of varying dimensions */
+    vdims[nvdims] = 4;
+    nvdims++;
+  }
+  else {
+    edimid = -999;
+    evarid = -999;
+  }
+
+  /* Check to make sure at least one dimension is varying */
+  if (nvdims==0) {
+    gaprnt(0,"ncwrite error: defined variable has no varying dimensions\n");
+    goto err;
+  }
+
+  /* The dimids array is used to pass the dimids of the dimensions of the variable. 
+     The unlimited dimension must come first on the list of dimids, 
+     but in this case there is no unlimited dimension.  
+     The first dimid is the dimension that varies slowest, the outermost dimension, E in GrADS
+     The last  dimid is the dimension that varies fastest, the innermost dimension, X in GrADS 
+  */
+  for (i=0; i<nvdims; i++) {
+    if      (vdims[nvdims-1-i] == 4) dimids[i] = edimid; 
+    else if (vdims[nvdims-1-i] == 3) dimids[i] = tdimid; 
+    else if (vdims[nvdims-1-i] == 2) dimids[i] = zdimid; 
+    else if (vdims[nvdims-1-i] == 1) dimids[i] = ydimid; 
+    else if (vdims[nvdims-1-i] == 0) dimids[i] = xdimid; 
+  }
+
+  /* define the netCDF variable */
+  if (pcm->sdfprec==8) {
+    rc = nc_def_var(pcm->ncwid, name, NC_DOUBLE, nvdims, dimids, &varid);
+  }
+  else if (pcm->sdfprec==4) {
+    rc = nc_def_var(pcm->ncwid, name, NC_FLOAT, nvdims, dimids, &varid);
+  }
+  if (rc) {
+    snprintf(pout,255,"ncwrite error from nc_def_var (%s): \n ",name);
+    gaprnt(0,pout);
+    handle_error(rc);
+    goto err;
+  }
+ 
+#if HAVENETCDF4 == 1
+  /* If user has not set chunksizes, default chunk is a global 2D grid */
+  if (pcm->sdfchunk || pcm->sdfzip) {
+    /* set chunk sizes */
+    chunksize = (size_t*)galloc(nvdims*sizeof(size_t),"chnksz");
+    for (i=0; i<nvdims; i++) {
+      if      (vdims[nvdims-1-i] == 4) chunksize[i] = pcm->echunk ? pcm->echunk : 1 ; 
+      else if (vdims[nvdims-1-i] == 3) chunksize[i] = pcm->tchunk ? pcm->tchunk : 1 ; 
+      else if (vdims[nvdims-1-i] == 2) chunksize[i] = pcm->zchunk ? pcm->zchunk : 1 ; 
+      else if (vdims[nvdims-1-i] == 1) chunksize[i] = pcm->ychunk ? pcm->ychunk : pfi->dnum[1] ; 
+      else if (vdims[nvdims-1-i] == 0) chunksize[i] = pcm->xchunk ? pcm->xchunk : pfi->dnum[0] ; 
+    }
+    /* define variable as chunked */
+    rc = nc_def_var_chunking (pcm->ncwid, varid, NC_CHUNKED, chunksize);
+    if (rc) {
+      snprintf(pout,255,"ncwrite error from nc_def_var_chunking (%s): \n ",name);
+      gaprnt(0,pout);
+      handle_error(rc);
+      goto err;
+    }
+  }
+  if (pcm->sdfzip) {
+    /* compression settings: shuffle on, deflate level 1 */
+    rc = nc_def_var_deflate (pcm->ncwid, varid, 1, 1, 1); 
+    if (rc) {
+      snprintf(pout,255,"ncwrite error from nc_def_var_deflate (%s): \n ",name);
+      gaprnt(0,pout);
+      handle_error(rc);
+      goto err;
+    }
+  }
+#endif
+  
+  /* assign undef attribute to the netCDF variables. 
+     The undef attribute value is taken from pcm->undef instead of pfi->undef.
+     When the variable is defined, undef values are copied from pcm->undef.
+   */
+  if (pcm->sdfprec==8) {
+    rc = nc_put_att_double(pcm->ncwid, varid, "_FillValue", NC_DOUBLE, 1, &pcm->undef);
+  }
+  else if (pcm->sdfprec==4) {
+    flundef = (gafloat)pcm->undef;
+    rc = nc_put_att_float(pcm->ncwid, varid, "_FillValue", NC_FLOAT, 1, &flundef);
+  }
+  if (rc) {
+    snprintf(pout,255,"ncwrite error from nc_put_att (%s): \n ",name);
+    gaprnt(0,pout);
+    handle_error(rc);
+    goto err;
+  }
+  /* add any user-defined attributes */
+  if (sdfwatt(pcm, varid, name, NULL, NULL)) goto err;
+  if (sdfwatt(pcm, NC_GLOBAL, "global", NULL, NULL)) goto err;
+
+  /* End define mode. */
+  rc = nc_enddef(pcm->ncwid);
+  if (rc) {
+    gaprnt(0,"ncwrite error from nc_enddef: \n ");
+    handle_error(rc);
+    goto err;
+  }
+
+  /* Write the coordinate variable data */
+  if (pcm->vdim[0] || pcm->sdfwpad) if (sdfwdim (pfi, pcm, 0, xvarid)) goto err;
+  if (pcm->vdim[1] || pcm->sdfwpad) if (sdfwdim (pfi, pcm, 1, yvarid)) goto err;
+  if (pcm->vdim[2] || pcm->sdfwpad) if (sdfwdim (pfi, pcm, 2, zvarid)) goto err;
+  if (pcm->vdim[3] || pcm->sdfwpad) if (sdfwdim (pfi, pcm, 3, tvarid)) goto err;
+  if (pcm->vdim[4] || pcm->sdfwpad==2) if (sdfwdim (pfi, pcm, 4, evarid)) goto err;
+
+  /* set the start and count array values */
+  for (i=0; i<nvdims; i++) {
+    if      (vdims[nvdims-1-i] == 4) count[i] = pfi->dnum[4];
+    else if (vdims[nvdims-1-i] == 3) count[i] = pfi->dnum[3];
+    else if (vdims[nvdims-1-i] == 2) count[i] = pfi->dnum[2];
+    else if (vdims[nvdims-1-i] == 1) count[i] = pfi->dnum[1];
+    else if (vdims[nvdims-1-i] == 0) count[i] = pfi->dnum[0];
+    start[i] = 0;
+  }
+
+  /* Write the variable data. */
+  nelems = (off_t)pfi->dnum[0] * (off_t)pfi->dnum[1] * (off_t)pfi->dnum[2] * (off_t)pfi->dnum[3] * (off_t)pfi->dnum[4];
+  if (pcm->sdfprec==8) {
+    /* copy undef values into rbuf array where mask is 0 */
+    for (pos=0; pos<nelems; pos++) if (*(pfi->ubuf+pos)==0) *(pfi->rbuf+pos) = pcm->undef;
+    /* write the grid of doubles */
+    rc = nc_put_vara_double(pcm->ncwid, varid, start, count, pfi->rbuf);
+    if (rc) {
+      gaprnt(0,"ncwrite error from nc_put_vara_double: \n ");
+      handle_error(rc);
+      goto err;    
+    }
+  } 
+  else if (pcm->sdfprec==4) {
+    /* allocate a new array for float value grid */
+    flbuf = (gafloat *)galloc(nelems*sizeof(gafloat),"flbuf");
+    if (flbuf==NULL) {
+      gaprnt(0,"ncwrite error: unable to allocate memory for floating point buffer\n");
+      goto err;
+    }
+    /* copy undef values into array where mask is 0 */
+    for (pos=0; pos<nelems; pos++) {
+      if (*(pfi->ubuf+pos)==1)
+	*(flbuf+pos) = (gafloat)*(pfi->rbuf+pos);
+      else
+	*(flbuf+pos) = flundef;
+    }
+    /* write out the grid of floats */
+    rc = nc_put_vara_float(pcm->ncwid, varid, start, count, flbuf);
+    if (rc) {
+      gaprnt(0,"ncwrite error from nc_put_vara_float: \n ");
+      handle_error(rc);
+      gree(flbuf,"f333");
+      goto err;    
+    }
+    gree(flbuf,"f334");
+  }
+
+  /* Close the file. */
+  if (chunksize) gree(chunksize,"f335");
+  rc = nc_close(pcm->ncwid);
+  if (pcm->sdfwname) 
+    snprintf(pout,255,"Wrote variable %s to %s\n",name,pcm->sdfwname);
+  else 
+    snprintf(pout,255,"Wrote variable %s to grads.sdfwrite.nc\n",name);
+  gaprnt(2,pout);
+
+  return 0;
+
+
+ err:
+  if (chunksize) gree(chunksize,"f335");
+  if (pcm->ncwid != -999) nc_close(pcm->ncwid);
+  pcm->ncwid = -999; 
+  return 1;
+#endif
+  return(0);
+}
+
+
+void set_nc_cache(size_t newsize) {
+#if HAVENETCDF4==1
+  size_t size,nelems;
+  gafloat preemption;
+  gaint rc;
+
+  /* Get the cache size, nelems, and preemption policy. */
+  rc = nc_get_chunk_cache(&size, &nelems, &preemption);
+  size = newsize;
+  nelems = 51203;
+  /* Set the new cache size and nelems, recycle preemption policy. */
+  rc = nc_set_chunk_cache(newsize, nelems, preemption);
+  if (rc != NC_NOERR) {
+    gaprnt(1,"Warning: Unable to change the NetCDF cache parameters \n");
+  }
+#endif
+  return;
+}
+
+
+/* Routine to open a shapefile 
+   1. Tries to open filename as provided by user
+   2. Parses GASHP envv, which can have more than one directory, and prepends dirs to filename
+   3. Prepends GADDIR directory (only one dir) to filename 
+   N.B. Same code as gaopdbf routine below, make sure any mods go into both routines.
+*/
+#if USESHP==1
+SHPHandle gaopshp(char *shparg) {
+  SHPHandle id=NULL;
+  gaint i,j,len,sz,ch1,ch2;
+  char *sdir,*fname;
+
+  /* get length of shapefile name provided by user (ch2) */
+  ch2 = 0;
+  i = 0;
+  while (*(shparg+i)) { i++; ch2++; }
+
+  /* first try just the filename */
+  if ((id=SHPOpen(shparg,"rb"))!=NULL) return(id);
+
+  /* next try the directories in the GASHP environment variable */
+  sdir = getenv("GASHP");
+  while (sdir!=NULL) {
+    /* ch1 is length of directory harvested from GASHP */
+    ch1 = 0;
+    i = 0;
+    /* delimters are: space, semicolon, comma, or colon. NULL is at end of GASHP string  */
+    while (*(sdir+i)!=' ' && *(sdir+i)!=';' && *(sdir+i)!=',' && *(sdir+i)!=':' && *(sdir+i)!='\0') {i++; ch1++;} 
+    /* build new file name: directory + shparg + extra "/" (if necessary) + "/0" */
+    sz = ch1 + ch2 + 2;    
+    fname = (char *)galloc(sz,"shpname");
+    if (fname==NULL) {
+      gaprnt (0,"Memory allocation error for shapefile name\n");
+      return(NULL);
+    }
+    for (j=0; j<ch1; j++) *(fname+j) = *(sdir+j);            /* copy dir harvested from sdir to fname */
+    len = ch1;      
+    if (*(fname+ch1-1)!='/') { *(fname+ch1) = '/'; len++; }  /* add slash to fname if needed */
+    for (j=0; j<ch2; j++) *(fname+len+j) = *(shparg+j);      /* copy shparg to fname */
+    len += ch2;
+    *(fname+len)='\0';
+    /* try to open new filename */
+    if ((id=SHPOpen(fname,"rb"))!=NULL) {
+      gree(fname);                    
+      return(id);                                   /* success! */
+    } 
+    gree(fname);                                    /* release filename */
+    sdir+=ch1;                                      /* advance to delimiter */
+    if (*(sdir)=='\0') break;                       /* end of GASHP */
+    else sdir++;                                    /* advance past delimiter */
+    while (*(sdir)==' ' && *(sdir)!='\0') sdir++;   /* advance past any extra spaces */
+  }
+  
+  /* final option: try prepending GADDIR */
+  if ((id=SHPOpen(gxgnam(shparg),"rb"))!=NULL) return(id);
+ 
+  /* give up */
+  snprintf(pout,255,"Error: Unable to open shapefile \"%s\" \n",shparg);
+  gaprnt(0,pout);
+  return (NULL); 
+}
+
+/* open a shapefile attribute data base file 
+   1. Tries to open filename as provided by user
+   2. Parses GASHP envv, which can have more than one directory, and prepends dirs to filename
+   3. Prepends GADDIR directory (only one dir) to filename 
+   N.B. Same code as gaopshp routine above, make sure any mods go into both routines.
+*/
+DBFHandle gaopdbf(char *shparg) {
+  DBFHandle id=NULL;
+  gaint i,j,len,sz,ch1,ch2;
+  char *sdir,*fname;
+
+  /* get length of shapefile name provided by user (ch2) */
+  ch2 = 0;
+  i = 0;
+  while (*(shparg+i)) { i++; ch2++; }
+
+  /* first try just the filename */
+  if ((id=DBFOpen(shparg,"rb"))!=NULL) return(id);
+
+  /* next try the directories in the GASHP environment variable */
+  sdir = getenv("GASHP");
+  while (sdir!=NULL) {
+    /* ch1 is length of directory harvested from GASHP */
+    ch1 = 0;
+    i = 0;
+    /* delimters are: space, semicolon, comma, or colon. NULL is at end of GASHP string */
+    while (*(sdir+i)!=' ' && *(sdir+i)!=';' && *(sdir+i)!=',' && *(sdir+i)!=':' && *(sdir+i)!='\0') {i++; ch1++;} 
+    /* build new file name: directory + shparg + extra "/" (if necessary) + "/0" */
+    sz = ch1 + ch2 + 2;    
+    fname = (char *)galloc(sz,"shpname");
+    if (fname==NULL) {
+      gaprnt (0,"Memory allocation error for shapefile name\n");
+      return(NULL);
+    }
+    for (j=0; j<ch1; j++) *(fname+j) = *(sdir+j);            /* copy dir harvested from sdir to fname */
+    len = ch1;      
+    if (*(fname+ch1-1)!='/') { *(fname+ch1) = '/'; len++; }  /* add slash to fname if needed */
+    for (j=0; j<ch2; j++) *(fname+len+j) = *(shparg+j);      /* copy shparg to fname */
+    len += ch2;
+    *(fname+len)='\0';
+    /* try to open new filename */
+    if ((id=DBFOpen(fname,"rb"))!=NULL) {
+      gree(fname);                    
+      return(id);                                   /* success! */
+    } 
+    gree(fname);                                    /* release filename */
+    sdir+=ch1;                                      /* advance to delimiter */
+    if (*(sdir)=='\0') break;                       /* end of GASHP */
+    else sdir++;                                    /* advance past delimiter */
+    while (*(sdir)==' ' && *(sdir)!='\0') sdir++;   /* advance past any extra spaces */
+  }
+  
+  /* final option: try prepending GADDIR */
+  if ((id=DBFOpen(gxgnam(shparg),"rb"))!=NULL) return(id);
+ 
+  /* give up */
+  snprintf(pout,255,"Error: Unable to open shapefile \"%s\" \n",shparg);
+  gaprnt(0,pout);
+  return (NULL); 
+}
+#endif
+
+
+
+/* Parse a shapefile attribute (data base field). 
+   Return NULL for error, pointer to dbfld structure if successful */
+#if USESHP==1
+struct dbfld *parsedbfld (char *ch) {
+  gaint jj,len;
+  char fldname[512], fldtype[512], fldvalue[512];
+  void *value=NULL;
+  struct dbfld *field;
+  size_t sz;
+  DBFFieldType dbtype;
+  
+  /* get the field name */
+  len = 0;
+  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t' && *(ch+len)!='\0') len++;
+  if (len>11) {
+    gaprnt (2,"Warning: attribute name is too long, truncating to 11 characters\n");
+    len = 11;
+  }
+  for (jj=0; jj<len; jj++) fldname[jj] = *(ch+jj);
+  fldname[len] = '\0';
+  
+  /* get the field type */
+  if ( (ch=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing attribute type and value \n"); 
+    goto err;
+  } 
+  len = 0;
+  while (*(ch+len)!=' ' && *(ch+len)!='\n' && *(ch+len)!='\t' && *(ch+len)!='\0') len++;
+  for (jj=0; jj<len; jj++) fldtype[jj] = *(ch+jj);
+  fldtype[len] = '\0';
+  
+  /* See if field type matches accepted types */
+  if (!(strncasecmp(fldtype,"string",6)) || 
+      !(strncasecmp(fldtype,"char",4))) {
+    dbtype = FTString; 
+  } else if (!(strncasecmp(fldtype,"int", 3))) {
+    dbtype = FTInteger;
+  } else if (!(strncasecmp(fldtype,"double", 6))) {
+    dbtype = FTDouble;
+  } else {
+    gaprnt (2,"Warning: Invalid attribute type \n"); 
+    goto err;
+  }
+  
+  /* get the attribute value */
+  if ((ch=nxtwrd(ch))==NULL ) {
+    gaprnt (2,"Warning: Missing attribute value \n"); 
+    goto err;
+  } 
+  getstr (fldvalue, ch, 512);
+  /* Get length of field value */  
+  len=strlen(fldvalue);
+
+  /* check if int and double values parse ok -- Maybe not necessary */
+
+  /* allocate space for the field value */
+  sz = (len+1) * sizeof(char);
+  if ((value = (void *)galloc(sz,"valuec")) == NULL) {
+    gaprnt (0,"Error: memory allocation failed for shapefile attribute \n");
+    goto err;
+  }
+  strcpy(value,fldvalue);
+
+  /* Everything parsed and allocated OK, so allocate and populate a dbfld structure */
+  sz = sizeof(struct dbfld);
+  field = (struct dbfld *) galloc(sz,"dbfield");
+  if (field != NULL) {
+    strcpy(field->name,fldname);
+    field->type = dbtype;
+    field->len = len;
+    field->value = value;
+    field->flag = 0;        /* static field -- value same for each shape */   
+    field->next = NULL;
+  } else {
+    gaprnt (0,"Error: memory allocation failed for attribute metadata\n");
+    goto err;
+  }
+  /* return the pointer to the field structure */
+  return field;
+
+ err:
+  if (value) gree(value,"g184");
+  return(NULL);
+}
+#endif
+ 
diff --git a/src/gautil.c b/src/gautil.c
new file mode 100644
index 0000000..381e4ce
--- /dev/null
+++ b/src/gautil.c
@@ -0,0 +1,2389 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Originally authored by B. Doty */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <limits.h>
+#include <string.h>
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+
+#include "config.h"
+#if READLINE == 1
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include "readline/readline.h"
+#include "readline/history.h"
+#endif
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+#if READLINE == 1
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include "readline/readline.h"
+#include "readline/history.h"
+#endif
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include "grads.h"
+#include "gx.h"
+
+struct gamfcmn mfcmn;
+
+static char pout[256];   /* Build Error msgs here */
+
+char *gatxtl(char *str, gaint color);
+
+/* Retrieves the next command from the user.  Leading blanks
+   are stripped.  The number of characters entered before the
+   CR is returned.                                                    */
+
+gaint nxtcmd (char *cmd, char *prompt) {
+gaint past,cnt;
+
+  printf ("%s ",gatxtl(prompt,-1));
+  past = 0;
+  cnt = 0;
+  while (1) {
+    *cmd = getchar();
+    if (*cmd == EOF) return (-1);
+    if (*cmd == '\n') {
+      cmd++;
+      *cmd = '\0';
+      return (cnt);
+    }
+    if (past || *cmd != ' ') {
+      cmd++; cnt++; past = 1;
+    }
+  }
+}
+
+/* Retrieves the next command from the user.  Leading blanks
+   are stripped.  The number of characters entered before the
+   CR is returned.                                                    */
+
+#if READLINE == 1
+gaint nxrdln (char *cmd, char *prompt) {
+char *ch, *ch2;
+
+  ch=readline(gatxtl(prompt,-1));
+  if ( ch== NULL) {
+    return(-1);
+  } else {
+    ch2 = ch;
+    while (*ch == ' ') ch++;   /* Skip leading blanks */
+    strcpy(cmd, ch);
+    if (*ch) add_history(ch);   /* Skip blank lines */
+  }
+  return(strlen(cmd)+1);
+
+}
+#endif
+
+/* Date/Time manipulation routines.  Note that these routines
+   are not particularly efficient, thus Date/Time conversions
+   should be kept to a minimum.                                      */
+
+static gaint mosiz[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
+static gaint momn[13] = {0,44640,40320,44640,43200,44640,43200,
+                        44640,44640,43200,44640,43200,44640};
+static gaint mnacum[13] = {0,0,44640,84960,129600,172800,217440,
+                        260640,305280,349920,393120,437760,480960};
+static gaint mnacul[13] = {0,0,44640,86400,131040,174240,218880,
+                        262080,306720,351360,394560,439200,482400};
+
+/* Add an offset to a time.  Output to dto.                          */
+
+void timadd (struct dt *dtim, struct dt *dto) {
+gaint i;
+gaint cont;
+
+  /* First add months and years.  Normalize as needed.               */
+  dto->mo += dtim->mo;
+  dto->yr += dtim->yr;
+
+  while (dto->mo>12) {
+    dto->mo -= 12;
+    dto->yr++;
+  }
+
+  /* Add minutes, hours, and days directly.  Then normalize
+     to days, then normalize extra days to months/years.             */
+
+  dto->mn += dtim->mn;
+  dto->hr += dtim->hr;
+  dto->dy += dtim->dy;
+
+  if (dto->mn > 59) {
+    i = dto->mn / 60;
+    dto->hr += i;
+    dto->mn = dto->mn - (i*60);
+  }
+  if (dto->hr > 23) {
+    i = dto->hr / 24;
+    dto->dy += i;
+    dto->hr = dto->hr - (i*24);
+  }
+
+  cont = 1;
+  while (dto->dy > mosiz[dto->mo] && cont) {
+    if (dto->mo==2 && qleap(dto->yr)) {
+      if (dto->dy == 29) cont=0;
+      else {
+        dto->dy -= 29;
+        dto->mo++;
+      }
+    } else {
+      dto->dy -= mosiz[dto->mo];
+      dto->mo++;
+    }
+    while (dto->mo > 12) {dto->mo-=12; dto->yr++;}
+  }
+}
+
+/* Subtract an offset from a time.  Subtract minutes/hours/days
+   first so that we will exactly reverse the operation of timadd     */
+
+void timsub (struct dt *dtim, struct dt *dto) {
+gaint s1,s2;
+
+  /* Subtract minutes, hour, and days directly.  Then normalize
+     to days, then normalize deficient days from months/years.       */
+
+  dto->mn = dtim->mn - dto->mn;
+  dto->hr = dtim->hr - dto->hr;
+  dto->dy = dtim->dy - dto->dy;
+  s1 = dto->mo; s2 = dto->yr;
+  dto->mo = dtim->mo;
+  dto->yr = dtim->yr;
+
+  while (dto->mn < 0) {dto->mn+=60; dto->hr--;}
+  while (dto->hr < 0) {dto->hr+=24; dto->dy--;}
+
+  while (dto->dy < 1) {
+    dto->mo--;
+    if (dto->mo < 1) {dto->mo=12; dto->yr--;}
+    if (dto->mo==2 && qleap(dto->yr)) dto->dy += 29;
+    else dto->dy += mosiz[dto->mo];
+  }
+
+  /* Now subtract months and years.  Normalize as needed.            */
+
+  dto->mo = dto->mo - s1;
+  dto->yr = dto->yr - s2;
+
+  while (dto->mo < 1) {dto->mo+=12; dto->yr--;}
+
+  /* Adjust for leaps */
+
+  if (dto->mo==2 && dto->dy==29 && !qleap(dto->yr)) {
+    dto->mo=3; dto->dy=1;
+  }
+}
+
+/* Convert from Absolute time (year/month/day/etc.) to grid
+   coordinate.                                                       */
+
+gadouble t2gr (gadouble *vals, struct dt *dtim) {
+struct dt stim;
+gaint eyear,mins;
+gadouble val,*moincr,*mnincr,rdiff;
+
+  /* Get constants associated with this conversion                   */
+
+  stim.yr = (gaint)(*vals+0.1);
+  stim.mo = (gaint)(*(vals+1)+0.1);
+  stim.dy = (gaint)(*(vals+2)+0.1);
+  stim.hr = (gaint)(*(vals+3)+0.1);
+  stim.mn = (gaint)(*(vals+4)+0.1);
+
+  moincr = vals+5;
+  mnincr = vals+6;
+
+  /* If the increment for this conversion is days, hours, or minutes,
+     then we do our calculations in minutes.  If the increment is
+     months or years, we do our calculations in months.              */
+
+  if (*mnincr>0.1) {
+    mins = timdif(&stim,dtim);
+    rdiff = (gadouble)mins;
+    val = rdiff/(*mnincr);
+    val += 1.0;
+    return (val);
+  } else {
+    eyear = stim.yr;
+    if (stim.yr > dtim->yr) eyear = dtim->yr;
+    rdiff = (((dtim->yr - eyear)*12) + dtim->mo) -
+            (((stim.yr - eyear)*12) + stim.mo);
+    stim.yr = dtim->yr;
+    stim.mo = dtim->mo;
+    mins = timdif(&stim,dtim);
+    if (mins>0) {
+      if (dtim->mo==2 && qleap(dtim->yr) ) {
+        rdiff = rdiff + (((gadouble)mins)/41760.0);
+      } else {
+        rdiff = rdiff + (((gadouble)mins)/((gadouble)momn[dtim->mo]));
+      }
+    }
+    val = rdiff/(*moincr);
+    val += 1.0;
+    return (val);
+  }
+}
+
+/* Convert from a t grid coordinate to an absolute time.           */
+
+void gr2t (gadouble *vals, gadouble gr, struct dt *dtim) {
+struct dt stim;
+gadouble *moincr,*mnincr;
+gadouble v;
+
+  /* Get constants associated with this conversion                   */
+  stim.yr = (gaint)(*vals+0.1);
+  stim.mo = (gaint)(*(vals+1)+0.1);
+  stim.dy = (gaint)(*(vals+2)+0.1);
+  stim.hr = (gaint)(*(vals+3)+0.1);
+  stim.mn = (gaint)(*(vals+4)+0.1);
+  moincr = vals+5;
+  mnincr = vals+6;
+
+  /* Initialize output time                                          */
+  dtim->yr = 0;
+  dtim->mo = 0;
+  dtim->dy = 0;
+  dtim->hr = 0;
+  dtim->mn = 0;
+
+  /* Do conversion if increment is in minutes.                       */
+  if (*mnincr>0.1) {
+    v = *mnincr * (gr-1.0);
+    if (v>0.0) v = v + 0.5;   /* round */
+    else v = v - 0.5;
+    dtim->mn = (gaint)v;
+    if (dtim->mn<0) {
+      dtim->mn = -1 * dtim->mn;
+      timsub (&stim,dtim);
+    } else {
+      timadd (&stim,dtim);
+    }
+    return;
+
+  /* Do conversion if increment is in months.  Same as for minutes,
+     except special handling is required for partial months.   
+     JMA There is a bug here, and some precision decisions that need attention */
+
+  } else {
+    v = *moincr * (gr-1.0);
+    if (v<0.0) dtim->mo = (gaint)(v-0.9999); /* round (sort of)       */
+    else dtim->mo = (gaint)(v+0.0001);
+    v = v - (gadouble)dtim->mo;                /* Get fractional month  */
+    if (dtim->mo<0) {
+      dtim->mo = -1 * dtim->mo;
+      timsub (&stim,dtim);
+    } else timadd (&stim,dtim);
+    if (v<0.0001) return;         /* if fraction small, return       */
+
+    if (dtim->mo==2 && qleap(dtim->yr) ) {
+      v = v * 41760.0;
+    } else {
+      v = v * (gadouble)momn[dtim->mo];
+    }
+    stim = *dtim;
+    dtim->yr = 0;
+    dtim->mo = 0;
+    dtim->dy = 0;
+    dtim->hr = 0;
+    dtim->mn = (gaint)(v+0.5);
+    timadd (&stim,dtim);
+    return;
+  }
+}
+
+/* Calculate the difference between two times and return the
+   difference in minutes.   The calculation is time2 - time1, so
+   if time2 is earlier than time1, the result is negative.           */
+
+gaint timdif (struct dt *dtim1, struct dt *dtim2) {
+gaint min1,min2,yr;
+struct dt *temp;
+gaint swap,mo1,mo2;
+
+  swap = 0;
+  if (dtim1->yr > dtim2->yr) {
+    temp = dtim1;
+    dtim1 = dtim2;
+    dtim2 = temp;
+    swap = 1;
+  }
+
+  min1 = 0;
+  min2 = 0;
+
+  yr = dtim1->yr;
+  while (yr < dtim2->yr) {
+    if (qleap(yr)) min2 += 527040L;
+    else min2 += 525600L;
+    yr++;
+  }
+
+  mo1 = dtim1->mo;
+  mo2 = dtim2->mo;
+  if (qleap(dtim1->yr)) {
+    min1 = min1+mnacul[mo1]+(dtim1->dy*1440L)+(dtim1->hr*60L)+dtim1->mn;
+  } else {
+    min1 = min1+mnacum[mo1]+(dtim1->dy*1440L)+(dtim1->hr*60L)+dtim1->mn;
+  }
+  if (qleap(dtim2->yr)) {
+    min2 = min2+mnacul[mo2]+(dtim2->dy*1440L)+(dtim2->hr*60L)+dtim2->mn;
+  } else {
+    min2 = min2+mnacum[mo2]+(dtim2->dy*1440L)+(dtim2->hr*60L)+dtim2->mn;
+  }
+  if (swap) return (min1-min2);
+  else return (min2-min1);
+}
+
+/* Test for leap year.  Rules are:
+
+      Divisible by 4, it is a leap year, unless....
+      Divisible by 100, it is not a leap year, unless...
+      Divisible by 400, it is a leap year.                           */
+
+gaint qleap (gaint year)  {
+gaint i,y;
+
+/*mf - disable if 365 day calendar mf*/
+
+ if(mfcmn.cal365 == 1) return(0);
+
+  y = year;
+
+  i = y / 4;
+  i = (i*4) - y;
+  if (i!=0) return (0);
+
+  i = y / 100;
+  i = (i*100) - y;
+  if (i!=0) return (1);
+
+  i = y / 400;
+  i = (i*400) - y;
+  if (i!=0) return (0);
+
+  return (1);
+
+
+}
+
+static char *mons[12] = {"jan","feb","mar","apr","may","jun",
+			 "jul","aug","sep","oct","nov","dec"};
+
+/* Parse an absolute date/time value.  Format is:
+
+   12:00z 1jan 1989 (jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec)
+
+   Must have Z or Month abbrev, or value is invalid.  'def' contains
+   higher order missing values (usually from tmin in pst).  Lower order
+   values are defaulted to be: dy = 1, hr = 0, mn = 0.              */
+
+char *adtprs (char *ch, struct dt *def, struct dt *dtim) {
+gaint val,flag,i;
+char *pos;
+char monam[5];
+
+  pos = ch;
+
+  dtim->mn = 0;
+  dtim->hr = 0;
+  dtim->dy = 1;
+
+  if (*ch>='0' && *ch<='9') {
+  flag = 0;
+    ch = intprs (ch,&val);
+    if (*ch == ':' || tolower(*ch) == 'z') {
+      if (val>23) {
+        gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+        snprintf(pout,255,"  Hour = %i -- greater than 23\n",val);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      dtim->hr = val;
+      if (*ch == ':') {
+        ch++;
+        if (*ch>='0' && *ch<='9') {
+          ch = intprs (ch,&val);
+          if (val>59) {
+            gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+            snprintf(pout,255,"  Minute = %i -- greater than 59\n",val);
+            gaprnt (0,pout);
+            return (NULL);
+          }
+          if (tolower(*ch)!='z') {
+            gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+            gaprnt (0,"  'z' delimiter is missing \n");
+            return (NULL);
+          }
+          dtim->mn = val;
+          ch++;
+          if (*ch>='0' && *ch<='9') ch = intprs (ch,&val);
+          else val = def->dy;
+        } else {
+          gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+          gaprnt (0,"  Missing minute value \n");
+          return (NULL);
+        }
+      } else {
+        ch++;
+        if (*ch>='0' && *ch<='9') ch = intprs (ch,&val);
+        else val = def->dy;
+      }
+    } else flag = 2;
+    dtim->dy = val;
+  } else flag = 1;
+
+  monam[0] = tolower(*ch);
+  monam[1] = tolower(*(ch+1));
+  monam[2] = tolower(*(ch+2));
+  monam[3] = '\0';
+
+  i = 0;
+  while (i<12 && !cmpwrd(monam,mons[i]) ) i++;
+  i++;
+
+  if (i==13) {
+    if (flag==1) {
+      gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+      gaprnt (0,"  Expected month abbreviation, none found\n");
+      return (NULL);
+    }
+    if (flag==2) {
+      gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+      gaprnt (0,"  Missing month abbreviation or 'z' delimiter\n");
+      return (NULL);
+    }
+    dtim->mo = def->mo;
+    dtim->yr = def->yr;
+  } else {
+    dtim->mo = i;
+    ch+=3;
+    /* parse year */
+    if (*ch>='0' && *ch<='9') {
+      /* use fullyear only if year 1 = 0001*/
+      if(*(ch+2)>='0' && *(ch+2)<='9') {
+	mfcmn.fullyear=1;   /* 4-digit year */
+      } else {
+	mfcmn.fullyear=0;   /* 2-digit year */
+      }
+      ch = intprs (ch,&val);
+    } else {
+      val = def->yr;
+    }
+
+    /* turn off setting of < 100 years to 1900 or 2000 */
+    if(mfcmn.fullyear == 0) {
+      if (val<50) val+=2000;
+      else if (val<100) val+=1900;
+    }
+    dtim->yr = val;
+  }
+
+  i = mosiz[dtim->mo];
+  if (dtim->mo==2 && qleap(dtim->yr)) i = 29;
+  if (dtim->dy > i) {
+    gaprnt (0,"Syntax Error:  Invalid Date/Time value.\n");
+    snprintf(pout,255,"  Day = %i -- greater than %i \n",dtim->dy,i);
+    gaprnt (0,pout);
+    return (NULL);
+  }
+  return (ch);
+}
+
+/* Parse a relative date/time (offset).  Format is:
+
+   nn (yr/mo/dy/hr/mn)
+
+   Examples:  5mo
+              1dy12hr
+              etc.
+
+   Missing values are filled in with 0s.                             */
+
+char *rdtprs (char *ch, struct dt *dtim) {
+gaint flag,val;
+char *pos;
+char id[3];
+
+  pos = ch;
+
+  dtim->yr = 0;
+  dtim->mo = 0;
+  dtim->dy = 0;
+  dtim->hr = 0;
+  dtim->mn = 0;
+
+  flag = 1;
+
+  while (*ch>='0' && *ch<='9') {
+    flag = 0;
+    ch = intprs(ch,&val);
+    id[0] = *ch; id[1] = *(ch+1); id[2] = '\0';
+    if (cmpwrd("yr",id)) dtim->yr = val;
+    else if (cmpwrd("mo",id)) dtim->mo = val;
+    else if (cmpwrd("dy",id)) dtim->dy = val;
+    else if (cmpwrd("hr",id)) dtim->hr = val;
+    else if (cmpwrd("mn",id)) dtim->mn = val;
+    else {
+      gaprnt (0,"Syntax Error:  Invalid Date/Time offset.\n");
+      snprintf(pout,255,"  Expecting yr/mo/dy/hr/mn, found %s\n",id);
+      gaprnt (0,pout);
+      return (NULL);
+    }
+    ch+=2;
+  }
+  if (flag) {
+    gaprnt (0,"Syntax Error:  Invalid Date/Time offset.\n");
+    gaprnt (0,"  No offset value given\n");
+    return (NULL);
+  }
+  return (ch);
+}
+
+
+/* Compares two strings.  A match occurs if the leading
+   blank-delimited words in the two strings match.  CR and NULL also
+   serve as delimiters.                                               */
+
+gaint cmpwrd (char *ch1, char *ch2) {
+
+  while (*ch1==' '||*ch1=='\t') ch1++;  /* Advance past leading blanks.     */
+  while (*ch2==' '||*ch2=='\t') ch2++;
+
+  while (*ch1 == *ch2) {
+    if (*ch1==' '||*ch1=='\t'||*ch1=='\0'||*ch1=='\n'||*ch1=='\r' ) return (1);
+    ch1++; ch2++;
+  }
+
+  if ( (*ch1==' '||*ch1=='\t'||*ch1=='\0'||*ch1=='\n'||*ch1=='\r') &&
+       (*ch2==' '||*ch2=='\t'||*ch2=='\0'||*ch2=='\n'||*ch2=='\r') ) return (1);
+  return (0);
+}
+/* case insensitive version of cmpwrd  */
+
+gaint cmpwrdl (char *ch1, char *ch2) {
+  if(ch1 == NULL || ch2 == NULL) return(0);
+
+  while (*ch1==' '||*ch1=='\t') ch1++;  /* Advance past leading blanks.     */
+  while (*ch2==' '||*ch2=='\t') ch2++;
+
+  while (tolower(*ch1) == tolower(*ch2)) {
+    if (*ch1==' '||*ch1=='\t'||*ch1=='\0'||*ch1=='\n'||*ch1=='\r' ) return (1);
+    ch1++; ch2++;
+  }
+
+  if ( (*ch1==' '||*ch1=='\t'||*ch1=='\0'||*ch1=='\n'||*ch1=='\r' ) &&
+       (*ch2==' '||*ch2=='\t'||*ch2=='\0'||*ch2=='\n'||*ch2=='\r' ) ) return (1);
+  return (0);
+}
+
+/* Moves a pointer to the start of the next blank-delimited word
+   in a string.  If not found, NULL is returned.                     */
+
+char * nxtwrd (char *ch) {
+
+  while (*ch!=' '&&*ch!='\t') {                     /* Skip 1st word  */
+    if (*ch == '\0' || *ch == '\n' || *ch == '\r') return (NULL);
+    ch++;
+  }
+  while (*ch==' '||*ch=='\t') ch++;                 /* Find next word */
+  if (*ch == '\0' || *ch == '\n' || *ch == '\r') return (NULL);
+  return (ch);
+}
+
+
+/* Linear conversion routine for dimension conversions.               */
+
+gadouble liconv (gadouble *vals, gadouble v) {
+  return ( (*vals * v) + *(vals+1) );
+}
+
+/* Non-linear scaling routine for discrete levels.  Linear interp
+   between levels.  Scaling beyond upper and lower bounds is
+   linear based on the last and first grid spacing, respectively.
+   In each case a pointer to a list of values is provided.  The
+   list contains in its first element the number of values
+   in the list.    */
+
+/* Convert a grid value to a world coordinate value.
+   This operation needs to be efficient, since it gets done
+   very often.  */
+
+gadouble gr2lev (gadouble *vals, gadouble gr) {
+gaint i;
+  if (gr<1.0) return ( *(vals+1) + (1.0-gr)*(*(vals+1)-*(vals+2)) );
+  if (gr>*vals) {
+    i = (gaint)(*vals+0.1);
+    return ( *(vals+i) + (gr-*vals)*(*(vals+i)-*(vals+i-1)) );
+  }
+  i = (gaint)gr;
+  return (*(vals+i)+((gr-(gadouble)i)*(*(vals+i+1)-*(vals+i))));
+}
+
+/* Convert from world coordinate value to grid value.  This operation
+   is not set up to be efficient, under the assumption that it won't
+   get done all that often.  */
+
+gadouble lev2gr (gadouble *vals, gadouble lev) {
+gaint i,num;
+gadouble gr;
+  num = (gaint)(*vals+0.1);
+  for (i=1; i<num; i++) {
+    if ( (lev >= *(vals+i) && lev <= *(vals+i+1)) ||
+         (lev <= *(vals+i) && lev >= *(vals+i+1)) ) {
+      gr = (gadouble)i + (lev - *(vals+i))/(*(vals+i+1) - *(vals+i));
+      return (gr);
+    }
+  }
+  if (*(vals+1)<*(vals+num)) {
+    if (lev<*(vals+1)) {
+      gr = 1.0 + ((lev-*(vals+1))/(*(vals+2)-*(vals+1)));
+      return (gr);
+    }
+    gr = (gadouble)i + ((lev-*(vals+i))/(*(vals+i)-*(vals+i-1)));
+    return (gr);
+  } else {
+    if (lev>*(vals+1)) {
+      gr = 1.0 + ((lev-*(vals+1))/(*(vals+2)-*(vals+1)));
+      return (gr);
+    }
+    gr = (gadouble)i + ((lev-*(vals+i))/(*(vals+i)-*(vals+i-1)));
+    return (gr);
+  }
+}
+
+/* Convert from ensemble number to ensemble name */
+char *e2ens (struct gafile *pfi, gadouble e) {
+
+  char *name;
+  if ((gaint)(e-0.99) < pfi->dnum[4]) {
+    name = pfi->ens1[(gaint)(e-0.99)].name;
+    return name;
+  }
+  else return NULL;
+}
+
+
+
+/* Parses a number in a character string.
+   This routine will detect numbers of the form:
+       nnnn
+       -nnnn
+
+   Args:    ch     - pointer to the number, in character form.
+            val    - integer value returned
+            return value  - address of 1st character past the
+                            number parsed.  NULL if no number found
+                            at pointer ch or if the number is an
+                            invalid format.
+             */
+
+char *intprs (char *ch, gaint *val) {
+
+gaint nflag,flag;
+
+  nflag = 0;
+  if (*ch=='-') { nflag = 1; ch++; }
+  else if (*ch=='+') ch++;
+
+  *val = 0;
+  flag = 1;
+
+  while (*ch>='0' && *ch<='9') {
+    *val = *val*10 + (gaint)(*ch-'0');
+    flag = 0;
+    ch++;
+  }
+
+  if (flag) return (NULL);
+
+  if (nflag) *val = -1 * *val;
+  return (ch);
+}
+
+char *longprs (char *ch, long *val) {
+
+gaint nflag,flag;
+
+  nflag = 0;
+  if (*ch=='-') { nflag = 1; ch++; }
+  else if (*ch=='+') ch++;
+
+  *val = 0;
+  flag = 1;
+
+  while (*ch>='0' && *ch<='9') {
+    *val = *val*10 + (gaint)(*ch-'0');
+    flag = 0;
+    ch++;
+  }
+
+  if (flag) return (NULL);
+
+  if (nflag) *val = -1 * *val;
+  return (ch);
+}
+
+
+/* Converts strings to double */
+char * getdbl(char *ch, gadouble *val) {
+  char * pos;
+  gadouble res;
+
+  res = strtod(ch, &pos);
+  if (pos==ch) {
+    return NULL;
+  } else {
+    *val = res;
+    return pos;
+  }
+}
+
+/* Converts strings to double */
+char * getflt(char *ch, gafloat *val) {
+char * pos;
+  *val = (gafloat)strtod(ch, &pos);
+  if (pos==ch) {
+    return NULL;
+  } else {
+    return pos;
+  }
+}
+
+
+
+/* dimprs parses a dimension 'expression', ie, where the user
+   specifies an absolute or relative dimension value.
+   The format is:
+
+   dim op val
+
+   where:  dim = x,y,z,t,e,lat,lon,lev,time,ens,offt
+           op  = +, -, or =
+           val = dimension value
+
+   Examples are:
+           t=1
+           lev=500
+           time=00:00z01jan1989
+
+   The coordinates are evaluated with respect to the coordinate
+   transformations of the file descriptor passed.  Grid
+   coordinates are returned.  Relative offsets are evaluated
+   from the values in the status block.
+
+   In addition, r=radius is also supported.  The dimension value
+   returned is the radius, and the dimension number returned
+   is 10. This is only valid for stn type files.
+
+   wflag is set to 
+   0 if the dimension expression was grid coordinates; 
+   1 if it was world coordinates; 
+   2 if forecast time offsets are used
+                                                                */
+
+char *dimprs (char *ch, struct gastat *pst, struct gafile *pfi,
+              gaint *dim, gadouble *d, gaint type, gaint *wflag) {
+struct dt dtim;
+struct gaens *ens;
+gadouble (*conv) (gadouble *, gadouble);
+gadouble *cvals,v;
+/* gadouble g1,g2; */
+gaint i,op,len,enum1;
+char *pos;
+char name[15],ename[20];
+  
+  /* parse the dimension name */
+  i = 0;
+  while (*ch>='a' && *ch<='z' && i<6) {
+    name[i] = *ch;
+    ch++; i++;
+  }
+  name[i] = '\0';
+  if (i>4) {
+    gaprnt (0,"Syntax Error:  Invalid dimension expression \n");
+    snprintf(pout,255,"  Expecting x/y/z/t/offt/e/lon/lat/lev/time/ens, found %s\n",name);
+    gaprnt (0,pout);
+    return (NULL);
+  }
+
+  /* parse the operator */
+  if      (*ch == '=') op = 0;
+  else if (*ch == '+') op = 1;
+  else if (*ch == '-') op = 2;
+  else {
+    gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+    snprintf(pout,255,"  Expecting +/-/= operator, found %c\n",*ch);
+    gaprnt (0,pout);
+    return (NULL);
+  }
+
+  /* dimension is TIME */
+  ch++;
+  if (cmpwrd("time",name)) {
+    if (op==0) {
+      if ((pos=adtprs(ch,&(pst->tmin),&dtim)) == NULL) {
+        gaprnt (0,"  Invalid absolute time in dimension expression\n");
+        return (NULL);
+      }
+    } else {
+      if ((pos=rdtprs(ch,&dtim)) == NULL) {
+        gaprnt (0,"  Invalid relative time in dimension expression\n");
+	return (NULL);
+      }
+    }
+  } 
+  /* dimension is ENS */
+  else if (cmpwrd("ens",name)) {
+    /* parse the ensemble name */
+    pos = ch;
+    len=0;
+    while (len<16 && *pos!=')' ) {
+      ename[len] = *pos;
+      len++; 
+      pos++;
+    }
+    ename[len] = '\0';
+  }
+  /* all other dimensions */
+  else {
+    if ((pos=getdbl(ch,&v)) == NULL) {
+      gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+      gaprnt (0,"  Dimension value missing or invalid\n");
+      return (NULL);
+    }
+  }
+  ch = pos;
+
+  /* We now have all the info we need about this dimension expression to evaluate it.  */
+  if      (cmpwrd("x",name))    *dim = 0;
+  else if (cmpwrd("y",name))    *dim = 1;
+  else if (cmpwrd("z",name))    *dim = 2;
+  else if (cmpwrd("t",name))    *dim = 3;
+  else if (cmpwrd("offt",name)) *dim = 3;
+  else if (cmpwrd("e",name))    *dim = 4;
+  else if (cmpwrd("lon",name))     *dim = 5;
+  else if (cmpwrd("lat",name))     *dim = 6;
+  else if (cmpwrd("lev",name))     *dim = 7;
+  else if (cmpwrd("time",name))    *dim = 8;
+  else if (cmpwrd("ens",name))     *dim = 9;
+  else if (type==0 && cmpwrd("r",name)) *dim = 10;
+  else {
+    gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+    snprintf(pout,255,"  Expecting x/y/z/t/offt/e/lat/lon/lev/time/ens, found %s\n",name);
+    gaprnt (0,pout);
+    return (NULL);
+  }
+
+  /* for station expressions */
+  if (*dim==10) {
+    *d = v;
+    return (ch);
+  }
+
+  /* dimension expression is given in grid coordinates: x, y, z, t, offt, or e */
+  *wflag = 0;          
+  if (*dim < 5) {  
+    if (cmpwrd("offt",name)) *wflag=2;     /* trip the time offset flag */
+    if (op==0) {
+      *d = v + pfi->dimoff[*dim];          /* straight override of fixed dimension value */
+      return (ch);
+    } else {
+      /* make sure the dimension is not varying */
+      if (*dim==pst->idim || *dim==pst->jdim) {
+	gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+	gaprnt (0,"  Cannot use an offset value with a varying dimension\n");
+	snprintf(pout,255,"  Varying dimension = %i \n",*dim);
+	gaprnt (0,pout);
+	return (NULL);
+      }
+      /* get current dimension value in grid coordinates from gastat structure */
+      if (*dim == 3) {
+        *d = t2gr(pfi->abvals[3],&(pst->tmin));  
+      } 
+      else {
+        if (pfi->type==1 || pfi->type==4) { 
+          conv = pfi->ab2gr[*dim];
+          cvals = pfi->abvals[*dim];
+          *d = conv(cvals,pst->dmin[*dim]);
+        } else {
+          *d = pst->dmin[*dim];
+        }
+      }
+      /* combine offset with current dimension value */
+      if (op==1) *d = *d + v;
+      if (op==2) *d = *d - v;
+      return (ch);
+    }
+  } 
+  /* dimension expression is given in world coordinates: lon, lat, lev, time, or ens */
+  else {                        
+    *dim = *dim - 5;
+    *wflag = 1;          
+/*     if (cmpwrd("offtime",name)) { */
+/*       /\* determine the size of the time offset in grid units *\/ */
+/*       g1 = t2gr(pfi->abvals[3],&(pst->tmin)); */
+/*       timadd (&(pst->tmin),&dtim); */
+/*       g2 = t2gr(pfi->abvals[3],&dtim); */
+/*       v = g2 - g1; */
+/*       *wflag=2;      /\* trip the time offset flag *\/ */
+/*     } */
+    if (op>0) {
+      /* check to make sure dimension isn't varying */
+      if (*dim==pst->idim || *dim==pst->jdim) {
+        gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+        gaprnt (0,"  Cannot use an offset value with a varying dimension\n");
+        snprintf(pout,255,"  Varying dimension = %i \n",*dim);
+        gaprnt (0,pout);
+        return (NULL);
+      }
+      /* check to make sure dimension isn't E */
+      if (*dim==4) {
+	gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+	gaprnt (0,"  Cannot use an offset value with an ensemble name\n");
+	return (NULL);
+      } 
+      /* combine offset with current dimension value from gastat structure */
+      if (*dim==3) {
+        if (op==1) timadd (&(pst->tmin),&dtim);
+        if (op==2) timsub (&(pst->tmin),&dtim);
+      } 
+      else {
+        if (op==1) v = pst->dmin[*dim] + v;
+        if (op==2) v = pst->dmin[*dim] - v;
+      }
+    }
+
+    if (*dim == 4) {
+      /* loop over ensembles, looking for matching name */
+      ens = pfi->ens1;
+      i=0;
+      enum1=-1;
+      while (i<pfi->dnum[*dim]) {
+	if (strcmp(ename,ens->name) == 0) enum1=i;  /* grid coordinate of matching name */
+	i++; ens++;
+      }
+      if (enum1<0) {
+	gaprnt (0,"Syntax Error:  Invalid dimension expression\n");
+	snprintf(pout,255,"  Ensemble name \"%s\" not found\n",ename);
+	gaprnt (0,pout);
+	return (NULL);
+      }
+      /* straight override of ensemble grid coordinate */
+      *d = enum1 + 1 + pfi->dimoff[*dim];
+      return (ch);
+    } 
+    /* get the grid coordinate for the new (combined) dimension value */
+    else if (*dim == 3) {
+      *d = t2gr(pfi->abvals[3],&dtim);
+    } else {
+      if (pfi->type==1 || pfi->type==4) {  /* grids  */
+        conv = pfi->ab2gr[*dim];
+        cvals = pfi->abvals[*dim];
+        *d = conv(cvals,v);
+      } else {
+        *d = v;                            /* station data */
+      }
+    }
+    return (ch);
+  }
+}
+
+/*mf version
+  convert all upper case alphabetic characters to lower case.
+  The GrADS system is case insensitive, and assumes lower case
+  internally in most cases. Does not turn to lower case if in "'s
+*/
+void lowcas (char *ch) {
+gaint i;
+gaint qflag=0;
+
+  while (*ch!='\0' && *ch!='\n') {
+    i = *ch;
+    if(*ch == '\"' && qflag == 0 ) {
+      qflag=1;
+      } else if(*ch == '\"' && qflag == 1 ) {
+	qflag=0;
+      }
+    if (i>64 && i<91 && qflag==0) {
+      i+=32;
+      *ch = i;
+    } else if(i == 95) {
+      *ch=i;
+    }
+    ch++;
+  }
+}
+
+/* convert to upper case */
+void uppcas (char *ch) {
+gaint i;
+
+  while (*ch!='\0' && *ch!='\n') {
+    i = *ch;
+    if (i>96 && i<123) {
+      i -= 32;
+      *ch = i;
+    }
+    ch++;
+  }
+}
+
+/* Copies a string of a specified length, or when \0 or \n is hit.
+   Trailing blanks are removed, and the output string is terminated
+   with '\0'.                                                         */
+
+void getstr (char *ch1, char *ch2, gaint len) {
+char *ch;
+
+  ch = ch1;
+  while (len>0 && *ch2!='\n' && *ch2!='\0') {
+    *ch1 = *ch2;
+    len--;
+    ch1++;  ch2++;
+  }
+  ch1--;
+  while (ch1>=ch && *ch1==' ') ch1--;
+  ch1++;
+  *ch1 = '\0';
+}
+
+/* Copies a word of a specified length, or when \0 or \n or \r or ' ' is
+   encountered.  The word is terminated with '\0'. ch2 is src, ch1 is dest */
+
+void getwrd (char *ch1, char *ch2, gaint len) {
+char *ch;
+
+  ch = ch1;
+  while (len>0 && *ch2!='\n' && *ch2!='\0' && *ch2!='\r' && *ch2!=' ' ) {
+    *ch1 = *ch2;
+    len--;
+    ch1++;  ch2++;
+  }
+  *ch1 = '\0';
+}
+
+/* Determines word length up to next delimiter */
+
+gaint wrdlen (char *ch2) {
+gaint len;
+  len = 0;
+  while (*ch2!='\n' && *ch2!='\0' && *ch2!=' ' && *ch2!='\t') {
+    len++;
+    ch2++;
+  }
+  return(len);
+}
+
+/* Get minimum and maximum grid value.  Set rmin and rmax in the
+   grid descriptor.                                                  */
+
+void gamnmx (struct gagrid *pgr) {
+gadouble *r;
+gaint i,size,cnt;
+char *rmask;
+
+  size = pgr->isiz * pgr->jsiz;
+  if (size==1) return;
+  pgr->rmin=  9.99E35;
+  pgr->rmax= -9.99E35;
+  r     = pgr->grid;
+  rmask = pgr->umask; 
+  cnt=0;
+  for (i=0;i<size;i++) {
+    if (*rmask == 1) {
+      cnt++;
+      if (pgr->rmin>*r) pgr->rmin = *r;
+      if (pgr->rmax<*r) pgr->rmax = *r;
+    }
+    r++; rmask++;
+  }
+  if (cnt==0 || pgr->rmin==9.99e35 || pgr->rmax==-9.99e35) {
+    pgr->rmin = pgr->undef;
+    pgr->rmax = pgr->undef;
+    pgr->umin = pgr->umax = 0;
+  }
+  else {
+    pgr->umin = pgr->umax = 1;
+  }
+}
+
+/*  Determine min and max values of station data */
+
+void gasmnmx (struct gastn *stn) {
+struct garpt *rpt;
+
+  stn->smin = stn->undef;
+  stn->smax = stn->undef;
+  rpt = stn->rpt;
+  while (rpt!=NULL) {
+    if (rpt->umask == 1) {
+      if (stn->smin == stn->undef) {
+	stn->smin = rpt->val;
+      }
+      else {
+	if (stn->smin > rpt->val) {
+	  stn->smin = rpt->val;
+	}
+      }
+      if (stn->smax == stn->undef) {
+	stn->smax = rpt->val;
+      }
+      else {
+	if (stn->smax < rpt->val) {
+	  stn->smax = rpt->val;
+	}
+      }
+    }
+    rpt = rpt->rpt;
+  }
+}
+
+/* Remove blanks from a string */
+gaint garemb (char *ch) {
+char *cc;
+gaint cnt;
+gaint qflag=0;
+
+  cc = ch;
+  cnt = 0;
+
+  while (*ch!='\n' && *ch!='\0') {
+    /* do not remove blanks if string in quotes */
+    if (*ch == '\"' && qflag == 0) {
+      qflag=1;
+    } else if (*ch == '\"' && qflag == 1) {
+      qflag=0;
+    }
+
+    if (((*ch!=' ') || qflag ) && (*ch!='\"')) {
+      *cc = *ch;
+      cc++; cnt++;
+    }
+    ch++;
+  }
+  *cc = '\0';
+  return (cnt);
+}
+
+static gadouble glts15[40] = {
+       -86.60,-82.19,-77.76,-73.32,-68.88,-64.43,-59.99,
+       -55.55,-51.11,-46.66,-42.22,-37.77,-33.33,-28.89,
+       -24.44,-20.00,-15.55,-11.11, -6.67, -2.22,  2.22,
+         6.67, 11.11, 15.55, 20.00, 24.44, 28.89, 33.33,
+        37.77, 42.22, 46.66, 51.11, 55.55, 59.99, 64.43,
+        68.88, 73.32, 77.76, 82.19, 86.60};
+static gadouble glts20[52] = {
+       -87.38,-83.98,-80.56,-77.13,-73.71,-70.28,-66.85,
+       -63.42,-59.99,-56.57,-53.14,-49.71,-46.28,-42.85,
+       -39.43,-36.00,-32.57,-29.14,-25.71,-22.28,-18.86,
+       -15.43,-12.00, -8.57, -5.14, -1.71,  1.71,  5.14,
+         8.57, 12.00, 15.43, 18.86, 22.28, 25.71, 29.14,
+        32.57, 36.00, 39.43, 42.85, 46.28, 49.71, 53.14,
+        56.57, 59.99, 63.42, 66.85, 70.28, 73.71, 77.13,
+        80.56, 83.98, 87.38};
+static gadouble glts30[80] = {
+       -88.29, -86.07, -83.84, -81.61, -79.37, -77.14, -74.90,
+       -72.67, -70.43, -68.20, -65.96, -63.72, -61.49, -59.25,
+       -57.02, -54.78, -52.55, -50.31, -48.07, -45.84, -43.60,
+       -41.37, -39.13, -36.89, -34.66, -32.42, -30.19, -27.95,
+       -25.71, -23.48, -21.24, -19.01, -16.77, -14.53, -12.30,
+       -10.06,  -7.83,  -5.59,  -3.35,  -1.12,   1.12,   3.35,
+         5.59,   7.83,  10.06,  12.30,  14.53,  16.77,  19.01,
+        21.24,  23.48,  25.71,  27.95,  30.19,  32.42,  34.66,
+        36.89,  39.13,  41.37,  43.60,  45.84,  48.07,  50.31,
+        52.55,  54.78,  57.02,  59.25,  61.49,  63.72,  65.96,
+        68.20,  70.43,  72.67,  74.90,  77.14,  79.37,  81.61,
+        83.84,  86.07,  88.29};
+
+static gadouble glats[102] = {
+ -88.66,-86.91,-85.16,-83.41,-81.65,-79.90,-78.14,-76.39,-74.63,
+ -72.88,-71.12,-69.36,-67.61,-65.85,-64.10,-62.34,-60.58,-58.83,
+ -57.07,-55.32,-53.56,-51.80,-50.05,-48.29,-46.54,-44.78,-43.02,
+ -41.27,-39.51,-37.76,-36.00,-34.24,-32.49,-30.73,-28.98,-27.22,
+ -25.46,-23.71,-21.95,-20.19,-18.44,-16.68,-14.93,-13.17,-11.41,
+  -9.66, -7.90, -6.15, -4.39, -2.63, -0.88,  0.88,  2.63,  4.39,
+   6.15,  7.90,  9.66, 11.41, 13.17, 14.93, 16.68, 18.44, 20.19,
+  21.95, 23.71, 25.46, 27.22, 28.98, 30.73, 32.49, 34.24, 36.00,
+  37.76, 39.51, 41.27, 43.02, 44.78, 46.54, 48.29, 50.05, 51.80,
+  53.56, 55.32, 57.07, 58.83, 60.58, 62.34, 64.10, 65.85, 67.61,
+  69.36, 71.12, 72.88, 74.63, 76.39, 78.14, 79.90, 81.65, 83.41,
+  85.16, 86.91, 88.66 };
+
+static gadouble m32lts[32] = {-20.453, -18.01, -15.763, -13.738,
+  -11.95, -10.405, -9.097, -8.010, -7.120, -6.392, -5.253, -4.25,
+  -3.25, -2.25, -1.25, -0.25, 0.25, 1.25, 2.25, 3.25, 4.25, 5.253,
+  6.392, 7.12, 8.01, 9.097, 10.405, 11.95, 13.738, 15.763, 18.01,
+  20.453};
+
+/* From Mike Timlin */
+static gadouble gltst62[94] = {
+        -88.542, -86.6531, -84.7532, -82.8508, -80.9473, -79.0435, 
+        -77.1394, -75.2351, -73.3307, -71.4262, -69.5217, -67.6171, 
+        -65.7125, -63.8079, -61.9033, -59.9986, -58.0939, -56.1893, 
+        -54.2846, -52.3799, -50.4752, -48.5705, -46.6658, -44.7611, 
+        -42.8564, -40.9517, -39.047, -37.1422, -35.2375, -33.3328, 
+        -31.4281, -29.5234, -27.6186, -25.7139, -23.8092, -21.9044, 
+        -19.9997, -18.095, -16.1902, -14.2855, -12.3808, -10.47604, 
+        -8.57131, -6.66657, -4.76184, -2.8571, -0.952368, 0.952368, 
+        2.8571, 4.76184, 6.66657, 8.57131, 10.47604, 12.3808, 14.2855, 
+        16.1902, 18.095, 19.9997, 21.9044, 23.8092, 25.7139, 27.6186, 
+        29.5234, 31.4281, 33.3328, 35.2375, 37.1422, 39.047, 40.9517, 
+        42.8564, 44.7611, 46.6658, 48.5705, 50.4752, 52.3799, 54.2846, 
+        56.1893, 58.0939, 59.9986, 61.9033, 63.8079, 65.7125, 67.6171, 
+        69.5217, 71.4262, 73.3307, 75.2351, 77.1394, 79.0435, 80.9473, 
+        82.8508, 84.7532, 86.6531, 88.542 };
+
+/* Given the starting point and the length, return the MOM32 lats */
+
+gadouble *gamo32 (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 32) {
+    gaprnt (0,"Open Error: Invalid MOM32 scaling.\n");
+    gaprnt (0,"  Maximum 32 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gamo32");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: MOM32 Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = m32lts[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+
+/* Given the starting point and the length, return the gaussian lats */
+
+gadouble *gagaus (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 102) {
+    gaprnt (0,"Open Error: Invalid GAUSR40 scaling.\n");
+    gaprnt (0,"  Maximum 102 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gagaus");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: Gaussian Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = glats[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+/* Given the starting point and the length, return the gaussian lats
+  for R30 grids */
+
+gadouble *gags30 (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 80) {
+    gaprnt (0,"Open Error: Invalid GAUSR30 scaling.\n");
+    gaprnt (0,"  Maximum 80 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gags30");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: Gaussian Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = glts30[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+/* Given the starting point and the length, return the gaussian lats
+  for R20 grids */
+
+gadouble *gags20 (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 52) {
+    gaprnt (0,"Open Error: Invalid GAUSR20 scaling.\n");
+    gaprnt (0,"  Maximum 52 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gags20");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: Gaussian Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = glts20[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+/* Given the starting point and the length, return the gaussian lats
+  for R15 grids */
+
+gadouble *gags15 (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 40) {
+    gaprnt (0,"Open Error: Invalid GAUSR15 scaling.\n");
+    gaprnt (0,"  Maximum 40 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gags15");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: Gaussian Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = glts15[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+/* Given the starting point and the length, return the gaussian lats
+  for T62 grids */ 
+/* From Mike Timlin */
+
+gadouble *gagst62 (gaint istrt, gaint num) {
+gaint size;
+gadouble *vals;
+size_t sz;
+
+  istrt--;
+  if (istrt+num > 94) {
+    gaprnt (0,"Open Error: Invalid GAUST62 scaling.\n");
+    gaprnt (0,"  Maximum 94 latitudes exceeded \n");
+    return (NULL);
+  }
+  sz = (num+3) * sizeof(gadouble);
+  vals = (gadouble *)galloc(sz,"gagst62");
+  if (vals==NULL) {
+    gaprnt (0,"Memory Allocation Error: Gaussian Grid Scaling\n");
+    return (NULL);
+  }
+  *vals = (gadouble)num;
+  for (size=0; size<num; size++) *(vals+size+1) = gltst62[size+istrt];
+  *(vals+num+1) = -999.9;
+  return (vals);
+}
+
+char *monc[12] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG",
+                  "SEP","OCT","NOV","DEC"};
+
+gaint gat2ch (struct dt *dtim, gaint tinc, char *ch, gaint chlen) {
+gaint mn1,mn2,hr1,hr2,dy1,dy2,len,mnth;
+
+  mnth = dtim->mo - 1L;
+  mn1 = dtim->mn/10L;
+  mn2 = dtim->mn - (mn1*10);
+  hr1 = dtim->hr/10L;
+  hr2 = dtim->hr - (hr1*10);
+  dy1 = dtim->dy/10L;
+  dy2 = dtim->dy - (dy1*10);
+  if (tinc==1) {
+    snprintf(ch,chlen-1,"%04i",dtim->yr);
+  }
+  else if (tinc==2) {
+    if (dtim->yr==9999L) {
+      snprintf(ch,chlen-1,"%s",monc[mnth]);
+    } else {
+      snprintf(ch,chlen-1,"%s%04i",monc[mnth],dtim->yr);
+    }
+  }
+  else if (tinc==3) {
+    snprintf(ch,chlen-1,"%i%i%s%04i",dy1,dy2,monc[mnth],dtim->yr);
+  }
+  else if (tinc==4) {
+    snprintf(ch,chlen-1,"%i%iZ%i%i%s%04i",hr1,hr2,dy1,dy2,monc[mnth],dtim->yr);
+  }
+  else if (tinc==5) {
+    snprintf(ch,chlen-1,"%i%i:%i%iZ%i%i%s%04i",hr1,hr2,mn1,mn2,dy1,dy2,monc[mnth],dtim->yr);
+  }
+  else snprintf(ch,chlen-1,"???");
+  len=0;
+  while (ch[len]) len++;
+  return (len);
+}
+
+/* Compare two strings given the length.  */
+/* Return 0 if the string match, otherwise 1.  */
+
+gaint cmpch (char *str1, char *str2, gaint len) {
+
+  while (len>0) {
+    len--;
+    if (*(str1+len) != *(str2+len)) return (1);
+  }
+  return (0);
+}
+
+/* Free anything hung off a gastat block */
+
+void gafree (struct gastat *pst) {
+
+  if (pst->type == 1) {
+    gagfre (pst->result.pgr);
+    pst->result.pgr=NULL;
+  } else {
+    gasfre (pst->result.stn);
+    pst->result.stn=NULL;
+  }
+}
+
+void gagfre (struct gagrid *pgr) {
+
+  if (pgr==NULL) return;
+  if (pgr->alocf) {
+    if (pgr->ivals != NULL) gree(pgr->ivals,"f88");
+    if (pgr->jvals != NULL) gree(pgr->jvals,"f89");
+  }
+  if (pgr->idim>-1) {
+    gree(pgr->grid,"f90");
+    gree(pgr->umask,"f91");
+  }
+  gree(pgr,"f92");
+}
+
+void gasfre (struct gastn *stn) {
+gaint i;
+  if (stn==NULL) return;
+  if (stn->tvals) {
+    gree(stn->tvals,"f237");
+  }
+  if (stn->rpt) {
+    for (i=0; i<BLKNUM; i++) {
+      if (stn->blks[i] != NULL) gree(stn->blks[i],"f238");
+    }
+  }
+  gree(stn,"f239");
+}
+
+
+/* Expand file names prefixed with '^' from data descriptor
+   files */
+
+void fnmexp (char *out, char *in1, char *in2) {
+char *pos, *ch, envv[20], *envr, CR=13;
+gaint i,j;
+
+  if (*in1=='$') {
+    in1++;
+    i = 0;
+    while (*in1!='/' && *in1!='\0' && i<16) {
+      envv[i] = *in1;
+      i++; in1++;
+    }
+    envv[i] = '\0';
+    envr = gxgsym(envv);
+    if (envr) {
+      i = 0; j = 0;
+      while (*(envr+j)) {
+        *(out+i) = *(envr+j);
+        i++; j++;
+      }
+      /* handle CR for descriptor files created under MS Windows */
+      while (*in1!='\0' && *in1!=' ' && *in1!='\n' && *in1!=CR) {
+        *(out+i) = *in1;
+        i++; in1++;
+      }
+      *(out+i) = '\0';
+    }
+    return;
+  }
+  ch = in2;
+  pos=NULL;
+  while (*ch!='\0' && *ch!=' ' && *ch!='\n') {
+    if (*ch=='/') pos=ch;
+    ch++;
+  }
+  if (pos) pos++;
+  while (pos!=NULL && in2<pos) {
+    *out = *in2;
+    out++; in2++;
+  }
+  in1++;
+  while (*in1!='\0' && *in1!=' ' && *in1!='\n' && *in1!=CR) {
+    *out = *in1;
+    out++; in1++;
+  }
+  *out = '\0';
+}
+
+/* Given a file name template and a dt structure, fill in to get the file name */
+
+char *gafndt (char *fn, struct dt *dtim, struct dt *dtimi, gadouble *vals, 
+	      struct gachsub *pch1st, struct gaens *ens1st, gaint t, gaint e, gaint *flag) {
+struct gachsub *pchsub;
+struct gaens *ens;
+struct dt stim;
+gaint len,olen,iv,tdif,i,tused,eused,mo,doy,dys,hrs,mns;
+char *fnout, *in, *out, *work, *in2, *out2;
+size_t sz;
+
+  tused = eused = 0;
+  olen = 0;
+  while (*(fn+olen)) olen++;
+  olen+=5;
+  sz = olen;
+  fnout = (char *)galloc(sz+1,"fnout");
+  if (fnout==NULL) return (NULL);
+
+  in = fn;
+  out = fnout;
+
+  while (*in) {
+    pchsub = pch1st;
+    ens = ens1st;
+    /* handle template strings for initial time */
+    if (*in=='%' && *(in+1)=='i') {
+      tused=1;
+      if (*(in+2)=='x' && *(in+3)=='1') { 
+        snprintf(out,sz,"%i",dtimi->yr/10);
+        while (*out) out++;
+        in+=4;
+      } else if (*(in+2)=='x' && *(in+3)=='3') {
+        snprintf(out,sz,"%03i",dtimi->yr/10);
+        out+=3; in+=4;
+      } else if (*(in+2)=='y' && *(in+3)=='2') {
+        iv = dtimi->yr/100;
+        iv = dtimi->yr - iv*100;
+        snprintf(out,sz,"%02i",iv);
+        out+=2;  in+=4;
+      } else if (*(in+2)=='y' && *(in+3)=='4') {
+        snprintf(out,sz,"%04i",dtimi->yr);
+        out+=4;  in+=4;
+      } else if (*(in+2)=='m' && *(in+3)=='1') {
+          snprintf(out,sz,"%i",dtimi->mo);
+        while (*out) out++;
+        in+=4;
+      } else if (*(in+2)=='m' && *(in+3)=='2') {
+        snprintf(out,sz,"%02i",dtimi->mo);
+        out+=2;  in+=4;
+      } else if (*(in+2)=='m' && *(in+3)=='h') {
+        if (dtimi->dy < 16) *out='a';
+        else *out = 'b';
+        out+=1;  in+=4;
+      } else if (*(in+2)=='m' && *(in+3)=='H') {
+        if (dtimi->dy < 16) *out='A';
+        else *out = 'B';
+        out+=1;  in+=4;
+      } else if (*(in+2)=='m' && *(in+3)=='c') {
+        *out = *(mons[dtimi->mo-1]);
+        *(out+1) = *(mons[dtimi->mo-1]+1);
+        *(out+2) = *(mons[dtimi->mo-1]+2);
+        out+=3;  in+=4;
+      } else if (*(in+2)=='d' && *(in+3)=='1') {
+        snprintf(out,sz,"%i",dtimi->dy);
+        while (*out) out++;
+        in+=4;
+      } else if (*(in+2)=='d' && *(in+3)=='2') {
+        snprintf(out,sz,"%02i",dtimi->dy);
+        out+=2;  in+=4;
+      } else if (*(in+2)=='h' && *(in+3)=='1') {
+        snprintf(out,sz,"%i",dtimi->hr);
+        while (*out) out++;
+        in+=4;
+      } else if (*(in+2)=='h' && *(in+3)=='2') {
+        snprintf(out,sz,"%02i",dtimi->hr);
+        out+=2;  in+=4;
+      } else if (*(in+2)=='h' && *(in+3)=='3') {
+        snprintf(out,sz,"%03i",dtimi->hr);
+        out+=3;  in+=4;
+      } else if (*(in+2)=='n' && *(in+3)=='2') {
+        snprintf(out,sz,"%02i",dtimi->mn);
+        out+=2;  in+=4;
+      } else if (*(in+2)=='j' && *(in+3)=='3') {
+	doy = dtimi->dy;
+	mo = dtimi->mo-1;
+	while (mo>0) {
+	  doy += mosiz[mo];
+	  if (mo==2 && qleap(dtimi->yr)) doy+=1;
+	  mo--;
+	}
+	snprintf(out,sz,"%03i",doy);
+	out+=3;  in+=4;
+      } else {
+        *out = *in;
+        in++; out++;
+      }
+    } 
+    /* handle template strings for any time */
+    else if (*in=='%' && *(in+1)=='x' && *(in+2)=='1') {   /* decade */
+      tused=1;
+      snprintf(out,sz,"%i",dtim->yr/10);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='x' && *(in+2)=='3') { 
+      tused=1;
+      snprintf(out,sz,"%03i",dtim->yr/10);
+      out+=3; in+=3;
+    } else if (*in=='%' && *(in+1)=='y' && *(in+2)=='2') {   /* year */
+      tused=1;
+      iv = dtim->yr/100;
+      iv = dtim->yr - iv*100;
+      snprintf(out,sz,"%02i",iv);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='y' && *(in+2)=='4') {
+      tused=1;
+      snprintf(out,sz,"%04i",dtim->yr);
+      out+=4;  in+=3;
+    } else if (*in=='%' && *(in+1)=='m' && *(in+2)=='1') {   /* month */
+      tused=1;
+      snprintf(out,sz,"%i",dtim->mo);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='m' && *(in+2)=='2') {
+      tused=1;
+      snprintf(out,sz,"%02i",dtim->mo);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='m' && *(in+2)=='h') {
+      tused=1;
+      if (dtim->dy < 16) *out='a';
+      else *out = 'b';
+      out+=1;  in+=3;
+    } else if (*in=='%' && *(in+1)=='m' && *(in+2)=='H') {
+      tused=1;
+      if (dtim->dy < 16) *out='A';
+      else *out = 'B';
+      out+=1;  in+=3;
+    } else if (*in=='%' && *(in+1)=='m' && *(in+2)=='c') {
+      tused=1;
+      *out = *(mons[dtim->mo-1]);
+      *(out+1) = *(mons[dtim->mo-1]+1);
+      *(out+2) = *(mons[dtim->mo-1]+2);
+      out+=3;  in+=3;
+    } else if (*in=='%' && *(in+1)=='d' && *(in+2)=='1') {   /* day */
+      tused=1;
+      snprintf(out,sz,"%i",dtim->dy);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='d' && *(in+2)=='2') {
+      tused=1;
+      snprintf(out,sz,"%02i",dtim->dy);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='h' && *(in+2)=='1') {   /* hour */
+      tused=1;
+      snprintf(out,sz,"%i",dtim->hr);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='h' && *(in+2)=='2') {
+      tused=1;
+      snprintf(out,sz,"%02i",dtim->hr);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='h' && *(in+2)=='3') {
+      tused=1;
+      snprintf(out,sz,"%03i",dtim->hr);
+      out+=3;  in+=3;
+    } else if (*in=='%' && *(in+1)=='n' && *(in+2)=='2') {   /* minute */
+      tused=1;
+      snprintf(out,sz,"%02i",dtim->mn);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='j' && *(in+2)=='3') {   /* julian day */
+      tused=1;
+      doy = dtim->dy;
+      mo = dtim->mo-1;
+      while (mo>0) {
+	doy += mosiz[mo];
+	if (mo==2 && qleap(dtim->yr)) doy+=1;
+	mo--;
+      }
+      snprintf(out,sz,"%03i",doy);
+      out+=3;  in+=3;
+    } 
+    /* time index t, starting with 1 */
+    else if (*in=='%' && *(in+1)=='t' && *(in+2)=='1') {   
+      tused=1;
+      snprintf(out,sz,"%i",t);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='2') {
+      tused=1;
+      snprintf(out,sz,"%02i",t);
+      out+=2;  in+=3;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='3') {
+      tused=1;
+      snprintf(out,sz,"%03i",t);
+      out+=3;  in+=3;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='4') {
+      tused=1;
+      snprintf(out,sz,"%04i",t);
+      out+=4;  in+=3;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='5') {
+      tused=1;
+      snprintf(out,sz,"%05i",t);
+      out+=5;  in+=3;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='6') {
+      tused=1;
+      snprintf(out,sz,"%06i",t);
+      out+=6;  in+=3;
+    } 
+    /* time index t, starting with 0 */
+    else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='1') {   
+      tused=1;
+      snprintf(out,sz,"%i",t-1);
+      while (*out) out++;
+      in+=4;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='2') {
+      tused=1;
+      snprintf(out,sz,"%02i",t-1);
+      out+=2;  in+=4;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='3') {
+      tused=1;
+      snprintf(out,sz,"%03i",t-1);
+      out+=3;  in+=4;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='4') {
+      tused=1;
+      snprintf(out,sz,"%04i",t-1);
+      out+=4;  in+=4;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='5') {
+      tused=1;
+      snprintf(out,sz,"%05i",t-1);
+      out+=5;  in+=4;
+    } else if (*in=='%' && *(in+1)=='t' && *(in+2)=='m' && *(in+3)=='6') {
+      tused=1;
+      snprintf(out,sz,"%06i",t-1);
+      out+=6;  in+=4;
+    }
+    /* forecast hour */
+    else if (*in=='%' && *(in+1)=='f' && *(in+2)=='2') {
+      tused=1;
+      stim.yr = (gaint)(*vals+0.1);
+      stim.mo = (gaint)(*(vals+1)+0.1);
+      stim.dy = (gaint)(*(vals+2)+0.1);
+      stim.hr = (gaint)(*(vals+3)+0.1);
+      stim.mn = (gaint)(*(vals+4)+0.1);
+      tdif = timdif(dtimi,dtim);
+      /* tdif = (tdif+30)/60; */
+      tdif = tdif/60;   /* forecast hour not rounded up anymore */
+      if (tdif<99) snprintf(out,sz,"%02i",tdif);
+      else snprintf(out,sz,"%i",tdif);
+      while (*out) out++;
+      in+=3;
+    } else if (*in=='%' && *(in+1)=='f' && *(in+2)=='3') {
+      tused=1;
+      stim.yr = (gaint)(*vals+0.1);
+      stim.mo = (gaint)(*(vals+1)+0.1);
+      stim.dy = (gaint)(*(vals+2)+0.1);
+      stim.hr = (gaint)(*(vals+3)+0.1);
+      stim.mn = (gaint)(*(vals+4)+0.1);
+      tdif = timdif(dtimi,dtim); 
+      /* tdif = (tdif+30)/60; */
+      tdif = tdif/60;   /* forecast hour not rounded up anymore */
+      if (tdif<999) snprintf(out,sz,"%03i",tdif);
+      else snprintf(out,sz,"%i",tdif);
+      while (*out) out++;
+      in+=3;
+    } 
+    /* forecast minute */
+    else if (*in=='%' && *(in+1)=='f' && *(in+2)=='n' && *(in+3)=='2') {
+      tused=1;
+      stim.yr = (gaint)(*vals+0.1);
+      stim.mo = (gaint)(*(vals+1)+0.1);
+      stim.dy = (gaint)(*(vals+2)+0.1);
+      stim.hr = (gaint)(*(vals+3)+0.1);
+      stim.mn = (gaint)(*(vals+4)+0.1);
+      tdif = timdif(dtimi,dtim); 
+      if (tdif<99) snprintf(out,sz,"%02i",tdif);
+      else snprintf(out,sz,"%i",tdif);
+      while (*out) out++;
+      in+=4;
+    } 
+    /* forecast time in hours/minutes (hhnn) */ 
+    else if (*in=='%' && *(in+1)=='f' && *(in+2)=='h' && *(in+3)=='n') {
+      tused=1;
+      stim.yr = (gaint)(*vals+0.1);
+      stim.mo = (gaint)(*(vals+1)+0.1);
+      stim.dy = (gaint)(*(vals+2)+0.1);
+      stim.hr = (gaint)(*(vals+3)+0.1);
+      stim.mn = (gaint)(*(vals+4)+0.1);
+      tdif = timdif(dtimi,dtim); 
+      hrs = tdif/60;
+      mns = tdif - (hrs*60);
+      if (hrs<99) snprintf(out,sz,"%02i%02i",hrs,mns);
+      else snprintf(out,sz,"%i%02i",hrs,mns);
+      while (*out) out++;
+      in+=4;
+    } 
+    /* forecast time in days/hours/minutes (ddhhnn) */ 
+    else if (*in=='%' && *(in+1)=='f' && *(in+2)=='d' && *(in+3)=='h' && *(in+4)=='n') {
+      tused=1;
+      stim.yr = (gaint)(*vals+0.1);
+      stim.mo = (gaint)(*(vals+1)+0.1);
+      stim.dy = (gaint)(*(vals+2)+0.1);
+      stim.hr = (gaint)(*(vals+3)+0.1);
+      stim.mn = (gaint)(*(vals+4)+0.1);
+      tdif = timdif(dtimi,dtim); 
+      dys = tdif/1440;
+      hrs = (tdif - (dys*1440))/60;
+      mns = tdif - (dys*1440) - (hrs*60);
+      if (dys<99) snprintf(out,sz,"%02i%02i%02i",dys,hrs,mns);
+      else snprintf(out,sz,"%i%02i%02i",dys,hrs,mns);
+      while (*out) out++;
+      in+=5;
+    } 
+    /* string substitution */
+    else if (*in=='%' && *(in+1)=='c' && *(in+2)=='h') {
+      tused=1;
+      while (pchsub) {
+        if (t>=pchsub->t1 && (pchsub->t2 == -99 || t<=pchsub->t2) ) {
+          len = wrdlen(pchsub->ch);    /* Reallocate output string */
+          olen += len;
+	  sz = olen;
+          work = (char *)galloc(sz+1,"work");
+          if (work==NULL) {
+            gree(fnout,"f240");
+            return (NULL);
+          }
+          in2 = fnout; 
+	  out2 = work;
+          while (in2!=out) {
+            *out2 = *in2;
+            in2++; out2++;
+          }
+          gree(fnout,"f241");     
+          fnout = work;
+          out = out2;
+          getwrd(out,pchsub->ch,len);
+          out += len;
+          break;
+        }
+        pchsub = pchsub->forw;
+      }
+      in+=3;
+    } 
+    /* ensemble name substitution */
+    else if  (*in=='%' && *(in+1)=='e') {
+      eused=1;
+      if (ens == NULL) {
+	gree(fnout,"f242");
+	return (NULL);
+      } else {
+	/* advance through array of ensemble structures, till we reach ensemble 'e' */
+	i=1;
+	while (i!=e) { i++; ens++; }
+	len = strlen(ens->name);
+	if (len < 1) {
+	  gree(fnout,"f243");
+	  return (NULL);
+	}
+	olen += len;
+	sz = olen;
+	work = (char *)galloc(sz+1,"work2");     /* Reallocate output string */
+	if (work==NULL) {
+	  gree(fnout,"f244");
+	  return (NULL);
+	}
+	in2 = fnout;            /* copy the string we've got so far */
+	out2 = work;
+	while (in2!=out) {
+	  *out2 = *in2;
+	  in2++; out2++;
+	}
+	gree(fnout,"f245");
+	fnout = work;
+	out = out2;
+	getwrd(out,ens->name,len);
+	out += len;
+      }
+      in+=2;
+    }
+    else {
+      *out = *in;
+      in++; out++;
+    }
+  }
+  *out = '\0';
+  if (eused==1 && tused==1) {
+    *flag = 3;                       /* templating on E and T */
+  } 
+  else if (eused==1 && tused==0) {
+    *flag = 2;                       /* templating only on E */
+  }
+  else if (eused==0 && tused==1) { 
+    *flag = 1;                       /* templating only on T */
+  }
+  else {
+    *flag = 0;                       /* no templating */
+  }
+  return (fnout);
+}
+
+/* Byte swap requested number of 2 byte elements */
+
+void gabswp2 (void *r, gaint cnt) {
+gaint i;
+char *ch1,*ch2,cc1,cc2;
+
+  ch1 = (char *)r;
+  ch2 = ch1+1;
+  for (i=0; i<cnt; i++) {
+    cc1 = *ch1;
+    cc2 = *ch2;
+    *ch1 = cc2;
+    *ch2 = cc1;
+    ch1+=2; ch2+=2;
+  }
+}
+
+/* Byte swap requested number of 4 byte elements */
+
+void gabswp (void *r, gaint cnt) {
+gaint i;
+char *ch1,*ch2,*ch3,*ch4,cc1,cc2;
+
+  ch1 = (char *)r;
+  ch2 = ch1+1;
+  ch3 = ch2+1;
+  ch4 = ch3+1;
+  for (i=0; i<cnt; i++) {
+    cc1 = *ch1;
+    cc2 = *ch2;
+    *ch1 = *ch4;
+    *ch2 = *ch3;
+    *ch3 = cc2;
+    *ch4 = cc1;
+    ch1+=4; ch2+=4; ch3+=4; ch4+=4;
+  }
+}
+
+/* Byte swap requested number of 8 byte elements */
+
+void gabswp8 (void *r, gaint cnt) {
+gaint i;
+char *ch;
+
+  ch = (char *)r;
+  for (i=0; i<cnt; i++) {
+    ganbswp (ch+i*8, 8);
+  }
+}
+
+/* joew 071902 Byte swap a single element with the width given */
+void ganbswp(char *buf, gaint cnt) {
+  gaint i, j;
+  char tmp;
+  for (i=0, j=cnt-1; i<cnt/2; i++,j--) {
+    tmp = buf[i];
+    buf[i] = buf[j];
+    buf[j] = tmp;
+  }
+}
+
+/* Byte swap a report header from a station data file */
+
+void gahswp (struct rpthdr *hdr) {
+  gabswp((gafloat *)(&(hdr->lat)),5);
+}
+
+/* Return day of week for date/time  0=sunday, 6=saturday */
+
+gaint dayweek (struct dt *dtime) {
+struct dt anch;
+gaint i,j;
+  if (dtime->yr<1950 || dtime->yr>2020) return(7);
+  anch.yr = 1950;
+  anch.mo = 1;
+  anch.dy = 1;
+  anch.hr = 0;
+  anch.mn = 0;
+  i = timdif(&anch,dtime);
+  i = i/1440;
+  j = i/7;
+  i = i - j*7;
+  return(i);
+}
+
+/*
+ * convert an IBM float to single precision number v1.0
+ *
+ *                      Wesley Ebisuzaki
+ */
+
+gafloat ibm2flt(unsigned char *ibm) {
+gaint positive, power;
+gauint abspower;
+galint mant;
+gadouble value, exp;
+
+ positive = (ibm[0] & 0x80) == 0;
+ mant = (ibm[1] << 16) + (ibm[2] << 8) + ibm[3];
+ power = (gaint) (ibm[0] & 0x7f) - 64;
+ abspower = power > 0 ? power : -power;
+ 
+ exp = 16.0;
+ value = 1.0;
+ while (abspower) {
+   if (abspower & 1) {
+     value *= exp;
+   }
+   exp = exp * exp;
+   abspower >>= 1;
+ }
+ 
+ if (power < 0) value = 1.0 / value;
+ value = value * mant / 16777216.0;
+ if (positive == 0) value = -value;
+ return (gafloat)value;
+}
+
+/*
+ * convert a float to an IBM single precision number v1.0
+ *
+ *                      Wesley Ebisuzaki
+ *
+ * doesn't handle subnormal numbers
+ */
+
+gaint flt2ibm(gafloat x, unsigned char *ibm) {
+gaint sign, exp, i;
+gadouble mant;
+
+ if (x == 0.0) {
+   ibm[0] = ibm[1] = ibm[2] = ibm[3] = 0;
+   return 0;
+ }
+ 
+ /* sign bit */
+ if (x < 0.0) {
+   sign = 128;
+   x = -x;
+ }
+ else sign = 0;
+ 
+ mant = frexp((gadouble) x, &exp);
+ 
+ if (mant >= 1.0) {
+   mant = 0.5;
+   exp++;
+ }
+ while (exp & 3) {
+   mant *= 0.5;
+   exp++;
+ }
+ 
+ exp = exp/4 + 64;
+ 
+ if (exp < 0) {
+   fprintf(stderr,"underflow in flt2ibm\n");
+   ibm[0] = ibm[1] = ibm[2] = ibm[3] = 0;
+   return 0;
+ }
+ if (exp > 127) {
+   fprintf(stderr,"overflow in flt2ibm\n");
+   ibm[0] = sign | 127;
+   ibm[1] = ibm[2] = ibm[3] = 255;
+   return -1;
+ }
+ 
+ /* normal number */
+ 
+ ibm[0] = sign | exp;
+ 
+ mant = mant * 256.0;
+ i = floor(mant);
+ mant = mant - i;
+ ibm[1] = i;
+ 
+ mant = mant * 256.0;
+ i = floor(mant);
+ mant = mant - i;
+ ibm[2] = i;
+ 
+ ibm[3] = floor(mant*256.0);
+ 
+ return 0;
+}
+
+/* wesley ebisuzaki v0.1
+ *
+ * takes 4 byte character string (single precision ieee big-endian)
+ * and returns a float
+ *
+ * doesn't handle NAN, infinity and any other funny stuff in ieee
+ *
+ * ansi C
+ */
+
+gafloat ieee2flt(unsigned char *ieee) {
+gadouble fmant;
+gaint exp;
+
+ if (ieee[0] == 0 && ieee[1] == 0 && ieee[2] == 0 && ieee[3] == 0)
+   return (gafloat) 0.0;
+ 
+ exp = ((ieee[0] & 127) << 1) + (ieee[1] >> 7);
+ fmant = (gadouble) ((gaint) ieee[3] + (gaint) (ieee[2] << 8) +
+		     (gaint) ((ieee[1] | 128) << 16));
+ if (ieee[0] & 128) fmant = -fmant;
+ return (gafloat) (ldexp(fmant, (gaint) (exp - 128 - 22)));
+}
+
+gadouble ieee2dbl(unsigned char *ieee) {
+gadouble fmant;
+gaint exp;
+
+ if (ieee[0] == 0 && ieee[1] == 0 && ieee[2] == 0 && ieee[3] == 0)
+   return (gadouble) 0.0;
+ 
+ exp = ((ieee[0] & 127) << 1) + (ieee[1] >> 7);
+ fmant = (gadouble) ((gaint) ieee[3] + (gaint) (ieee[2] << 8) +
+		     (gaint) ((ieee[1] | 128) << 16));
+ if (ieee[0] & 128) fmant = -fmant;
+ return (gadouble) (ldexp(fmant, (gaint) (exp - 128 - 22)));
+}
+
+
+/*
+ * convert a float to an ieee single precision number v1.1
+ * (big endian)
+ *                      Wesley Ebisuzaki
+ *
+ * bugs: doesn't handle subnormal numbers
+ * bugs: assumes length of integer >= 25 bits
+ */
+
+gaint flt2ieee(gafloat x, unsigned char *ieee) {
+gaint sign, exp;
+gauint umant;
+gadouble mant;
+
+ if (x == 0.0) {
+   ieee[0] = ieee[1] = ieee[2] = ieee[3] = 0;
+   return 0;
+ }
+ /* sign bit */
+ if (x < 0.0) {
+   sign = 128;
+   x = -x;
+ }
+ else sign = 0;
+ mant = frexp((gadouble) x, &exp);
+ umant = mant * 16777216 + 0.5;
+ if (umant >= 16777216) {
+   umant = umant / 2;
+   exp++;
+ }
+ /* bit 24 should be a 1 .. not used in ieee format */
+ exp = exp - 1 + 127;
+ if (exp < 0) {
+   /* signed zero */
+   ieee[0] = sign;
+   ieee[1] = ieee[2] = ieee[3] = 0;
+   return 0;
+ }
+ if (exp > 255) {
+   /* signed infinity */
+   ieee[0] = sign + 127;
+   ieee[1] = 128;
+   ieee[2] = ieee[3] = 0;
+   return 0;
+ }
+ /* normal number */
+ ieee[0] = sign + (exp >> 1);
+ ieee[3] = umant & 255;
+ ieee[2] = (umant >> 8) & 255;
+ ieee[1] = ((exp & 1) << 7) + ((umant >> 16) & 127);
+ return 0;
+}
+
+/* Copies indicated scaling info into newly allocated 
+   gadouble array.  args:
+ 
+   vals -- input scaling array
+   lin  -- input is linear or levels
+   dir  -- direction of scaling info:
+              0 for gr to ab 
+              1 for ab to gr
+   dim  -- dimension the scaling info is for
+
+   lin, dir, and dim are provided solely to figure out how
+   many values are to be copied.  This assumes knowledge
+   of how the various scaling items are set up.  */
+   
+
+gadouble *cpscal (gadouble *vals, gaint lin, gaint dir, gaint dim) {
+gaint i,num;
+gadouble *vvv;
+size_t sz;
+
+ if (dim<0) {
+   gaprnt (0,"cpscal error:  dim is not >= 0 \n");
+   return (NULL);
+ }
+ if (dim==3) {
+   num = 8;
+ }
+ else {
+   if (lin==1) num = 3;
+   else num = (gaint)(*vals+0.5) + 5;
+ }
+ sz = sizeof(gadouble)*num;
+ vvv = (gadouble *)galloc(sz,"cpscal");
+ if (vvv==NULL) {
+   snprintf(pout,255,"cpscal memory allocation error; dim=%d lin=%d num=%d\n",dim,lin,num);
+   gaprnt(0,pout);
+   return (NULL);
+ }
+ for (i=0; i<num; i++) {
+   *(vvv+i) = *(vals+i);
+ }
+ return (vvv);
+}
+
+
+
+/*  handle var name of the form longnm=>abbrv
+    or just the abbrv with no long name */
+
+gaint getvnm (struct gavar *pvar, char *mrec) {
+gaint ib,i,j,k,len,flag;
+
+  ib = 0;
+  while (*(mrec+ib)==' ') ib++;
+
+  if (*(mrec+ib)=='\0' || *(mrec+ib)=='\n') return(1);
+
+  /* Scan for the '=>' string */
+  len = 0;
+  i = ib;
+  flag = 0;
+
+  while (1) {
+    if (*(mrec+i)==' ' || *(mrec+i)=='\0' || *(mrec+i)=='\n') break;
+    if (*(mrec+i)=='=' && *(mrec+i+1)=='>') {
+      flag = 1;
+      break;
+    }
+    len++ ; i++; 
+  }
+
+  if (flag) {
+    for (j=ib; j<i; j++) {
+      k = j-ib;
+      pvar->longnm[k] = *(mrec+j); 
+      /* substitute ~ for spaces in longname */
+      if (pvar->longnm[k]=='~') pvar->longnm[k]=' '; 
+    }
+    pvar->longnm[len] = '\0';
+    i+=2;
+  } else {
+    i = 0;
+    pvar->longnm[0] = '\0';
+  } 
+
+  if (*(mrec+i)=='\n' || *(mrec+i)=='\0') return (1);
+
+  getwrd (pvar->abbrv, mrec+i, 15);
+  lowcas(pvar->abbrv);
+
+  /* Check if 1st character is lower-case alphabetic */
+  if (islower(*(pvar->abbrv))) return(0);
+  else return (1);
+}
+
+
+/*  Parse ensemble names in EDEF record */
+gaint getenm (struct gaens *ens, char *mrec) {
+gaint i;
+
+  i = 0;
+  if (*(mrec+i)=='\n' || *(mrec+i)=='\0') return (1);
+  getwrd (ens->name, mrec+i, 15);
+  return(0);
+
+}
+
+/* Test if two doubles are equal; returns 1 if args are not equal */
+gaint dequal(gadouble op1, gadouble op2, gadouble tolerance) {
+  if (fabs(op1 - op2) <= tolerance) return(0) ;
+  else return(1) ;
+}
+
+
+/* Following two routines used in GRIB2 handling */
+
+/* applies the scale factor to scaled grib2 code values */
+gadouble scaled2dbl(gaint scale_factor, gaint scale_value) {
+   if (scale_factor == 0) return (gadouble) scale_value;
+   return scale_value * Int_Power(0.1, scale_factor);
+}
+/*  returns x**y  */
+gadouble Int_Power(gadouble x, gaint y) {
+  gadouble value;
+  if (y < 0) {
+    y = -y;
+    x = 1.0 / x;
+  }
+  value = 1.0;
+  while (y) {
+    if (y & 1) {
+      value *= x;
+    }
+    x = x * x;
+    y >>= 1;
+  }
+  return value;
+}
+
+
+#ifndef HAVE_FSEEKO
+
+gaint fseeko(FILE *stream, off_t offset, gaint whence) {
+  fseek(stream, (long)offset, whence);
+}
+
+off_t ftello(FILE *stream) {
+  return (off_t)ftell(stream);
+}
+#endif
+
+
+
diff --git a/src/grads.c b/src/grads.c
new file mode 100644
index 0000000..e28aaf6
--- /dev/null
+++ b/src/grads.c
@@ -0,0 +1,600 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Main program for GrADS (Grid Analysis and Display System).
+   This program loops on commands from the user, and calls the
+   appropriate routines based on the command entered.             */
+
+/* GrADS originally authored by Brian E. Doty.  Many others have 
+   contributed over the years...  
+
+   Jennifer M. Adams 
+   Reinhard Budich 
+   Luigi Calori 
+   Wesley Ebisuzaki 
+   Mike Fiorino 
+   Graziano Giuliani 
+   Matthias Grzeschik
+   Tom Holt 
+   Don Hooper 
+   James L. Kinter 
+   Steve Lord 
+   Gary Love 
+   Karin Meier 
+   Matthias Munnich 
+   Uwe Schulzweida 
+   Arlindo da Silva 
+   Michael Timlin 
+   Pedro Tsai 
+   Joe Wielgosz 
+   Brian Wilkinson 
+   Katja Winger
+
+   We apologize if we have neglected your contribution --
+   but let us know so we can add your name to this list.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <signal.h>
+#include "grads.h"
+
+#if USEGUI == 1
+#include "gagui.h"
+#endif
+
+#if READLINE ==1
+#include <time.h>
+#include <stdlib.h>
+#include <readline/history.h>
+extern gaint history_length;
+void write_command_log(char *logfile);
+#endif
+
+struct gacmn gcmn;  
+static struct gawgds wgds;   
+extern struct gamfcmn mfcmn;
+
+int main (int argc, char *argv[])  {
+
+void command_line_help(void) ;
+void gxdgeo (char *);
+void gxend (void);
+void gatxti(gaint on, gaint cs);
+char *gatxtl(char *str,gaint level);
+
+char cmd[500];
+gaint rc,i,j,land,port,cmdflg,hstflg,gflag,xwideflg,killflg,ratioflg;
+gaint metabuff,size=0,g2size=0;
+gaint txtcs=-2;
+gaint ipcflg = 0; /* for IPC friendly interaction via pipes */
+char *icmd,*arg,*rc1;
+void gasigcpu() ;
+gaint wrhstflg=0; 
+gadouble aspratio;
+char *logfile,*userhome=NULL;
+
+/*--- common block sets before gainit ---*/
+gcmn.batflg = 0;
+land = 0;
+port = 0;
+cmdflg = 0;
+metabuff = 0;
+hstflg = 1; 
+gflag = 0;
+xwideflg = 0;
+icmd = NULL;
+arg = NULL;
+rc1 = NULL;
+killflg = 0;
+ratioflg = 0;
+aspratio = -999.9;
+
+#if READLINE == 1
+#ifdef __GO32__  /* MSDOS case */ 
+logfile= (char *) malloc(22);
+logfile= "c:\windows\grads.log";
+#else  /* Unix */
+userhome=getenv("HOME");
+if (userhome==NULL) {
+  logfile=NULL;
+}
+else {
+  logfile= (char *) malloc(strlen(userhome)+12);
+  if(logfile==NULL) {
+    printf("Memory allocation error for logfile name.\n");
+  }
+  else {
+    strcpy(logfile,userhome);
+    strcat(logfile,"/.grads.log");
+  }
+}
+#endif /* __GO32__ */
+#endif /* READLINE == 1 */
+
+if (argc>1) {
+  for (i=1; i<argc; i++) {
+    if (*(argv[i])=='-' &&
+	*(argv[i]+1)=='h' && *(argv[i]+2)=='e' && *(argv[i]+3)=='l' && *(argv[i]+4)=='p') {
+      command_line_help();     /* answer a cry for help */
+      return(0);
+    } else if (cmdflg==1) {    /* next arg is the command to execute */
+      icmd = argv[i];
+      cmdflg = 0;
+    } else if (metabuff) {     /* next arg is the metafile buffer size */
+      arg = argv[i];
+      rc1 = intprs(arg,&size);
+      if (rc1!=NULL) metabuff = 0;
+    } else if ((txtcs==-1) && (*argv[i]!='-')) {  /* next arg is optional colorization scheme */
+      txtcs = (gaint) strtol(argv[i], (char **)NULL, 10);
+      if (txtcs>2) {
+        printf("Valid colorization schemes are 0, 1, or 2. Colorization option %d ignored. \n",txtcs);
+        txtcs = -2;
+      }
+    } else if (ratioflg) {    /* next arg is aspect ratio */
+        aspratio = atof(argv[i]);
+        ratioflg = 0;
+    } else if (gflag) {        /* next arg is the geometry string */
+      gxdgeo(argv[i]);
+      gflag=0;
+    } else if (wrhstflg && *(argv[i])!='-') {   /* next arg is optional log file name */
+        logfile=argv[i];
+    } else if (*(argv[i])=='-') {
+      j = 1;
+      while (*(argv[i]+j)) {
+	if      (*(argv[i]+j)=='a') ratioflg = 1;    /* aspect ratio to follow */
+	else if (*(argv[i]+j)=='b') gcmn.batflg = 1; /* batch mode */
+	else if (*(argv[i]+j)=='c') cmdflg = 1;      /* command to follow */
+	else if (*(argv[i]+j)=='C') txtcs = -1;      /* text color scheme */
+	else if (*(argv[i]+j)=='E') hstflg = 0;      /* disable command line editing */
+	else if (*(argv[i]+j)=='g') gflag = 1;       /* geometry specification to follow */
+	else if (*(argv[i]+j)=='H') wrhstflg = 1;    /* write history to log file */
+	else if (*(argv[i]+j)=='l') land = 1;        /* landscape mode */
+	else if (*(argv[i]+j)=='m') metabuff = 1;    /* metafile buffer size to follow */
+	else if (*(argv[i]+j)=='p') port = 1;        /* portrait mode */
+	else if (*(argv[i]+j)=='W') xwideflg = 1;    /* use software to control wide lines (undocumented) */
+	else if (*(argv[i]+j)=='u') {                /* unbuffer output: needed for IPC via pipes */
+	  hstflg = 0;                                /* no need for readline in IPC mode */
+	  ipcflg = 1;
+	  setvbuf(stdin,  (char *) NULL,  _IONBF, 0 );
+	  setvbuf(stdout, (char *) NULL,  _IONBF, 0 );
+	  setvbuf(stderr, (char *) NULL,  _IONBF, 0 );
+	}
+	else if (*(argv[i]+j)=='x') killflg = 1;     /* quit after finishing (usually used with -c) */
+	else printf ("Unknown command line option: %c\n",*(argv[i]+j));
+	j++;
+      }
+    } else printf ("Unknown command line keyword: %s\n",argv[i]);
+  }
+}
+
+if (txtcs > -2) gatxti(1,txtcs); /* turn on text colorizing */
+
+if (ratioflg==1) printf ("Note: -a option was specified, but no aspect ratio was provided\n");
+if (cmdflg==1)   printf ("Note: -c option was specified, but no command was provided\n");
+if (gflag==1)    printf ("Note: -g option was specified, but no geometry specification was provided\n");
+if (metabuff==1) printf ("Note: -m option was specified, but no metafile buffer size was provided\n");
+
+if (ipcflg) printf("\n<IPC>" );  /* delimit splash screen */
+
+printf ("\nGrid Analysis and Display System (GrADS) Version %s\n",gatxtl(GRADS_VERSION,0));
+printf ("Copyright (c) 1988-2011 by Brian Doty and the\n");
+printf ("Institute for Global Environment and Society (IGES)\n");
+printf ("GrADS comes with ABSOLUTELY NO WARRANTY\n");
+printf ("See file COPYRIGHT for more information\n\n");
+
+gacfg(0);
+
+
+if (!land && !port && aspratio<-990) {
+  nxtcmd (cmd,"Landscape mode? ('n' for portrait): ");
+  if (cmd[0]=='n') port = 1;
+}
+if (port) {
+  gcmn.xsiz = 8.5;
+  gcmn.ysiz = 11.0;
+} else {
+  gcmn.xsiz = 11.0;
+  gcmn.ysiz = 8.5;
+}
+if (aspratio>-990) { /* user has specified aspect ratio */
+  if (aspratio>0.2 && aspratio < 5.0) {   /* range is limited here. */
+    if (aspratio < 1.0) {
+      gcmn.xsiz = 11.0*aspratio;
+      gcmn.ysiz = 11.0;
+    } else {
+      gcmn.ysiz = 11.0/aspratio;
+      gcmn.xsiz = 11.0;
+    }
+  }
+  else {
+    gaprnt(1,"Warning: Aspect ratio must be between 0.2 and 5.0 -- defaulting to landscape mode\n");
+  }
+}
+
+if(xwideflg) gxwdln();
+
+gainit();
+mfcmn.cal365=-999;
+mfcmn.warnflg=2;
+mfcmn.winx=-999;      /* Window x  */         
+mfcmn.winy=-999;      /* Window y */     
+mfcmn.winw=0;         /* Window width */ 
+mfcmn.winh=0;         /* Window height */ 
+mfcmn.winb=0;         /* Window border width */
+gcmn.pfi1 = NULL;                     /* No data sets open      */
+gcmn.pfid = NULL;
+gcmn.fnum = 0;
+gcmn.dfnum = 0;
+gcmn.undef = -9.99e8;         /* default undef value */
+gcmn.fseq = 10; 
+gcmn.pdf1 = NULL;
+gcmn.grflg = 0;
+gcmn.devbck = 0;
+gcmn.sdfwname = NULL;
+gcmn.sdfwtype = 1;
+gcmn.sdfwpad = 0;
+gcmn.sdfchunk = 0;
+gcmn.sdfzip = 0;
+gcmn.sdfprec = 8;
+gcmn.ncwid = -999;
+gcmn.xchunk = 0;
+gcmn.ychunk = 0;
+gcmn.zchunk = 0;
+gcmn.tchunk = 0;
+gcmn.echunk = 0;
+gcmn.attr = NULL;
+gcmn.ffile = NULL;
+gcmn.sfile = NULL;
+gcmn.fwname = NULL;
+gcmn.gtifname = NULL;    /* for GeoTIFF output */
+gcmn.tifname = NULL;     /* for KML output */
+gcmn.kmlname = NULL;     /* for KML output */
+gcmn.kmlflg = 1;         /* default KML output is an image file */
+gcmn.shpfname = NULL;    /* for shapefile output */
+gcmn.shptype = 2;        /* default shape type is line */
+gcmn.fwenflg = BYTEORDER;
+gcmn.fwsqflg = 0;        /* default is stream */
+gcmn.fwexflg = 0;        /* default is not exact -- old bad way */
+gcmn.gtifflg = 1;        /* default geotiff output format is float */
+if (size) gcmn.hbufsz = size;
+if (g2size) gcmn.g2bufsz = g2size;
+gcmn.cachesf = 1.0;      /* global scale factor for netcdf4/hdf5 cache */
+gcmn.fillpoly = -1;      /* default is to not fill shapefile polygons */
+gcmn.marktype = 3;       /* default is to draw points as closed circe */
+gcmn.marksize = 0.05;    /* default mark size */
+for (i=0; i<32; i++) {
+  gcmn.clct[i] = NULL;  /* initialize collection pointers */
+  gcmn.clctnm[i] = 0;
+}
+
+
+gafdef();
+
+gagx(&gcmn);
+
+#if !defined(__CYGWIN32__) && !defined(__GO32__)
+  signal(CPULIMSIG, gasigcpu) ;  /* CPU time limit signal; just exit   -hoop */
+#endif
+
+#if READLINE == 1
+if (wrhstflg && logfile != NULL) {
+  printf("Command line history in %s\n",logfile);
+  history_truncate_file(logfile,256); 
+  read_history(logfile); /* read last 256 cmd */
+}
+#endif
+
+if (icmd) rc = gacmd(icmd,&gcmn,0);
+else      rc = 0;
+signal(2,gasig);  /* Trap cntrl c */
+
+#if USEGUI == 1
+if (!ipcflg) 
+  gagui_main (argc, argv);   /*ams Initializes GAGUI, and if the environment
+                               variable GAGUI is set it starts a GUI
+                               script. Otherwise, it just returns. ams*/
+#endif
+if (ipcflg) printf("\n<RC> %d </RC>\n</IPC>\n",rc);
+
+/* Main command line loop */
+while (rc>-1) {
+
+  if (killflg) return(99);
+
+#if READLINE == 1
+#if defined(MM_NEW_PROMPT) 
+  char prompt[13];
+  if (hstflg) {
+    snprintf(prompt,12,"ga[%d]> ",history_length+1);
+    rc=nxrdln(&cmd[0],prompt);
+  }
+#else
+  if (hstflg) rc=nxrdln(&cmd[0],"ga-> ");
+#endif
+  else rc=nxtcmd(&cmd[0],"ga> ");
+#else
+  rc=nxtcmd(&cmd[0],"ga> ");
+#endif
+  
+  if (rc < 0) {
+    strcpy(cmd,"quit");   /* on EOF, just quit */
+    printf("[EOF]\n");
+  }
+
+  if (ipcflg) printf("\n<IPC> %s", cmd );  /* echo command in IPC mode */
+
+  gcmn.sig = 0;
+  rc = gacmd(cmd,&gcmn,0);
+
+  if (ipcflg) printf("\n<RC> %d </RC>\n</IPC>\n",rc);
+}
+
+/* All done */
+gxend();
+
+#if READLINE == 1
+ if (wrhstflg) write_command_log(logfile);
+#endif
+
+exit(0);
+
+}
+
+/* query the global cache scale factor */
+gadouble qcachesf (void) {
+  return(gcmn.cachesf); 
+}
+
+/* Initialize most gacmn values.  Values involving real page size,
+   and values involving open files, are not modified   */
+
+void gainit (void) {
+gaint i;
+
+  gcmn.wgds = &wgds;
+  gcmn.wgds->fname = NULL;
+  gcmn.wgds->opts = NULL;
+  gcmn.hbufsz = 1000000;
+  gcmn.g2bufsz = 10000000;
+  gcmn.loopdim = 3;
+  gcmn.csmth = 0;
+  gcmn.cterp = 1;
+  gcmn.cint = 0;
+  gcmn.cflag = 0;
+  gcmn.ccflg = 0;
+  gcmn.cmin = -9.99e33;
+  gcmn.cmax = 9.99e33;
+  gcmn.arrflg = 0;
+  gcmn.arlflg = 1;
+  gcmn.ahdsiz = 0.05;
+  gcmn.hemflg = -1;
+  gcmn.aflag = 0;
+  gcmn.axflg = 0;
+  gcmn.ayflg = 0;
+  gcmn.rotate = 0;
+  gcmn.xflip = 0;
+  gcmn.yflip = 0;
+  gcmn.gridln = -9;
+  gcmn.zlog = 0;
+  gcmn.log1d = 0;
+  gcmn.coslat = 0;
+  gcmn.numgrd = 0;
+  gcmn.gout0 = 0;
+  gcmn.gout1 = 1;
+  gcmn.gout1a = 0;
+  gcmn.gout2a = 1;
+  gcmn.gout2b = 4;
+  gcmn.goutstn = 1;
+  gcmn.cmark = -9;
+  gcmn.grflag = 1;
+  gcmn.grstyl = 5;
+  gcmn.grcolr = 15;
+  gcmn.blkflg = 0;
+  gcmn.dignum = 0;
+  gcmn.digsiz = 0.07;
+  gcmn.reccol = 1;
+  gcmn.recthk = 3;
+  gcmn.lincol = 1;
+  gcmn.linstl = 1;
+  gcmn.linthk = 3;
+
+  gcmn.mproj = 2;
+  gcmn.mpdraw = 1;
+  gcmn.mpflg = 0;
+  gcmn.mapcol = -9; gcmn.mapstl = 1; gcmn.mapthk = 1;
+  for (i=0; i<256; i++) {
+    gcmn.mpcols[i] = -9;
+    gcmn.mpstls[i] = 1;
+    gcmn.mpthks[i] = 3;
+  }
+  gcmn.mpcols[0] = -1;  gcmn.mpcols[1] = -1; gcmn.mpcols[2] = -1;
+  gcmn.mpdset[0] = (char *)galloc(7,"mpdset0");
+  *(gcmn.mpdset[0]+0) = 'l'; 
+  *(gcmn.mpdset[0]+1) = 'o';
+  *(gcmn.mpdset[0]+2) = 'w'; 
+  *(gcmn.mpdset[0]+3) = 'r';
+  *(gcmn.mpdset[0]+4) = 'e'; 
+  *(gcmn.mpdset[0]+5) = 's';
+  *(gcmn.mpdset[0]+6) = '\0';
+  for (i=1;i<8;i++) gcmn.mpdset[i]=NULL;
+
+  gcmn.strcol = 1;
+  gcmn.strthk = 3;
+  gcmn.strjst = 0;
+  gcmn.strrot = 0.0;
+  gcmn.strhsz = 0.1;
+  gcmn.strvsz = 0.12;
+  gcmn.anncol = 1;
+  gcmn.annthk = 6;
+  gcmn.tlsupp = 0;
+  gcmn.xlcol = 1;
+  gcmn.ylcol = 1;
+  gcmn.xlthck = 4;
+  gcmn.ylthck = 4;
+  gcmn.xlsiz = 0.11;
+  gcmn.ylsiz = 0.11;
+  gcmn.xlflg = 0;
+  gcmn.ylflg = 0;
+  gcmn.xtick = 1;
+  gcmn.ytick = 1;
+  gcmn.xlint = 0.0;
+  gcmn.ylint = 0.0;
+  gcmn.xlpos = 0.0;
+  gcmn.ylpos = 0.0;
+  gcmn.ylpflg = 0;
+  gcmn.yllow = 0.0;
+  gcmn.xlside = 0;
+  gcmn.ylside = 0;
+  gcmn.clsiz = 0.09;
+  gcmn.clcol = -1;
+  gcmn.clthck = -1;
+  gcmn.stidflg = 0;
+  gcmn.grdsflg = 1;
+  gcmn.timelabflg = 1;
+  gcmn.stnprintflg = 0;
+  gcmn.fgcnt = 0;
+  gcmn.barflg = 0;
+  gcmn.bargap = 0;
+  gcmn.barolin = 0;
+  gcmn.clab = 1;
+  gcmn.clskip = 1;
+  gcmn.xlab = 1;
+  gcmn.ylab = 1;
+  gcmn.clstr = NULL;
+  gcmn.xlstr = NULL;
+  gcmn.ylstr = NULL;
+  gcmn.xlabs = NULL;
+  gcmn.ylabs = NULL;
+  gcmn.dbflg = 0;
+  gcmn.rainmn = 0.0;
+  gcmn.rainmx = 0.0;
+  gcmn.rbflg = 0;
+  gcmn.miconn = 0;
+  gcmn.impflg = 0;
+  gcmn.impcmd = 1;
+  gcmn.strmden = 5;
+  gcmn.strmarrd = 0.4;
+  gcmn.strmarrsz = 0.05;
+  gcmn.strmarrt = 1;
+  gcmn.frame = 1;
+  gcmn.pxsize = gcmn.xsiz;
+  gcmn.pysize = gcmn.ysiz;
+  gcmn.vpflag = 0;
+  gcmn.xsiz1 = 0.0;
+  gcmn.xsiz2 = gcmn.xsiz;
+  gcmn.ysiz1 = 0.0;
+  gcmn.ysiz2 = gcmn.ysiz;
+  gcmn.paflg = 0;
+  for (i=0; i<10; i++) gcmn.gpass[i] = 0;
+  gcmn.btnfc = 1;
+  gcmn.btnbc = 0;
+  gcmn.btnoc = 1;
+  gcmn.btnoc2 = 1;
+  gcmn.btnftc = 1;
+  gcmn.btnbtc = 0;
+  gcmn.btnotc = 1;
+  gcmn.btnotc2 = 1;
+  gcmn.btnthk = 3;
+  gcmn.dlgpc = -1;
+  gcmn.dlgfc = -1;
+  gcmn.dlgbc = -1;
+  gcmn.dlgoc = -1;
+  gcmn.dlgth = 3;
+  gcmn.dlgnu = 0;
+  for (i=0; i<15; i++) gcmn.drvals[i] = 1;
+  gcmn.drvals[1] = 0; gcmn.drvals[5] = 0;
+  gcmn.drvals[9] = 0;
+  gcmn.drvals[14] = 1;
+  gcmn.sig = 0;
+  gcmn.lfc1 = 2;
+  gcmn.lfc2 = 3;
+  gcmn.wxcols[0] = 2; gcmn.wxcols[1] = 10; gcmn.wxcols[2] = 11;
+  gcmn.wxcols[3] = 7; gcmn.wxcols[4] = 15;
+  gcmn.wxopt = 1;
+  gcmn.ptflg = 0;
+  gcmn.ptopt = 1;
+  gcmn.ptden = 5;
+  gcmn.ptang = 0;
+  gcmn.statflg = 0;
+  gcmn.prstr = NULL;  gcmn.prlnum = 8; 
+  gcmn.prbnum = 1; gcmn.prudef = 0;
+  gcmn.dwrnflg = 1;
+  gcmn.xexflg = 0; gcmn.yexflg = 0;
+  gcmn.cachesf = 1.0; 
+  gcmn.dblen = 12;
+  gcmn.dbprec = 6;
+
+
+}
+
+void gasig(gaint i) {
+  if (gcmn.sig) exit(0);
+  gcmn.sig = 1;
+}
+
+gaint gaqsig (void) {
+  return(gcmn.sig);
+}
+
+#if READLINE == 1
+/* write command history to log file */
+void write_command_log(char *logfile) {
+   char QuitLabel[60];
+   time_t thetime;
+   struct tm *ltime;
+   if ((thetime=time(NULL))!=0) {  
+      ltime=localtime(&thetime);
+      strftime(QuitLabel,59,"quit # (End of session: %d%h%Y, %T)",ltime);
+      remove_history(where_history());
+      add_history(QuitLabel);
+   }
+   write_history(logfile);  
+   return;
+}
+#endif
+
+/* output command line options */
+
+void command_line_help (void) {
+printf("\nCommand line options for GrADS version " GRADS_VERSION ": \n\n");
+printf("    -help       Prints out this help message \n");
+printf("    -a ratio    Sets the aspect ratio of the real page \n");
+printf("    -b          Enables batch mode (graphics window is not opened) \n");
+printf("    -c cmd      Executes the command 'cmd' after startup \n");
+printf("    -C N        Enables colorization of text with color scheme N (default scheme is 0)\n");
+printf("    -E          Disables command line editing \n");
+printf("    -g WxH+X+Y  Sets size of graphics window \n");
+printf("    -H fname    Enables command line logging to file 'fname' (default fname is $HOME/.grads.log) \n");
+printf("    -l          Starts in landscape mode with real page size 11 x 8.5 \n");
+printf("    -p          Starts in portrait mode with real page size 8.5 x 11 \n");
+printf("    -m NNN      Sets metafile buffer size to NNN (must be an integer) \n");
+printf("    -u          Unbuffers stdout/stderr, disables command line editing \n");
+printf("    -W          Uses X server to draw wide lines (faster) instead of software (better) \n");
+printf("    -x          Causes GrADS to automatically quit after executing supplied command (used with -c) \n");
+printf("\n    Options that do not require arguments may be concatenated \n");
+printf("\nExamples:\n");
+printf("   grads -pb \n");
+printf("   grads -lbxc \"myscript.gs\" \n");
+printf("   grads -Ca 1.7778 \n");
+printf("   grads -C 2 -a 1.7778 \n");
+printf("   grads -pHm 5000000 -g 1100x850+70+0 \n");
+printf("   grads -pH mysession.log -m 5000000 -g 1100x850+70+0 \n\n");
+}
+
+/* For CPU time limit signal */
+void gasigcpu(gaint i) {  
+    exit(1) ;
+}
diff --git a/src/grads.h b/src/grads.h
new file mode 100644
index 0000000..13ed035
--- /dev/null
+++ b/src/grads.h
@@ -0,0 +1,1289 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "gabufr.h"
+#if GRIB2==1
+#include "grib2.h"
+#endif
+#if USESHP==1
+#include "shapefil.h"
+#endif
+#if USEHDF5==1
+#include <hdf5.h>
+#endif
+
+/* Handling of missing data values. After the data I/O is done, 
+   grid values are tested to see if they are within a small range 
+   (+-value/EPSILON) of the missing value. If true, then the undef 
+   mask is set to 0. If false, then the grid data values are good, 
+   and the undef mask is set to 1. Everywhere else in the code, 
+   undef tests are done on the mask values, not the data. */
+
+#define EPSILON 1e5
+#define FUZZ_SCALE 1e-5
+
+/* RPTNUM: Number of garpt blocks to allocate per memory block
+   BLKNUM: Max number of memory requests
+   A max of RPTNUM*BLKNUM stations can be held per request
+   Static memory usage is sizeof(pointer) * BLKNUM bytes */
+
+#define RPTNUM 200
+#define BLKNUM 5000
+
+#ifdef __hpux
+#define CPULIMSIG _SIGXCPU
+#else
+#define CPULIMSIG SIGXCPU
+#endif
+
+ /*******************\
+ *  Data Structures  *
+ \*******************/
+
+/* Pointer to data object */
+union gadata {
+  struct gagrid *pgr;
+  struct gastn  *stn;
+};
+
+/* Date/time structure */
+struct dt {
+  gaint yr;
+  gaint mo;
+  gaint dy;
+  gaint hr;
+  gaint mn;
+};
+
+/* Collection structure */
+struct gaclct {
+  struct gaclct *forw;        /* Forward Pointer */
+  struct gastn  *stn;         /* Pointer to station data */
+  struct gastn  *stn2;        /* Pointer to station data */
+};
+
+/* Structure for info for the gxout "writegds" option, 
+   for writing data for the use of the GDS */
+struct gawgds {
+  char *fname;                /* File name to write */
+  char *opts;                 /* User specified options */
+};
+
+
+/*mf 9612105 Contains global information for Mike Fiorino and Gary Love 980114 mf*/
+
+struct gamfcmn {
+  gaint cal365 ;               /* 365 (no leap year) calendar */
+  gaint fullyear ;             /* 1 - must specify full year 0 old default */
+  gaint warnflg;               /* warning level flag for messages */
+  gaint winid;                 /* Window ID */
+  gaint winx;                  /* Window X position (upper left) */
+  gaint winy;                  /* Window Y position (upper left) */
+  gauint winw;                 /* Window width */
+  gauint winh;                 /* Window height */
+  gauint winb;                 /* Window border width */
+
+};
+
+/* Contains information about the user interface and graphics output. */
+struct gacmn {
+ 
+  gadouble dmin[5],dmax[5];    /* Current absolute coordinate limits    */
+                               /* Grid-to-world conversion info follows */
+  gadouble (*xgr2ab) (gadouble *, gadouble);
+  gadouble (*ygr2ab) (gadouble *, gadouble);
+  gadouble (*xab2gr) (gadouble *, gadouble);
+  gadouble (*yab2gr) (gadouble *, gadouble);
+  gadouble *xgrval;
+  gadouble *ygrval;
+  gadouble *xabval;
+  gadouble *yabval;
+  struct gawgds *wgds;         /* Pointer to gds output structure       */
+  gaint hbufsz;                /* Metafile buffer size                  */
+  gaint g2bufsz;               /* Grib2 cache buffer size               */
+  gaint pass;                  /* Number of passes since last clear     */
+  gaint gpass[10];             /* Number of passes for each gx type     */
+  gaint loopdim;               /* Looping dimension                     */
+  gaint loopflg;               /* Looping on or off                     */
+  struct gafile *pfi1;         /* Pointer to first gafile in chain      */
+  struct gafile *pfid;         /* Pointer to default gafile             */
+  gaint fnum;                  /* File count                            */
+  gaint dfnum;                 /* Default file number   */
+  gaint fseq;                  /* Unique sequence num for files opened  */
+  struct gadefn *pdf1;         /* Pointer to first define block         */
+  struct dt tmin,tmax;
+  gaint vdim[5];               /* Which dimensions vary?                */
+  gaint x1ex,x2ex,y1ex,y2ex;   /* For -ex flag on fwrite */
+  gaint xexflg,yexflg;         /* -ex -- are dims valid? */
+  gadouble pxsize,pysize;      /* Physical page size in inches          */
+  gaint orient;                /* Page orientation                      */
+  gaint vpflag;                /* If 1, virtual page being used         */
+  gadouble xsiz,xsiz1,xsiz2;   /* Physical plotting size in X direction */
+  gadouble ysiz,ysiz1,ysiz2;   /* Physical plotting size in Y direction */
+  gaint paflg;                 /* User has specified plotting area      */
+  gadouble pxmin,pxmax;        /* User specified plotting area          */
+  gadouble pymin,pymax;
+  gaint clab;                  /* control contour labels.               */
+  gaint clskip;                /* Contour label skipping                */
+  char *clstr;                 /* Contour label template                */
+  gadouble rainmn,rainmx;      /* control rainbow colors                */
+  gaint rbflg;                 /* User rainbow colors specified         */
+  gaint rbcols[256];           /* User rainbow colors                   */
+  gadouble cmin,cmax,cint;     /* User specified contour limits         */
+  gaint cflag;                 /* If true, user specifies contour levels*/
+  gadouble clevs[256];         /* User specified contour levels         */
+  gaint ccflg;                 /* If true, user specifies contour colors*/
+  gaint ccols[256];            /* User specified contour colors         */
+  gaint shdcls[256];           /* Shade colors after shading            */
+  gadouble shdlvs[256];        /* Shade levels                          */
+  gaint shdcnt;                /* Number of shdlvs, shdcls              */
+  gaint cntrcnt;               /* Number of contours (after countouring)*/
+  gaint cntrcols[256];         /* Contour colors (after contouring)     */
+  gadouble cntrlevs[256];      /* Contour levels (after contouring)     */
+  gaint ccolor,cstyle;         /* User contour/line appearance          */
+  gaint cthick;                /* User gx display line thickness        */
+  gaint cmark;                 /* Line marker type                      */
+  gaint csmth;                 /* Contour smoothing on or off           */
+  gaint cterp;                 /* Spline fit on or off                  */
+  gadouble rmin,rmax,rint;     /* Axis limits for 1-D plots             */
+  gadouble rmin2,rmax2,rint2;  /* Axis limits for 1-D plots             */
+  gaint aflag,aflag2;          /* Keep 1D axis limits fixed             */
+  gaint grflag,grstyl,grcolr;  /* Grid flag, linestyle, color           */
+  gaint dignum;                /* grid value plot control (gxout=grid)  */
+  gadouble digsiz;
+  gaint arrflg;                /* Use already set arrow scaling         */
+  gadouble arrsiz;             /* Arrow size in inches                  */
+  gaint arlflg;                /* Arrow label flag */
+  gadouble arrmag;             /* Vector magnitude producing arrsiz arrw*/
+  gadouble ahdsiz;             /* Arrow head size.       */
+  gaint hemflg;                /* -1; auto  0; nhem  1; shem */
+  gaint miconn;                /* Connect line graph accross missing    */
+  gaint strmden;               /* Streamline density indicator  */
+  gadouble strmarrd;           /* Streamline distance between arrowheads */
+  gadouble strmarrsz;          /* Streamline arrowhead size */
+  gaint strmarrt;              /* Streamline arrowhead type */
+  gaint mdlblnk,mdldig3;       /* Station model plot opts */
+  char *prstr;                 /* Format string for gxout print */
+  gaint prlnum;                /* Number of values per record */
+  gaint prbnum;                /* Number of blanks to add between values */
+  gaint prudef;                /* Undef printed as "undef" or value */
+  gaint fgvals[50];            /* Values for grid fill */
+  gaint fgcols[50];
+  gaint fgcnt;
+  gaint gridln;                /* Line attributes for gxout grid */
+  gaint stidflg;               /* Plot station ids with values      */
+  gadouble axmin,axmax,axint;  /* Overrides for X-axis labels           */
+  gadouble aymin,aymax,ayint;  /* Overrides for Y-axis labels           */
+  gaint axflg, ayflg;          /* Is override in effect for the axis?   */
+  gaint frame;                 /* Display frame?  */
+  gaint rotate;                /* Rotate plot from default orientation  */
+  gaint xflip, yflip;          /* Flip X or Y axes                      */
+  gaint zlog;                  /* Z coordinate in log scale */
+  gaint log1d;                 /* Log scaling for 1D plots              */
+  gaint coslat;                /* Lat coordinate scaled as cos lat */
+  gaint mproj;                 /* Map projection -- used for X,Y plot   */
+                               /*  only.  0 = no map.                   */
+  gaint mpdraw;                /* Draw map outline - 0=no               */
+  gadouble mpvals[10];         /* Map projection option values.         */
+  gaint mpflg;                 /* Map projection option values are set. */
+  char *mpdset[8];             /* Map data set names.                   */
+  gaint mpcols[256];           /* Map Color array                       */
+  gaint mpstls[256];           /* Map line styles array                 */
+  gaint mpthks[256];           /* Map line widths array                 */
+  gaint mapcol,mapstl,mapthk;  /* Default map color, style, thickness   */
+  gaint gout0;                 /* Graphics output type for stat.        */
+  gaint gout1;                 /* Graphics output type for 1-D.         */
+  gaint gout1a;                /* Graphics output type for 1-D.         */
+  gaint gout2a;                /* Graphics output type for 2-D.         */
+  gaint gout2b;                /* Graphics output type for 2-D.         */
+  gaint goutstn;               /* Graphics output type for stns */
+  gaint blkflg;                /* Leave certain values black when shadng*/
+  gadouble blkmin, blkmax;     /* Black range */
+  gaint reccol,recthk;         /* Draw Rectangle color, brdr thickness  */
+  gaint lincol,linstl,linthk;  /* Draw line color, style, thickness     */
+  gaint mcolor;                /* auto color (orange or grey)           */
+  gaint strcol,strthk,strjst;  /* Draw string color, thckns, justifictn */
+  gadouble strrot;             /* Draw string rotation */
+  gadouble strhsz,strvsz;      /* Draw string hor. size, vert. size     */
+  gaint anncol,annthk;         /* Draw title color, thickness           */
+  gaint grflg;                 /* Grey Scale flag   */
+  gaint devbck;                /* Device background */
+  gaint xlcol,xlthck,ylcol,ylthck,clcol,clthck;  /* color, thickness */
+  gaint xlside,ylside,ylpflg;
+  gadouble xlsiz,ylsiz,clsiz,xlpos,ylpos,yllow;         /* Axis lable size */
+  gadouble xlevs[50],ylevs[50]; /* User specified x/y axis labels  */
+  gaint xlflg,ylflg;           /* Number of user specified labels */
+  gaint xtick,ytick;           /* Number of extra tick marks      */
+  gadouble xlint,ylint;        /* User specified label increment */
+  char *xlstr, *ylstr;         /* user substitution string for labels */
+  gaint xlab,ylab;             /* Axis label options */
+  char *xlabs, *ylabs;         /* User specifies all labels */
+  gaint ixlabs, iylabs;        /* Count of user labels */
+  gaint tlsupp;                /* Suppress year or month of time labels */
+  gaint lfc1,lfc2;             /* Linefill colors */
+  gaint wxcols[5];             /* wx symbol colors */
+  gaint wxopt;                 /* wx options */
+  gaint tser;                  /* station time series type */
+  gaint bargap;                /* Bar Gap in percent  */
+  gaint barolin;               /* Bar outline flag */
+  gadouble barbase;            /* Bar Base Value      */
+  gaint barflg;                /* Bar flag: 1, use base value  */
+                               /*           0, draw from plot base */
+                               /*          -1, draw from plot top  */
+  gaint btnfc,btnbc,btnoc,btnoc2;     /* Current button attributes */
+  gaint btnftc,btnbtc,btnotc,btnotc2;
+  gaint btnthk;
+  gaint dlgfc,dlgbc,dlgoc;   /* Current dialog attributes */
+  gaint dlgpc,dlgth,dlgnu;
+  gaint drvals[15];          /* Attributes for drop menus */
+  char *shpfname;            /* shapefile write file name */
+  gaint shptype;             /* shapefile output type: 1=point, 2=line */
+  gaint gtifflg;             /* geotiff data type: 1=float 2=double */
+  char *gtifname;            /* geotiff write file name */
+  char *tifname;             /* kml image  file name */
+  char *kmlname;             /* kml text file name */
+  gaint kmlflg;              /* kml output: 1==img, 2==contours */
+  char *sdfwname;            /* netcdf/hdf write file name */
+  gaint sdfwtype;            /* type of sdf output: 1=classic, 2=nc4 */
+  gaint sdfwpad;             /* pad the sdf output with extra dims: 1=4D, 2=5D */
+  gaint sdfprec;             /* precision (8==double, 4==float, etc.) */
+  gaint sdfchunk;            /* flag to indicate whether or not to chunk */
+  gaint sdfzip;              /* flag to indicate whether or not to compress */
+  gaint ncwid;               /* netcdf write file id  */
+  gaint xchunk;              /* size of sdfoutput file chunk in X dimension */
+  gaint ychunk;              /* size of sdfoutput file chunk in Y dimension */
+  gaint zchunk;              /* size of sdfoutput file chunk in Z dimension */
+  gaint tchunk;              /* size of sdfoutput file chunk in T dimension */
+  gaint echunk;              /* size of sdfoutput file chunk in E dimension */
+  struct gaattr *attr;       /* pointer to link list of user-specified SDF attributes */
+#if USESHP==1
+  struct dbfld *dbfld;       /* pointer to link list of user-specified data base fields */
+#endif
+  gaint dblen;               /* total number of digits for formatting data base fields */
+  gaint dbprec;              /* precision digits for formatting data base fields: %len.prec */
+  FILE *ffile;               /* grads.fwrite file handle */
+  FILE *sfile;               /* grads.stnwrt file handle */
+  char *fwname;              /* fwrite file name */
+  gaint fwenflg;             /* fwrite byte order control */
+  gaint fwsqflg;             /* fwrite stream vs fortran seq */
+  gaint fwappend;            /* write mode (1): append */
+  gaint fwexflg;             /* fwrite exact grid dims */
+  gaint grdsflg;             /* Indicate whether to put grads atrib.  */
+  gaint timelabflg;          /* Indicate whether to put cur time atrib.  */
+  gaint stnprintflg;         /* Indicate whether to put cur time atrib.  */
+  gaint dbflg;               /* Double buffer mode flag     */
+  gaint batflg;              /* Batch mode */
+  gaint numgrd,relnum;       /* Number of data objects held           */
+  gaint type[16];            /* Data type of each data object         */
+  union gadata result[16];   /* Pointers to held data objects         */
+  struct gaclct *clct[32];   /* Anchor for collection */
+  gaint clctnm[32];          /* Number of items collected */
+  gaint clcttp[32];          /* Varying dimension of collection */
+  gaint lastgx;              /* Last gx plotted */
+  gaint xdim, ydim;          /* Which dimensions on X and Y axis */
+  gaint statflg;             /* stat txt output on all displays */
+  gaint impflg;              /* Implied run flag */
+  char *impnam;              /* Implided run script name */
+  gaint impcmd;              /* Implicit run */
+  gaint sig;                 /* User has signalled */
+  gaint ptflg;		     /* Pattern fill flag */
+  gaint ptopt;		     /* Pattern option: */
+			     /*		0, open  */
+			     /*		1, solid */
+			     /*		2, dot */
+			     /*		3, line  */
+  gaint ptden;		     /* Dot or line pattern density */
+  gaint ptang;		     /* Line pattern angle */
+  gaint dwrnflg;             /* Issue, or not, warnings about missing or constant data */
+  gadouble undef;            /* default or user-defined undef value for print and file output */
+  gadouble cachesf;          /* global scale factor for netcdf4/hdf5 cache size */
+  gaint fillpoly;            /* color to fill shapfile polygons, -1 for no fill */
+  gaint marktype;            /* type of mark for shapefile points */
+  gadouble marksize;         /* size of mark for shapefile points */
+};
+
+/* Sructure for string substitution in templating -- the %ch template.  
+   This forms a linked list chained from pchsub1 in gafile */
+struct gachsub {
+  struct gachsub *forw;       /* Forward pointer */
+  gaint t1;                   /* First time for this substitution */
+  gaint t2;                   /* Last time.  -99 indicates open ended */
+  char *ch;                   /* Substitution string */
+};
+
+/* Structure for ensemble metadata */
+struct gaens {
+  char name[16];             /* name of ensemble */
+  gaint length;              /* length of time axis */
+  struct dt tinit;           /* initial time */
+  gaint gt;                  /* initial time in grid units */
+  gaint grbcode[4];          /* grib2 codes */
+};
+
+/* GA status structure.  Contains necessary info about the scaling
+   and file structure in force.                                       */
+struct gastat {
+  struct gafile *pfi1;       /* Pointer to first gafile in chain      */
+  struct gafile *pfid;       /* Pointer to default gafile             */
+  struct gadefn *pdf1;       /* Pointer to first define block         */
+  struct gaclct **pclct;     /* Pointer to the collection pointers    */
+  union gadata result;       /* Result goes here                      */
+  struct dt tmin,tmax;
+  gadouble dmin[5],dmax[5];  /* Range of absolute dimensions          */
+  gaint fnum;                /* Default file number                   */
+  gaint type;                /* Result type (grid==1 or stn==0)       */
+  gaint idim,jdim;           /* Varying dimensions                    */
+};
+
+
+/* Description of a data file.                                        */
+  struct gafile {
+  struct gafile *pforw;      /* Forward pointer to next gafile block.
+                                List is anchored within gastat.       */
+  gaint fseq;                /* Unique sequence number for cache detection */
+  char name[4096];           /* File name or URL                      */
+  char *tempname;            /* File name of open file (differs with templates) */
+  char dnam[4096];           /* Descriptor file name                  */
+  char *mnam;                /* Map(index) file name */
+  FILE *infile;              /* File pointer.                         */
+  gaint type;                /* Type of file:  1 = grid
+                                               2 = simple station
+                                               3 = mapped station
+                                               4 = defined grid       */
+  char title[512];           /* Title -- describes the file.          */
+  gadouble undef;            /* Global undefined value for this file  */
+  gadouble ulow,uhi;         /* Undefined limits for missing data test  */
+  gafloat *sbuf;             /* Buffer for file I/O equal in length
+                                to the size needed to hold
+                                the largest station report            */
+  gadouble *rbuf;            /* Buffer for file I/O equal in length
+                                to one grid row in the file           */
+  unsigned char *pbuf;       /* Same as rbuf, for unpacking           */
+  char *bbuf;                /* Same as rbuf, for bit map I/O         */
+  char *ubuf;                /* Same as rbuf, for undef mask          */
+  gaint bswap;               /* Byte swapping needed */
+  gaint dhandle;             /* libgadap file handle.                 */
+  gaint dapinf[5];           /* pointer to coordinate variable indices
+				(first four elements are lon,lat,lev,time
+				fifth is station id)
+				for opendap station data only */
+  gaint mtype;               /* Stn map file type                     */
+  gaint *tstrt;              /* Pointer to list length dnum[3] of
+                                start points of times in the file     */
+  gaint *tcnt;               /* Count of stns for assctd time         */
+  gaint stcnt;               /* Count of mapped stids when stn data
+                                and map file is type stidmap.         */
+  gaint stpos;               /* Position in map file of start of
+                                stid info for map file type stidmap.  */
+  FILE *mfile;               /* File pointer to stidmap file          */
+  gaint dnum[5];               /* Dimension sizes for this file.        */
+  gaint tlpflg;                /* Circular file flag                    */
+  gaint tlpst;                 /* Start time offset in circular file    */
+  gaint vnum;                  /* Number of variables.                  */
+  gaint ivnum;                 /* Number of level independent variables
+                                for station data file                 */
+  gaint lvnum;                 /* Number of level dependent variables
+                                for station data file                 */
+  struct gavar *pvar1;       /* Pointer to an array of structures.
+                                Each structure in the array has info
+                                about the specific variable.          */
+  struct gaens *ens1;          /* pointer to array of ensemble structures */
+  long gsiz;                   /* Number of elements in a grid (x*y)    */
+                               /* This is for actual grid on disk,
+                                  not psuedo grid (when pp in force) */
+  long tsiz;                   /* Number of elements in an entire time
+                                  group (all variables at all levels
+                                  for one time).                        */
+  gaint trecs;                 /* Number of records (XY grids) per time
+                                  group.                                */
+  long fhdr;                   /* Number of bytes to ignore at file head*/
+  gaint wrap;                  /* The grid globally 'wraps' in X        */
+  gaint seqflg, yrflg, zrflg;  /* Format flags */
+  gaint ppflag;                /* Pre-projected data in use */
+  gaint pdefgnrl;              /* Keyword 'general' used instead of 'file' */
+  gaint ppwrot;                /* Pre-projection wind rotation flag */
+  gaint ppisiz, ppjsiz;        /* Actual size of preprojected grid */
+  gadouble ppvals[20];         /* Projection constants for pre-projected
+                                  grids.  Values depend on projection. */
+  gaint *ppi[9];               /* Pointers to offsets for pre-projected
+                                  grid interpolation */
+  gadouble *ppf[9];            /* Pointers to interpolation constants
+                                  for pre-projected grids */
+  gadouble *ppw;               /* Pointer to wind rotation array */
+  gadouble (*gr2ab[5]) (gadouble *, gadouble);
+                               /* Addresses of routines to do conversion
+                                  from grid coordinates to absolute
+                                  coordinates for X, Y, Z.  All Date/time
+                                  conversions handled by gr2t.          */
+  gadouble (*ab2gr[5]) (gadouble *, gadouble);
+                               /* Addresses of routines to do conversion
+                                  from absolute coordinates to grid
+                                  coordinates for X,Y,Z.  All date/time
+                                  conversions handled by t2gr.          */
+  gadouble *grvals[5];         /* Pointers to conversion information for
+                                  grid-to-absolute conversion routines. */
+  gadouble *abvals[5];         /* Pointers to conversion information for
+                                  absolute-to-grid conversion routines. */
+  gaint linear[5];             /* Indicates if a dimension has a linear
+                                  grid/absolute coord transformation
+                                  (Time coordinate always linear).      */
+  gaint dimoff[5];             /* Dimension offsets for defined grids   */
+  gaint climo;                 /* Climatological Flag (defined grids)   */
+  gaint cysiz;                 /* Cycle size for climo grids            */
+  gaint idxflg;                /* File records are indexed; 1==grib,station 2==grib2 */
+  gaint grbgrd;                /* GRIB Grid type */
+  struct gaindx *pindx;        /* Index Strucure if indexed file */
+  struct gaindxb *pindxb;      /* Index Strucure if off_t offsets are being used */
+#if GRIB2
+  struct gag2indx *g2indx;     /* Index Strucure if GRIB2 file */
+#endif
+  gaint tmplat;                /* File name templating:
+                                   3==templating on E and T 
+                                   2==templating only on E 
+                                   1==templating only on T, or when 
+                                      ddf has 'options template', but no % in dset 
+                                   0==no templating  */
+  gaint *fnums;                /* File number for each time */
+  gaint fnumc;                 /* Current file number that is open */
+  gaint fnume;                 /* Current ensemble file number that is open */
+  struct gachsub *pchsub1;     /* Pointer to first %ch substitution */
+  gaint errcnt;                /* Current error count */
+  gaint errflg;                /* Current error flag */
+  gaint ncflg;                 /* 1==netcdf  2==hdfsds */
+  gaint ncid;                  /* netcdf file id */
+  gaint sdid;                  /* hdf-sds file id */
+  gaint h5id;                  /* hdf5 file id */
+  gaint packflg;               /* Data are packed with scale and offset values */
+  gaint undefattrflg;          /* Undefined values are retrieved individually  */
+  char *scattr;                /* scale factor attribute name for unpacking data */
+  char *ofattr;                /* offset attribute name for unpacking data */
+  char *undefattr;             /* undef attribute name */
+  long xyhdr;                  /* Number of bytes to ignore at head of xy grids*/
+  gaint calendar;              /* Support for 365-day calendars */
+  gaint pa2mb;                 /* convert pressure values in descriptor file from Pa -> mb */
+  gaint bufrflg;               /* 1==dtype bufr */
+  struct bufrinfo *bufrinfo;   /* x,y pairs from descriptor file */ 
+  gabufr_dset *bufrdset;       /* pointer to parsed bufr data */
+  struct gaattr *attr;         /* pointer to link list of attribute metadata */
+  gaint nsdfdims; 
+  gaint sdfdimids[100];
+  gaint sdfdimsiz[100];
+  gaint time_type;             /* temporary flag for SDF time handling */
+  char sdfdimnam[100][129];
+  long cachesize;            /* default netcdf4/hdf5 cache size */
+};
+
+/* Structure that describes a grid (requestor or descriptor block).  */
+struct gagrid {
+  struct gafile *pfile;        /* Address of the associated gafile
+                                  structure to get the data from
+                                  (requestor block only)               */
+  gadouble *grid;              /* Address of the grid.                 */
+  gaint mnum;                  /* Number of grids when a multiple
+                                  grid result.  Note in this case, *grid
+                                  points to more than one grid, with the
+                                  "default" result being the 1st grid  */ 
+  gaint mtype;                 /* Type of multiple result grid         */
+  gaint *mnums;                /* See mvals  */
+  gadouble *mvals;             /* Metadata associated with a multiple
+                                  grid result.  What is here depends on
+                                  the value of mtype.                  */
+  gadouble undef;              /* Undefined value for this grid.       */
+  gadouble rmin,rmax;          /* Minimum/Maximum grid value
+                                  (rmin is set to the grid value when
+                                  isiz=jsiz=1.  *grid points to here.) */
+  char *umask;                 /* Mask for undefined values in the grid */
+  char umin,umax;              /* Min/max undefined mask values. 
+                                  (when isiz=jsiz=1, umin is set to the 
+                                  mask value and *umask points to umin) */
+  gaint isiz,jsiz;             /* isiz = number of elements per row.
+                                  jsiz = number of rows.               */
+  gaint idim,jdim;             /* Dimension of rows and columns.
+                                  -1 = This dimension does not vary
+                                   0 = X dimension (usually longitude)
+                                   1 = Y dimension (usually lattitude)
+                                   2 = Z dimension (usually pressure)
+                                   3 = Time
+                                   4 = Ensemble
+                                  If both dimensions are -1, then the
+                                  grid has one value, which will be
+                                  placed in rmin.                      */
+  gaint iwrld, jwrld;          /* World coordinates valid?             */
+  gaint dimmin[5],dimmax[5];   /* Dimension limits for each dimension
+                                  (X,Y,Z,T,E) in grid units.           */
+  struct gavar *pvar;          /* Pointer to the structure with info
+                                  on this particular variable.  If
+                                  NULL, this grid is the result of
+                                  an expression evaluation where the
+                                  variable type is unkown.             */
+  char *exprsn;                /* If grid is a 'final' result, this
+                                  will point to a character string that
+                                  contains the original expression.    */
+  gaint alocf;                  /* Scaling info allocated for us only  */
+  gadouble (*igrab) (gadouble *, gadouble);
+  gadouble (*jgrab) (gadouble *, gadouble);
+                                /* Addresses of routines to perform
+                                   grid-to-absolute coordinate
+                                   transforms for this grid's i and j
+                                   dimensions (unless i or j = 3).      */
+  gadouble (*iabgr) (gadouble *, gadouble);
+  gadouble (*jabgr) (gadouble *, gadouble);
+                                /* Absolute to grid conversion routines */
+  gadouble *ivals, *jvals;      /* Conversion info for grid to abs      */
+  gadouble *iavals, *javals;    /* Conversion info for abs to grid      */
+  gaint ilinr,jlinr;            /* Indicates if linear transformation   */
+  gaint toff;                   /* Indicates if T dim values are forecast offsets */
+};
+
+/* Structure that contains attribute metadata */
+struct gaattr {
+  struct gaattr *next;          /* Address of next attribute */
+  char  varname[129];           /* Name of variable or 'global' */
+  char  name[129];              /* Name of attribute -- e.g. "units" */
+  char  type[129];              /* Type of attribute -- e.g. "String", "Float32", etc. */
+  gaint nctype;                 /* NetCDF (or HDF) data type index value */
+  gaint len;                    /* Length of this attribute */
+  gaint fromddf;                /* Flag for attributes from descriptor file */
+  void  *value;                 /* Attribute value -- strings may contains blanks. */
+};
+
+#if USESHP==1
+/* Structure that contains dBase field metadata */
+struct dbfld {
+  struct dbfld *next;           /* Address of next data base field */
+  DBFFieldType type;            /* string, integer, double, or logical */
+  char name[12];                /* library interface limits length to 11 charaters */
+  gaint len;                    /* for type string: width of string
+				   for type int and double: total number of digits */
+  gaint prec; 			/* for type double: used with len for format string %len.prec */
+  gaint index;                  /* index value (for identifying this field in a list of fields) */
+  gaint flag;                   /* 0==static fiels (same for all shapes), 1==dynamic (varies w/ shape) */
+  void *value;                  /* field value */
+};
+#endif
+
+/* Structure that contains the x,y pairs for bufr time values */
+struct bufrtimeinfo {
+  gaint yrxy[2];
+  gaint moxy[2];
+  gaint dyxy[2]; 
+  gaint hrxy[2]; 
+  gaint mnxy[2];  
+  gaint scxy[2];  
+};
+
+/* Structure that contains the x,y pairs for file-wide bufr variables */
+struct bufrinfo {
+  gaint lonxy[2];
+  gaint latxy[2];
+  gaint levxy[2];
+  gaint stidxy[2];
+  struct bufrtimeinfo base,offset;   /* structures for base and offset time values */
+};
+
+/* Structure that contains the header (coordinate) info for a gabufr_msg */
+struct bufrhdr {
+  double lon;
+  double lat;
+  double lev;
+  double sec,offsec;
+  char   stid[8];
+  struct dt tvals,toffvals;
+};
+
+/* Structure that describes a report header in a stn file */
+struct rpthdr {
+  char id[8];                  /* Character station id           */
+  gafloat lat;                 /* Latitude of report             */
+  gafloat lon;                 /* Longitude of report            */
+  gafloat t;                   /* Time in relative grid units    */
+  gaint nlev;                  /* Number of levels following     */
+  gaint flag;                  /* Level independent var set flag */
+};
+
+/* Structure that describes a stid info block within a stidmap file */
+struct stninf {
+  char stid[8];
+  gaint offset;
+  gaint rcnt;
+};
+
+/* Structure that describes a single report                          */
+struct garpt {
+  struct garpt *rpt;           /* Address of next report               */
+  char stid[8];                /* Station id                           */
+  gadouble lat,lon,lev,tim;    /* Location of station                  */
+  gaint work;                  /* Work area                            */
+  gadouble val;                /* Value of variable                    */
+  char umask;                  /* Undef mask                           */
+};
+
+/* Structure that describes a collection of station reports.         */
+struct gastn {
+  struct garpt *rpt;           /* Address of start of link list        */
+  gaint rnum;                  /* Number of reports.                   */
+  struct garpt *blks[BLKNUM];  /* ptrs to memory holding rpts      */
+  struct gafile *pfi;          /* Address of the associated gafile
+                                  structure to get the data from
+                                  (requestor block only)               */
+  gadouble undef;              /* Undefined value for this data.       */
+  gadouble smin, smax;         /* Min and Max values for this data     */
+  gaint idim,jdim;             /* Varying dimensions for this data
+                                 -1 = This dimension does not vary
+                                  1 = X dimension (longitude)
+                                  2 = Y dimension (lattitude)
+                                  3 = Z dimension (pressure)
+                                  4 = Time                           */
+  gadouble dmin[5],dmax[5];    /* Dimension limits for each dimension
+                                  (X,Y,Z) in world coords.
+                                  Non-varying dimensions can have
+                                  limits in this structure.           */
+  gaint rflag;                 /* Get stations within specified radius in
+                                  degrees of fixed lat and lon         */
+  gadouble radius;             /* Radius */
+  gaint sflag;                 /* Get specific station  */
+  char stid[8];                /* Station id to get */
+  gaint tmin,tmax;             /* Grid limits of time */
+  gadouble ftmin,ftmax;        /* Float-valued grid limits of time, 
+			  	  equivalent to dmin[3],dmax[3]         */
+  gadouble *tvals;             /* Pointer to conversion info for the
+                                  time conversion routines.            */
+  struct gavar *pvar;          /* Pointer to the structure with info
+                                  on this particular variable.  If
+                                  NULL, this grid is the result of
+                                  an expression evaluation where the
+                                  variable type is unkown.             */
+  struct garpt **prev;         /* Used for allocating rpt structures   */
+  struct garpt *crpt;
+  gaint rptcnt,blkcnt;
+};
+
+/* Structure that describes a variable in a file.  These structures
+   are built in arrays that are hung off of gafile structures.         */
+struct gavar {
+  char varnm[128];             /* Variable description.                */
+  char abbrv[16];              /* Variable abbreviation.               */
+  char longnm[257];            /* netcdf/hdf var name if different     */
+  gadouble units[48];          /* Units indicator.                     
+				  Vals 0-7 are for variable codes:
+				  grib, non-float data, and nc/hdf dims;
+				  Vals 8-15 are for grib level codes;
+			          Vals 16-48 are for extra grib2 codes */
+  gaint g2aflg;                /* var requires additional grib2 codes  */
+  gaint offset;                /* Offset in grid elements of the start
+                                  of this variable within a time group
+                                  within this file.                    */
+  gaint recoff;                /* Record (XY grid) offset of the start
+                                  of this variable within a time group */
+  gaint ncvid;                 /* netcdf vid for this variable         */
+  gaint sdvid;                 /* hdf vid for this variable            */
+  gaint h5vid;                 /* hdf5 dataset id for this variable    */
+  gaint levels;                /* Number of levels for this variable.
+                                  0 is special and indiates one grid is
+                                  available for the surface only.      */
+  gaint dfrm;                  /* format  type indicator
+  				  1 - unsigned char
+				  4 - int  			       */
+  gaint var_t ;                /* variable t transform                 */
+  gadouble scale;              /* scale factor for unpacking data      */
+  gadouble add;                /* offset value for unpacking data      */
+  gadouble undef;              /* undefined value                      */
+  gaint vecpair;               /* Variable has a vector pair           */
+  gaint isu;                   /* Variable is the u-component of a vector pair */
+  gaint isdvar;                /* Variable is a valid data variable (for SDF files) */
+  gaint nvardims;              /* Number of variable dimensions        */
+  gaint vardimids[100];        /* Variable dimension IDs. 	       */
+#if USEHDF5==1
+  hid_t h5varflg;              /* hdf5 variable has been opened */
+  hid_t dataspace;             /* dataspace allocated for hdf5 variable */
+#endif
+};
+
+/* Structure that describes a function call.                           */
+struct gafunc {
+  gaint argnum;                /* Number of arguments found by fncprs  */
+  char *argpnt[20];            /* Pointers to the argument strings     */
+  char buff[1000];             /* Argument string buffer               */
+};
+
+/* Structure that describes a user defined function                    */
+struct gaufb {
+  struct gaufb *ufb;           /* Forward pointer                      */
+  char name[8];                /* Function name                        */
+  gaint alo,ahi;               /* Limits on number of args             */
+  gaint atype[8];              /* Types of args. 0=expr,1=float,2=int,3=char */
+  gaint sflg;                  /* Sequential or direct                 */
+  char *fname;                 /* Name of user executable              */
+  char *oname;                 /* File name for data transfer to user  */
+  char *iname;                 /* File name for data transfer from user */
+};
+
+/* Structure that describes a defined grid */
+struct gadefn {
+  struct gadefn *pforw;        /* Linked list pointer                  */
+  struct gafile *pfi;          /* File Structure containing the data   */
+  char abbrv[20];              /* Abbreviation assigned to this        */
+};
+
+/* Stack to evaluate the expression.  The stack consists of an
+   array of structures.                                               */
+struct smem {
+  gaint type;        /* Entry type: -2 stn,-1 grid,1=op,2='(',3=')'    */
+  union sobj {
+    gaint op;        /* Operator: 0=*, 1=/, 2=+                        */
+    struct gagrid *pgr; /* Operand (grid or stn)                      */
+    struct gastn *stn;
+  } obj;
+};
+
+/* Index structure, for when the records in a data file are indexed.
+   The indexing file will contain this structure at the front, followed
+   by the specified number of header and indexing values.  These
+   header and indexing values are file format specific. */
+
+struct gaindx {
+  gaint type;                   /* Indexing file type */
+  gaint hinum;                  /* Number of header ints */	       
+  gaint hfnum;                  /* Number of header floats */      
+  gaint intnum;                 /* Number of index ints (long) */  
+  gaint fltnum;                 /* Number of index floats */       
+  gaint *hipnt;                 /* Pointer to header int values */ 
+  gafloat *hfpnt;               /* Pointer to header float values */
+  gaint *intpnt;                /* Pointer to index int values */  
+  gafloat *fltpnt;              /* Pointer to index float values */
+} ;
+struct gaindxb {
+  gaint bignum;                 /* Number of off_t values */	       
+  off_t *bigpnt;                /* Pointer to off_t values */
+} ;
+
+#if GRIB2
+/* Structures for GRIB2 data */
+struct gag2indx {
+  gaint version;                /* Version number: 1: gaint offsets  2: off_t offsets */
+  gaint g2intnum;               /* Number of index offset values */  
+  gaint *g2intpnt;              /* Pointer to index g2ints */
+  off_t *g2bigpnt;              /* Pointer to record offsets when off_t offsets in use */
+} ;
+
+struct g2anchor {               /* structure for grib2 cache anchor */
+  struct g2buff *start;         /* pointer to next grid in cache */
+  struct g2buff *end;           /* pointer to previous grid in cache */
+  gaint total;                  /* size of cache */
+};
+
+struct g2buff {                 /* structure for grib2 cache grids*/
+  struct g2buff *next;          /* pointer to next grid in cache */
+  struct g2buff *prev;          /* pointer to previous grid in cache */
+  gaint fseq;                   /* file sequence number */
+  gaint z,t,e;                  /* grid coordinates of non-varying dimensions */
+  gaint size;                   /* number of grid points in the grid */
+  char abbrv[16];               /* name of variable */
+  gafloat *fld;                 /* grib2 field (returned by g2_getfld) */
+  char *mask;                   /* undef mask for grib2 field */
+};  
+#endif
+
+#if (USENETCDF == 1 || USEHDF == 1)
+typedef struct {
+    struct sdfnames *names1;                   /* Pointer to an array of varname structures. */
+    gaint xsrch,ysrch,zsrch,tsrch,esrch ;      /* if these need to be searched for */
+    gaint dvsrch;                              /* data var names need to be searched */
+    gaint isxdf;                               /* is it xdf */
+    gaint xsetup,ysetup,zsetup,tsetup,esetup;  /* if these need setting up */
+    gaint needtitle, needundef, needunpack;
+    gaint dvcount ;                            /* number of data variables */
+    gaint *dvsetup ;                           /* does this var need levelcnt and longname? */
+    gaint hasDDFundef ;
+    char *xdimname;
+    char *ydimname;
+    char *zdimname;
+    char *tdimname;
+    char *edimname;
+} GASDFPARMS ;
+
+struct sdfnames {
+  char abbrv[16];            /* GrADS var name                    */
+  char longnm[257];          /* netcdf/hdf var name if different  */
+};
+#endif
+ /***********************\
+ *  Function Prototypes  *
+ \***********************/
+
+/* Functions in GRADS.C */
+
+void gasig (gaint);
+gaint gaqsig (void);
+
+/* Functions in GAUSER:
+    gacmd:  Process a user command
+    gacln:  Reset variables
+    gaenab: Process an enable command
+    gadraw: Process a draw command
+    gadef:  Process a define command
+    gaudef: Process undefine command
+    gamodf: Modify defined grid
+    gaqury: Process a query command
+    gahelp: Process a help command
+    gaset:  Process the SET command
+    gadspl: Process a display command
+    gapars: Parse a compound expression for gadspl
+    gagrel: Release all held grids
+    gaopen: Open a data file from a descriptor file
+    cleanup: Clean up an input record
+    gaprnt: Process output messages
+    prntgaattr: Print out a descriptor attribute 
+    gagsdo: Execute command for a script
+    getpst: Allocate and initialize a gastat block              */
+
+void gainit (void);
+gadouble qcachesf (void);
+
+gaint gacmd (char *, struct gacmn *, gaint);
+void gacln (struct gacmn *,gaint);
+gaint gaenab (char *, struct gacmn *);
+gaint gadraw (char *, struct gacmn *);
+gaint gardrw (char *, struct gacmn *);
+gaint gaexec (char *, struct gacmn *);
+char *gagsdo (char *, gaint *);
+gaint gadef (char *, struct gacmn *, gaint);
+gaint gaudef (char *, struct gacmn *);
+gaint gamodf (char *, struct gacmn *);
+gaint gaqdef (char *, struct gacmn *, gaint);
+gaint gaqury (char *, char *, struct gacmn *);
+gaint gahelp (char *, struct gacmn *);
+gaint gaset (char *, char *, struct gacmn *);
+void set_nc_cache(size_t);
+#if USESHP==1
+SHPHandle gaopshp (char *);
+DBFHandle gaopdbf (char *);
+struct dbfld* parsedbfld (char *);
+#endif
+gaint gacoll (char *, struct gacmn *);
+gaint gadspl (char *, struct gacmn *);
+gaint gaspcl (char *, struct gacmn *);
+gaint gapars (char *, struct gastat *, struct gacmn *) ;
+void gagrel (struct gacmn *);
+gaint gaopen (char *, struct gacmn *);
+void cleanup (char *);
+void mygreta(char *);
+struct gastat *getpst (struct gacmn *);
+void gaprnt (gaint, char *);
+gaint prntgaattr (struct gafile *, char *, gaint, gaint);
+#if READLINE == 1
+gaint gahistory(char*, char *, struct gacmn *);
+#endif /* READLINE == 1 */
+gaint ncwrite (char *, struct gacmn *);
+gaint sdfwatt (struct gacmn*, gaint, char *, char *, char *);
+gaint sdfwdim (struct gafile *, struct gacmn *, gaint, gaint);
+gaint sdfdefdim (gaint, char *, gaint, gaint *, gaint *);
+
+gaint gaddes (char *, struct gafile *, gaint);
+gaint deflin (char *, struct gafile *, gaint, gaint);
+gaint deflev (char *, char *, struct gafile *, gaint);
+gaint ddfattr (char *, struct gafile *);
+struct gaattr *parseattr (char *);
+struct gafile *getpfi (void);
+void frepfi (struct gafile *, gaint);
+
+/* Functions in GAEXPR:
+    gaexpr: Evaluate an expression by creating a stack
+    eval:   Process the expression stack
+    gaoper: Perforam operation between two operands
+    gagrop: Perform a grid operation
+    gastop: Perform a station operation
+    gascop: Perform an op between a constant and stations
+    gagrvl: Put a constant in grid format
+    varprs: Parse a variable in the expression
+    getdfn: Search defined grid chain for a predifined grid
+    gagchk: Check validity of operation between two grids
+    stnvar: Handle specialized parsing of stn variable                */
+
+gaint gaexpr (char *, struct gastat *) ;
+gaint eval (gaint, struct smem *, gaint *);
+gaint gaoper (struct smem *, gaint, gaint, gaint, gaint);
+struct gagrid *gagrop (struct gagrid *, struct gagrid *, gaint, gaint);
+struct gastn *gastop (struct gastn *, struct gastn *, gaint, gaint);
+struct gastn *gascop (struct gastn *, gadouble, gaint, gaint);
+struct gagrid *gagrvl (gadouble);
+char *varprs (char *, struct gastat *) ;
+gaint gagchk (struct gagrid *, struct gagrid *, gaint);
+struct gafile *getdfn (char *, struct gastat *);
+char *stnvar (char *, char *, struct gafile *, struct gavar *,
+              struct gastat *);
+
+/* Functions in GAFUNC:
+    rtnprs: Parse and execute a function call
+    gafopr: Perform opration for two-op function call
+    gafdef: Read user function definition table
+                                                                     */
+
+char *rtnprs (char *, char *, struct gastat *) ;
+gaint gafopr (struct gastat *, struct gastat *, gaint );
+void gafdef (void);
+
+/* Functions in GAIO:
+    gaggrd: Get a grid from a data file
+    gagrow: Get a row of data, possibly wrapped, from the file
+    gafcor: Calculate file position of an item of data
+    garrow: Get an item or items from the data file
+    gagstn: Get a collection of stations
+    garead:
+    gaglvs: Get appropriate var and levs from rpt
+    gaarpt: Allocate report block
+    gasstn: Seek to location in station file
+    garstn: Read station data
+    gacstn: Cache a station report
+    gagdef: Get grid from defined variable
+    clicyc: Adjust for cyclic climatological defined variable
+    gagpre: Predefined variable access        
+    ganrow: Get an item or items from the netcdf data file
+    ganhow: Get an item or items from the HDF-SDS data file
+    gaopnc: Open a netcdf file 
+    gaophdf: Open an HDF-SDS file
+
+Note:  function prototype for garead is now in gaio.c
+*/
+
+gaint gaggrd (struct gagrid *);
+gaint gagrow (gadouble *, char *, gaint *);
+long gafcor (gaint, gaint, gaint, gaint);
+gaint garrow (gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *, gaint);
+gaint gagstn (struct gastn *);
+gaint gaglvs (gaint, struct rpthdr *, struct gastn *);
+struct garpt *gaarpt (struct gastn *);
+gaint gasstn (off_t);
+gaint garstn (gaint, char *, off_t);
+void gacstn (char *, char *, gaint, gaint);
+void gagcst (gaint, char *);
+gaint gagdef (void);
+void clicyc(gaint *);
+gaint gagpre (void);
+gaint gairow (gaint, gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *);
+gaint gaird (off_t, gaint, gaint, gaint, gaint, gaint);
+gaint gaprow (gaint, gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *);
+gaint gaopfn (gaint, gaint, gaint *, gaint *, struct gafile *);
+gaint gappcn (struct gafile *, gaint, gaint);
+void w3fb04 (gadouble, gadouble, gadouble, gadouble, gadouble *, gadouble *);
+void ll2lc (gadouble *, gadouble, gadouble, gadouble *, gadouble *, gadouble *);
+void ll2rotll (gadouble *, gadouble, gadouble, gadouble *, gadouble *, gadouble *);
+void gaiomg (void);
+gaint gancsetup (void);
+gaint gancgrid(gadouble *, char *, gaint, gaint);
+gaint gancrow (gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *);
+gaint gahrow  (gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *);
+gaint gah5row  (gaint, gaint, gaint, gaint, gaint, gaint, gadouble *, char *);
+gaint gaopnc (struct gafile *, gaint, gaint);
+gaint gaclosenc (struct gafile *);
+gaint gaclosehdf (struct gafile *);
+gaint gacloseh5 (struct gafile *);
+gaint gaophdf (struct gafile *, gaint, gaint);
+gaint gaoph5 (struct gafile *, gaint, gaint);
+gaint h5setup (void);
+#if USEHDF5==1
+gaint h5openvar (gaint,char*,hid_t*,hid_t*);
+gaint h5closevar (hid_t, hid_t);
+#endif
+gaint h5attr(gaint, char *, char *, gadouble *);
+gaint hdfattr (gaint, char *, gadouble *);
+gaint ncpattrs(gaint, char *, char *, gaint, gaint, char *);
+gaint hdfpattrs(gaint, char *, char *, gaint, gaint, char *);
+gaint h5pattrs(gaint, char *, char *, gaint, gaint, char *);
+void prntwrap(char *, char *, char *);
+#if GRIB2
+struct g2buff * g2check (gaint, gaint, gaint);
+struct g2buff * g2read (off_t, g2int, gaint, gaint, gaint);
+void g2clear(void);
+#endif
+
+/* Functions in GAGX:
+    gagx:   Initialize graphics interface
+    gaplot: Generalized graphics output routine
+    gas1d:  Set up scaling for a 1-D grid
+    gas2d:  Set up scaling for a 2-D grid
+    gagrph: Plot line graph
+    gacntr: Plot contour plot
+    gastrm: Plot streamline plot
+    gafgrd: Fill grid boxes
+    gashad: Plot shaded plot
+    gavect: Plot vector feild
+    gascat: Plot scatter plot from two grids
+    gaarrw: Plot individual arrow
+    gaplvl: Plot grid values
+    gawmap: Plot appropriate map
+    gacsel: Select a contour interval
+    gaaxis: Generate proper axis labels for axes
+    galnch: Convert a longitude value to character form
+    galtch: Convert a latitude value to character form
+    gaconv: Perform grid level scaling
+    gatinc: Get date/time increment for time axis
+    gasfil: Shade fill a grid sqaure
+    trfill: Fill half a grid square (triangle)
+    gagfil: Fill grids with shaded ranges
+    gaimap: Output grid with image dump
+                                                                      */
+void gagx (struct gacmn *);
+void gaplot (struct gacmn *);
+void gas1d (struct gacmn *, gadouble, gadouble, gaint, gaint, struct gagrid *, struct gastn *);
+void gas2d (struct gacmn *, struct gagrid *, gaint);
+void gagrph (struct gacmn *,gaint);
+void gastts (struct gacmn *);
+void gadprnt (struct gacmn *);
+void gaoutgds (struct gacmn *);
+void galfil (struct gacmn *);
+void lfint (gadouble, gadouble, gadouble, gadouble, gadouble *, gadouble *);
+void lfout (gadouble *, gadouble *, gadouble *, gadouble *, gaint, gaint);
+gaint gacntr (struct gacmn *, gaint, gaint);
+void gastrm (struct gacmn *);
+void gashad (struct gacmn *);
+void gavect (struct gacmn *, gaint);
+void gascat (struct gacmn *);
+void gafgrd (struct gacmn *);
+void gagtif (struct gacmn *, gaint);
+void gakml (struct gacmn *);
+void gashpwrt (struct gacmn *);
+#if USESHP==1
+struct dbfld* newdbfld (char *, DBFFieldType, gaint, gaint, gaint, char*);
+#endif
+void getcorners(struct gacmn *, struct gagrid *, gadouble *);
+void ij2ll (struct gacmn *, gadouble, gadouble, gadouble, gadouble, gadouble *, gaint);
+gaint write_kml(struct gacmn *, gadouble *);
+void gafwrt (struct gacmn *);
+void gastnwrt (struct gacmn *);
+void gaarrw (gadouble, gadouble, gadouble, gadouble, gadouble);
+void gaplvl (struct gacmn *);
+void gamscl (struct gacmn *);
+void gawmap (struct gacmn *, gaint);
+void gacsel (gadouble, gadouble, gadouble *, gadouble *, gadouble *);
+void gaaxis (gaint, struct gacmn *, gaint);
+gaint galnch (gadouble, char *);
+gaint galtch (gadouble, char *);
+void gaconv (gadouble, gadouble, gadouble *, gadouble *);
+void gagexp (gadouble *, gaint, gaint, gadouble *, gaint, gaint, char *, char *);
+void gaglin (gadouble *, gaint, gaint, gadouble *, gaint, gaint, char *, char *);
+struct gagrid *gaflip (struct gagrid *, struct gacmn *);
+gaint gatinc (struct gacmn *, struct dt *, struct dt *);
+void gasfil (gaint, gaint, float, float, float, float, float, float, float, float);
+void trfill (float, float, float, float, float, float, float, float,
+     float, gaint, gaint);
+void gafstn (struct gacmn *);
+void gapstn (struct gacmn *);
+void gawsym (struct gacmn *);
+void gasmrk (struct gacmn *);
+void gabarb (gadouble, gadouble, gadouble, gadouble, gadouble, gadouble, gadouble, gaint);
+void gapmdl (struct gacmn *);
+gaint gasmdl (struct gacmn *, struct garpt *, gadouble *, char *);
+gadouble wndexit (gadouble, gadouble, gadouble, gadouble, gadouble, gadouble *,
+                                   gadouble *, gadouble *, gadouble *);
+void gapprf (struct gacmn *);
+void gatser (struct gacmn *);
+void gampax (struct gacmn *);
+void wxsym (gaint, gadouble, gadouble, gadouble, gaint, gaint *);
+void wxprim (gaint, gadouble, gadouble, gadouble);
+void gagsav (gaint, struct gacmn *, struct gagrid *);
+void galnx (gadouble, gadouble, gadouble *, gadouble *);
+void galny (gadouble, gadouble, gadouble *, gadouble *);
+void gaalnx (gadouble, gadouble, gadouble *, gadouble *);
+void gaalny (gadouble, gadouble, gadouble *, gadouble *);
+void galogx (gadouble, gadouble, gadouble *, gadouble *);
+void galogy (gadouble, gadouble, gadouble *, gadouble *);
+void galog2 (gadouble, gadouble, gadouble *, gadouble *);
+void gaalogx (gadouble, gadouble, gadouble *, gadouble *);
+void gaalogy (gadouble, gadouble, gadouble *, gadouble *);
+void gaalog2 (gadouble, gadouble, gadouble *, gadouble *);
+void gaclx (gadouble, gadouble, gadouble *, gadouble *);
+void gacly (gadouble, gadouble, gadouble *, gadouble *);
+void gaaclx (gadouble, gadouble, gadouble *, gadouble *);
+void gaacly (gadouble, gadouble, gadouble *, gadouble *);
+void gagfil (gadouble *, gaint, gaint, gadouble *, gaint *, gaint, char *);
+void gaimap (gadouble *, gaint, gaint, gadouble *, gaint *, gaint, char *, 
+                   gadouble, gadouble, gadouble, gadouble);
+void gafram (struct gacmn *);
+void gaaxpl (struct gacmn *, gaint, gaint);
+void gaselc (struct gacmn *, gadouble, gadouble);
+gaint gashdc (struct gacmn *, gadouble);
+
+/* Functions in GAUTIL:
+    nxtcmd: Get next command from the user
+    timadd: Add an increment to a time
+    timsub: Subtract an increment from a time
+    t2gr:   Convert an absolute time to a grid value
+    gr2t:   Convert a grid value to an absolute time
+    timdif: Calculate difference between two times
+    qleap:  Determine if a year is a leap year
+    adtprs: Parse an absolute date/time expression
+    rdtprs: Parse a relative date/time expression
+    cmpwrd: Compare two character strings
+    nxtwrd: Point to the next blank delimited word in a string
+    liconv: Linear conversion routine
+    gr2lev: Discrete level scaling routine
+    lev2gr: Discrete level scaling routine
+    intprs: Parse an integer expression
+    longprs: Parse an long integer expression kk 020624 --- 
+    valprs: Parse a floating number expression
+    dimprs: Parse a dimension expression
+    lowcas: Convert a string to lower case
+    uppcas: Convert a string to upper case
+    getstr: Move part of a string to another string
+    getwrd: Get next word in a string as a string
+    gamnmx: Get minimum and maximum grid value
+    garemb: Remove blanks from and terminate a string
+    gagaus: Set up scaling for gaussian grid (R40)
+    gags30: Set up scaling for gaussian grid (R30)
+    gags20: Set up scaling for gaussian grid (R20)
+    gags15: Set up scaling for Ocean Grid (MOM32)
+    gamo32: Set up scaling for gaussian grid (R15)
+    gat2ch: Date/Time to character form
+    cmpch:  Compare two strings of specified length
+    gafree: Free stuff hung off pst block
+    gagfre: Free gagrid block and associated data
+    gasfre: Free gastn block and associated data
+    gagbb:  Unpack bit value
+    gagby:  Unpack byte value
+    gabswp: Byte swap data values
+    gahswp: Byte swap report header
+    flt2ibm: convert float to ibm float (ebisuzaki)
+    ibm2flt: convert ibm float to float (ebisuzaki)
+    cpscal: Copy grid scaling info
+    getvnm: Get variable long name and abbrv 
+    e2ens:  Converts ensemble number to name
+    getenm: Get ensemble name
+    dqual: test if two doubles are equal                                                 */
+
+gaint nxtcmd (char *, char *);
+void timadd (struct dt *, struct dt *);
+void timsub (struct dt *, struct dt *);
+gadouble t2gr (gadouble *, struct dt *);
+void gr2t (gadouble *, gadouble, struct dt *);
+gaint timdif (struct dt *, struct dt *);
+gaint qleap (gaint);
+char *adtprs (char *, struct dt *, struct dt *);
+char *rdtprs (char *, struct dt *);
+gaint cmpwrd (char *, char *);
+gaint cmpwrdl (char *, char *);
+char *nxtwrd (char *);
+gadouble liconv (gadouble *, gadouble);
+gadouble gr2lev (gadouble *, gadouble);
+gadouble lev2gr (gadouble *, gadouble);
+char *e2ens (struct gafile *, gadouble );
+char *intprs (char *, gaint *);
+char *longprs (char *, long *);
+char *getdbl (char *, gadouble *);
+char *getflt (char *, gafloat *);
+char *dimprs (char *, struct gastat *, struct gafile *, gaint *, gadouble *, gaint, gaint *);
+void lowcas (char *);
+void uppcas (char *);
+void getstr (char *, char *, gaint);
+void getwrd (char *, char *, gaint);
+void gamnmx (struct gagrid *);
+void gasmnmx (struct gastn *);
+gaint garemb (char *);
+gadouble *gagaus(gaint,gaint);
+gadouble *gags30(gaint,gaint);
+gadouble *gagst62(gaint,gaint);
+gadouble *gags20(gaint,gaint);
+gadouble *gags15(gaint,gaint);
+gadouble *gamo32(gaint,gaint);
+gaint gat2ch (struct dt *, gaint, char *, gaint);
+gaint cmpch (char *, char *, gaint);
+void gafree (struct gastat *);
+void gagfre (struct gagrid *);
+void gasfre (struct gastn *);
+void fnmexp (char *, char *, char *);
+gaint gagbb (unsigned char *, gaint, gaint);
+gaint gagby (unsigned char *, gaint, gaint);
+void gapby (gaint, unsigned char *, gaint, gaint);
+void gapbb (gaint, unsigned char *, gaint, gaint);
+char *gafndt (char *, struct dt *, struct dt *, gadouble *, 
+	      struct gachsub *, struct gaens *, gaint, gaint, gaint *);
+void gabswp2 (void *, gaint);
+void gabswp (void *, gaint);
+void gabswp8 (void *, gaint);
+void gahswp (struct rpthdr *);
+gaint dayweek (struct dt *);
+gaint wrdlen (char *);
+void ganbswp(char *, gaint);
+/* Wesley Ebisuzaki routines */
+gaint flt2ibm(gafloat x, unsigned char *ibm);
+gafloat ibm2flt(unsigned char *ibm);
+gafloat ieee2flt(unsigned char *);
+gadouble ieee2dbl(unsigned char *);
+gaint flt2ieee(gafloat , unsigned char *);
+gadouble scaled2dbl(gaint, gaint);
+gadouble Int_Power(gadouble, gaint );
+
+gadouble *cpscal (gadouble *, gaint, gaint, gaint);
+gaint getvnm (struct gavar *, char *);
+gaint getenm (struct gaens *, char *);
+gaint dequal(gadouble, gadouble, gadouble);
+gaint nxrdln (char *, char *);
+
+/* Functions in GASRCP:
+    gsfile: run a script file used in gauser.c */
+char *gsfile (char *, gaint *, gaint);
+
+/* Functions in gxX:
+    gxwdln: use X server for wide lines */
+void gxwdln(void);
+
+
+#ifdef USEGADAP
+/* Function in dodstn */
+gaint dappfi (char *, struct gafile *);  
+gaint dapget (struct gastn *);
+void  dapclo (struct gafile *);
+#endif
+
+
+/* Functions in bufrstn.c */
+void getbufrhdr (gabufr_val *, gabufr_val *, struct bufrinfo *, struct bufrhdr *, gaint, gaint *);
+gaint  getbufr (struct gastn *);
+struct garpt * sortrpt(struct garpt *);
+
+
+
+void gacfg (gaint); 
+void gaqufb (void); 
+gaint gxhpng (char *, gaint, gaint, gaint, gaint, char *, char *, gaint) ;
+
+
+#if (USENETCDF == 1 || USEHDF == 1)
+/* Functions in gasdf.c */
+gaint gasdfopen(char *, struct gacmn *) ;
+gaint gaxdfopen(char *, struct gacmn *) ;
+struct gaattr *find_att(char *, struct gaattr *, char *);
+struct gavar *find_var(struct gafile *, char *);
+gaint findX(struct gafile *, struct gavar **);
+gaint findY(struct gafile *, struct gavar **);
+gaint findZ(struct gafile *, struct gavar **, gaint *);
+gaint findT(struct gafile *, struct gavar **);
+gaint findE(struct gafile *, struct gavar **);
+gaint isdvar(struct gafile *, struct gavar *, gaint,  gaint, gaint, gaint, gaint) ;
+gaint read_metadata(struct gafile *);
+gaint read_hdfatts (gaint, char *, gaint, struct gafile *);
+gaint read_ncatts (gaint, gaint, char *, gaint, struct gafile *);
+gaint set_time_type (struct gafile *);
+void  initparms(GASDFPARMS *);
+void  freeparms(GASDFPARMS *);
+gaint read_one_dimension (struct gafile *, struct gavar *, gaint, gaint, gadouble *);
+gaint compare_units(char *, char *);
+gaint find_dim(struct gafile *, char *);
+void  handle_error(gaint);
+void  close_sdf(struct gafile *);
+gaint decode_standard_time(gadouble, gaint *, gaint *, gaint *, gaint *, gaint *, gafloat *);
+gaint decode_delta_t(char *, gaint *, gaint *, gaint *, gaint *, gaint *, gaint *);
+gaint init_standard_arrays (gaint);
+gaint gadxdf(struct gafile *, GASDFPARMS *);
+gaint gadsdf(struct gafile *, GASDFPARMS);
+gaint sdfdeflev(struct gafile *, struct gavar *, gaint, gaint) ;
+gaint getncvnm (struct sdfnames *, char *);
+#endif
+
+void *galloc(size_t,char *);
+void gree();
+void glook();
diff --git a/src/grib2scan.c b/src/grib2scan.c
new file mode 100644
index 0000000..67ecbed
--- /dev/null
+++ b/src/grib2scan.c
@@ -0,0 +1,845 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.
+    Written by Brian Doty and Jennifer M. Adams  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's present */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include "gatypes.h"
+
+/* global variables */
+struct dt {                          /* Date/time structure */
+  gaint yr;
+  gaint mo;
+  gaint dy;
+  gaint hr;
+  gaint mn;
+};
+
+struct gag2 {
+  gaint discipline,parcat,parnum;     /* Parameter identifiers */
+  gaint yr,mo,dy,hr,mn,sc;            /* Reference Time */
+  gaint sig;                          /* Significance of Reference Time */
+  gaint numdp;                        /* Number of data points */
+  gaint gdt;                          /* Grid Definition Template */
+  gaint pdt;                          /* Product Definition Template */
+  gaint drt;                          /* Data Representation Template */
+  gaint trui;                         /* Time range units indicator */
+  gaint ftime;                        /* Forecast time */
+  gaint lev1type,lev1sf,lev1;         /* Level 1 type, scale factor, scaled value */
+  gaint lev2type,lev2sf,lev2;         /* Level 2 type, scale factor, scaled value */
+  gaint enstype,enspertnum,ensderiv;  /* Ensemble metadata */
+  gaint comptype;                     /* Compression type (for JPEG2000 compression) */
+  gaint bmsflg;                       /* Bit Map Section flag */
+};
+gaint verb=0,ctl=1;
+char levs[100],units[100],extra[100];
+
+/* Function Declarations */
+gaint gagby (unsigned char *, gaint, gaint);
+gaint gagbb (unsigned char *, gaint, gaint);
+gaint sect1 (unsigned char *, struct gag2 *);
+gaint sect3 (unsigned char *, struct gag2 *);
+gaint sect4 (unsigned char *, struct gag2 *);
+gaint sect5 (unsigned char *, struct gag2 *);
+void CodeTable0p0  (gaint);
+void CodeTable1p2  (gaint);
+void CodeTable3p1  (gaint);
+void CodeTable4p4  (gaint);
+void CodeTable4p7  (gaint);
+void CodeTable4p10 (gaint);
+void CodeTable4p15 (gaint);
+void CodeTable5p0  (gaint);
+gadouble scaled2dbl(gaint, gaint);
+void timadd (struct dt *, struct dt *);
+
+
+/* MAIN PROGRAM */
+gaint main (gaint argc, char *argv[]) {
+ FILE *gfile=NULL;
+ struct gag2 g2;
+ off_t fpos;
+ char *ch;
+ unsigned char s0[16],work[260],*rec;
+ unsigned char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8;
+ gaint i,flg,iarg,rc,edition,rlen,roff,field,recnum;
+ gaint s1len,s2len,s3len=0,s4len,s5len,s6len,s7len;
+
+  
+ /* Scan input args. The filename is the argument that is not an option */
+ flg = 0;
+ if (argc>1) {
+   iarg = 1;
+   while (iarg<argc) {
+     ch = argv[iarg];
+     if (*(ch)=='-' && *(ch+1)=='v') { 
+       verb=1;
+     } 
+     else if (*(ch)=='-' && *(ch+1)=='V') { 
+       verb=2;
+     } 
+     else { 
+       gfile = fopen(ch,"rb");
+       if (gfile==NULL) {
+	 printf ("Could not open input file %s\n",ch);
+	 return(1);
+       }
+       flg = 1;
+     }
+     iarg++;
+   }
+ } 
+ if (!flg) {
+   printf ("Usage: grib2scan [-v] filename\n");
+   printf ("       Use -v for verbose output \n");
+   return (1);
+ }
+
+ /* Main loop through all GRIB records in the file */
+ fpos = 0;
+ recnum=1;
+ while (recnum) {
+   
+   /* Scan for the 'GRIB' char string */
+   flg = 0;
+   while (1) {
+     rc = fseeko(gfile,fpos,SEEK_SET);
+     rc = fread(work,1,260,gfile);
+/*      if (rc<260) { */
+     if (rc==0) {
+       printf ("EOF rc=%d\n",rc);
+       return(0);
+     }
+     for (i=0; i<257; i++) { 
+       if (*(work+i+0)=='G' && 
+	   *(work+i+1)=='R' &&
+	   *(work+i+2)=='I' && 
+	   *(work+i+3)=='B') { 
+	 fpos = fpos + (off_t)i;
+	 flg = 1;
+	 i = 999;
+       }
+     }
+     if (flg) break;
+     else fpos = fpos + (off_t)(256);
+   }
+   
+   /* Section 0, the Indicator Section */
+   rc = fseeko(gfile,fpos,SEEK_SET);
+   rc = fread(s0,1,16,gfile);
+   if (rc < 16) {
+     printf ("I/O Error Reading Section 0\n");
+     return(99);
+   }
+   if (s0[0]!='G' || s0[1]!='R' || s0[2]!='I' || s0[3]!='B') {
+     printf ("GRIB indicator not found \n");
+     return (2);
+   }
+   edition = gagby(s0,7,1);
+   if (edition != 2) {
+     printf ("GRIB edition number not 2; value = %i\n",edition);
+     return (3);
+   }
+   rlen = gagby(s0,8,4);   /* Note: need to fix gamach.c and elsewhere */  
+   if (rlen!=0) {
+     printf ("GRIB record length too large\n");
+     return (4);
+   }
+   rlen = gagby(s0,12,4);   
+   g2.discipline = gagby(s0,6,1);
+   i = fpos;
+   printf ("\nRecord %d ",recnum);
+   if (verb) printf("starts at %i of length %i \n",i,rlen); 
+   else printf("\n");
+   if (verb) {
+     printf (" Discipline=%d ",g2.discipline);
+     CodeTable0p0(g2.discipline);
+     printf ("\n");
+   }
+   
+   /* Read the entire GRIB 2 record */
+   rec = (unsigned char *)malloc(rlen);
+   if (rec==NULL) {
+     printf ("memory allocation error\n");
+     return (99);
+   }
+   rc = fseeko(gfile,fpos,SEEK_SET);
+   rc = fread(rec,1,rlen,gfile);
+   if (rc!=rlen) {
+     printf ("I/O Error reading GRIB2 record \n");
+     return(99);
+   }
+   
+   /* Section 1, the Identification Section */
+   roff = 16;
+   s1 = rec+roff;              
+   i = gagby(s1,4,1);
+   if (i!=1) {
+     printf ("Header error, section 1 expected, found %i\n",i);
+     return (5);
+   }
+   s1len = gagby(s1, 0,4);     
+   rc = sect1(s1,&g2);
+   if (rc) return (rc);
+   roff += s1len;
+   
+   /* Loop over multiple fields */
+   field = 1;
+   while (1) {
+     
+     printf (" Field %d ",field);
+     if (verb>1) printf("starts at location %i\n",roff);
+     else printf("\n");
+
+     /* Section 2, the Local Use Section */
+     s2 = rec+roff;
+     i = gagby(s2,4,1);
+     if (i==2) {
+       s2len = gagby(s2,0,4);
+       roff += s2len;
+     } else s2len = 0;
+     
+     /* Section 3, the Grid Definition Section */
+     s3 = rec+roff;
+     i = gagby(s3,4,1);
+     if (i==3) {
+       s3len = gagby(s3,0,4);  
+       rc = sect3(s3,&g2);
+       if (rc) return (rc);
+       roff += s3len;
+     } else if (field==1) {
+       printf ("Header error, section 3 expected, found %i\n",i);
+       return (5);
+     } 
+     
+     /* Section 4, the Product Definition Section */
+     s4 = rec+roff;
+     i = gagby(s4,4,1);
+     if (i!=4) {
+       printf ("Header error, section 4 expected, found %i\n",i);
+       return (5);
+     }
+     s4len  = gagby(s4,0,4);
+     rc = sect4(s4,&g2);
+     if (rc) return (rc);
+     roff += s4len;
+
+     /* Section 5, the Data Representation Section */
+     s5 = rec+roff;
+     i = gagby(s5,4,1);
+     if (i!=5) {
+       printf ("Header error, section 5 expected, found %i\n",i);
+       return (5);
+     }
+     s5len = gagby(s5,0,4);
+     rc = sect5(s5,&g2);
+     if (rc) return (rc);
+     roff += s5len;
+     
+     /* Section 6, the Bit Map Section*/
+     s6 = rec+roff;
+     i = gagby(s6,4,1);
+     if (i==6) {
+       s6len = gagby(s6,0,4);
+       g2.bmsflg = gagby(s6,5,1);
+       if (verb>1) printf("  BMI=%d \n",g2.bmsflg);
+       roff += s6len;
+     } else s6len = 0;
+     
+     /* Section 7, the Data Section */
+     s7 = rec+roff;
+     i = gagby(s7,4,1);
+     if (i!=7) {
+       printf ("Header error, section 7 expected, found %i\n",i);
+       return (5);
+     }
+     s7len = gagby(s7,0,4);
+     if (verb>1) printf ("  Lengths of Sections 1-7: %i %i %i %i %i %i %i\n",
+		       s1len, s2len, s3len, s4len, s5len, s6len, s7len);
+     roff += s7len;
+     
+     if (ctl) printf(" ctl:  var%d.%d   0,%s  %s  %s   description\n",recnum,field,levs,extra,units);  
+
+     /* Section 8, the End Section */
+     s8 = rec+roff;
+     if (*s8=='7' && *(s8+1)=='7' && *(s8+2)=='7' && *(s8+3)=='7') {
+       break;
+     }
+     
+
+     /* If it wasn't the End, look for another field */
+     field++;
+   }
+   
+   fpos = fpos + (off_t)rlen;
+   free(rec);
+   recnum++;
+ }
+ return(0);
+}
+
+/* Look at contents of Section 1 */
+gaint sect1 (unsigned char *s1, struct gag2 *pg2) {
+  pg2->sig = gagby(s1,11,1);     
+  pg2->yr  = gagby(s1,12,2);
+  pg2->mo  = gagby(s1,14,1);
+  pg2->dy  = gagby(s1,15,1);
+  pg2->hr  = gagby(s1,16,1);
+  pg2->mn  = gagby(s1,17,1);
+  pg2->sc  = gagby(s1,18,1);
+  printf (" Reference Time = %4i-%02i-%02i %02i:%02i:%02i  ",
+	  pg2->yr,pg2->mo,pg2->dy,pg2->hr,pg2->mn,pg2->sc); 
+  CodeTable1p2(pg2->sig);
+  printf("\n");
+  return(0);
+
+ }
+
+/* Look at contents of Section 3 */
+gaint sect3 (unsigned char *s3, struct gag2 *pg2) {
+  gaint nx,ny,angle,lat1,lon1,di,dj,lon2,lat2,nlats;
+  gaint rlon,dx,dy,latin1,latin2;
+  gaint sbit1,sbit2,sbit3,sbit4;
+
+  pg2->numdp = gagby(s3,6,4);    
+  pg2->gdt   = gagby(s3,12,2);
+  printf ("  GDT=%i ",pg2->gdt);
+  CodeTable3p1(pg2->gdt);
+  printf(" nx*ny=%d\n",pg2->numdp);
+  if (verb) {
+    if (pg2->gdt==0) {         /* lat-lon grid */
+      nx    = gagby(s3,30,4);
+      ny    = gagby(s3,34,4);
+      angle = gagby(s3,38,4);
+      if (angle==0) {
+	lat1 = gagby(s3,46,4);
+	lon1 = gagby(s3,50,4);
+	di   = gagby(s3,63,4);
+	dj   = gagby(s3,67,4);
+	printf("   XDEF %i linear %f %f\n",nx,lon1*1e-6,di*1e-6);
+	printf("   YDEF %i linear %f %f\n",ny,lat1*1e-6,dj*1e-6);
+      }
+    }
+    else if (pg2->gdt==20) {   /* Polar Stereographic */
+      nx    = gagby(s3,30,4);
+      ny    = gagby(s3,34,4);
+      lat1  = gagby(s3,38,4);
+      lon1  = gagby(s3,42,4);
+      rlon  = gagby(s3,51,4);
+      dx    = gagby(s3,55,4);
+      dy    = gagby(s3,59,4);
+      printf("   nx=%i ny=%i lon1=%f lat1=%f\n",nx, ny, lon1*1e-6, lat1*1e-6);
+      printf("   reflon=%f dx=%f dy=%f\n",rlon*1e-6,dx*1e-3,dy*1e-3); 
+
+    }
+    else if (pg2->gdt==30) {   /* Lambert Conformal */
+      nx     = gagby(s3,30,4);
+      ny     = gagby(s3,34,4);
+      lat1   = gagby(s3,38,4);
+      lon1   = gagby(s3,42,4);
+      rlon   = gagby(s3,51,4);
+      dx     = gagby(s3,55,4);
+      dy     = gagby(s3,59,4);
+      latin1 = gagby(s3,65,4);
+      latin2 = gagby(s3,69,4);
+      printf("   nx=%i ny=%i lon1=%f lat1=%f\n",nx, ny, lon1*1e-6, lat1*1e-6);
+      printf("   reflon=%f dx=%f dy=%f\n",rlon*1e-6, dx*1e-3, dy*1e-3); 
+      printf("   latin1=%f latin2=%f \n",latin1*1e-6, latin2*1e-6);
+      if (verb>1) {
+	sbit1 = gagbb(s3+64,0,1);
+	sbit2 = gagbb(s3+64,1,1);
+	sbit3 = gagbb(s3+64,2,1);
+	sbit4 = gagbb(s3+64,3,1);
+	printf("   scan_mode_bits = %i%i%i%i\n",sbit1, sbit2, sbit3, sbit4);
+      }      
+    }
+    else if (pg2->gdt==40) {   /* Gaussian lat-lon grid */
+      nx    = gagby(s3,30,4);
+      ny    = gagby(s3,34,4);
+      angle = gagby(s3,38,4);
+      if (angle==0) {
+	lat1  = gagby(s3,46,4);
+	lon1  = gagby(s3,50,4);
+	lat2  = gagby(s3,55,4);
+	lon2  = gagby(s3,59,4);
+	di    = gagby(s3,63,4);
+	nlats = gagby(s3,67,4);
+	printf("   nx=%i ny=%i di=%f nlats=%i\n",nx, ny, di*1e-6,nlats);
+	printf("   lon: %f to %f\n", lon1*1e-6, lon2*1e-6);
+	printf("   lat: %f to %f\n", lat1*1e-6, lat2*1e-6);
+      }
+    }
+  }
+  return (0);
+}
+
+/* Look at contents of Section 4 */
+gaint sect4 (unsigned char *s4, struct gag2 *pg2) {
+  struct dt reft,fcst,begt,endt;
+  gaint enstotal,sp,sp2,gotfcst;
+  gaint ptyp,llsf,llval,ulsf,ulval,llval2,i;
+  gadouble ll=0,ul=0;
+  gadouble lev1=0,lev2=0;
+  gaint var1,var2,var3,var4,var5,numtr,pos1,pos2;
+  gaint off,atyp,styp,s1sf,s1sval,s2sf,s2sval,wtyp,w1sf,w1sval,w2sf,w2sval;
+  gadouble s1,s2,w1,w2;
+  
+  pg2->pdt      = gagby(s4, 7,2);
+  pg2->parcat   = gagby(s4, 9,1); 
+  pg2->parnum   = gagby(s4,10,1); 
+  /* PDT 48 has 24 unique octets inserted after octet 11 instead of starting at octet 35 */
+  if (pg2->pdt==48) off=24; 
+  else off=0;
+  pg2->trui     = gagby(s4,17+off,1); 
+  pg2->ftime    = gagby(s4,18+off,4); 
+  pg2->lev1type = gagby(s4,22+off,1);
+  pg2->lev1sf   = gagby(s4,23+off,1);
+  /* check for a negative level value */
+  pg2->lev1 = gagbb(s4,(24+off)*8+1,31);
+  i = gagbb(s4,(24+off)*8,1);
+  if (i) pg2->lev1 = -1.0*pg2->lev1;
+  pg2->lev2type = gagby(s4,28+off,1);
+  pg2->lev2sf   = gagby(s4,29+off,1);
+  /* check for a negative level value */
+  pg2->lev2 = gagbb(s4,(30+off)*8+1,31);
+  i = gagbb(s4,(30+off)*8,1);
+  if (i) pg2->lev2 = -1.0*pg2->lev2;
+
+  /* get the reference time */
+  reft.yr = pg2->yr;
+  reft.mo = pg2->mo;
+  reft.dy = pg2->dy;
+  reft.hr = pg2->hr;
+  reft.mn = pg2->mn;
+  /* initialize forecast time structure */
+  fcst.yr = fcst.mo = fcst.dy = fcst.hr = fcst.mn = 0;  
+  gotfcst=0;
+  if      (pg2->trui== 0) {fcst.mn = pg2->ftime; gotfcst=1;}
+  else if (pg2->trui== 1) {fcst.hr = pg2->ftime; gotfcst=1;}
+  else if (pg2->trui== 2) {fcst.dy = pg2->ftime; gotfcst=1;}
+  else if (pg2->trui== 3) {fcst.mo = pg2->ftime; gotfcst=1;}
+  else if (pg2->trui== 4) {fcst.yr = pg2->ftime; gotfcst=1;}
+  else if (pg2->trui==10) {fcst.hr = pg2->ftime*3; gotfcst=1;}   /* 3Hr incr */
+  else if (pg2->trui==11) {fcst.hr = pg2->ftime*6; gotfcst=1;}   /* 6Hr incr */
+  else if (pg2->trui==12) {fcst.hr = pg2->ftime*12; gotfcst=1;}  /* 2Hr incr */
+  if (gotfcst) {
+    /* add reference time and forecast time together */
+    timadd(&reft,&fcst);
+  }
+
+  sp = -1;
+  sp2 = -1;
+  printf("  PDT=%d",pg2->pdt);
+  /* instantaneous fields */
+  if (pg2->pdt<=7 || pg2->pdt==15 || pg2->pdt==48) {
+    if (pg2->pdt<=7|| pg2->pdt==48) {
+      printf ("  %d ",pg2->ftime);
+      CodeTable4p4(pg2->trui);
+      printf ("Forecast");
+    }
+    else if (pg2->pdt==15) {
+      /* for PDT 4.15, get info about the type of spatial and statistical processing used */
+      /* pos2 is the location of octet for statistical process code (sp), subsequent octet is for spatial process */
+      pos2=34;
+      sp  = gagby(s4,pos2+0,1);
+      sp2 = gagby(s4,pos2+1,1);
+      printf("  Spatial ");
+      CodeTable4p10(sp);
+      printf(", ");
+      CodeTable4p15(sp2);
+    }
+    printf("  Valid Time = %4i-%02i-%02i %02i:%02i  ",fcst.yr,fcst.mo,fcst.dy,fcst.hr,fcst.mn);
+  }
+  /* fields spanning a time interval */
+  else if (pg2->pdt>=8 && pg2->pdt<=12) {
+    /* get the beg/end times and statistical process  */
+    /* pos1 is location of octets describing end of overall time period */
+    /* pos2 is the location of octet for statistical process code (sp) */
+    if      (pg2->pdt ==  8) {pos1=34; pos2=46;}
+    else if (pg2->pdt ==  9) {pos1=47; pos2=59;}
+    else if (pg2->pdt == 10) {pos1=35; pos2=47;}
+    else if (pg2->pdt == 11) {pos1=37; pos2=49;}
+    else if (pg2->pdt == 12) {pos1=36; pos2=48;}
+    
+    /* get the ending time of the overall averaging period */
+    endt.yr = gagby(s4,pos1+0,2);
+    endt.mo = gagby(s4,pos1+2,1);
+    endt.dy = gagby(s4,pos1+3,1);
+    endt.hr = gagby(s4,pos1+4,1);
+    endt.mn = gagby(s4,pos1+5,1);
+
+    /* get info about statistical processing */
+    sp   = gagby(s4,pos2+0,1);
+    var1 = gagby(s4,pos2+1,1);
+    var2 = gagby(s4,pos2+2,1);
+    var3 = gagby(s4,pos2+3,4);
+    var4 = gagby(s4,pos2+7,1);
+    var5 = gagby(s4,pos2+8,4);
+
+    /* get number of time specifications */
+    numtr = gagby(s4,pos1+7,1);       
+    if (numtr) {
+      if (var5==0) {   /* continuous statistical processing function */
+	printf("  %d ",var3);
+	CodeTable4p4(var2);
+	if (sp==255)
+	  printf("Interval");
+	else
+	  CodeTable4p10(sp);
+	printf("  BegTime = %4i-%02i-%02i %02i:%02i",fcst.yr,fcst.mo,fcst.dy,fcst.hr,fcst.mn);
+	printf("  EndTime = %4i-%02i-%02i %02i:%02i",endt.yr,endt.mo,endt.dy,endt.hr,endt.mn);
+      }
+    }
+  }
+  printf(" \n");
+
+  /* Print the grib codes that should be included in the descriptor file entry */
+  if (sp<0 || sp==255) {
+    printf ("   Parameter: disc,cat,num = %d,%d,%d\n",pg2->discipline,pg2->parcat,pg2->parnum);
+    if (ctl) sprintf (units,"%d,%d,%d",pg2->discipline,pg2->parcat,pg2->parnum);
+  }
+  else {
+    if (sp2<0) {
+      printf ("   Parameter: disc,cat,num,sp = %d,%d,%d,%d\n",pg2->discipline,pg2->parcat,pg2->parnum,sp);
+      if (ctl) sprintf (units,"%d,%d,%d,%d",pg2->discipline,pg2->parcat,pg2->parnum,sp);
+    }
+    else {
+      printf ("   Parameter: disc,cat,num,sp,sp2 = %d,%d,%d,%d,%d\n",pg2->discipline,pg2->parcat,pg2->parnum,sp,sp2);
+      if (ctl) sprintf (units,"%d,%d,%d,%d,%d",pg2->discipline,pg2->parcat,pg2->parnum,sp,sp2);
+    }
+  }
+
+  /* Get level information */
+  if (pg2->lev1 != -1) lev1 = scaled2dbl(pg2->lev1sf,pg2->lev1);
+  if (pg2->lev2type != 255) {  /* we have two level types */
+    if (pg2->lev2 != -1) {
+      lev2 = scaled2dbl(pg2->lev2sf,pg2->lev2);
+      if (pg2->lev2type == pg2->lev1type) {
+	printf ("   Levels: ltype,lval,lval2 = %d,%g,%g ",pg2->lev1type,lev1,lev2);
+	if (ctl) sprintf (levs,"%d,%g,%g",pg2->lev1type,lev1,lev2);
+      }
+      else {
+	printf ("   Levels: ltype,lval,lval2,ltype2 = %d,%g,%g,%d ",pg2->lev1type,lev1,lev2,pg2->lev2type);
+	if (ctl) sprintf (levs,"%d,%g,%g,%d",pg2->lev1type,lev1,lev2,pg2->lev2type);
+      }
+      if (verb) 
+	printf("  (sf1,sval1,sf2,sval2 = %d %d %d %d) \n",pg2->lev1sf,pg2->lev1,pg2->lev2sf,pg2->lev2);
+      else printf ("\n");
+    }
+    else {  /* level values are missing */
+      if (pg2->lev2type == pg2->lev1type) {
+	printf ("   Levels: ltype = %d \n",pg2->lev1type);
+	if (ctl) sprintf (levs,"%d",pg2->lev1type);
+      }
+      else {
+	printf ("   Levels: ltype,,,ltype2 = %d,,,%d \n",pg2->lev1type,pg2->lev2type);
+	if (ctl) sprintf (levs,"%d,,,%d",pg2->lev1type,pg2->lev2type);
+      }
+    }
+  }	
+  else {    /* only one level type */
+    if (pg2->lev1 != -1) {
+      printf ("   Level: ltype,lval = %d,%g ",pg2->lev1type,lev1);
+      if (ctl) sprintf (levs,"%d,%g",pg2->lev1type,lev1);
+      if (verb) printf("  (sf,sval = %d %d)",pg2->lev1sf,pg2->lev1);
+      printf ("\n");
+    }
+    else {
+      printf ("   Level: ltype = %d \n",pg2->lev1type);  /* level value is missing */
+      if (ctl) sprintf (levs,"%d",pg2->lev1type);
+    }
+  }
+
+  /* Ensemble Metadata */
+  if (pg2->pdt==1 || pg2->pdt==2 || pg2->pdt==11 || pg2->pdt==12) {
+    if (pg2->pdt==1 || pg2->pdt==11) {   /* individual ensemble members */
+      pg2->enstype    = gagby(s4,34,1); 
+      pg2->enspertnum = gagby(s4,35,1);
+      enstotal        = gagby(s4,36,1);
+      printf("   Ens: type,pert = %d,%d ",pg2->enstype,pg2->enspertnum); 
+      if (verb) printf("(total=%d) \n",enstotal);
+      else printf("\n");
+    }
+    else {                            /* derived fields from all ensemble members */
+      pg2->ensderiv   = gagby(s4,34,1);
+      enstotal        = gagby(s4,35,1);
+      printf("   Ens: deriv = %d  ",pg2->ensderiv);
+      if (verb) CodeTable4p7(pg2->ensderiv);
+      printf("\n");
+    }
+  }
+
+  /* Probability Forecasts */
+  /* The value of octet 35 (Forecast Probability Number) is not used by NCEP */
+  /* The value of octet 36 (Total Number of Forecast Probabilities) is the ensemble size */
+  /* We don't need to look at either of these octets */
+  if (pg2->pdt==9 || pg2->pdt==5) {
+    ptyp  = gagby(s4,36,1);
+    llsf  = gagby(s4,37,1);
+    /* check for a negative lower limit value */
+    llval = gagbb(s4,38*8+1,31);
+    i = gagbb(s4,38*8,1);
+    if (i) llval = -1.0*llval;
+    ulsf  = gagby(s4,42,1);
+    /* check for a negative upper limit value */
+    ulval = gagbb(s4,43*8+1,31);
+    i = gagbb(s4,43*8,1);
+    if (i) ulval = -1.0*ulval;
+    ll = scaled2dbl(llsf,llval);
+    ul = scaled2dbl(ulsf,ulval);
+    if (ptyp<=4) {
+      if (ptyp==2) {
+	printf ("   Prob: type,llim,ulim = %d,%g,%g",ptyp,ll,ul);
+	if (ctl) sprintf (extra,"a%d,%g,%g",ptyp,ll,ul);
+      }
+      else if (ptyp==0 || ptyp==3) {
+	printf ("   Prob: type,lim = %d,%g",ptyp,ll);  
+	if (ctl) sprintf (extra,"a%d,%g",ptyp,ll);  
+      }
+      else {
+	printf ("   Prob: type,lim = %d,%g",ptyp,ul);  
+	if (ctl) sprintf (extra,"a%d,%g",ptyp,ul);  
+      }
+    }
+    else if (ptyp==255) printf ("   Probability Type is missing");
+    else printf ("   Probability Type = %d",ptyp);
+
+    /* decoding code table 4p9 */
+    if (verb) {
+      if      (ptyp==0) printf ("  (Probability of event below %g)",ll); 
+      else if (ptyp==1) printf ("  (Probability of event above %g)",ul);
+      else if (ptyp==2) printf ("  (Probability of event between %g and %g)",ll,ul);
+      else if (ptyp==3) printf ("  (Probability of event above %g)",ll);
+      else if (ptyp==4) printf ("  (Probability of event below %g)",ul);
+    }
+    if (verb>1) printf ("   (llsf,llval=%d,%d  ulsf,ulval=%d,%d)",llsf,llval,ulsf,ulval);
+    printf("\n");
+  }
+
+  /* Optical Properties of Aerosols */
+  if (pg2->pdt==48) {
+    atyp   = gagby(s4,11,2);
+    styp   = gagby(s4,13,1);
+    s1sf   = gagby(s4,14,1);
+    s1sval = gagby(s4,15,4);
+    s2sf   = gagby(s4,19,1);
+    s2sval = gagby(s4,20,4);
+    wtyp   = gagby(s4,24,1);
+    w1sf   = gagby(s4,25,1);
+    w1sval = gagby(s4,26,4);
+    w2sf   = gagby(s4,30,1);
+    w2sval = gagby(s4,31,4);
+    s1 = scaled2dbl(s1sf,s1sval);
+    s2 = scaled2dbl(s2sf,s2sval);
+    w1 = scaled2dbl(w1sf,w1sval);
+    w2 = scaled2dbl(w2sf,w2sval);
+    if (atyp!=65535) {
+      if (styp!=255) {
+	if (wtyp!=255) {
+	  printf ("   Aerosol: atyp,styp,s1,s2,wtyp,w1,w1 = %d,%d,%g,%g,%d,%g,%g",atyp,styp,s1,s2,wtyp,w1,w2);
+	  if (ctl) sprintf (extra,"a%d,%d,%g,%g,%d,%g,%g",atyp,styp,s1,s2,wtyp,w1,w2);
+	}
+	else {
+	  printf ("   Aerosol: atyp,styp,s1,s2 = %d,%d,%g,%g",atyp,styp,s1,s2);
+	  if (ctl) sprintf (extra,"a%d,%d,%g,%g",atyp,styp,s1,s2);
+	}
+      }
+      else {
+	if (wtyp!=255) {
+	  printf ("   Aerosol: atyp,wtyp,w1,w1 = %d,%d,%g,%g",atyp,wtyp,w1,w2);
+	  if (ctl) sprintf (extra,"a%d,%d,%g,%g",atyp,wtyp,w1,w2);
+	}
+	else {
+	  printf ("   Aerosol: atyp = %d",atyp);
+	  if (ctl) sprintf (extra,"a%d",atyp);
+	}
+      }
+    }
+    if (verb) {
+      if (styp<=11) {
+	/* code table 4p91 */
+	if      (styp==0)  printf("  (size is < %g)",s1);
+	else if (styp==1)  printf("  (size is > %g)",s2);
+	else if (styp==2)  printf("  (size is >= %g and < %g)",s1,s2);
+	else if (styp==3)  printf("  (size is > %g)",s1);
+	else if (styp==4)  printf("  (size is < %g)",s2);
+	else if (styp==5)  printf("  (size is <= %g)",s1);
+	else if (styp==6)  printf("  (size is >= %g)",s2);
+	else if (styp==7)  printf("  (size is >= %g and <= %g)",s1,s2);
+	else if (styp==8)  printf("  (size is >= %g)",s1);
+	else if (styp==9)  printf("  (size is <= %g)",s2);
+	else if (styp==10) printf("  (size is > %g and <= %g)",s1,s2);
+	else if (styp==11) printf("  (size is = %g)",s1);
+      }
+      if (wtyp<=11) {
+	/* code table 4p91 */
+	if      (wtyp==0)  printf("  (wavelength is < %g)",w1);
+	else if (wtyp==1)  printf("  (wavelength is > %g)",w2);
+	else if (wtyp==2)  printf("  (wavelength is >= %g and < %g)",w1,w2);
+	else if (wtyp==3)  printf("  (wavelength is > %g)",w1);
+	else if (wtyp==4)  printf("  (wavelength is < %g)",w2);
+	else if (wtyp==5)  printf("  (wavelength is <= %g)",w1);
+	else if (wtyp==6)  printf("  (wavelength is >= %g)",w2);
+	else if (wtyp==7)  printf("  (wavelength is >= %g and <= %g)",w1,w2);
+	else if (wtyp==8)  printf("  (wavelength is >= %g)",w1);
+	else if (wtyp==9)  printf("  (wavelength is <= %g)",w2);
+	else if (wtyp==10) printf("  (wavelength is > %g and <= %g)",w1,w2);
+	else if (wtyp==11) printf("  (wavelength is = %g)",w1);
+      }
+      if (verb>1) printf("\n            (size: sf1,val1=%d,%d  sf2,val2=%d,%d)",s1sf,s1sval,s2sf,s2sval);
+      if (verb>1) printf("  (wavelength: sf1,val1=%d,%d  sf2,val2=%d,%d)",w1sf,w1sval,w2sf,w2sval);
+    }
+    printf(" \n");
+  }
+  return(0);
+}
+
+/* Look at contents of Section 5 */
+gaint sect5 (unsigned char *s5, struct gag2 *pg2) {
+  gafloat r;
+  gaint e,d,nbits,otype;
+
+  if (verb) {
+    pg2->drt = gagby(s5,9,2);
+    r        = gagby(s5,11,4);
+    e        = gagby(s5,15,2);
+    d        = gagby(s5,17,2);
+    nbits    = gagby(s5,19,1);
+    otype    = gagby(s5,20,1);
+    printf ("  DRT=%i ",pg2->drt);
+    CodeTable5p0(pg2->drt);
+    if (pg2->drt == 40) {  
+      pg2->comptype = gagby(s5,21,1);
+      if (pg2->comptype==0) printf(" (Lossless) ");
+      if (pg2->comptype==1) printf(" (Lossy) ");
+    }
+    printf("\n");
+  }
+  return(0);
+}
+
+
+/* Discipline */
+void CodeTable0p0 (gaint i) {
+  if      (i== 0) printf ("(Meteorological)");
+  else if (i== 1) printf ("(Hydrological)");
+  else if (i== 2) printf ("(Land Surface)");
+  else if (i== 3) printf ("(Space)");
+  else if (i==10) printf ("(Oceanographic)");
+}
+/* Significance of Reference Time */
+void CodeTable1p2 (gaint i) {
+  if      (i==0) printf ("(Analysis)");
+  else if (i==1) printf ("(Start of Forecast)");
+  else if (i==2) printf ("(Verifying Time of Forecast)");
+  else if (i==3) printf ("(Observation Time)");
+}
+/* Grid Definition Template Number */
+void CodeTable3p1 (gaint i) {
+  if      (i==0)   printf("(Lat/Lon)");
+  else if (i==1)   printf("(Rotated Lat/Lon)");
+  else if (i==2)   printf("(Stretched Lat/Lon)");
+  else if (i==3)   printf("(Rotated and Stretched Lat/Lon)");
+  else if (i==10)  printf("(Mercator)");
+  else if (i==20)  printf("(Polar Stereographic)");
+  else if (i==30)  printf("(Lambert Conformal)");
+  else if (i==31)  printf("(Albers Equal Area)");
+  else if (i==40)  printf("(Gaussian Lat/Lon)");
+  else if (i==41)  printf("(Rotated Gaussian Lat/Lon)");
+  else if (i==42)  printf("(Stretched Gaussian Lat/Lon)");
+  else if (i==43)  printf("(Rotated and Stretched Gaussian Lat/Lon)");
+  else if (i==50)  printf("(Spherical Harmonic Coefficients)");
+  else if (i==51)  printf("(Rotated Spherical Harmonic Coefficients)");
+  else if (i==52)  printf("(Stretched Spherical Harmonic Coefficients)");
+  else if (i==53)  printf("(Rotated and Stretched Spherical Harmonic Coefficients)");
+  else if (i==90)  printf("(Orthoraphic)");
+  else if (i==100) printf("(Triangular Grid Based on an Icosahedron)");
+  else if (i==110) printf("(Equatorial Azimuthal Equidistant Projection)");
+  else if (i==120) printf("(Azimuth-Range Projection)");
+}
+/* Time Range Unit Indicator */
+void CodeTable4p4 (gaint i) {
+  if      (i==0)  printf ("Minute ");
+  else if (i==1)  printf ("Hour ");
+  else if (i==2)  printf ("Day ");
+  else if (i==3)  printf ("Month ");
+  else if (i==4)  printf ("Year ");
+  else if (i==5)  printf ("Decade ");
+  else if (i==6)  printf ("Normal ");
+  else if (i==7)  printf ("Century ");
+  else if (i==10) printf ("3-Hour ");
+  else if (i==11) printf ("6-Hour ");
+  else if (i==12) printf ("12-Hour ");
+  else if (i==13) printf ("Second ");
+}
+/* Derived Ensemble Forecast */
+void CodeTable4p7 (gaint i) {
+  if      (i==0)  printf ("Unweighted Mean All Members ");
+  else if (i==1)  printf ("Weighted Mean All Members ");
+  else if (i==2)  printf ("StdDev (Cluster Mean) ");
+  else if (i==3)  printf ("StdDev (Cluster Mean, normalized) ");
+  else if (i==4)  printf ("Spread of All Members ");
+  else if (i==5)  printf ("Large Anomaly Index All Members ");
+  else if (i==6)  printf ("Unweighted Mean Cluster Members ");
+}
+/* Type of Statistical Processing */
+void CodeTable4p10 (gaint i) {
+  if      (i==0)  printf ("Average");
+  else if (i==1)  printf ("Accumulation");
+  else if (i==2)  printf ("Maximum");
+  else if (i==3)  printf ("Minimum");
+  else if (i==4)  printf ("Diff(end-beg)");
+  else if (i==5)  printf ("RMS");
+  else if (i==6)  printf ("StdDev");
+  else if (i==7)  printf ("Covariance");
+  else if (i==8)  printf ("Diff(beg-end)");
+  else if (i==9)  printf ("Ratio");
+}
+/* Type of Spatial Processing */
+void CodeTable4p15 (gaint i) {
+  if      (i==0)  printf ("No interpolation");
+  else if (i==1)  printf ("Bilinear interpolation");
+  else if (i==2)  printf ("Bicubic interpolation");
+  else if (i==3)  printf ("Nearest neighbor");
+  else if (i==4)  printf ("Budget interpolation");
+  else if (i==5)  printf ("Spectral interpolation");
+  else if (i==6)  printf ("Neighbor budget interpolation");
+  else            printf ("sp2=%d",i);
+}
+/* Data Representation Template Number */
+void CodeTable5p0 (gaint i) {
+  if      (i==0)  printf ("(Grid Point Data - Simple Packing)");
+  else if (i==1)  printf ("(Matrix Value at Grid Point - Simple Packing)");
+  else if (i==2)  printf ("(Grid Point Data - Complex Packing)");
+  else if (i==3)  printf ("(Grid Point Data - Complex Packing and Spatial Differencing)");
+  else if (i==40) printf ("(Grid Point Data - JPEG2000 Compression)");
+  else if (i==41) printf ("(Grid Point Data - PNG Compression )");
+  else if (i==50) printf ("(Spectral Data - Simple Packing)");
+  else if (i==51) printf ("(Spectral Data - Simple Packing)");
+}
+
+void gaprnt (gaint i, char *ch) {
+  printf ("%s",ch);
+}
+char *gxgsym(char *ch) {
+  return (getenv(ch));
+}
+
+
diff --git a/src/gribmap.c b/src/gribmap.c
new file mode 100644
index 0000000..a7d3ce1
--- /dev/null
+++ b/src/gribmap.c
@@ -0,0 +1,246 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define DRIVER_GAGMAP
+#include "grads.h"
+#include "gagmap.h"
+#include "gx.h"
+
+extern struct gamfcmn mfcmn;
+gaint help=0;
+void command_line_help(void) ;
+
+gaint main (gaint argc, char *argv[]) {
+
+
+/* ---------------- command line processing   ------------------- */
+
+/* Initialize */
+  skip=0;
+  verb=0;         /* verbose default is NO */
+  quiet=0;        /* quiet mode default is NO */
+  bigflg=0;       /* assume small <2GB files sizes */
+  g1ver=3;        /* default version for grib1 maps */
+  g2ver=1;        /* default version for grib2 maps */
+  scaneof=0;      /* option to ignore failure to find data at end of file */
+  scanEOF=0;      /* option to ignore failure to find data at end of file */
+  scanlim=1000;   /* the default # of max bytes between records */
+  notau=0;        /* force time to be base time */
+  tauave=0;       /* use end time (default) for averaged products vs. start time */
+  tauflg=0;       /* search for a fixed tau in filling the 4-D volume */
+  tauoff=0;       /* the fixed tau in h */
+  tau0=0;         /* set the base dtg for tau search */
+  update=0;       /* set the base dtg for tau search */
+  write_map=1;    /* write out the map  */
+  diag=0;         /* full diagnostics */
+  mpiflg=0;
+  ifile = NULL;
+  no_min=0;	  /* keep minutes code */
+
+  mfcmn.fullyear=1; /* initialize the GrADS calendar so it is set to the file calendar in gaddes */
+
+  if (argc>1) {
+    iarg = 1;
+    while (iarg<argc) {
+      flg = 1;
+      ch = argv[iarg];
+      if (*ch=='-' && *(ch+1)=='i') {         /* input filename, data descriptor file */
+        iarg++;
+        if (iarg<argc) {
+          ifile = argv[iarg];
+          flg = 0;
+        } else iarg--;                        /* Let error message pop */
+      }
+      else if (*ch=='-' && *(ch+1)=='0') {    /* Ignore forecast time so that the */
+        notau = 1;                            /* reference time is the valid time */ 
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='1') {    /* Create machine-specific version 1 map */
+        g1ver = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='2') {    /* Create machine-independent version 2 map */
+        g1ver = 2;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='b' && *(ch+2)=='i' && *(ch+3)=='g') {    /* >2GB sizes */
+        if (sizeof(off_t) != 8) {
+          printf ("Gribmap Error:  -big flag requires size of off_t to be 8.\n");
+          printf ("                The size of off_t is %ld\n",sizeof(off_t));
+          return (4);
+        }
+        bigflg=1;
+        g1ver=4;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='b') {    /* Valid time for averages is beginning of period */
+        tauave=1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='d') {    /* Diagnostic output -- has no effect anymore */
+        diag=1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='e') {    /* Ignore junk bytes at end of file (ECMWF) */
+        scaneof = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='E') {    /* Ignore junk bytes at middle or end of file (ECMWF) */
+        scanEOF = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='f') {    /* Match only the given forecast time */
+        tauflg = 1;
+        ch+=2;
+        i = 0;
+        while(*(ch+i) && i<900) {
+          if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+          i++;
+        }
+        if (i<900) {
+          sscanf(ch,"%i",&tauoff);
+          flg = 0;
+        }
+      }
+      else if (*ch=='-' && *(ch+1)=='h' && *(ch+2)=='e' && *(ch+3)=='l' && *(ch+4)=='p' ) {
+	help=1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='h') {          /* Header bytes to skip before scanning */
+        ch+=2;
+	i = 0;
+	while(*(ch+i) && i<900) {
+	  if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+	  i++;
+	}
+	if (i<900) {
+	  sscanf(ch,"%i",&skip);
+	  flg = 0;
+	}
+      }
+      else if (*ch=='-' && *(ch+1)=='m' && *(ch+2)=='i' && *(ch+3)=='n' && *(ch+4)=='0') { /* Ignore minutes */
+        no_min = 1;
+        flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='m') {         /* Use base time from descriptor instead of grib header */
+        mpiflg = 1;
+        flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='N') {    /* Do not write a map file */
+        write_map=0;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='q') {    /* Quiet mode */
+        quiet=1;
+	verb=0;
+        flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='s') {    /* Skip over bytes between records */ 
+        scanflg = 1;
+        ch+=2;
+        i = 0;
+        while(*(ch+i) && i<900) {
+          if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+          i++;
+        }
+        if (i<900) {
+          sscanf(ch,"%i",&scanlim);
+          flg = 0;
+        }
+      }
+      else if (*ch=='-' && *(ch+1)=='t' && *(ch+2)=='0') {  /* Match only if base time == initial time */
+        tau0=1;
+        flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='u') {    /* Update existing map (for templated data sets) */
+	printf("The -u option has been temporarily disabled\n");
+	/* update = 1; */
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='v') {    /* Verbose mode */
+        if(!quiet) verb=1;
+        flg = 0;
+      }
+      if (flg) {
+        printf ("Invalid command line argument: %s  Ignored.\n",argv[iarg]);
+      }
+      iarg++;
+    }
+
+  } 
+  else {
+    command_line_help();
+  }
+
+  if (help) {
+    command_line_help();
+    return(0);
+  }
+
+  mfcmn.cal365=-1; /* initialize the GrADS calendar so it is set to the file calendar in gaddes */
+  rc=gribmap();
+  return(rc);
+}
+
+
+void command_line_help (void) {
+
+/* output command line options */
+printf("This is gribmap for GrADS Version " GRADS_VERSION "\n");
+printf("creates the index file for using GRIB data in grads\n\n");
+printf("Command line options are as follows: \n\n");
+printf("   -0        ignores the forecast time in the mapping; only uses the base time\n");
+/* printf("   -1        creates a machine specific version 1 map \n"); */
+/* printf("   -2        creates a machine-INDEPENDENT version 2 map \n"); */
+printf("   -b        set the valid time for averages to be the beginning of the period rather than the end (default)\n\n");
+printf("   -big      required if the GRIB1 or GRIB2 files are > 2 Gb\n\n");
+printf("   -e        ignores junk bytes (non GRIB msg) at end of file (e.g., ECMWF GRIB files)\n");
+printf("   -E        ignores junk bytes in middle and/or end of GRIB file\n");
+printf("   -fNNNN    forces a match for forecast time in hours = NNNNN (e.g., f24 for t=24 h)\n");
+printf("   -hNNNN    where NNNN is the # of header bytes to look for first GRIB messages (default is 100)\n");
+printf("   -help     prints out this help\n");
+printf("   -i fname  provides the name of data descriptor file to map\n");
+printf("   -m        uses the initial time from the descriptor file instead of the base time in the grib header \n");
+printf("   -min0     ignores minutes code \n");
+printf("   -N        does NOT write out the map \n");
+printf("   -q        quiet mode gives no listing except for errors\n");
+printf("   -sNNNN    where NNNN is the maximum # of bytes to skip between GRIB messages (default is 1000)\n");
+printf("   -t0       forces a match if base time in the GRIB header equals the initial time in the descriptor file\n");
+/* printf("   -u        updates existing gribmap (N.B. This option is temporarily disabled)\n"); */
+printf("   -v        verbose option shows details of the mapping\n");
+printf("\n");
+}
+
+void gaprnt (gaint i, char *ch) {
+  printf ("%s",ch);
+}
+
+char *gxgsym(char *ch) {
+  return (getenv(ch));
+}
+
+gadouble qcachesf(void) {
+  return(1.0);
+}
+
+void set_nc_cache(size_t arg) {
+  return;
+}
diff --git a/src/gribscan.c b/src/gribscan.c
new file mode 100644
index 0000000..96152db
--- /dev/null
+++ b/src/gribscan.c
@@ -0,0 +1,1283 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+#include <malloc.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "grads.h"
+#include "gx.h"
+#include "gvt.h"
+
+#define NULCH '\0'
+gaint help=0;
+void command_line_help(void) ;
+
+/*---
+  OLD grib decoding routine...
+---*/
+
+FILE *gfile,*ofile;
+
+struct grhdr {
+  gaint vers;
+  gaint len;  
+  gaint pdslen,gdslen,bmslen,bdslen;
+  gaint ptvn;
+  gaint center;
+  gaint procid;
+  gaint gridid;
+  gaint gdsflg,bmsflg;
+  gaint parm;
+  gaint ltyp;
+  gaint level;
+  gaint l1,l2;
+  struct dt dtim;
+  gaint ftu,p1,p2,tri;
+  gaint century;
+  float dsf;
+  gaint gpv,gnv,gtyp,gicnt,gjcnt,gsf1,gsf2,gsf3;
+  gaint bnumr;
+  gaint bunb;
+  off_t bpos;
+  gaint dgflg; 
+  gaint dpflg;
+  gaint doflg;
+  gaint dfflg;
+  gaint dbusd;
+  float bsf;
+  float ref;
+  gaint bnum;
+  off_t dpos;
+};
+
+struct grib_gds_ll{
+  unsigned char *gds;
+  gaint len;
+  gaint nv;
+  gaint pv;
+  gaint drt;
+  gaint ni;
+  gaint nj;
+  gaint lat1;
+  gaint lon1;
+  gaint rcdi;
+  gaint rcre;
+  gaint rcuv;
+  gaint lat2;
+  gaint lon2;
+  gaint dx;
+  gaint dy;
+  gaint smi;
+  gaint smj;
+  gaint smdir;
+};
+
+/* gds for NMC lat/lon grids */
+
+struct grib_gds_ll gdsn2; 
+
+/* function init */
+
+void gds_init(struct grib_gds_ll *, gaint ) ;
+gaint gribhdr(struct grhdr *);
+void malloc_err( gaint ) ;
+
+gaint iok[3],iokwrite;      
+gaint irec=0;          /* record counter */
+gaint gdsout=0;        /* GDS output flag */
+gaint bdsout=0;        /* BDS output flag */
+gaint qout=0;          /* essential GrADS GRIB parms */
+gaint qout1=0;         /* file name + essential GrADS GRIB parms for first record only */
+gaint delim=0;         /* comma deliminated output */
+gaint verb=0;          /* verbose */
+gaint silent=0;        /* silent mode */
+gaint gaout=0;         /* ascii output */
+gaint gaoutfld=-999;   /* which fields to dump */
+gaint gaouttau=-999;   /* which taus to dump */
+gaint gaoutlev=-999;   /* which levs to dump */
+gaint gfout=0;         /* float output */
+gaint ggout=0;         /* GRIB output */
+gaint gvout=0;         /* output the variable name, title units based on NMC tables */
+gaint xyrevflg;        /* flag indicating whether we have the reversed lat/lon FNMOC grid */
+
+
+off_t fpos;  /* File pointer into GRIB file */
+off_t flen;
+gaint nullsk;
+gaint scanflg,scanlim=2000;
+
+char *ofname,*ifname;
+
+gaint main (gaint argc, char *argv[]) {
+ struct grhdr ghdr;
+ gaint cnt,rc,i,flg,iarg,len,skip;
+ char cmd[256], *ch;
+ unsigned char rec[50000], *uch;
+ 
+ skip   = -999;
+ nullsk = -999;
+ ifname = NULL;
+ ofname = NULL;
+
+ if (argc>1) {
+    iarg = 1;
+    while (iarg<argc) {
+
+      flg = 1;
+      ch = argv[iarg];
+
+      if (*(ch)=='-' && *(ch+1)=='h' && *(ch+2)=='e' && *(ch+3)=='l' && *(ch+4)=='p' ) {
+	command_line_help();
+	return(0);
+      } else if (*ch=='-' && *(ch+1)=='i') {
+        iarg++; 
+        if (iarg<argc) {
+	  ifname = (char *)malloc(strlen(argv[iarg])+1);
+          strcpy(ifname,argv[iarg]);
+          flg = 0;
+        } else iarg--;   /* Let error message pop */
+      }
+      else if (*ch=='-' && *(ch+1)=='o' && *(ch+2) == NULCH ) {
+        iarg++; 
+        if (iarg<argc) {
+	  ofname = (char *)malloc(strlen(argv[iarg])+1);
+          strcpy(ofname,argv[iarg]);
+          flg = 0;
+        } else iarg--;   /* Let error message pop */
+      }
+      else if (*ch=='-' && *(ch+1)=='n') {
+        ch+=2;
+        i = 0;
+        while(*(ch+i) && i<900) {
+          if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+          i++;
+        }
+        if (i<900) {
+          sscanf(ch,"%i",&nullsk);
+          flg = 0;
+        }
+      }
+      else if (*ch=='-' && *(ch+1)=='g' && *(ch+2)=='d' ) {
+	gdsout = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='g' && *(ch+2)=='v' ) {
+	gvout = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='v' ) {
+	verb = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='S' ) {
+	silent = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='b' && *(ch+2)=='d'  ) {
+	bdsout = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='d' ) {
+	delim = 1;
+	flg = 0;
+      }      
+      else if (*ch=='-' && *(ch+1)=='q' && *(ch+2)=='1' ) {
+	qout1 = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='o' && *(ch+2)=='g' ) {
+	ggout = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='o' && *(ch+2)=='a' ) {
+	gaout = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='s' && *(ch+2)=='p' ) {
+	flg = 0;
+        ch+=3;
+        if (*ch != NULCH) {
+          i = 0;
+          while(*(ch+i) && i<900) {
+            if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+            i++;
+          }
+          if (i<900) {
+            sscanf(ch,"%i",&gaoutfld);
+            flg = 0;
+          }
+	}
+      }
+      else if (*ch=='-' && *(ch+1)=='s' && *(ch+2)=='t' ) {
+	flg = 0;
+        ch+=3;
+        if (*ch != NULCH) {
+          i = 0;
+          while(*(ch+i) && i<900) {
+            if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+            i++;
+          }
+          if (i<900) {
+            sscanf(ch,"%i",&gaouttau);
+            flg = 0;
+          }
+	}
+      }
+      else if (*ch=='-' && *(ch+1)=='s' && *(ch+2)=='l' ) {
+	flg = 0;
+        ch+=3;
+        if (*ch != NULCH) {
+          i = 0;
+          while(*(ch+i) && i<900) {
+            if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+            i++;
+          }
+          if (i<900) {
+            sscanf(ch,"%i",&gaoutlev);
+            flg = 0;
+          }
+	}
+      }
+      else if (*ch=='-' && *(ch+1)=='o' && *(ch+2)=='f' ) {
+	gfout = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='q' ) {
+	qout = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='s') {
+        scanflg = 1;
+	ch+=2;
+        i = 0;
+        while(*(ch+i) && i<900) {
+          if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+          i++;
+        }
+        if (i<900) {
+          sscanf(ch,"%i",&scanlim);
+	  printf("scanlim = %d\n",scanlim);
+          flg = 0;
+        }
+      }
+      else if (*ch=='-' && *(ch+1)=='h') {
+        ch+=2;
+        if (*ch=='n' && *(ch+1)=='m' &&  *(ch+2)=='c') {
+          skip = -1;
+          flg = 0;
+        } else if (*ch == NULCH) {
+	  skip = -999;
+	  flg = 0;
+	} else {
+          i = 0;
+          while(*(ch+i) && i<900) {
+            if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+            i++;
+          }
+          if (i<900) {
+            sscanf(ch,"%i",&skip);
+            flg = 0;
+          }
+        }
+      }
+      if (flg) {
+        printf ("Invalid command line argument: %s  Ignored.\n",argv[iarg]);
+      }
+      iarg++;
+    }
+  }
+  
+  if (ifname == NULL) { 
+    command_line_help();
+    cnt = nxtcmd (cmd,"Enter name of GRIB file: ");
+    if (cnt==0) return(1);
+    getwrd(ifname,cmd,250);
+  }
+
+  gfile = fopen(ifname,"rb");
+  if (gfile==NULL) {
+    printf ("Could not open GRIB file.  File name is:\n");
+    printf ("  %s\n",ifname);
+    return(1);
+  }
+
+  /* open output file */
+  
+  if(ofname == NULL) {
+   ofname = (char *)malloc(7+5);
+   strcat(ofname,"zy0x1w2");
+  }
+
+  if(gaout) {
+    strcat(ofname,".asc");
+    ofile = fopen(ofname,"w");
+    if (ofile==NULL) {
+      printf ("Could not open ASCII output file: zy0x1w2.ascii");
+      return(1);
+    }
+  } else if (gfout) {
+    strcat(ofname,".dat");
+    ofile = fopen(ofname,"wb");
+    if (ofile==NULL) {
+      printf ("Could not open float  output file: zy0x1w2.ascii");
+      return(1);
+    }
+  } else if (ggout) {
+    strcat(ofname,".grb");
+    ofile = fopen(ofname,"wb");
+    if (ofile==NULL) {
+      printf ("Could not open NMC GRIB output file: zy0x1w2.grb");
+      return(1);
+    }
+  }    
+
+  /* initialize NMC lat/lon gds for grid #2 */
+
+  if (ggout) gds_init(&gdsn2,2);
+
+  /* Get file size */
+
+  rc = fseeko(gfile,0L,2);
+  if (rc) return(50);
+
+  flen = ftell(gfile);
+
+  /* Set up to skip appropriate amount.  */
+
+ if (skip == -999) { 
+
+   /* we have no idea what the header is; find it within reason */
+
+   /* read in four bytes */
+ 
+   rc = fseeko(gfile,0,0);
+   if (rc) return(50);
+
+   uch=&rec[0]; 
+   rc = fread(uch,sizeof(char),4,gfile);
+   if (rc < 4) return(50);
+
+   fpos = 0;
+   while (fpos < flen && !(*(uch)=='G' && *(uch+1)=='R' &&
+	 *(uch+2)=='I' && *(uch+3)=='B') ) {
+       fpos++;
+       rc = fseeko(gfile,fpos,0);
+       if (rc) return(50);
+       rc = fread(uch,1,4,gfile);
+       if (rc<4) fpos = flen;
+     }
+ 
+   if (fpos == flen) {
+     printf ("GRIB header not found.  File apparantly not GRIB data\n");
+     printf ("->%c%c%c%c%c%c<-\n",*uch,*(uch+1),*(uch+2),*(uch+3),*(uch+4),*(uch+5));
+     return (99);
+   } else {
+     if (verb) printf("the header is %lld bytes long\n",fpos);
+   }
+
+ } else if (skip > -1) {
+
+   /* fixed header length */
+
+   fpos = skip;
+
+ } else {
+
+   /* hard-wired nmc header */
+
+    rc = fseeko(gfile,0,0);
+    if (rc) return(50);
+
+    rc = fread (rec,1,100,gfile);
+    if (rc<100) {
+      printf ("I/O Error reading header\n");
+      return (1);
+    }
+    len = gagby(rec,88,4);
+    fpos = len*2 + 100;
+  }
+
+  /* We are positioned.  Go read the first GRIB header */
+
+  while (1) {
+    rc = gribhdr(&ghdr);
+    if (rc) break;
+  }
+
+  fclose (gfile);
+  if (gaout || ggout || gfout) fclose(ofile);
+
+/* error conditions */
+
+  if (rc == 2) {
+    return(0);
+  } else if (rc==50) {
+    printf ("I/O Error reading GRIB file\n");
+    printf ("Possible cause: premature EOF\n");
+    return(1);
+  } else if (rc==51) {
+    printf ("I/O Error reading GRIB file\n");
+    printf ("Possible cause: premature EOF\n");
+    return(1);
+  } else if (rc==52) {
+    printf ("I/O Error reading GRIB file\n");
+    printf ("premature EOF between records\n");
+    return(1);
+  } else if (rc==53 && verb) {
+    printf ("Junk at end of GRIB file\n");
+    return(1);
+  } else if (rc==99) {
+    printf ("GRIB format error\n");
+    return(1);
+  }
+
+  if(verb) printf ("Reached EOF\n"); 
+  return(0);
+}
+
+void gds_init(struct grib_gds_ll *gds, gaint nmc_grid) {
+  
+gaint bstrt;
+  
+  if(nmc_grid == 2) {
+    gds->len=32;
+    gds->gds = (unsigned char *)malloc(gds->len);
+    gds->nv=0;
+    gds->pv=255;
+    gds->drt=0;
+    gds->ni=144;
+    gds->nj=73;
+    gds->lat1=90000;
+    gds->lon1=0;
+    gds->rcdi=0;
+    gds->rcre=0;
+    gds->rcuv=0;
+    gds->dx=2500;
+    gds->dy=2500;
+    gds->lat2=-90000;
+    gds->lon2=-2500;
+    gds->smi=0;
+    gds->smj=0;
+    gds->smdir=0;
+
+    /* code it up */
+    gapby(gds->len,gds->gds,0,3);       /* octets 1-3 length of GDS */  
+    gapby(gds->nv,gds->gds,3,1);        /* octet 4 -- nv number of vertical coordinates */
+    gapby(gds->pv,gds->gds,4,1);        /* octet 5 -- pv location of vert coors */
+    gapby(gds->drt,gds->gds,5,1);       /* octet 6 -- data representation type (TABLE 6) */
+    gapby(gds->ni,gds->gds,6,2);        /* octets 7-8 -- number of lons */
+    gapby(gds->nj,gds->gds,8,2);        /* octets 9-10 -- number of lats */
+    bstrt=10*8;                         /* octets 11-13, 14-16  lat1, lon1 */
+    if(gds->lat1 < 0) {
+      gapbb(1,gds->gds,bstrt,1);
+      gds->lat1=-gds->lat1;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->lat1,gds->gds,bstrt,23);
+    bstrt+=23;
+    if(gds->lon1 < 0) {
+      gapbb(1,gds->gds,bstrt,1);
+      gds->lon1=-gds->lon1;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->lon1,gds->gds,bstrt,23);
+    bstrt+=23;
+    gapbb(gds->rcdi,gds->gds,bstrt,1);   /* octet 17 resolution component flag -- table 7 */
+    bstrt++; 
+    gapbb(gds->rcre,gds->gds,bstrt,1);
+    bstrt++;
+    gapbb(0,gds->gds,bstrt,2);
+    bstrt+=2;
+    gapbb(gds->rcuv,gds->gds,bstrt,1);
+    bstrt++;
+    gapbb(0,gds->gds,bstrt,3);
+    bstrt+=3;
+    if(gds->lat2 < 0) {                  /* octets 18-20,21-23 -- lat2,lon2 */
+      gapbb(1,gds->gds,bstrt,1);
+      gds->lat2=-gds->lat2;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->lat1,gds->gds,bstrt,23);
+    bstrt+=23;
+    
+    if(gds->lon2 < 0) {
+      gapbb(1,gds->gds,bstrt,1);
+      gds->lon2=-gds->lon2;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->lon2,gds->gds,bstrt,23);
+    bstrt+=23;
+    if(gds->dx < 0) {                    /* octets 24-25 -- dlon */
+      gapbb(1,gds->gds,bstrt,1);
+      gds->dx=-gds->dx;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->dx,gds->gds,bstrt,15);
+    bstrt+=15;
+    if(gds->dy < 0) {                    /* octets 26-27 -- dlat */
+      gapbb(1,gds->gds,bstrt,1);
+      gds->dy=-gds->dy;
+    } else {
+      gapbb(0,gds->gds,bstrt,1);
+    }
+    bstrt++;
+    gapbb(gds->dy,gds->gds,bstrt,15);
+    bstrt+=15;
+    
+    gapbb(gds->smi,gds->gds,bstrt,1);
+    bstrt++;
+    gapbb(gds->smj,gds->gds,bstrt,1);
+    bstrt++;
+    gapbb(gds->smdir,gds->gds,bstrt,1);
+    bstrt++;
+    gapbb(0,gds->gds,bstrt,5);
+    bstrt+=5;
+    gapby(0,gds->gds,28,4);               /* octets 29 -32 - reserved 0 filled */
+  }
+}
+
+
+/* Read a GRIB header, and get needed info out of it.  */
+
+gaint gribhdr (struct grhdr *ghdr) {
+unsigned char rec[512],*ch;
+gaint i,j,ifnmoc,jfnmoc,inmc,jnmc,len,rc,sign,mant;
+off_t cpos,cposis;
+gaint npts=0,bstrt,yy;
+float la1,la2,lo1,lo2,ladi,lodi;
+gaint *gr=NULL,*gri=NULL;
+float *grf=NULL,*grfi=NULL;
+
+struct grib_len {     /* length of grib sections */
+  gaint is;
+  gaint pds;
+  gaint gds;
+  gaint bms;
+  gaint bds;
+  gaint es;
+  gaint msg;
+} glen;
+
+struct grib {         /* grib data */
+  unsigned char *is;
+  unsigned char *pds;
+  unsigned char *gds;
+  unsigned char *bms;
+  unsigned char *bds;
+  unsigned char es[4];
+} gd;
+
+
+  if (fpos>=flen) return(1);
+
+  /* Position at start of next record */
+  rc = fseeko(gfile,fpos,0);
+  if (rc) return(50);
+
+  /* Read start of record -- length, version number */
+  rc = fread(rec,1,8,gfile);
+  if (rc<8){
+    if(fpos+8 >= flen) return(51);
+    else return(51);
+  }
+  if (*rec!='G' || *(rec+1)!='R' || *(rec+2)!='I' || *(rec+3)!='B') {
+
+    /* look for data between records BY DEFAULT */ 
+    i = 1;
+    fpos += i;
+    rc = fseeko(gfile,fpos,0);
+    if (rc) return(50);
+    ch=&rec[0];
+    rc = fread(ch,sizeof(unsigned char),4,gfile);
+    while ( (fpos < flen-4) && (i < scanlim) && !( *ch=='G' && *(ch+1)=='R' &&
+			   *(ch+2)=='I' && *(ch+3)=='B' ) ) {
+      fpos++;
+      i++;
+      rc = fseeko(gfile,fpos,0);
+      if (rc) return(50);
+      rc = fread(ch,sizeof(unsigned char),4,gfile);
+      if (rc<4) return(50);
+    } 
+    if (i == scanlim ) {
+      printf ("GRIB header not found in scanning between records\n");
+      printf ("->%c%c%c%c<-\n",*rec,*(rec+1),*(rec+2),*(rec+3));
+      return (52);
+    } else if (fpos == flen -4) {
+      return (53);
+    }
+    /* SUCCESS redo the initial read */    
+    rc = fseeko(gfile,fpos,0);
+    if (rc) return(50);
+    rc = fread(rec,1,8,gfile);
+    if (rc<8){
+      if(fpos+8 >= flen) return(51);
+      else return(52);
+    }
+  }
+  cpos = fpos;
+  cposis = fpos;
+
+  /* store IS */
+  glen.is=8;
+  gd.is = (unsigned char *)malloc(glen.is);
+  if(gd.is == NULL) malloc_err(1);
+  memcpy (gd.is,&rec[0],glen.is);
+  ghdr->vers = gagby(rec,7,1);
+  if (ghdr->vers>1) {
+    printf ("File is not GRIB version 0 or 1, 0 or 1 is required. \n");
+    printf (" Version number is %i\n",ghdr->vers);
+    return (99);
+  }
+  /* bump the record # */
+  irec++;
+  if (ghdr->vers==0) {
+    cpos += 4;
+    rc = fseeko(gfile,cpos,0);
+    if (rc) return(50);
+  } else {
+    ghdr->len = gagby(rec,4,3);
+    glen.msg = ghdr->len;
+    cpos = cpos + 8;
+    rc = fseeko(gfile,cpos,0);
+    if (rc) return(50);
+  }
+
+/*
+  PPPPPPPPPPPPPP DDDDDDDDDDDDDD SSSSSSSSSSSSSSS
+*/
+
+  rc = fread(rec,1,3,gfile);
+  if (rc<3) return(50);
+  len = gagby(rec,0,3);
+  ghdr->pdslen = len;
+  cpos = cpos + len;
+  rc = fread(rec+3,1,len-3,gfile);
+  if (rc<len-3) return(50);
+
+  /* mf store PDS */
+
+  gd.pds=NULL;
+  glen.pds=0;
+  if(ggout || gaout || gfout) {
+    glen.pds=len;
+    gd.pds = (unsigned char *)malloc(glen.pds);
+    if(gd.pds == NULL) malloc_err(2);
+    memcpy (gd.pds,&rec[0],glen.pds);
+  }
+
+  /* get info from PDS */
+
+  ghdr->ptvn = gagby(rec,3,1);
+  ghdr->center = gagby(rec,4,1);
+  ghdr->procid = gagby(rec,5,1);
+  ghdr->gridid = gagby(rec,6,1);
+  ghdr->gdsflg = gagbb(rec+7,0,1);
+  ghdr->bmsflg = gagbb(rec+7,1,1);
+  ghdr->parm = gagby(rec,8,1);
+  ghdr->ltyp = gagby(rec,9,1);
+  ghdr->level = gagby(rec,10,2);
+  ghdr->l1 = gagby(rec,10,1);
+  ghdr->l2 = gagby(rec,11,1);
+  ghdr->dtim.yr = gagby(rec,12,1);
+  yy=ghdr->dtim.yr;
+  ghdr->dtim.mo = gagby(rec,13,1);
+  ghdr->dtim.dy = gagby(rec,14,1);
+  ghdr->dtim.hr = gagby(rec,15,1);
+  ghdr->dtim.mn = gagby(rec,16,1);
+  ghdr->ftu = gagby(rec,17,1);
+  ghdr->tri = gagby(rec,20,1);
+  if (ghdr->tri==10) {
+    ghdr->p1 = gagby(rec,18,2);
+    ghdr->p2 = 0;
+  } else {
+    ghdr->p1 = gagby(rec,18,1);
+    ghdr->p2 = gagby(rec,19,1);
+  }
+/*
+ghdr->nave = gagby(rec,21,2);
+ghdr->nmiss = gagby(rec,23,1);
+*/
+  if (len>24) {
+    ghdr->century = gagby(rec,24,1);
+    ghdr->dtim.yr = ghdr->dtim.yr + (ghdr->century-1)*100;
+  } else {
+    ghdr->century = -999;
+    if (ghdr->dtim.yr>49) ghdr->dtim.yr += 1900;
+    else ghdr->dtim.yr += 2000;
+  }
+  if (len>25) {
+/*
+ghdr->subcent = gagby(rec,25,1);
+*/
+    ghdr->dsf = (float)gagbb(rec+26,1,15);
+    i = gagbb(rec+26,0,1);
+    if (i) ghdr->dsf = -1.0*ghdr->dsf;
+    ghdr->dsf = pow(10.0,ghdr->dsf);
+    if(ghdr->dsf == 0.0) ghdr->dsf = 1.0;  /* mf make sure dsf != 0 */
+  } else ghdr->dsf = 1.0;
+
+if(!silent) {
+if(qout) {
+
+  if(ghdr->ltyp == 100) {
+    printf("%d, F ,%d,%d,%d,%d,%5g, T ,%d,%d,%d,%d,%d,%d,%d,%d",
+	   irec,ghdr->parm,ghdr->ltyp,ghdr->level,
+	   ghdr->tri,ghdr->dsf,
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2);
+
+    if(gvout) printf(", V , %s, %s, %s",
+		 vt[ghdr->parm].name,vt[ghdr->parm].desc,vt[ghdr->parm].units);
+
+    printf(", G ,%d, BDTG, %02d%02d%02d%02d ",ghdr->gridid,
+	   yy,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr);
+
+  } else {
+    printf("%d, F ,%d,%d,%d,%d,%d,%d,%5g, T ,%d,%d,%d,%d,%d,%d,%d,%d",
+	   irec,ghdr->parm,ghdr->ltyp,ghdr->level,
+	   ghdr->l1,ghdr->l2,ghdr->tri,ghdr->dsf,
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2);
+    if(gvout) printf(", V ,%s ,%s ,%s",
+		 vt[ghdr->parm].name,vt[ghdr->parm].desc,vt[ghdr->parm].units);
+    printf(", G ,%d, BDTG, %02d%02d%02d%02d ",ghdr->gridid,
+	   yy,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr);
+  }
+  if(!bdsout) printf("\n");
+
+} else if(qout1 == 1) {
+
+  if(ghdr->ltyp == 100) {
+    printf("%40s, F ,%d,%d,%d,%d,%d,%d,%5g, T ,%d,%d,%d,%d,%d,%d,%d,%d",
+	   ifname,ghdr->parm,ghdr->ltyp,ghdr->level,
+	   ghdr->l1,ghdr->l2,ghdr->tri,ghdr->dsf,
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2);
+    printf(", G ,%d, BDTG, %02d%02d%02d%02d ",ghdr->gridid,
+	   yy,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr);
+  } else {
+    printf("%40s, F ,%d,%d,%d,%d,%d,%d,%5g, T ,%d,%d,%d,%d,%d,%d,%d,%d",
+	   ifname,ghdr->parm,ghdr->ltyp,ghdr->level,
+	   ghdr->l1,ghdr->l2,ghdr->tri,ghdr->dsf,
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2);
+    printf(", G ,%d, BDTG, %02d%02d%02d%02d ",ghdr->gridid,
+	   yy,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr);
+  }
+  if(!bdsout) printf("\n");
+  return(2);
+
+} else if( qout == 0 ) {
+
+  if( delim ) {
+    printf("PDS,%d,%d,%d,%d,%d,%d,%d,",
+	   irec,ghdr->gridid,ghdr->parm,ghdr->ltyp,ghdr->level,ghdr->l1,ghdr->l2);
+    printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%g",
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2,ghdr->tri,ghdr->dsf);
+    if(gvout) printf(",%s,%s,%s",
+		 vt[ghdr->parm].name,vt[ghdr->parm].desc,vt[ghdr->parm].units);
+  } else {
+    printf("PDS #%-4d %2d %3d %3d %4d %3d %3d BMSFLG: %1d ",
+	   irec,ghdr->gridid,ghdr->parm,ghdr->ltyp,ghdr->level,ghdr->l1,ghdr->l2,ghdr->bmsflg);
+    printf("%4d %02d %02d %02d %02d % 3d % 3d % 3d % 3d %8g",
+	   ghdr->dtim.yr,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr,
+	   ghdr->dtim.mn,ghdr->ftu,ghdr->p1,ghdr->p2,ghdr->tri,ghdr->dsf);
+    if(gvout) printf(" %6s %38s %16s",
+		 vt[ghdr->parm].name,vt[ghdr->parm].desc,vt[ghdr->parm].units);
+
+  }
+
+  if(gdsout == 0 && !bdsout) printf("\n");
+
+}
+}
+
+/*
+  GGGGGGGGGGGGGGG DDDDDDDDDDDDDDDDDDDD SSSSSSSSSSSSSSS
+*/
+
+  gd.gds=NULL;
+  glen.gds=0;
+  if (ghdr->gdsflg) {
+
+    rc = fread(rec,1,3,gfile);
+    if (rc<3) return(50);
+    len = gagby(rec,0,3);
+    ghdr->gdslen = len;
+    cpos = cpos + len;
+    rc = fread(rec+3,1,len-3,gfile);
+    if (rc<len-3) return(50);
+
+  /* mf store GDS */
+ 
+    if(ggout || gaout || gfout) {
+      glen.gds=len;
+      gd.gds = (unsigned char *)malloc(glen.gds);
+      if(gd.gds == NULL) malloc_err(3);
+      memcpy (gd.gds,&rec[0],glen.gds);
+    }
+
+    ghdr->gpv = gagby(rec,3,1);
+    ghdr->gnv = gagby(rec,4,1);
+    ghdr->gtyp = gagby(rec,5,1);
+    ghdr->gicnt = gagby(rec,6,2);
+    ghdr->gjcnt = gagby(rec,8,2);
+
+    la1 = gagbb(rec+10,1,23)*0.001;
+    i = gagbb(rec+10,0,1);
+    if (i) la1 = -1*la1;
+    lo1 = gagbb(rec+13,1,23)*0.001;
+    i = gagbb(rec+13,0,1);
+
+    if (i) lo1 = -1*lo1;
+    la2 = gagbb(rec+17,1,23)*0.001;
+    i = gagbb(rec+17,0,1);
+    if (i) la2 = -1*la2;
+    lo2 = gagbb(rec+20,1,23)*0.001;
+    i = gagbb(rec+20,0,1);
+    if (i) lo2 = -1*lo2;
+    lodi = gagby(rec,23,2);
+    ghdr->gsf1 = gagbb(rec+27,0,1);
+    ghdr->gsf2 = gagbb(rec+27,1,1);
+    ghdr->gsf3 = gagbb(rec+27,2,1);
+    ladi = gagby(rec,25,2);
+    if(ghdr->gtyp == 0) {
+      ladi *= 0.001;
+      lodi *= 0.001;
+    } else {
+      ladi *= 1.0;
+      lodi *= 1.0;
+    }
+/*
+   special case of thinned grids in lat from ecmwf .......
+*/
+  npts=0;
+  if(ghdr->gicnt == 65535) {
+    yy=gagby(rec,28,4);
+    for(i=0;i<(ghdr->gdslen-32)/2;i++) {
+      yy=gagby(rec,32+i*2,2);
+      npts += yy;
+/*      printf("qqq i yy = %d %d\n",i+1,yy); */
+    }
+  }
+
+if(!silent) {
+    if( gdsout && qout == 0 ) {
+      if( delim ) {
+	printf(",GDS,%d,%d,%d,%-6.3f,%-6.3f,%-6.3f,%-6.3f,%-6.3f,%-6.3f,",
+	       ghdr->gtyp,ghdr->gicnt,ghdr->gjcnt,lo1,lo2,lodi,la1,la2,ladi);
+	printf("%d,%d,%1d",ghdr->gsf1,ghdr->gsf2,ghdr->gsf3);
+      } else {
+	printf(" GDS % 3d % 3d % 3d %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f",
+	       ghdr->gtyp,ghdr->gicnt,ghdr->gjcnt,lo1,lo2,lodi,la1,la2,ladi);
+	printf(" %1d %1d %1d",ghdr->gsf1,ghdr->gsf2,ghdr->gsf3);
+	printf(" GDS pv nv % 3d % 3d",ghdr->gpv,ghdr->gnv);
+      }
+      if(!bdsout) printf("\n");
+
+    }
+
+  }
+
+  }
+
+/*
+  BBBBBBBBBBBBBBB MMMMMMMMMMMMMMMMMMM SSSSSSSSSSSSSSSSS
+*/
+
+  gd.bms=NULL;
+  ghdr->bmslen = 0;
+  glen.bms=0;
+  if (ghdr->bmsflg && ghdr->gicnt != 65535) {
+    rc = fread(rec,1,6,gfile);
+    if (rc<6) return(50);
+    len = gagby(rec,0,3);
+    ghdr->bmslen = len;
+
+  /* mf store BMS */
+
+    if(ggout || gaout || gfout) {
+      glen.bms=len;
+
+      gd.bms = (unsigned char *)malloc(glen.bms);
+      if(gd.bms == NULL) malloc_err(4);
+      rc=fread(gd.bms,1,glen.bms,gfile);
+    }
+
+    ghdr->bnumr = gagby(rec,4,2);
+    ghdr->bunb = gagby(rec,3,1);
+    ghdr->bpos = cpos+6;
+    cpos = cpos + len;
+    rc = fseeko(gfile,cpos,0);
+    if (rc) return(50);
+
+  } 
+/*
+  BBBBBBBBBBBBBB DDDDDDDDDDDDDDDDDD SSSSSSSSSSSSSSSSS
+*/
+
+  rc = fread(rec,1,11,gfile);
+  if (rc<11) return(50);
+  len = gagby(rec,0,3);
+  ghdr->bdslen = len;
+  ghdr->dgflg = gagbb(rec+3,1,0);
+  ghdr->dpflg = gagbb(rec+3,1,1);
+  ghdr->doflg = gagbb(rec+3,1,2);
+  ghdr->dfflg = gagbb(rec+3,1,3);
+
+/*
+  if (ghdr->dpflg) {
+    printf ("GRIB data does not use simple packing.  Cannot handle.\n");
+    return(99);
+  }
+*/
+  i = gagby(rec,4,2);
+  if (i>32767) i = 32768-i;
+  ghdr->bsf = pow(2.0,(float)i);
+
+  i = gagby(rec,6,1);
+  sign = 0;
+  if (i>127) {
+    sign = 1;
+    i = i - 128;
+  }
+  mant = gagby(rec,7,3);
+  if (sign) mant = -mant;
+  ghdr->ref = (float)mant * pow(16.0,(float)(i-70));
+
+  ghdr->bnum = gagby(rec,10,1);
+  ghdr->dpos = cpos+11;
+
+  /* find number of DEFINED grid points */
+
+  if(!ghdr->dfflg && ghdr->bnum !=0 && npts != 0) {
+    ghdr->dbusd = gagbb(rec+3,4,4);
+    npts = ( (len-11)*8 - ghdr->dbusd)/ghdr->bnum;
+  } else {
+    npts = (len-13)*8;
+  }
+
+  /* bump the file pointer and output */
+
+  if (ghdr->vers==0) {
+    ghdr->len=8+ghdr->pdslen+ghdr->gdslen +ghdr->bmslen + ghdr->bdslen;
+    fpos = fpos + ghdr->len;
+    printf ("\nLengths: pds,gds,bms,bds = %i %i %i %i \n",
+      ghdr->pdslen,ghdr->gdslen,ghdr->bmslen,ghdr->bdslen);
+  } else fpos = fpos + ghdr->len;
+
+  if(verb) {
+    printf ("\nLengths: pds,gds,bms,bds = %d %d %d %d \n",
+	    ghdr->pdslen,ghdr->gdslen,ghdr->bmslen,ghdr->bdslen);
+  }
+
+  if( bdsout && !silent ) {
+    if ( !qout) {
+      if( delim ) {
+	printf(",BDS,%d,%10g,%d,%lld,%d",ghdr->bnum,ghdr->ref,npts,cposis,ghdr->len);
+      } else {
+	printf(" BDS % 3d %10g % 10d % 10lld % 10d",ghdr->bnum,ghdr->ref,npts,cposis,ghdr->len);
+      }
+    } else {
+      printf(", B ,%2d,%g,%d,%lld,%d",ghdr->bnum,ghdr->ref,npts,cposis,ghdr->len);
+    }
+    printf("\n");
+  } 
+    if(verb) printf("npts = %d %d %d\n",npts,ghdr->center,ghdr->gridid);
+
+  /* mf store BDS  and get data  */
+
+  gd.bds=NULL;
+
+  if(ggout || gaout || gfout) {
+
+    glen.bds=len;
+    gd.bds = (unsigned char *)malloc(glen.bds);
+    if(gd.bds == NULL) malloc_err(5);
+
+
+    rc = fseeko(gfile,cpos,0);
+    rc = fread(gd.bds,1,glen.bds,gfile);
+    if (rc<glen.bds) return(50);
+
+    gr = (gaint *)malloc(npts*sizeof(gaint));
+    if(gr == NULL) malloc_err(6);
+
+    if(gaout || gfout) {
+
+      grf = (float *)malloc(npts*sizeof(float));
+      if(grf == NULL) malloc_err(7);
+
+    }
+
+    /* decode the grib data to int and float */
+
+    bstrt=11*8;
+    for(i=0;i<npts;i++) {
+      *(gr+i)  = gagbb(gd.bds,bstrt,ghdr->bnum);
+      if(gaout || gfout) {
+	*(grf+i) = ( ghdr->ref + (float)(*(gr+i)) * ghdr->bsf )/ghdr->dsf;
+      }
+      bstrt += ghdr->bnum;
+    }
+/*
+  invert to NMC grid if FNMOC 2.5 global grid
+*/
+
+    xyrevflg=0;
+
+    if(ghdr->center == 58 && ghdr->gridid == 223) {
+
+      xyrevflg=1;
+      gri = (gaint *)malloc(npts*sizeof(gaint));
+      if(gri == NULL) malloc_err(8);
+      grfi = (float *)malloc(npts*sizeof(float));
+      if(grfi == NULL) malloc_err(9);
+
+      for(i=0;i<npts;i++) {
+
+	ifnmoc=i%73+1;
+	jfnmoc=i/73+1;
+	inmc=jfnmoc+24;
+	if(inmc>144) inmc=inmc-144;
+	jnmc=ifnmoc;
+	j=(jnmc-1)*144+inmc-1; 
+	
+	if(gfout || gaout) {
+	  *(grfi+j)=*(grf+i);
+	} else if(ggout) {
+	  *(gri+j)=*(gr+i);
+	}
+      }
+    
+      if(ggout) {
+
+    /* encode ints to GRIB and load into bds */
+	
+	bstrt=11*8;
+	for(i=0;i<npts;i++) {
+	  gapbb(*(gri+i),gd.bds,bstrt,ghdr->bnum);
+	  bstrt += ghdr->bnum;
+	}
+
+    /* fix century problem */
+
+        gapby(20,gd.pds,24,1);
+
+    /* change the grid param */
+
+	gapby(2,gd.pds,6,1);
+
+    /* change the gdsflg */
+      
+	gapbb(1,gd.pds,7*8,1);
+
+	gapby(2,gd.pds,6,1);
+
+   /* calc the length of the GRIB msg */
+     
+	len = glen.is + glen.pds + gdsn2.len + glen.bds + 4;
+	gapby(len,gd.is,4,3);
+
+   /* write out the GRIB msg */
+        
+        rc=fwrite(gd.is,1,glen.is,ofile);
+        rc=fwrite(gd.pds,1,glen.pds,ofile);
+        rc=fwrite(gdsn2.gds,1,gdsn2.len,ofile);
+        rc=fwrite(gd.bds,1,glen.bds,ofile);
+	strncpy((char*)gd.es,"7777",4);
+        rc=fwrite(gd.es,1,4,ofile);
+
+      }
+
+
+    } /* end of check for FNMOC 73x144 grids */
+
+
+/* conditions for dumping fields */
+
+    iok[0]=0;
+    iok[1]=0;
+    iok[2]=0;
+    iokwrite=0;
+
+    if( gaoutfld != -999 ) {
+      iok[0]=-1;
+      if(ghdr->parm == gaoutfld ) iok[0]=1;
+    }
+    if( gaouttau != -999 ) {
+      iok[1]=-1;
+      if(ghdr->p1 == gaouttau ) iok[1]=1;
+    }
+
+    if( gaoutlev != -999 ) {
+      iok[2]=-1;
+      if( ghdr->level == gaoutlev ) iok[2]=1;
+    }
+/*	special restrictions */
+
+    if( (iok[0] != 0) || (iok[1] != 0) || (iok[2] != 0) ) {
+
+	if( iok[0] == 1 && iok[1] == 0 && iok[2] == 0 ) iokwrite=1;
+	if( iok[0] == 0 && iok[1] == 1 && iok[2] == 0 ) iokwrite=1;
+	if( iok[0] == 0 && iok[1] == 0 && iok[2] == 1 ) iokwrite=1;
+	if( iok[0] == 1 && iok[1] == 1 && iok[2] == 0 ) iokwrite=1;
+	if( iok[0] == 0 && iok[1] == 1 && iok[2] == 1 ) iokwrite=1;
+	if( iok[0] == 1 && iok[1] == 0 && iok[2] == 1 ) iokwrite=1;
+	if( iok[0] == 1 && iok[1] == 1 && iok[2] == 1 ) iokwrite=1;
+
+    } else {
+/*	dump all fields */
+      if( gaout || gfout || ggout ) iokwrite = 1;
+    }
+
+    if( iokwrite ) {
+
+      if (gaout) {
+
+/* ASCII I/O */
+
+
+	fprintf(ofile,"GRIB parm#= % 3d  npts= % 6d  grid id=% 3d\n",
+		ghdr->parm,npts,ghdr->gridid);
+	fprintf(ofile,"Base DTG= %02d%02d%02d%02d  ",
+		yy,ghdr->dtim.mo,ghdr->dtim.dy,ghdr->dtim.hr);
+	fprintf(ofile,"ftu= % 2d  p1= % 4d  p2= % 4d  tri= % 5d\n",
+		ghdr->ftu,ghdr->p1,ghdr->p2,ghdr->tri);
+	for (i=0;i<npts;i++) {
+	  if(xyrevflg) {
+	    fprintf(ofile,"%8g",*(grfi+i));
+	  } else { 
+	    fprintf(ofile,"%8g",*(grf+i));
+	  }
+          if((i+1)%10 == 0 ) fprintf(ofile,"\n");
+	}
+	fprintf(ofile,"\n");
+      } else if(gfout) {
+
+/* float I/O */
+
+	if(xyrevflg) {
+	  rc=fwrite(grfi,sizeof(float),npts,ofile);
+	} else {
+	  rc=fwrite(grf,sizeof(float),npts,ofile);
+	}
+
+	if(rc != npts) return(51);
+
+      } else if(ggout && !xyrevflg) {
+
+/* GRIB I/O */
+
+	rc=fwrite(gd.is,1,glen.is,ofile);
+	rc=fwrite(gd.pds,1,glen.pds,ofile);
+	if(gd.gds != NULL) rc=fwrite(gd.gds,1,glen.gds,ofile);
+	if(gd.bms != NULL) rc=fwrite(gd.bms,1,glen.bms,ofile);
+	rc=fwrite(gd.bds,1,glen.bds,ofile);
+	strncpy((char*)gd.es,"7777",4);
+	rc=fwrite(gd.es,1,4,ofile);
+	
+      }
+
+    }
+
+  }
+
+  free (gd.is);
+  if(gd.pds != NULL) {
+    free (gd.pds);
+  }
+  if(gd.gds != NULL) {
+    free(gd.gds);
+  }
+  if(gd.bms != NULL) free(gd.bms);
+
+  if(xyrevflg) {
+    free(gri); 
+    free(grfi);
+  }
+
+  if(gfout || gaout) {
+    free(grf);
+  }
+
+  if(ggout || gaout || gfout) {
+    free(gr);
+    free(gd.bds); 
+  } 
+
+
+  return(0);
+
+}
+
+void malloc_err(gaint i) {
+  printf("Malloc error # %d \n",i);
+  exit(69);
+}
+void gaprnt (gaint i, char *ch) {
+  printf ("%s",ch);
+}
+
+
+void command_line_help(void) {
+/*--- 
+  output command line options 
+---*/
+
+printf("gribscan utility for GrADS Version " GRADS_VERSION " \n");
+printf("extracts grid and variable information from GRIB data\n");
+printf("command line options: \n");
+printf("          -help   Just this help\n");
+printf("          -i      input GRIB file\n");
+printf("          -v      verbose listing\n");
+printf("          -d      comma deliminited format for the listing\n");
+printf("          -q      list essential GRIB parameters for the GrADS interface\n");
+printf("          -q1     list only one line of essential GRIB parameters for the GrADS interface\n");
+printf("          -S      silent option (no listing)\n");
+printf("          -gv     list variable names, description and units based on the NCEP tables\n");
+printf("          -gd     display info from the Grid Definition Section\n");
+printf("          -bd     display info from the Binary Data Section\n");
+printf("          -o      output file name (default is zy0x1w2.EEE)\n");
+printf("                EEE = asc for ASCII output\n");
+printf("                EEE = dat for binary float output\n");
+printf("                EEE = grb for GRIBoutput\n");
+printf("          -og     output GRIB\n");
+printf("          -of     output binary floats\n");
+printf("          -og     output ASCII\n");
+printf("          -spNNNN output only parameter number NNNN\n");
+printf("          -slNNNN output only level NNNN\n");
+printf("          -stNNNN output only forecast time NNNN\n");
+printf("          -sNNNN  where NNNN is the maximum number of bytes to skip between GRIB messages (default is 1000)\n");
+printf("          -hnmc   SPECIAL OPTION for NCEP (before the name change from NMC)\n\n");
+printf("   Example:\n\n");
+printf("   gribscan -gd -bd -d -i mygrib.data\n");
+
+}
+
+char *gxgsym(char *ch) {
+  return (getenv(ch));
+}
+
+
diff --git a/src/gs.h b/src/gs.h
new file mode 100644
index 0000000..553ff5e
--- /dev/null
+++ b/src/gs.h
@@ -0,0 +1,184 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#define RSIZ 3600  /* increased from 600 in version 1.9 */
+
+/* One of these gets allocated for each record in the file */
+
+/* Record types:
+                  1 - statement
+                  2 - assignment
+                  3 - while
+                  4 - endwhile
+                  5 - continue
+                  6 - break
+                  7 - if
+                  8 - else
+                  9 - endif
+                  10 - return
+                  11 - function  */
+
+struct gsrecd {
+  struct gsrecd *forw;  /* Link list pointer */
+  struct gsrecd *refer; /* Position of end of code block */
+  struct gsfdef *pfdf;  /* Pointer to file def for this record */
+  char *pos;            /* Start of record */
+  char *epos;           /* Position of start of expression, if any */
+  gaint num;              /* Record number in file */
+  gaint type;             /* Record type */
+};
+
+/* Following structure describes a file that has been read in
+   to become part of the running script.  */
+
+struct gsfdef {
+  struct gsfdef *forw;  /* Link list pointer */
+  struct gsrecd *precd; /* Record descriptor for start of this file */
+  char *name;           /* Text name of the file  */
+  char *file;           /* The contents of the file */
+};
+
+/* Following structure is a member of a link list providing the
+   current value of a variable.    */
+
+struct gsvar {
+  struct gsvar *forw;      /* Forward pointer             */
+  char name[16];           /* Variable name               */
+  char *strng;             /* Value of variable           */
+};
+
+/* Following structure is a member of a link list pointing to
+   all the functions contained within a file.  */
+
+struct gsfnc {
+  struct gsfnc *forw;      /* Forward pointer */
+  struct gsrecd *recd;     /* Record block for function   */
+  char name[16];           /* Name of function            */
+};
+
+/* Following structure hold information on open files
+   accessed via the read/write/close user callable functions */
+
+struct gsiob {
+  struct gsiob *forw;      /* Forward pointer  */
+  FILE *file;              /* File pointer     */
+  char *name;              /* File name        */
+  gaint flag;                /* Status flag: 1-read 2-write  */
+};
+
+/* Following structure holds global pointers needed by all the
+   gs routines, and anchors most global memory allocations */
+
+struct gscmn {
+  struct gsfdef *ffdef;    /* Head of input file link list */
+  struct gsfdef *lfdef;    /* Last in chain of input files */
+  struct gsrecd *frecd;    /* Head of record descriptor link list */   
+  struct gsrecd *lrecd;    /* Last in record list list */
+  struct gsvar *fvar;      /* Head of variable linklist   */
+  struct gsfnc *ffnc;      /* Head of function list       */
+  struct gsiob *iob;       /* Head of file I/O list       */
+  struct gsvar *gvar;      /* Head of global var list     */
+  struct gsvar *farg;      /* Pointer to function arglist */
+  char *fname;             /* Pointer to user-entered file name   */
+  char *fprefix;           /* File name prefix for loading functions */
+  char *ppath;             /* Private path for gsf loads */
+  char *rres;              /* Pointer to function result  */
+  char *gsfnm;             /* Most recent file name read in */
+  gaint gsfflg;              /* Dynamic load script functions from files */
+  gaint rc;                  /* Exit value                  */
+};
+
+/* Operator codes:  ordered by precedence
+
+                    1: |   logical or
+                    2: &   logical and
+                    3: =   equality
+                    4: !=  not equal
+                    5: >   greater than
+                    6: >=  greater than or equal
+                    7: <   less than
+                    8: <=  less than or equal
+                    9: %   concatenation
+                   10: +   addition
+                   11: -   subtraction
+                   12: *   multiplication
+                   13: /   division
+                   14: !   unary not
+                   15: -   unary minus                        */
+
+char *opchars[13] = {"!=",">=","<=","|","&","=",">","<","%",
+       "+","-","*","/"};
+gaint opvals[13] = {4,6,8,1,2,3,5,7,9,10,11,12,13};
+gaint optyps[15] = {0,0,1,1,1,1,1,1,0,2,2,2,2,0,2};
+gaint opmins[7] = {14,12,10,9,3,2,1};
+gaint opmaxs[7] = {15,13,11,9,8,2,1};
+
+/* Stack to evaluate the expression.  The stack consists of an
+   doubly linked list of structures.                              */
+
+struct stck {
+  struct stck *pforw;               /* Forward Pointer  */
+  struct stck *pback;               /* Backwards Pointer */
+  gaint type;        /* Entry type: 0=oprnd,1=oprtr,2='(',3=')'        */
+  union tobj {
+    gaint op;                         /* Operator */
+    char *strng;                    /* Operand  */
+  } obj;
+};
+
+/* Function prototypes */
+
+void gsfree (struct gscmn *);
+struct gsrecd *gsrtyp (char **, gaint *, gaint *);
+gaint gsblck (struct gsrecd *, struct gscmn *);
+struct gsrecd *gsbkst (struct gsrecd *, struct gsrecd *,
+     struct gsrecd *, gaint *);
+struct gsrecd *gsbkdo (struct gsrecd *, struct gsrecd *,
+     struct gsrecd *, gaint *);
+struct gsrecd *gsbkif (struct gsrecd *, struct gsrecd *,
+     struct gsrecd *, gaint *);
+gaint gsrunf (struct gsrecd *, struct gscmn *);
+void gsfrev (struct gsvar *);
+struct gsrecd *gsruns (struct gsrecd *, struct gscmn *, gaint *);
+struct gsrecd *gsrund (struct gsrecd *, struct gscmn *, gaint *);
+struct gsrecd *gsruni (struct gsrecd *, struct gscmn *, gaint *);
+gaint gsstmn (struct gsrecd *, struct gscmn *);
+gaint gsassn (struct gsrecd *, struct gscmn *);
+char *gsexpr (char *, struct gscmn *);
+struct stck *gseval (struct stck *);
+char *gscnst (char **);
+char *gsgopd (char **, struct gscmn *);
+char *gsfunc (char *, char *, struct gscmn *);
+char *gsfvar (char *, struct gscmn *);
+gaint gsrvar (struct gscmn *, char *, char *);
+void stkdmp (struct stck *);
+void gsnum (char *, gaint *, gaint *, gadouble *);
+struct stck *gsoper (struct stck *);
+
+/* Functions for searching and reading script files */
+
+gaint gsgsfrd (struct gscmn *, gaint, char *);
+FILE *gsonam (struct gscmn *, struct gsfdef *);
+FILE *gsogsf(struct gscmn *, struct gsfdef *, char *);
+char *gsstcp (char *);
+gaint gsdelim (char);
+char *gsstad (char *, char *);
+
+/* script functions */
+
+gaint gsfsub (struct gscmn *);
+gaint gsfwrd (struct gscmn *);
+gaint gsflin (struct gscmn *);
+gaint gsfpwd (struct gscmn *);
+gaint gsfrd (struct gscmn *);
+gaint gsfwt (struct gscmn *);
+gaint gsfcl (struct gscmn *);
+gaint gsfval (struct gscmn *);
+gaint gsfsln (struct gscmn *);
+gaint gsflog (struct gscmn *, gaint);
+
+gaint gsstmt (struct gsrecd *, struct gscmn *); 
+gaint gsfallw (struct gscmn *);
+gaint gsfpath (struct gscmn *);
+gaint gsfmath (struct gscmn *, gaint);
diff --git a/src/gscrpt.c b/src/gscrpt.c
new file mode 100644
index 0000000..9a113c3
--- /dev/null
+++ b/src/gscrpt.c
@@ -0,0 +1,3641 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* This file contains the routines that implement the GrADS scripting
+   language.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "grads.h"
+#include "gs.h"
+
+static char *rcdef = "rc              ";
+static char *redef = "result          ";
+
+/*  Execute a script, from one or more files. 
+    Beware: various levels of recursion are used.     */
+
+char *gsfile (char *cmd, gaint *retc, gaint impp) {
+struct gsvar *parg;
+struct gscmn *pcmn;
+char *ch,*fname,*res;
+gaint len,rc,i;
+
+  /* Point to (and delimit) the file name from the cmd line */
+
+  while (*cmd==' ') cmd++;
+  fname = cmd;
+  while (*cmd!=' '&& *cmd!='\0'&&*cmd!='\n') cmd++;
+  if (*cmd=='\n') *cmd = '\0';
+  else if (*cmd==' ') {
+    *cmd = '\0';
+    cmd++;
+    while (*cmd==' ') cmd++;
+  }
+
+  /* Allocate the common structure; this anchors most allocated
+     memory for executing this script */
+
+  pcmn = (struct gscmn *)malloc(sizeof(struct gscmn));
+  if (pcmn==NULL) {
+    printf ("Error executing script file: --> %s <--\n",fname);
+    printf ("  Memory allocation error \n");
+    *retc = 1;
+    return(NULL);
+  }
+  pcmn->ffdef = NULL;
+  pcmn->lfdef = NULL;
+  pcmn->frecd = NULL;
+  pcmn->lrecd = NULL;
+  pcmn->fvar = NULL;
+  pcmn->ffnc = NULL;
+  pcmn->iob = NULL;
+  pcmn->gvar = NULL;
+  pcmn->farg = NULL;
+  pcmn->fname = fname;  /* Don't free this later */
+  pcmn->fprefix = NULL;
+  pcmn->ppath = NULL;
+  pcmn->rres = NULL;
+  pcmn->gsfflg = 0;   /* No dynamic functions by default.
+                         The gsfallow function controls this. */
+  res = NULL;
+
+  /* Open, read, and scan the script file. */
+  
+  rc = gsgsfrd (pcmn,0,fname);
+
+  if (rc) {
+    gsfree(pcmn);
+    if (rc==9) {
+      if (impp) {      /* This should be handled by caller -- fix later */
+        gaprnt (0,"Unknown command: ");
+        gaprnt (0,fname);
+        gaprnt (0,"\n");
+      } else {
+        printf ("Error opening script file: %s\n",fname);
+      }
+    }
+    *retc = 1;
+    return(NULL);
+  }
+
+  /* Get ready to start executing the script.
+     Allocate a var block and provide arg string */
+
+  parg = (struct gsvar *)malloc(sizeof(struct gsvar));
+  if (parg==NULL) {
+    printf ("Memory allocation error:  Script variable buffering\n");
+    goto retrn;
+  }
+  parg->forw = NULL;
+  ch = cmd;
+  len = 0;
+  while (*(ch+len)!='\0' && *(ch+len)!='\n') len++;
+  parg->strng = (char *)malloc(len+1);
+  if (parg->strng==NULL) {
+    printf ("Memory allocation error:  Script variable buffering\n");
+    free (parg);
+    goto retrn;
+  }
+  for (i=0; i<len; i++) *(parg->strng+i) = *(ch+i);
+  *(parg->strng+len) = '\0';
+  pcmn->farg = parg;
+
+  /* Execute the main function. */
+
+  rc = gsrunf(pcmn->frecd, pcmn);
+  res = pcmn->rres;
+  if (rc==999) rc = -1;
+
+  /*  We are done.  Return.  */
+
+retrn:
+  gsfree (pcmn);
+  *retc = rc;
+  return (res);
+}
+
+/* Free gscmn and associated storage */
+
+void gsfree (struct gscmn *pcmn) {
+struct gsfdef *pfdf, *tfdf;
+struct gsrecd *precd, *trecd;
+struct gsfnc *pfnc, *tfnc;
+struct gsiob *piob, *tiob;
+
+  pfdf = pcmn->ffdef;
+  while (pfdf) {
+    tfdf = pfdf->forw;
+    if (pfdf->name) free(pfdf->name);
+    if (pfdf->file) free(pfdf->file);
+    free (pfdf);
+    pfdf = tfdf;
+  }
+  gsfrev(pcmn->gvar);
+  gsfrev(pcmn->fvar);
+  precd = pcmn->frecd; 
+  while (precd) {
+    trecd = precd->forw;
+    free (precd);
+    precd = trecd;
+  }
+  pfnc = pcmn->ffnc;
+  while (pfnc) {
+    tfnc = pfnc->forw;
+    free (pfnc);
+    pfnc = tfnc;
+  }
+  piob = pcmn->iob;
+  while (piob) {
+    fclose (piob->file);
+    free (piob->name);
+    tiob = piob->forw;
+    free (piob);
+    piob = tiob;
+  }
+  if (pcmn->fprefix) free(pcmn->fprefix);
+  if (pcmn->ppath) free(pcmn->ppath);
+  free (pcmn);
+}
+
+/* Read in the main script or a script function (.gsf)
+   and scan the contents, adding to the chain of 
+   recd descriptors if appropriate.  
+   When lflag is zero we are reading the main script; 
+   when 1 we are handling a .gsf file (and the name of
+   the function is provided as pfnc.
+
+   return codes:  0:  normal
+                  1:  error; message already printed
+                  9:  couldn't open file; message not yet printed */
+   
+gaint gsgsfrd (struct gscmn *pcmn, gaint lflag, char *pfnc) {
+struct gsfdef *pfdf, *tfdf; 
+struct gsrecd *rectmp, *reccur=NULL;
+char *sfile,*fpos,*ch;
+FILE *ifile;
+gaint rc,flen,len,reccnt,first;
+
+  /* First allocate a gsfdef file, and chain it off of
+     gscmn.  Gets freed at end of script execution; we are
+     careful to set NULLS so things are freed properly
+     if an error occurs and execution falls thru. */ 
+
+  pfdf = (struct gsfdef *)malloc(sizeof(struct gsfdef));
+  if (pfdf==NULL) {
+    printf ("Memory allocation error:  script initialization\n");
+    return (1);
+  }
+
+  if (pcmn->ffdef==NULL) pcmn->ffdef = pfdf;
+  else {
+    tfdf = pcmn->ffdef;
+    while (tfdf->forw) tfdf = tfdf->forw;
+    tfdf->forw = pfdf;
+  }
+  pfdf->forw = NULL;
+  pfdf->name = NULL;
+  pfdf->file = NULL;
+
+  pcmn->lfdef = pfdf;
+
+  /* Open the file */
+
+  if (lflag==0) {
+    ifile = gsonam(pcmn, pfdf);
+  } else {
+    ifile = gsogsf(pcmn, pfdf, pfnc);
+  }
+
+  if (ifile==NULL) return (9);
+
+  /* Read in the file */
+
+  fseek(ifile,0L,2);
+  flen = ftell(ifile);
+  fseek(ifile,0L,0);
+
+  sfile = (char *)malloc(flen+1);
+  if (sfile==NULL) {
+    printf ("Error executing script file: %s\n",pfdf->name);
+    printf ("  Unable to allocate memory for file read\n");
+    return(1);
+  }
+
+  len = flen;
+  fpos = sfile;
+  while (len>511) {
+    rc = fread(fpos,1,512,ifile);
+    if (rc!=512) {
+      printf ("I/O Error reading script file: %s\n",pfdf->name);
+      free (sfile);
+      return (1);
+    }
+    fpos+=512;
+    len-=512;
+  }
+  rc = fread(fpos,1,len,ifile);
+  if (rc!=len) {
+    printf ("I/O Error reading script file: %s\n",pfdf->name);
+    printf ("  Return code = %i, %i\n",rc, len);
+    free (sfile);
+    return (1);
+  }
+  fclose (ifile);
+  *(sfile+flen) = '\0';
+
+  /* Remove cr for PC version */
+
+  ch = sfile;
+  while (*ch!='\0') {
+    if ((gaint)(*ch)==13) *ch = ' ';
+    if ((gaint)(*ch)==10) fpos = ch;
+    ch++;
+  }
+  flen = (fpos-sfile) + 1;
+  *(sfile+flen) = '\0';
+
+  /* Above for pc version */
+
+  pfdf->file = sfile;
+
+  /* Build link list of record descriptor blocks.
+     Append to existing list if handling a .gsf */
+
+  first = 1;
+  fpos = sfile;
+  reccnt = 1;
+  while (fpos-sfile<flen) {
+    rectmp = gsrtyp (&fpos,&reccnt,&rc);
+    if (rc) return (1); 
+    if (rectmp!=NULL) {
+      if (pcmn->frecd==NULL) {
+        pcmn->frecd = rectmp;
+        pfdf->precd = rectmp;
+        reccur = rectmp;
+        first = 0;
+      } else {
+        if (first) {
+          reccur = pcmn->lrecd;
+          pfdf->precd = rectmp;
+          first = 0;
+        }
+        reccur->forw = rectmp;
+        reccur = rectmp;
+      }
+      reccur->forw = NULL;
+      reccur->pfdf = pfdf;
+    }
+  }
+  pcmn->lrecd = reccur;
+
+  /* Resolve flow-control blocks */
+
+  rc = gsblck (pfdf->precd, pcmn);
+  if (rc) return(1);  
+
+  return(0);
+}
+
+/* Determine what kind of record in the script file we have,
+   and fill in a record descriptor block.                  */
+
+struct gsrecd *gsrtyp (char **ppos, gaint *reccnt, gaint *rc) {
+char *fpos,*pos;
+struct gsrecd *recd;
+char ch[20];
+gaint i, eflg, cflg;
+
+   /* Ignore comments */
+
+   fpos = *ppos;
+   if (*fpos=='*' || *fpos=='#') {
+     while (*fpos!='\n') fpos++;
+     fpos++;
+     *ppos = fpos;
+     *rc = 0;
+     *reccnt = *reccnt+1;
+     return (NULL);
+   }
+
+   /* Ignore blank lines */
+
+   while (*fpos==' ') fpos++;
+   if (*fpos=='\n' || *fpos==';') {
+     if (*fpos=='\n') *reccnt = *reccnt+1;
+     fpos++;
+     *ppos = fpos;
+     *rc = 0;
+     return (NULL);
+   }
+
+   /* We found something, so allocate a descriptor block */
+
+   recd = (struct gsrecd *)malloc(sizeof(struct gsrecd));
+   if (recd==NULL) {
+     printf ("Memory allocation error: script scan\n");
+     *rc = 1;
+     return(NULL);
+   }
+   recd->forw = NULL;
+   recd->pos = fpos;
+   recd->num = *reccnt;
+   recd->refer = NULL;
+
+   /* Check for assignment statement first */
+
+   eflg = 0;
+   recd->epos = NULL;
+   pos = fpos;
+   recd->type = -9;
+   if ((*pos>='a'&&*pos<='z')||(*pos>='A'&&*pos<='Z')||*pos=='_') {
+     while ( (*pos>='a' && *pos<='z') ||
+             (*pos>='A' && *pos<='Z') ||
+             (*pos=='.') || (*pos=='_') ||
+             (*pos>='0' && *pos<='9') ) pos++;
+     while (*pos==' ') pos++;
+     if (*pos=='=') {
+       recd->type = 2;
+       fpos = pos+1;
+       eflg = 1;
+     }
+   }
+
+   /* Check for other keywords:  if, while, etc.  */
+
+   if (recd->type!=2) {
+     i = 0;
+     while (*(fpos+i)!='\n' && *(fpos+i)!=';' && i<9) {
+       ch[i] = *(fpos+i);
+       i++;
+     }
+     ch[i] = '\0';
+     lowcas(ch);
+
+     if (cmpwrd(ch,"if")||!cmpch(ch,"if(",3)) {
+       fpos+=2;
+       eflg = 1;
+       recd->type = 7;
+     } else if (cmpwrd(ch,"else")) {
+       fpos+=4;
+       recd->type = 8;
+     } else if (cmpwrd(ch,"endif")) {
+       fpos+=5;
+       recd->type = 9;
+     } else if (cmpwrd(ch,"while")||!cmpch(ch,"while(",6)) {
+       fpos+=5;
+       eflg = 1;
+       recd->type = 3;
+     } else if (cmpwrd(ch,"endwhile")) {
+       fpos+=8;
+       recd->type = 4;
+     } else if (cmpwrd(ch,"continue")) {
+       fpos+=8;
+       recd->type = 5;
+     } else if (cmpwrd(ch,"break")) {
+       fpos+=5;
+       recd->type = 6;
+     } else if (cmpwrd(ch,"return")||!cmpch(ch,"return(",7)) {
+       fpos+=6;
+       recd->type = 10;
+       eflg = 1;
+     } else if (cmpwrd(ch,"function")) {
+       fpos+=8;
+       recd->type = 11;
+       eflg = 1;
+     } else if (cmpwrd(ch,"say")) {
+       fpos+=3;
+       recd->type = 12;
+       eflg = 1;
+     } else if (cmpwrd(ch,"print")) {
+       fpos+=5;
+       recd->type = 12;
+       eflg = 1;
+     } else if (cmpwrd(ch,"prompt")) {
+       fpos+=6;
+       recd->type = 15;
+       eflg = 1;
+     } else if (cmpwrd(ch,"pull")) {
+       fpos+=4;
+       recd->type = 13;
+       eflg = 1;
+     } else if (cmpwrd(ch,"exit")) {
+       fpos+=4;
+       recd->type = 14;
+       eflg = 1;
+     } else {
+       recd->type = 1;
+       recd->epos = fpos;
+     }
+   }
+
+   /* Locate expression */
+
+   if (eflg) {
+     while (*fpos==' ') fpos++;
+     if (*fpos=='\n' || *fpos==';') {
+       recd->epos = NULL;
+     } else recd->epos = fpos;
+   }
+
+   /* Advance to end of record */
+
+   cflg = 0;
+   while (1) {
+     if (!cflg && *fpos==';') break;
+     if (*fpos=='\n') break;
+     if (*fpos =='\'') {
+       if (cflg==1) cflg = 0;
+       else if (cflg==0) cflg = 1;
+     } else if (*fpos=='\"') {
+       if (cflg==2) cflg = 0;
+       else if (cflg==0) cflg = 2;
+     }
+     fpos++;
+   }
+
+   /* Remove trailing blanks */
+
+   pos = fpos-1;
+   while (*pos==' ') {*pos='\0'; pos--;}
+
+   /* Finish building rec block and return */
+
+   if (*fpos=='\n') *reccnt = *reccnt + 1;
+   *fpos = '\0';
+   fpos++;
+   *ppos = fpos;
+   *rc = 0;
+   return (recd);
+}
+
+/*  Resolve flow-control blocks.  Scan each function
+    seperately.                                      */
+
+gaint gsblck (struct gsrecd *recd, struct gscmn *pcmn) {
+struct gsfnc *pfnc,*prev,*cfnc;
+gaint rc,i;
+char *fch;
+
+  /* Loop looking at statements.  If a function definition, allocate a
+     function block and chain it.   */
+
+  while (recd) {
+    recd = gsbkst (recd, NULL, NULL, &rc);
+    if (rc) return(rc);
+
+    /* If a function, allocate a function block */
+
+    if (recd!=NULL && recd->type==11) {
+      pfnc = (struct gsfnc *)malloc(sizeof(struct gsfnc));
+      if (pfnc==NULL) {
+        printf ("Error allocating memory: script scan\n");
+        return(1);
+      }
+
+      /* Chain it */
+
+      if (pcmn->ffnc==NULL) {
+        pcmn->ffnc = pfnc;
+      } else {
+        cfnc = pcmn->ffnc;
+        while (cfnc) {
+          prev = cfnc;
+          cfnc = cfnc->forw;
+        }
+        prev->forw = pfnc;
+      }
+      pfnc->forw = NULL;
+
+      /* Fill it in */
+
+      pfnc->recd = recd;
+      for (i=0; i<16; i++) pfnc->name[i]=' ';
+      fch = recd->epos;
+      if (fch==NULL) goto err;
+      if ((*fch>='a'&&*fch<='z')||(*fch>='A'&&*fch<='Z')) {
+        i = 0;
+        while ( (*fch>='a'&&*fch<='z') ||
+                (*fch>='A'&&*fch<='Z') ||
+                (*fch>='0'&&*fch<='9') ||
+                 *fch=='_' ) {
+          if (i>15) {
+            printf ("Function name too long\n");
+            goto err;
+          }
+          pfnc->name[i] = *fch;
+          fch++; i++;
+        }
+      } else {
+        printf ("Invalid function name\n");
+        goto err;
+      }
+      while (*fch==' ') fch++;
+      if (*fch==';'||*fch=='\0') recd->epos = NULL;
+      else recd->epos = fch;
+      recd = recd->forw;
+    }
+  }
+  return (0);
+
+err:
+  printf ("Error in %s: Invalid function statement",recd->pfdf->name);
+  printf (" at line %i\n",recd->num);
+  printf ("  In file %s\n",recd->pfdf->name);
+  return (1);
+}
+
+/*  Figure out status of a statement.  Recursively resolve
+    if/then/else and while/endwhile blocks.  Return pointer
+    to next statement (unless a function statement). */
+
+struct gsrecd *gsbkst (struct gsrecd *recd, struct gsrecd *ifblk,
+                                     struct gsrecd *doblk, gaint *rc) {
+gaint ret;
+
+  if (recd->type==3) {
+    recd = gsbkdo(recd->forw, NULL, recd, &ret);
+    if (ret) { *rc = ret; return(NULL);}
+  }
+  else if (recd->type==4) {
+    printf ("Unexpected endwhile.  Incorrect loop nesting.\n");
+    if (ifblk) {
+       printf ("  Expecting endif before endwhile for ");
+       printf ("if statement at line %i\n",ifblk->num);
+    }
+    printf ("  Error occurred scanning line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    *rc = 1;
+    return(NULL);
+  }
+  else if (recd->type==5) {
+    if (doblk==NULL) {
+      printf ("Unexpected continue.  No associated while\n");
+      printf ("  Error occurred scanning line %i\n",recd->num);
+      printf ("  In file %s\n",recd->pfdf->name);
+      printf ("  Statement is ignored\n");
+    }
+    recd->refer = doblk;
+  }
+  else if (recd->type==6) {
+    if (doblk==NULL) {
+      printf ("Unexpected break.  No associated while\n");
+      printf ("  Error occurred scanning line %i\n",recd->num);
+      printf ("  In file %s\n",recd->pfdf->name);
+      printf ("  Statement is ignored\n");
+    }
+    recd->refer = doblk;
+  }
+  else if (recd->type==7) {
+    recd = gsbkif(recd->forw, recd, doblk, &ret);
+    if (ret) { *rc = ret; return(NULL);}
+  }
+  else if (recd->type==8) {
+    printf ("Unexpected else.  Incorrect if block nesting.\n");
+    printf ("  Error occurred scanning line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    *rc = 1;
+    return(NULL);
+  }
+  else if (recd->type==9) {
+    printf ("Unexpected endif.  Incorrect if block nesting.\n");
+    printf ("  Error occurred scanning line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    *rc = 1;
+    return(NULL);
+  }
+  else if (recd->type==11) {
+    *rc = 0;
+    return (recd);
+  }
+  *rc = 0;
+  return (recd->forw);
+}
+
+/* Resolve an while/endwhile block.  Recursively resolve any
+   nested elements. */
+
+struct gsrecd *gsbkdo (struct gsrecd *recd, struct gsrecd *ifblk,
+                                     struct gsrecd *doblk, gaint *rc) {
+gaint ret;
+
+  ret = 0;
+  while (recd!=NULL && recd->type!=4 && recd->type!=11 && ret==0) {
+    recd = gsbkst(recd, ifblk, doblk, &ret);
+  }
+  if (ret==0 && (recd==NULL || recd->type==11)) {
+    printf ("Unable to locate ENDWHILE statement");
+    printf (" for the WHILE statement at line %i\n",doblk->num);
+    printf ("  In file %s\n",doblk->pfdf->name);
+    *rc = 1;
+    return(NULL);
+  }
+  *rc = ret;
+  if (ret==0) {
+    recd->refer = doblk;
+    doblk->refer = recd;
+    return (recd);
+  } else return(NULL);
+}
+
+/*  Resolve if/else/endif block */
+
+struct gsrecd *gsbkif (struct gsrecd *recd, struct gsrecd *ifblk,
+                                     struct gsrecd *doblk, gaint *rc) {
+gaint ret,eflg;
+struct gsrecd *elsblk=NULL;
+
+  eflg = 0;
+  ret = 0;
+  while (recd!=NULL && recd->type!=11 && recd->type!=9 && ret==0) {
+    if (recd->type==8 && eflg==0) {
+      elsblk = recd;
+      eflg = 1;
+      recd = recd->forw;
+    } else recd = gsbkst(recd, ifblk, doblk, &ret);
+  }
+  if (ret==0 && (recd==NULL || recd->type==11)) {
+    printf ("Unable to locate ENDIF statement");
+    printf (" for the IF statement at line %i\n",ifblk->num);
+    printf ("  In file %s\n",ifblk->pfdf->name);
+    *rc = 1;
+    return(NULL);
+  }
+  *rc = ret;
+  if (ret==0) {
+    recd->refer = ifblk;
+    if (eflg) {
+      ifblk->refer = elsblk;
+      elsblk->refer = recd;
+    } else {
+      ifblk->refer = recd;
+    }
+    return (recd);
+  } else return(NULL);
+}
+
+/* Execute the function pointed to by recd and with the
+   arguments pointed to by farg in pcmn */
+
+gaint gsrunf (struct gsrecd *recd, struct gscmn *pcmn) {
+struct gsvar *fvar, *tvar, *avar, *nvar, *svar;
+gaint i, ret, len;
+char fnm[20],*ch;
+
+  svar = pcmn->fvar;     /* Save caller's args  */
+  avar = NULL;           /* Create new arg list */
+
+  /* First two variables in var list are rc and result */
+
+  fvar = NULL;
+  fvar = (struct gsvar *)malloc(sizeof(struct gsvar));
+  if (fvar==NULL) goto merr;
+  fvar->forw = NULL;
+  for (i=0; i<16; i++) fvar->name[i] = *(rcdef+i);
+  fvar->strng = (char *)malloc(1);
+  if (fvar->strng==NULL) goto merr;
+  *(fvar->strng) = '\0';
+
+  tvar = (struct gsvar *)malloc(sizeof(struct gsvar));
+  if (tvar==NULL) goto merr;
+  tvar->forw = NULL;
+  fvar->forw = tvar;
+  for (i=0; i<16; i++) tvar->name[i] = *(redef+i);
+  tvar->strng = (char *)malloc(1);
+  if (tvar->strng==NULL) goto merr;
+  *(tvar->strng) = '\0';
+
+  /* If the recd is a function record, check the prototype
+     list to assign variables.  Add these variables to
+     the variable list */
+
+  avar = pcmn->farg;
+  if (recd->type==11 && recd->epos) {
+    ch = recd->epos;
+    if (*ch!='(') goto argerr;
+    ch++;
+    while (1) {
+      while (*ch==' ') ch++;
+      if (*ch==')') break;
+      if ((*ch>='a'&&*ch<='z') || (*ch>='A'&&*ch<='Z')) {
+        len = 0;
+        for (i=0; i<16; i++) fnm[i] = ' ';
+        while ( (*ch>='a' && *ch<='z') ||
+                (*ch>='A' && *ch<='Z') ||
+                (*ch=='.') || (*ch=='_') ||
+                (*ch>='0' && *ch<='9') ) {
+          fnm[len] = *ch;
+          len++; ch++;
+          if (len>15) goto argerr;
+        }
+      } else goto argerr;
+      if (avar) {
+        nvar = avar;
+        avar = avar->forw;
+      } else {
+        nvar = (struct gsvar *)malloc(sizeof(struct gsvar));
+        if (nvar==NULL) goto merr;
+        nvar->strng = (char *)malloc(len+1);
+        if (nvar->strng==NULL) {
+          free(nvar);
+          goto merr;
+        }
+        for (i=0; i<len; i++) *(nvar->strng+i) = fnm[i];
+        *(nvar->strng+len) = '\0';
+      }
+      for (i=0; i<16; i++) nvar->name[i] = fnm[i];
+      tvar->forw = nvar;
+      nvar->forw = NULL;
+      tvar = nvar;
+      while (*ch==' ') ch++;
+      if (*ch==')') break;
+      if (*ch==',') ch++;
+    }
+  }
+
+  /* If the calling arg list was too long, discard the
+     unused var blocks */
+
+  gsfrev (avar);
+
+  /* Execute commands until we are done.  Flow control is
+     handled recursively. */
+
+  pcmn->fvar = fvar;
+  pcmn->rc = 0;
+  ret = 0;
+  if (recd->type==11) recd = recd->forw;
+  while (recd && ret==0) {
+    recd = gsruns(recd, pcmn, &ret);
+  }
+  if (ret==1 || ret==2) {
+    printf ("Error in gsrunf:  Internal Logic Check 8\n");
+    ret = 1;
+  } else if (ret==3) ret=0;
+  gsfrev (fvar);
+  pcmn->fvar = svar;       /* Restore caller's arg list */
+  return (ret);
+
+merr:
+
+  printf ("Error allocating variable memory\n");
+  gsfrev(fvar);
+  gsfrev(avar);
+  pcmn->fvar = svar;
+  return (99);
+
+argerr:
+
+  printf ("Error:  Invalid function list\n");
+  printf ("  Error occurred on line %i\n",recd->num);
+  printf ("  In file %s\n",recd->pfdf->name);
+  gsfrev(fvar);
+  gsfrev(avar);
+  pcmn->fvar = svar;
+  return (99);
+}
+
+/* Free a link list of variable blocks */
+
+void gsfrev (struct gsvar *var) {
+struct gsvar *nvar;
+
+  while (var) {
+    nvar = var->forw;
+    if (var->strng) free (var->strng);
+    free (var);
+    var = nvar;
+  }
+}
+
+/* Execute a statement in the scripting language */
+
+struct gsrecd *gsruns (struct gsrecd *recd, struct gscmn *pcmn, gaint *rc) {
+gaint ret, ntyp;
+gaint lv;
+gadouble vv;
+char *res;
+
+  if (gaqsig()) {
+    *rc = 99;
+    return (NULL);
+  }
+
+  /* Statement */
+
+  if (recd->type==1) {
+    *rc = gsstmt (recd, pcmn);
+    return (recd->forw);
+  }
+
+  /* Assignment */
+
+  else if (recd->type==2) {
+    *rc = gsassn (recd, pcmn);
+    return (recd->forw);
+  }
+
+  /* While */
+
+  else if (recd->type==3) {
+    recd = gsrund (recd, pcmn, &ret);
+    *rc = ret;
+    return (recd);
+  }
+
+  /* Endwhile */
+
+  else if (recd->type==4) {
+    printf ("Error in gsruns:  Internal Logic Check 8\n");
+    *rc = 99;
+    return (NULL);
+  }
+
+  /* Continue */
+
+  else if (recd->type==5) {
+    if (recd->refer) {
+      *rc = 1;
+      return (NULL);
+    }
+  }
+
+  /* Break */
+
+  else if (recd->type==6) {
+    if (recd->refer) {
+      *rc = 2;
+      return (NULL);
+    }
+  }
+
+  /* If */
+
+  else if (recd->type==7) {
+    recd = gsruni (recd, pcmn, &ret);
+    *rc = ret;
+    return (recd);
+  }
+
+  /* Else */
+
+  else if (recd->type==8) {
+    printf ("Error in gsruns:  Internal Logic Check 12\n");
+    *rc = 99;
+    return (NULL);
+  }
+
+  /* Endif */
+
+  else if (recd->type==9) {
+    printf ("Error in gsruns:  Internal Logic Check 16\n");
+    *rc = 99;
+    return (NULL);
+  }
+
+  /* Return */
+
+  else if (recd->type==10) {
+    if (recd->epos) {
+      pcmn->rres = gsexpr(recd->epos, pcmn);
+      if (pcmn->rres==NULL) {
+        printf ("  Error occurred on line %i\n",recd->num);
+        printf ("  In file %s\n",recd->pfdf->name);
+        *rc = 99;
+        return (NULL);
+      }
+    } else pcmn->rres = NULL;
+    *rc = 3;
+    return (NULL);
+  }
+
+  /* Function statement (ie, implied return) */
+
+  else if (recd->type==11) {
+    pcmn->rres = NULL;
+    *rc = 3;
+    return (NULL);
+  }
+
+  /* 'say' command */
+
+  else if (recd->type==12 || recd->type==15) {
+    if (recd->epos) res = gsexpr(recd->epos, pcmn);
+    else {
+      printf ("\n");
+      *rc = 0;
+      return (recd->forw);
+    }
+    if (res==NULL) {
+      printf ("Error occurred on line %i\n",recd->num);
+      printf ("  In file %s\n",recd->pfdf->name);
+      *rc = 99;
+      return (NULL);
+    }
+    if (recd->type==12) printf ("%s\n",res);
+    else printf ("%s",res);
+    free (res);
+    return (recd->forw);
+  }
+
+  /* Pull command */
+
+  else if (recd->type==13) {
+    *rc = gsassn (recd, pcmn);
+    return (recd->forw);
+  }
+
+  /* Exit command */
+
+  else if (recd->type==14) {
+    if (recd->epos) {
+      res = gsexpr(recd->epos, pcmn);
+      if (res==NULL) {
+        printf ("  Error occurred on line %i\n",recd->num);
+        printf ("  In file %s\n",recd->pfdf->name);
+        *rc = 99;
+        return (NULL);
+      }
+      gsnum (res, &ntyp, &lv, &vv);
+      if (ntyp!=1) {
+        printf ("Error on Exit Command:  Non Integer Argument\n");
+        printf ("  Error occurred on line %i\n",recd->num);
+        printf ("  In file %s\n",recd->pfdf->name);
+        *rc = 99;
+        return (NULL);
+      }
+      pcmn->rc = lv;
+      free (res);
+    } else {
+      pcmn->rc = 0;
+    }
+    *rc = 4;
+    return (NULL);
+  }
+
+  /* Anything else? */
+
+  else {
+    printf ("Error in gsruns:  Internal Logic Check 16\n");
+    *rc = 99;
+    return (NULL);
+  }
+  return (NULL);
+}
+
+/*  Execute a while loop */
+
+struct gsrecd *gsrund (struct gsrecd *recd, struct gscmn *pcmn, gaint *rc) {
+struct gsrecd *dorec;
+gaint ret;
+char *rslt;
+
+
+  rslt = gsexpr(recd->epos, pcmn);
+  if (rslt==NULL) {
+    printf ("  Error occurred on line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    *rc = 99;
+    return (NULL);
+  }
+  dorec = recd;
+
+  ret = 0;
+  while (*rslt!='0' || *(rslt+1)!='\0') {
+    recd = dorec->forw;
+    ret = 0;
+    while (ret==0 && recd->type!=4) {
+      recd = gsruns (recd, pcmn, &ret);
+    }
+    if (ret>1) break;
+    free(rslt);
+    rslt = gsexpr(dorec->epos, pcmn);
+    if (rslt==NULL) {
+      printf ("  Error occurred on line %i\n",recd->num);
+      printf ("  In file %s\n",recd->pfdf->name);
+      *rc = 99;
+      return (NULL);
+    }
+  }
+  free(rslt);
+  if (ret<3) ret=0;
+  *rc = ret;
+  recd = dorec->refer;
+  return (recd->forw);
+}
+
+/*  Execute an if block */
+
+struct gsrecd *gsruni (struct gsrecd *recd, struct gscmn *pcmn, gaint *rc) {
+gaint ret;
+char *rslt;
+
+  rslt = gsexpr(recd->epos, pcmn);
+  if (rslt==NULL) {
+    printf ("  Error occurred on line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    *rc = 99;
+    return (NULL);
+  }
+
+  if (*rslt=='0' && *(rslt+1)=='\0') recd = recd->refer;
+  free (rslt);
+
+  if (recd->type != 9) {
+    recd = recd->forw;
+    ret = 0;
+    while (ret==0 && recd->type!=8 && recd->type!=9) {
+      recd = gsruns (recd, pcmn, &ret);
+    }
+    if (ret) {
+      *rc = ret;
+      return (NULL);
+    }
+    if (recd->type==8) recd = recd->refer;
+  }
+  *rc = 0;
+  return (recd->forw);
+}
+
+/* Execute a statement that is to be passed to the program
+   environment, and get a response back. */
+
+gaint gsstmt (struct gsrecd *recd, struct gscmn *pcmn) {
+struct gsvar *pvar;
+gaint rc;
+char *res, *buf, *tmp;
+
+  res = gsexpr (recd->epos, pcmn);
+  if (res==NULL) {
+    printf ("  Error occurred on line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    return(99);
+  }
+
+  /* Execute the command */
+
+  buf = gagsdo (res, &rc);
+  free (res);
+
+  /* We want to reflect the quit command back to the scripting
+     language so we really do quit.  */
+
+  if (rc==-1) {
+    if (buf) free(buf);
+    return (999);
+  }
+
+  /* Put the return code and command response into the appropriate
+     variables.  We ASSUME that rc and result are variables that
+     are at the start of the link list. */
+
+  pvar = pcmn->fvar;
+  tmp = (char *)malloc(6);
+  if (tmp==NULL) {
+    printf ("Memory allocation error\n");
+    if (buf) free (buf);
+    return (99);
+  }
+  snprintf(tmp,5,"%i",rc);
+  free (pvar->strng);
+  pvar->strng = tmp;
+
+  pvar = pvar->forw;
+  if (buf==NULL) {
+    tmp = (char *)malloc(1);
+    if (tmp==NULL) {
+      printf ("Memory allocation error\n");
+      return (99);
+    }
+    *tmp = '\0';
+  } else tmp = buf;
+  free (pvar->strng);
+  pvar->strng = tmp;
+  return(0);
+}
+
+/* Execute an assignment or pull command*/
+
+gaint gsassn (struct gsrecd *recd, struct gscmn *pcmn) {
+struct gsvar *var, *pvar=NULL;
+gaint rc,i,flg;
+char *res, *pos;
+char varnm[16];
+
+  /* Evaluate expression or read user input */
+
+  if (recd->type==13) {
+    res = (char *)malloc(RSIZ);
+    if (res==NULL) {
+      printf ("Memory allocation Error\n");
+      return (99);
+    }
+    for (i=0; i<10; i++) *(res+i) = '\0';
+    fgets(res,512,stdin);
+    /* Replace newline character or return character at end of user input string with null */
+    for (i=0; i<512; i++) {
+/*       if (*(res+i) == '\n') *(res+i)='\0';  */
+      if ((*(res+i) == '\n') || (*(res+i) == '\r')) *(res+i)='\0';   
+    }
+  } else {
+    res = gsexpr (recd->epos, pcmn);
+    if (res==NULL) {
+      printf ("  Error occurred on line %i\n",recd->num);
+      printf ("  In file %s\n",recd->pfdf->name);
+      return (99);
+    }
+  }
+
+  /* Get variable name */
+
+  for (i=0; i<16; i++) varnm[i] = ' ';
+  if (recd->type==13) pos = recd->epos;
+  else pos = recd->pos;
+  i=0;
+  while (*pos!=' ' && *pos!='=' && i<16 && *pos!='\0') {
+    varnm[i] = *pos;
+    pos++; i++;
+  }
+
+  /* Resolve possible compound name. */
+
+  rc = gsrvar (pcmn, varnm, varnm);
+  if (rc) {
+    printf ("  Error occurred on line %i\n",recd->num);
+    printf ("  In file %s\n",recd->pfdf->name);
+    return(99);
+  }
+
+  /* See if this variable name already exists */
+
+  if (varnm[0]=='_') var = pcmn->gvar;
+  else var = pcmn->fvar;
+  if (var==NULL) flg = 1;
+  else flg = 0;
+  while (var) {
+    for (i=0; i<16; i++) {
+      if (varnm[i] != var->name[i]) break;
+    }
+    if (i==16) break;
+    pvar = var;
+    var = var->forw;
+  }
+
+  /* If it didn't, create it.  If it did, release old value */
+
+  if (var==NULL) {
+    var = (struct gsvar *)malloc(sizeof(struct gsvar));
+    if (var==NULL) {
+      printf ("Error allocating memory for variable\n");
+      return (99);
+    }
+    if (flg) {
+      if (varnm[0]=='_' ) pcmn->gvar = var;
+      else pcmn->fvar = var;
+    } else pvar->forw = var;
+    var->forw = NULL;
+    for (i=0; i<16; i++) var->name[i] = varnm[i];
+  } else {
+    free (var->strng);
+  }
+
+  /* Assign new value */
+
+  var->strng = res;
+
+  return(0);
+}
+
+/* Dump stack.  Any member of the list may be passed */
+
+void stkdmp (struct stck *stack) {
+
+  while (stack->pback) stack = stack->pback;
+  while (stack) {
+    if (stack->type==0) {
+      printf ("Operand: %s\n",stack->obj.strng);
+    }
+    else if (stack->type==1) {
+      printf ("Operator: %i \n",stack->obj.op);
+    }
+    else if (stack->type==2) printf ("Left paren '('\n");
+    else if (stack->type==3) printf ("Right paren ')'\n");
+    else printf ("Type = %i \n",stack->type);
+    stack = stack->pforw;
+  }
+}
+
+/* Evaluate an expression in the GrADS scripting language.
+   The expression must be null terminated.  The result string
+   is returned, or if an error occurs, NULL is returned.    */
+
+char *gsexpr (char *expr, struct gscmn *pcmn) {
+struct stck *curr, *snew, *sold;
+char *pos;
+gaint state, uflag, i, flag;
+
+  /* First element on stack is artificial left paren.  We
+     will match with artificial right paren at end of expr
+     to force final expression evaluation.  */
+
+  curr = (struct stck *)malloc(sizeof(struct stck));
+  if (curr==NULL) goto err2;
+  curr->pback = NULL;
+  curr->pforw = NULL;
+  curr->type = 2;
+
+  /* Initial state */
+
+  state = 1;
+  uflag = 0;
+  pos = expr;
+
+  /* Loop while parsing expression.  Each loop iteration deals with
+     the next element of the expression.  Each expression element
+     is pushed onto the expression stack.  When a right paren is
+     encountered, the stack is evaluated back to the matching left
+     paren, with the intermediate result restacked.                 */
+
+  while (1) {
+
+    /* Allocate next link list item so its ready when we need it  */
+
+    snew = (struct stck *)malloc(sizeof(struct stck));
+    if (snew==NULL) goto err2;
+    curr->pforw = snew;
+    sold = curr;
+    curr = snew;
+    curr->pforw = NULL;
+    curr->pback = sold;
+    curr->type = -1;
+
+    /* Advance past any imbedded blanks */
+
+    while (*pos==' ') pos++;
+
+    /* End of expr?  If so, leave loop.  */
+
+    if (*pos=='\0') break;
+
+    /*  The state flag determines what is expected next in the
+        expression.  After an operand, we would expect an operator,
+        for example -- or a ')'.  And after an operator, we would
+        expect an operand, among other things.                      */
+
+    if (state) {                     /* Expect oprnd, unary op, '(' */
+
+      /*  Handle a left paren. */
+
+      if (*pos=='(') {
+        curr->type = 2;
+        pos++;
+        uflag = 0;
+      }
+
+      /* Unary minus */
+
+      else if (*pos=='-') {
+        if (uflag) goto err1;
+        curr->type = 1;
+        curr->obj.op = 15;
+        pos++;
+        uflag = 1;
+      }
+
+      /* Unary not */
+
+      else if (*pos=='!') {
+        if (uflag) goto err1;
+        curr->type = 1;
+        curr->obj.op = 14;
+        pos++;
+        uflag = 1;
+      }
+
+      /*  Handle a constant   */
+
+      else if (*pos=='\"' || *pos=='\'' ||
+               (*pos>='0' && *pos<='9') ) {
+        curr->type = 0;
+        curr->obj.strng = gscnst(&pos);
+        if (curr->obj.strng==NULL) goto err3;
+        state = 0;
+        uflag = 0;
+      }
+
+      /*  Handle a variable or function call */
+
+      else if ( (*pos>='a' && *pos<='z') ||
+                (*pos>='A' && *pos<='Z') ||
+                (*pos=='_')) {
+        curr->type = 0;
+        curr->obj.strng = gsgopd(&pos, pcmn);
+        if (curr->obj.strng==NULL) goto err3;
+        state = 0;
+        uflag = 0;
+      }
+
+      /*  Anything else is an error.  */
+
+      else {
+        goto err1;
+      }
+
+    } else {                         /* Expect operator or ')'      */
+
+      uflag = 0;
+
+      /*  Handle right paren.   */
+
+      if (*pos==')') {
+        curr->type = 3;
+        pos++;
+        snew = gseval(curr);
+        if (snew==NULL) goto err3;
+        curr = snew;
+      }
+
+      /*  Handle implied concatenation - check for operand */
+
+      else if (*pos=='\"' || *pos=='\'' || *pos=='_' ||
+                (*pos>='0' && *pos<='9') ||
+                (*pos>='a' && *pos<='z') ||
+                (*pos>='A' && *pos<='Z') ) {
+        curr->type = 1;
+        curr->obj.op = 9;
+        state = 1;
+      }
+
+      /*  Handle operator   */
+
+      else {
+        flag = -1;
+        for (i=0; i<13; i++) {
+          if (*pos != *(opchars[i])) continue;
+          if (*(opchars[i]+1) && (*(pos+1)!=*(opchars[i]+1))) continue;
+          flag = opvals[i];
+          break;
+        }
+        if (flag<0) goto err1;
+        curr->type = 1;
+        curr->obj.op = flag;
+        state = 1;
+        if (i<3) pos += 2;
+        else pos++;
+      }
+    }
+  }
+
+  /*  We get here when the end of the expression is reached.
+      If the last thing stacked wasn't an operand or a closing
+      paren, then an error.    */
+
+  if (sold->type!=0 && sold->type!=3) goto err1;
+
+  /*  Put an artificial right paren at the end of the stack
+      (to match the artificial opening paren), then do a
+      final evaluation of the stack.  If the result doesn't
+      resolve to one operand, then unmatched parens or something */
+
+  curr->type = 3;
+/*
+  stkdmp(curr);
+*/
+  snew = gseval(curr);
+  if (snew==NULL) goto err3;
+  curr = snew;
+  if (curr->pback != NULL) goto err4;
+  if (curr->pforw != NULL) goto err4;
+/*
+  stkdmp (curr);
+*/
+
+  /*  The expression has been evaluated without error.
+      Free the last stack entry and return the result.     */
+
+  pos = curr->obj.strng;
+  free (curr);
+  return (pos);
+
+  /* Handle errors.  Issue error messages, free stack and
+     associated memory.  */
+
+  err1:
+
+  printf ("Syntax Error\n");
+  goto err3;
+
+  err2:
+
+  printf ("Memory Allocation Error\n");
+  goto err3;
+
+  err4:
+
+  printf ("Unmatched parens\n");
+  goto err3;
+
+  err3:
+
+  while (curr->pback) curr = curr->pback;
+  while (curr!=NULL) {
+    if (curr->type==0) free (curr->obj.strng);
+    sold = curr;
+    curr = curr->pforw;
+    free (sold);
+  }
+  return (NULL);
+}
+
+/*  Evaluate the stack between opening and closing parentheses.
+    This is done by making multiple passes at decreasing
+    precedence levels, and evaluating all the operators at that
+    precedence level.  When the final result is obtained, it is
+    placed on the end of the stack without the parens.           */
+
+struct stck *gseval (struct stck *curr) {
+struct stck *sbeg, *srch, *stmp;
+gaint i;
+
+  /* Locate matching left paren. */
+
+  sbeg = curr;
+  while (sbeg) {
+    if (sbeg->type==2) break;
+    sbeg = sbeg->pback;
+  }
+  if (sbeg==NULL) {
+    printf ("Unmatched parens\n");
+    return (NULL);
+  }
+
+  /* Make a pass between the parens at each precedence level.  */
+
+  for (i=0; i<7; i++) {
+/*
+    stkdmp(sbeg);
+*/
+    srch = sbeg;
+    while (srch != curr) {
+       if (srch->type==1 &&
+           srch->obj.op>=opmins[i] && srch->obj.op<=opmaxs[i]) {
+         srch = gsoper(srch);
+         if (srch==NULL) return(NULL);
+       }
+      srch = srch->pforw;
+    }
+  }
+
+  /* Make sure we are down to one result.  If not, we are in
+     deep doodoo */
+
+  srch = sbeg->pforw;
+  srch = srch->pforw;
+  if (srch != curr) {
+    printf ("Logic error 8 in gseval \n");
+    return (NULL);
+  }
+
+  /* Remove the parens from the linklist */
+
+  srch = sbeg->pforw;
+  srch->pforw = curr->pforw;
+  srch->pback = sbeg->pback;
+  stmp = sbeg->pback;
+  if (stmp) stmp->pforw = srch;
+  stmp = curr->pforw;
+  if (stmp) stmp->pback = srch;
+  free(sbeg);
+  free(curr);
+
+  return (srch);
+}
+
+/* Perform an operation.  Unstack the operator and operands,
+   and stack the result in their place.  Return a pointer to
+   the link list element representing the result.           */
+
+struct stck *gsoper (struct stck *soper) {
+struct stck *sop1, *sop2, *stmp;
+gaint op, ntyp1, ntyp2, ntype=0, comp=0, len;
+gadouble v1, v2, v;
+gaint iv1, iv2, iv;
+char *s1, *s2, *ch, *res, buf[25];
+
+  /* Get pointers to the operands.  If a potentially numeric
+     operation, do string to numeric conversion.             */
+
+  op = soper->obj.op;
+  sop1 = soper->pback;
+  sop2 = soper->pforw;
+  if (optyps[op-1]) {
+    gsnum (sop2->obj.strng, &ntyp2, &iv2, &v2);
+    if (op<14) gsnum (sop1->obj.strng, &ntyp1, &iv1, &v1);
+    else ntyp1 = ntyp2;
+    if (ntyp1==1 && ntyp2==1) ntype = 1;
+    else if (ntyp1==0 || ntyp2==0) ntype = 0;
+    else ntype = 2;
+  }
+
+  /* If an op that requires numbers, check to make sure we
+     can do it.  */
+
+  if (optyps[op-1]==2 && ntype == 0 ) {
+    printf ("Non-numeric args to numeric operation\n");
+    return (NULL);
+  }
+
+  /* Perform actual operations. */
+
+  /* Logical or, and */
+
+  if (op==1 || op==2) {
+    s1 = sop1->obj.strng;
+    s2 = sop2->obj.strng;
+    res = malloc(2);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return (NULL);
+    }
+    *(res+1) = '\0';
+    if (op==1) {
+      if ( (*s1=='0' && *(s1+1)=='\0') &&
+           (*s2=='0' && *(s2+1)=='\0')  ) *res = '0';
+      else *res = '1';
+    } else {
+      if ( (*s1=='0' && *(s1+1)=='\0') ||
+           (*s2=='0' && *(s2+1)=='\0') ) *res = '0';
+      else *res = '1';
+    }
+  }
+
+  /* Logical comparitive */
+
+  else if (op>2 && op<9) {
+    res = malloc(2);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return (NULL);
+    }
+    *(res+1) = '\0';
+
+    /* Determine relationship between the ops */
+
+    if (ntype==2) {
+      if (v1<v2) comp = 1;
+      else if (v1==v2) comp = 3;
+      else comp = 2;
+    } else if (ntype==1) {
+      if (iv1<iv2) comp = 1;
+      else if (iv1==iv2) comp = 3;
+      else comp = 2;
+    } else {
+      s1 = sop1->obj.strng;
+      s2 = sop2->obj.strng;
+      while (*s1 && *s2) {
+        if (*s1<*s2) {
+          comp = 1;
+          break;
+        }
+        if (*s1>*s2) {
+          comp = 2;
+          break;
+        }
+        s1++; s2++;
+      }
+      if (*s1=='\0'&&*s2=='\0') comp = 3;
+      else if (*s1=='\0') comp = 1;
+      else if (*s2=='\0') comp = 2;
+    }
+
+    /* Apply relationship to specific op */
+
+    if (op==3) {
+      if (comp==3) *res = '1';
+      else *res = '0';
+    } else if (op==4) {
+      if (comp!=3) *res = '1';
+      else *res = '0';
+    } else if (op==5) {
+      if (comp==2) *res = '1';
+      else *res = '0';
+    } else if (op==6) {
+      if (comp==2 || comp==3) *res = '1';
+      else *res = '0';
+    } else if (op==7) {
+      if (comp==1) *res = '1';
+      else *res = '0';
+    } else {
+      if (comp==1 || comp==3) *res = '1';
+      else *res = '0';
+    }
+  }
+
+  /* String concatenation */
+
+  else if (op==9) {
+    s1 = sop1->obj.strng;
+    s2 = sop2->obj.strng;
+    len = strlen(s1) + strlen(s2);
+    res = malloc(len+1);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return(NULL);
+    }
+    ch = res;
+    while (*s1) {
+      *ch = *s1;
+      s1++; ch++;
+    }
+    while (*s2) {
+      *ch = *s2;
+      s2++; ch++;
+    }
+    *ch = '\0';
+  }
+
+  /*  Handle arithmetic operator */
+
+  else if (op<14 && op>9) {
+/*
+    if (ntype==1) {
+      if (op==10) iv = iv1+iv2;
+      else if (op==11) iv = iv1-iv2;
+      else if (op==12) iv = iv1*iv2;
+      else {
+        if (iv2==0) {
+          printf ("Divide by zero\n");
+          return (NULL);
+        }
+        iv = iv1 / iv2;
+      }
+      snprintf(buf,24,"%i",iv);
+    } else {
+      if (op==10) v = v1+v2;
+      else if (op==11) v = v1-v2;
+      else if (op==12) v = v1*v2;
+      else {
+        if (v2==0.0) {
+          printf ("Divide by zero\n");
+          return (NULL);
+        }
+        v = v1 / v2;
+      }
+      snprintf(buf,24,"%.15g",v);
+    }
+*/
+      if (op==10) v = v1+v2;
+      else if (op==11) v = v1-v2;
+      else if (op==12) v = v1*v2;
+      else {
+        if (v2==0.0) {
+          printf ("Divide by zero\n");
+          return (NULL);
+        }
+        v = v1 / v2;
+      }
+      snprintf(buf,24,"%.15g",v);
+/**/
+    len = strlen(buf) + 1;
+    res = malloc(len);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return (NULL);
+    }
+    strcpy(res,buf);
+  }
+
+  /*  Do unary not operation */
+
+  else if (op==14) {
+    res = malloc(2);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return (NULL);
+    }
+    *(res+1) = '\0';
+    s2 = sop2->obj.strng;
+    if (*s2=='\0' || (*s2=='0' && *(s2+1)=='\0')  ) *res = '1';
+    else *res = '0';
+  }
+
+  /* Do unary minus operation */
+
+  else if (op==15) {
+    if (ntype==1) {
+      iv = -1 * iv2;
+      snprintf(buf,24,"%i",iv);
+    } else {
+      v = -1.0 * v2;
+      snprintf(buf,24,"%.15g",v);
+    }
+    len = strlen(buf) + 1;
+    res = malloc(len);
+    if (res==NULL) {
+      printf ("Memory allocation error\n");
+      return (NULL);
+    }
+    strcpy(res,buf);
+  }
+
+  else {
+    printf ("Logic error 12 in gsoper\n");
+    return (NULL);
+  }
+
+  /* Rechain, Free stuff and return */
+
+  free (sop2->obj.strng);
+  if (op<14) free(sop1->obj.strng);
+  sop2->obj.strng = res;
+  if (op<14) {
+    sop2->pback = sop1->pback;
+    stmp = sop1->pback;
+    stmp->pforw = sop2;
+    free (sop1);
+  } else {
+    sop2->pback = soper->pback;
+    stmp = soper->pback;
+    stmp->pforw = sop2;
+  }
+  free (soper);
+  return (sop2);
+}
+
+/* Obtain the value of an operand.  This may be either a
+   variable or a function.                                */
+
+char *gsgopd (char **ppos, struct gscmn *pcmn) {
+char *pos, *res;
+char name[16];
+gaint i,pflag;
+
+  pos = *ppos;
+  for (i=0; i<16; i++) name[i]=' ';
+  i = 0;
+  pflag = 0;
+  while ( (*pos>='a' && *pos<='z') ||
+          (*pos>='A' && *pos<='Z') ||
+          (*pos=='.') || (*pos=='_') ||
+          (*pos>='0' && *pos<='9')   ) {
+    if (*pos=='.') pflag = 1;
+    if (i>15) {
+      printf ("Variable name too long - 1st 16 chars are: ");
+      for (i=0; i<16; i++) printf ("%c",name[i]);
+      printf ("\n");
+      return (NULL);
+    }
+    name[i] = *pos;
+    pos++; i++;
+  }
+  while (*pos==' ') pos++;
+
+  /* Handle a function call -- this is a recursive call all the
+     way back to gsrunf.   */
+
+  if (*pos=='(') {
+    if (pflag) {
+      printf ("Invalid function name: ");
+      for (i=0; i<16; i++) printf ("%c",name[i]);
+      printf ("\n");
+      return (NULL);
+    }
+    pos = gsfunc(pos, name, pcmn);
+    if (pos==NULL) return(NULL);
+    *ppos = pos;
+    res = pcmn->rres;
+    if (res==NULL) {
+      res = (char *)malloc(1);
+      if (res==NULL) {
+        printf ("Memory allocation error\n");
+        return (NULL);
+      }
+      *res = '\0';
+    }
+    pcmn->rres = NULL;
+    return(res);
+  }
+
+  *ppos = pos;
+  res = gsfvar(name, pcmn);
+  return (res);
+}
+
+/* Call a function.  */
+
+char *gsfunc (char *pos, char *name, struct gscmn *pcmn) {
+struct gsfnc *pfnc;
+struct gsvar *avar, *nvar, *cvar=NULL;
+char *astr, *res;
+gaint len, rc, i, cflg, pcnt;
+
+  avar = NULL;
+
+  /*  Get storage for holding argument expressions */
+
+  len = 0;
+  while (*(pos+len)) len++;
+  astr = (char *)malloc(len);
+  if (astr==NULL) {
+    printf ("Memory allocation error \n");
+    return (NULL);
+  }
+
+  /*  Evaluate each argument found.  Allocate a gsvar block
+      for each one, and chain them together */
+
+  pos++;
+  pcnt = 0;
+  while (!(*pos==')'&&pcnt==0)) {
+    cflg = 0;
+    len = 0;
+    while (*pos) {
+      if (!cflg && (*pos==',' || (*pos==')'&&pcnt==0))) break;
+      if (!cflg) {
+        if (*pos=='(') pcnt++;
+        if (*pos==')') pcnt--;
+        if (pcnt<0) break;
+      }
+      if (*pos =='\'') {
+        if (cflg==1) cflg = 0;
+        else if (cflg==0) cflg = 1;
+      } else if (*pos=='\"') {
+        if (cflg==2) cflg = 0;
+        else if (cflg==0) cflg = 2;
+      }
+      *(astr+len) = *pos;
+      pos++; len++;
+    }
+    if (*pos=='\0') {
+      printf ("Unmatched parens on function call\n");
+      pos = NULL;
+      goto retrn;
+    }
+    *(astr+len) = '\0';
+    res = gsexpr(astr, pcmn);
+    if (res==NULL) {
+      printf ("Error occurred processing function arguments\n");
+      pos = NULL;
+      goto retrn;
+    }
+    nvar = (struct gsvar *)malloc(sizeof(struct gsvar));
+    if (nvar==NULL) {
+      printf ("Memory allocation error\n");
+      pos = NULL;
+      goto retrn;
+    }
+    nvar->strng = res;
+    if (avar==NULL) avar = nvar;
+    else cvar->forw = nvar;
+    cvar = nvar;
+    cvar->forw = NULL;
+    if (*pos==',') pos++;
+  }
+  pos++;
+
+  /*  We are all set up to invoke the function.  So now we need
+      to find the function.  Look for internal functions first */
+
+  pcmn->farg = avar;
+  if (cmpwrd(name,"substr")) rc = gsfsub(pcmn);
+  else if (cmpwrd(name,"subwrd")) rc = gsfwrd(pcmn);
+  else if (cmpwrd(name,"sublin")) rc = gsflin(pcmn);
+  else if (cmpwrd(name,"wrdpos")) rc = gsfpwd(pcmn);
+  else if (cmpwrd(name,"strlen")) rc = gsfsln(pcmn);
+  else if (cmpwrd(name,"valnum")) rc = gsfval(pcmn);
+  else if (cmpwrd(name,"read")) rc = gsfrd(pcmn);
+  else if (cmpwrd(name,"write")) rc = gsfwt(pcmn);
+  else if (cmpwrd(name,"close")) rc = gsfcl(pcmn);
+  else if (cmpwrd(name,"gsfallow")) rc = gsfallw(pcmn);
+  else if (cmpwrd(name,"gsfpath")) rc = gsfpath(pcmn);
+  else if (cmpwrd(name,"math_log")) rc = gsfmath(pcmn,1);
+  else if (cmpwrd(name,"math_log10")) rc = gsfmath(pcmn,2);
+  else if (cmpwrd(name,"math_cos")) rc = gsfmath(pcmn,3);
+  else if (cmpwrd(name,"math_sin")) rc = gsfmath(pcmn,4);
+  else if (cmpwrd(name,"math_tan")) rc = gsfmath(pcmn,5);
+  else if (cmpwrd(name,"math_atan")) rc = gsfmath(pcmn,6);
+  else if (cmpwrd(name,"math_atan2")) rc = gsfmath(pcmn,7);
+  else if (cmpwrd(name,"math_sqrt")) rc = gsfmath(pcmn,8);
+  else if (cmpwrd(name,"math_abs")) rc = gsfmath(pcmn,9);
+  else if (cmpwrd(name,"math_acosh")) rc = gsfmath(pcmn,10);
+  else if (cmpwrd(name,"math_asinh")) rc = gsfmath(pcmn,11);
+  else if (cmpwrd(name,"math_atanh")) rc = gsfmath(pcmn,12);
+  else if (cmpwrd(name,"math_cosh")) rc = gsfmath(pcmn,13);
+  else if (cmpwrd(name,"math_sinh")) rc = gsfmath(pcmn,14);
+  else if (cmpwrd(name,"math_exp")) rc = gsfmath(pcmn,15);
+  else if (cmpwrd(name,"math_fmod")) rc = gsfmath(pcmn,16);
+  else if (cmpwrd(name,"math_pow")) rc = gsfmath(pcmn,17);
+  else if (cmpwrd(name,"math_sinh")) rc = gsfmath(pcmn,18);
+  else if (cmpwrd(name,"math_tanh")) rc = gsfmath(pcmn,19);
+  else if (cmpwrd(name,"math_acos")) rc = gsfmath(pcmn,20);
+  else if (cmpwrd(name,"math_asin")) rc = gsfmath(pcmn,21);
+  else if (cmpwrd(name,"math_format")) rc = gsfmath(pcmn,22);
+  else if (cmpwrd(name,"math_nint")) rc = gsfmath(pcmn,23);
+  else if (cmpwrd(name,"math_int")) rc = gsfmath(pcmn,24);
+  else if (cmpwrd(name,"math_mod")) rc = gsfmath(pcmn,25);
+  else if (cmpwrd(name,"math_strlen")) rc = gsfmath(pcmn,26);
+
+  /*  Not an intrinsic function.  See if it is a function
+      within the file we are currently working on.  */
+
+  else {
+    pfnc = pcmn->ffnc;
+    while (pfnc) {
+      if (!cmpch(pfnc->name,name,16)) break;
+      pfnc = pfnc->forw;
+    }
+
+    /* If not found, try to load it, assuming this is 
+       currently allowed */
+
+    if (pfnc==NULL && pcmn->gsfflg!=0) {
+      rc = gsgsfrd (pcmn, 1, name);     /* Load function file */
+      if (rc==0) {                      /* Now look again */
+        pfnc = pcmn->ffnc;
+        while (pfnc) {
+          if (!cmpch(pfnc->name,name,16)) break;
+          pfnc = pfnc->forw;
+        }
+        if (pfnc==NULL) {
+          printf ("Loaded function file %s\n",pcmn->lfdef->name);
+          printf ("  But... ");
+        }
+      } else if (rc!=9) {        /* An error ocurred */
+        printf ("Error while loading function: ");
+        for (i=0; i<16; i++) printf("%c",name[i]);
+        printf ("\n");
+        pos = NULL;
+        goto retrn;
+      }                         /* File not found (rc==9) just */
+    }                           /*   fall thru and give msg below */
+    if (pfnc) {
+      rc = gsrunf(pfnc->recd, pcmn);
+    } else {
+      printf ("Function not found: ");
+      for (i=0; i<16; i++) printf("%c",name[i]);
+      printf ("\n");
+      pos = NULL;
+      goto retrn;
+    }
+  }
+  if (rc>0) pos = NULL;
+  avar = NULL;
+
+retrn:
+  gsfrev(avar);
+  free (astr);
+  return(pos);
+}
+
+/* Find the value of a variable */
+
+char *gsfvar (char *iname, struct gscmn *pcmn) {
+struct gsvar *var;
+char *ch, *src, name[16];
+gaint len,i;
+
+  /* Resolve possible compound name. */
+
+  i = gsrvar (pcmn, iname, name);
+  if (i) return(NULL);
+
+  /* See if this variable name already exists */
+
+  if (name[0]=='_') var = pcmn->gvar;
+  else var = pcmn->fvar;
+
+  while (var) {
+    for (i=0; i<16; i++) {
+      if (name[i] != var->name[i]) break;
+    }
+    if (i==16) break;
+    var = var->forw;
+  }
+
+  /* If it didn't, use var name.  If it did, use current value */
+
+  if (var==NULL) {
+    len = 0;
+    while (name[len]!=' ' && len<16) len++;
+    src = name;
+  } else {
+    len = 0;
+    while (*(var->strng+len)) len++;
+    src = var->strng;
+  }
+  ch = malloc(len+1);
+  if (ch==NULL) {
+    printf ("Error allocating memory for variable \n");
+    return (NULL);
+  }
+  for (i=0; i<len; i++) *(ch+i) = *(src+i);
+  *(ch+len) = '\0';
+  return (ch);
+}
+
+/*  Resolve compound variable name */
+
+gaint gsrvar (struct gscmn *pcmn, char *name, char *oname) {
+struct gsvar *var;
+char rname[16],sname[16];
+gaint len,pos,tpos,cnt,i;
+
+  for (i=0; i<16; i++) rname[i] = ' ';
+  pos = 0;
+  len = 0;
+  while (pos<16) {
+    if (len>15) {
+      if (*(name+pos)!=' ') {
+        printf ("Compound variable name too long: ");
+        for (i=0; i<16; i++) printf ("%c",*(name+i));
+        return (1);
+      }
+      break;
+    }
+    rname[len] = *(name+pos);
+    len++;
+    if (*(name+pos)=='.') {                  /* Split off sub name */
+      pos++;
+      cnt = 0;
+      tpos = pos;
+      for (i=0; i<16; i++) sname[i] = ' ';
+      while (*(name+tpos)!='.' && *(name+tpos)!=' ' && tpos<16) {
+        sname[cnt] = *(name+tpos);
+        tpos++; cnt++;
+      }
+      if (cnt>0) {                          /* See if it's a var  */
+        if (*sname=='_') var = pcmn->gvar;
+        else var = pcmn->fvar;
+        while (var) {
+          for (i=0; i<16; i++) {
+            if (*(sname+i) != var->name[i]) break;
+          }
+          if (i==16) break;
+          var = var->forw;
+        }
+        if (var!=NULL) {                    /* If so, use value   */
+          cnt = 0;
+          while (len<16 && *(var->strng+cnt)!='\0') {
+            rname[len] = *(var->strng+cnt);
+            cnt++; len++;
+          }
+          if (len==16 && *(var->strng+cnt)=='\0') {
+            printf ("Compound variable name too long: ");
+            for (i=0; i<16; i++) printf ("%c",*(name+i));
+            return (1);
+          }
+          pos = tpos;                       /* Advance pointer    */
+        }
+      }
+    } else pos++;
+  }
+
+  for (i=0; i<16; i++) *(oname+i) = rname[i];
+/*
+  for (i=0; i<16; i++) printf ("%c",*(oname+i));
+  printf ("\n");
+*/
+  return (0);
+}
+
+
+/*  Retreive a constant */
+
+char *gscnst (char **ppos) {
+char *pos, *ch, *cpos, delim;
+gaint len, i, dflg, eflg;
+
+  pos = *ppos;
+
+  /* Handle integer constant */
+
+  if (*pos>='0'&&*pos<='9') {
+    len = 0;
+    dflg = 1;
+    while ( (*pos>='0'&&*pos<='9') ||
+            (dflg && *pos=='.')  ) {
+      if (*pos=='.') dflg = 0;
+      pos++;
+      len++;
+    }
+    eflg = 0;
+    if ( (*pos=='e' || *pos=='E') )  {
+       if ( *(pos+1)>='0' && *(pos+1)<='9' ) eflg = 1;
+       else if ( *(pos+1)=='-' || *(pos+1)=='+' ) {
+         if ( *(pos+2)>='0' && *(pos+2)<='9' ) eflg = 2;
+       }
+    }
+    if (eflg) {
+      pos += eflg;    /* Skip past 'e' and exponent sign */
+      len += eflg;
+      while ( *pos>='0'&&*pos<='9' ) { 
+        pos++;
+        len++;
+      }
+    }
+      
+    ch = malloc(len+1);
+    if (ch==NULL) {
+      printf ("Memory allocation error \n");
+      return (NULL);
+    }
+    pos = *ppos;
+    for (i=0; i<len; i++) *(ch+i) = *(pos+i);
+    *(ch+len) = '\0';
+    *ppos = pos+len;
+    return (ch);
+  }
+
+  /* Handle string constant */
+
+  delim = *pos;
+  len = 0;
+  pos++;
+  while (*pos) {
+    if (*pos==delim && *(pos+1)==delim) {
+      len++;
+      pos += 2;
+      continue;
+    }
+    if (*pos==delim) break;
+    len++;
+    pos++;
+  }
+  if (*pos=='\0') {
+    printf ("Non-terminated constant\n");
+    return (NULL);
+  }
+  ch = malloc(len+1);
+  if (ch==NULL) {
+    printf ("Memory allocation error \n");
+    return (NULL);
+  }
+
+  pos = *ppos;
+  cpos = ch;
+  pos++;
+  while (1) {
+    if (*pos==delim && *(pos+1)==delim) {
+      *cpos = *pos;
+      cpos++;
+      pos += 2;
+      continue;
+    }
+    if (*pos==delim) break;
+    *cpos = *pos;
+    pos++; cpos++;
+  }
+  *cpos = '\0';
+  *ppos = pos+1;
+  return (ch);
+}
+
+/* Determine if an operand is a numeric.  Numerics must not
+   have any leading or trailing blanks, and must be
+   either integer or floating values.  */
+
+void gsnum (char *strng, gaint *type, gaint *ival, gadouble *val) {
+char *ch;
+gaint dflg,eflg,len;
+
+  ch = strng;
+  len = 0;
+
+  dflg = 0;  /* we found a decimal point */
+  eflg = 0;  /* we found an exponent */
+
+  if (*ch=='\0') {
+    *type = 0;
+    return;
+  }
+  if (*ch<'0' || *ch>'9') { 
+    if (*ch=='+' || *ch=='-') {
+      ch++; len++;
+      if (*ch=='.') {
+        dflg = 1;
+        ch++; len++;
+      }
+    } else if (*ch=='.') {
+      dflg = 1;
+      ch++; len++;
+    } else {
+      *type = 0;
+      return;
+    }
+  }
+  if (*ch<'0' || *ch>'9') {  /* should be a number at this point */ 
+    *type = 0;
+    return;
+  }
+  while (*ch) {
+    if (*ch<'0' || *ch>'9') {
+      if (*ch=='.') {
+        if (dflg) break;
+        dflg = 1;
+      } else break;
+    }
+    ch++;
+    len++;
+  }
+
+  if (*ch=='E'||*ch=='e') {
+    eflg = 1;
+    ch++; len++;
+    if (*ch=='+' || *ch=='-') {
+      ch++; len++;
+    }
+    if (*ch<'0' || *ch>'9') {
+      *type = 0;
+      return;
+    }
+    while (*ch>='0' && *ch<='9') {
+      ch++; len++;
+    }
+  }
+  if (*ch) {
+    *type = 0;
+    return;
+  }
+  if (!dflg&&!eflg&&len<10) {
+    *ival = atol(strng);
+    *val = (gadouble)(*ival);
+    *type = 1;
+  } else {
+    *val = atof(strng);
+    *type = 2;
+  }
+  return;
+}
+
+/*  Intrinsic functions.  */
+
+/* Substring function.  Expects three args:  string, start, length */
+
+gaint gsfsub (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *ch, *res;
+gaint ret, ntype, strt, len, i;
+gaint lstrt,llen;
+gadouble v;
+
+  pcmn->rres = NULL;
+
+  /* Attempt to convert 2nd and thrd args to integer */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in substr:  1st argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in substr:  2nd argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  gsnum (pvar->strng, &ntype, &lstrt, &v);
+  strt = lstrt;
+  if (ntype!=1 || strt<1) {
+    printf ("Error in substr:  2nd argument invalid.\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in substr:  3rd argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  gsnum (pvar->strng, &ntype, &llen, &v);
+  len = llen;
+  if (ntype!=1 || len<1) {
+    printf ("Error in substr:  3rd argument invalid.\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(len+1);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Move the desired substring.  NULL return is possible. */
+
+  pvar = pcmn->farg;
+  i = 1;
+  ch = pvar->strng;
+  while (*ch && i<strt) {ch++; i++;}  /* Don't start past end of string */
+  i = 0;
+  while (*ch && i<len) {
+    *(res+i) = *ch;
+    ch++;
+    i++;
+  }
+  *(res+i) = '\0';
+
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to get specified word in a string */
+
+gaint gsfwrd (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *ch, *res;
+gaint ret, ntype, wnum, i, len;
+gaint lwnum;
+gadouble v;
+
+  pcmn->rres = NULL;
+
+  /* Attempt to convert 2nd arg to integer. */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in subwrd:  1st argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in subwrd:  2nd argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  gsnum (pvar->strng, &ntype, &lwnum, &v);
+  wnum = lwnum;
+  if (ntype!=1 || wnum<1) {
+    printf ("Error in subwrd:  2nd argument invalid.\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Find the desired word in the string */
+
+  pvar = pcmn->farg;
+  ch = pvar->strng;
+  i = 0;
+  while (*ch) {
+    if (*ch==' '||*ch=='\n'||*ch=='\t'||i==0) {
+      while (*ch==' '||*ch=='\n'||*ch=='\t') ch++;
+      if (*ch) i++;
+      if (i==wnum) break;
+    } else ch++;
+  }
+
+
+  /* Get length of returned word. */
+
+  len = 0;
+  while (*(ch+len)!='\0' && *(ch+len)!=' '
+         && *(ch+len)!='\t' && *(ch+len)!='\n') len++;
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(len+1);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  for (i=0; i<len; i++) *(res+i) = *(ch+i);
+  *(res+len) = '\0';
+
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to get specified line in a string */
+
+gaint gsflin (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *ch, *res;
+gaint ret, ntype, lnum, i, len;
+gaint llnum;
+gadouble v;
+
+  pcmn->rres = NULL;
+
+  /* Attempt to convert 2nd arg to integer. */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in sublin:  1st argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in sublin:  2nd argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  gsnum (pvar->strng, &ntype, &llnum, &v);
+  lnum = llnum;
+  if (ntype!=1 || lnum<1) {
+    printf ("Error in sublin:  2nd argument invalid.\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Find the desired line in the string */
+
+  pvar = pcmn->farg;
+  ch = pvar->strng;
+  i = 1;
+  while (*ch && i<lnum) {
+    if (*ch=='\n') i++;
+    ch++;
+  }
+
+  /* Get length of returned line. */
+
+  len = 0;
+  while (*(ch+len)!='\0' && *(ch+len)!='\n') len++;
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(len+1);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  for (i=0; i<len; i++) *(res+i) = *(ch+i);
+  *(res+len) = '\0';
+
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/* Read function.  Expects one arg: the file name.
+   Returnes a two line result -- an rc, and the record read */
+
+gaint gsfrd (struct gscmn *pcmn) {
+FILE *ifile;
+struct gsvar *pvar;
+struct gsiob *iob,*iobo;
+char *res,*name,rc,*ch;
+gaint ret,n;
+
+  pcmn->rres = NULL;
+  res = (char *)malloc(RSIZ);
+  if (res==NULL) {
+    printf ("Memory allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Get file name */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in read:  File name missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  name = pvar->strng;
+  if (*name=='\0') {
+    printf ("Error in read:  NULL File Name\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Check to see if the file is already open */
+
+  iob = pcmn->iob;
+  iobo = iob;
+  while (iob) {
+    if (!strcmp(name,iob->name)) break;
+    iobo = iob;
+    iob = iob->forw;
+  }
+
+  /* If it was not open, open it and chain a new iob */
+
+  if (iob==NULL) {
+    ifile = fopen(name,"r");
+    if (ifile==NULL) {
+      rc = '1';
+      goto rslt;
+    }
+    iob = (struct gsiob *)malloc(sizeof(struct gsiob));
+    if (iob==NULL) {
+      printf ("Memory allocation error\n");
+      ret = 1;
+      goto retrn;
+    }
+    if (pcmn->iob==NULL) pcmn->iob = iob;
+    else iobo->forw = iob;
+    iob->forw = NULL;
+    iob->file = ifile;
+    iob->name = name;
+    iob->flag = 1;
+    pvar->strng = NULL;
+  } else {
+    if (iob->flag!=1) {
+      rc = '8';
+      printf ("Error in read:  attempt to read a file open for write\n");
+      printf ("  File name = %s\n",iob->name);
+      goto rslt;
+    }
+    ifile = iob->file;
+  }
+
+  /* Read the next record into the buffer area */
+
+  ch = fgets(res+2, RSIZ-3, ifile);
+  if (ch==NULL) {
+    if (feof(ifile)) rc = '2';
+    else rc = '9';
+    goto rslt;
+  }
+  rc = '0';
+  /* Remove cr for PC/cygwin version */
+  ch = res+2;
+  n=strlen(ch);
+  if ( n > 1 ) {
+    if ( (gaint)ch[n-2] == 13 ) {
+       ch[n-2] = ch[n-1];
+       ch[n-1] = '\0';
+     }
+   }
+  /* Complete return arg list */
+
+rslt:
+
+  *res = rc;
+  *(res+1) = '\n';
+  ret = 0;
+  pcmn->rres = res;
+  res = NULL;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  if (res) free(res);
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/* Write function.  Expects two or three args:  file name,
+   output record, and optional append flag.  Returns a return code. */
+
+gaint gsfwt (struct gscmn *pcmn) {
+FILE *ofile;
+struct gsvar *pvar, *pvars;
+struct gsiob *iob, *iobo;
+char *res, *name, rc, *orec;
+gaint ret,appflg,len;
+
+  pcmn->rres = NULL;
+  res = (char *)malloc(2);
+  if (res==NULL) {
+    printf ("Memory allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Get file name */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in write:  File name missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  name = pvar->strng;
+  if (*name=='\0') {
+    printf ("Error in write:  NULL File Name\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvars = pvar;
+
+  /* Get output record */
+
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in write:  Output Record arg is missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  orec = pvar->strng;
+
+  /* Check for append flag */
+
+  pvar = pvar->forw;
+  if (pvar==NULL) appflg = 0;
+  else appflg = 1;
+
+  /* Check to see if the file is already open */
+
+  iob = pcmn->iob;
+  iobo = iob;
+  while (iob) {
+    if (!strcmp(name,iob->name)) break;
+    iobo = iob;
+    iob = iob->forw;
+  }
+
+  /* If it was not open, open it and chain a new iob */
+
+  if (iob==NULL) {
+    if (appflg) ofile = fopen(name,"a+");
+    else ofile = fopen(name,"w");
+    if (ofile==NULL) {
+      rc = '1';
+      goto rslt;
+    }
+    iob = (struct gsiob *)malloc(sizeof(struct gsiob));
+    if (iob==NULL) {
+      printf ("Memory allocation error\n");
+      ret = 1;
+      goto retrn;
+    }
+    if (pcmn->iob==NULL) pcmn->iob = iob;
+    else iobo->forw = iob;
+    iob->forw = NULL;
+    iob->file = ofile;
+    iob->name = name;
+    iob->flag = 2;
+    pvars->strng = NULL;
+  } else {
+    if (iob->flag!=2) {
+      rc = '8';
+      printf ("Error in write: attempt to write a file open for read\n");
+      printf ("  File name = %s\n",iob->name);
+      goto rslt;
+    }
+    ofile = iob->file;
+  }
+
+  /* Write the next record */
+
+  len = 0;
+  while (*(orec+len)) len++;
+  *(orec+len) = '\n';
+  len++;
+  fwrite (orec,1,len,ofile);
+  rc = '0';
+
+  /* Complete return arg list */
+
+rslt:
+
+  *res = rc;
+  *(res+1) = '\n';
+  ret = 0;
+  pcmn->rres = res;
+  res = NULL;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  if (res) free(res);
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/* Close function.  Expects one arg:  file name.
+   Returns a return code:  0, normal, 1, file not open */
+
+gaint gsfcl (struct gscmn *pcmn) {
+struct gsvar *pvar;
+struct gsiob *iob, *iobo;
+char *name, *res, rc;
+gaint ret;
+
+  pcmn->rres = NULL;
+  res = (char *)malloc(2);
+  if (res==NULL) {
+    printf ("Memory allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Get file name */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in close:  File name missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  name = pvar->strng;
+  if (*name=='\0') {
+    printf ("Error in close:  NULL File Name\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Check to see if the file is already open */
+
+  iob = pcmn->iob;
+  iobo = iob;
+  while (iob) {
+    if (!strcmp(name,iob->name)) break;
+    iobo = iob;
+    iob = iob->forw;
+  }
+
+  /* If it was not open, print message and return */
+
+  if (iob==NULL) {
+    rc = '1';
+    printf ("Error in close:  file not open\n");
+    printf ("  File name = %s\n",name);
+  } else {
+    fclose (iob->file);
+    if (iob==pcmn->iob) pcmn->iob = iob->forw;
+    else iobo->forw = iob->forw;
+    free (iob);
+    rc = '0';
+  }
+
+  /* Complete return arg list */
+  *res = rc;
+  *(res+1) = '\0';
+  ret = 0;
+  pcmn->rres = res;
+  res = NULL;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  if (res) free(res);
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to return position of specified word in a string */
+
+gaint gsfpwd (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *ch, *res;
+gaint ret, ntype, wnum, i, pos;
+gaint lwnum;
+gadouble v;
+
+  pcmn->rres = NULL;
+
+  /* Attempt to convert 2nd arg to integer. */
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in wrdpos:  1st argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  pvar = pvar->forw;
+  if (pvar==NULL) {
+    printf ("Error in wrdpos:  2nd argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+  gsnum (pvar->strng, &ntype, &lwnum, &v);
+  wnum = lwnum;
+  if (ntype!=1 || wnum<1) {
+    printf ("Error in wrdpos:  2nd argument invalid.\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Find the desired word in the string */
+
+  pvar = pcmn->farg;
+  ch = pvar->strng;
+  i = 0;
+  while (*ch) {
+    if (*ch==' '||*ch=='\n'||*ch=='\t'||i==0) {
+      while (*ch==' '||*ch=='\n'||*ch=='\t') ch++;
+      if (*ch) i++;
+      if (i==wnum) break;
+    } else ch++;
+  }
+
+  /* Calculcate position of the desired word */
+
+  if (*ch=='\0') pos = 0;
+  else pos = 1 + ch - pvar->strng;
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(12);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  snprintf(res,11,"%i",pos);
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to return the length of a string */
+
+gaint gsfsln (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *res;
+gaint ret, len;
+
+  pcmn->rres = NULL;
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in strlen:  Argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+ 
+  len = 0;
+  while (*(pvar->strng+len)) {
+    len++;
+    if (len==9999999) break;
+  }
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(12);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  snprintf(res,11,"%i",len);
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to check if a string is a valid numeric */
+
+gaint gsfval (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *res;
+gaint ret, ntype;
+gaint lwnum;
+gadouble v;
+
+  pcmn->rres = NULL;
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in valnum:  Argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  gsnum (pvar->strng, &ntype, &lwnum, &v);
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(12);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  snprintf(res,11,"%i",ntype);
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to control gsf loading.  */
+
+gaint gsfallw (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *res;
+gaint ret, i;
+
+  pcmn->rres = NULL;
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in gsfallow:  Argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  i = 999;
+  if (cmpwrd(pvar->strng, "on")) i = 1;
+  if (cmpwrd(pvar->strng, "On")) i = 1;
+  if (cmpwrd(pvar->strng, "ON")) i = 1;
+  if (cmpwrd(pvar->strng, "off")) i = 0;
+  if (cmpwrd(pvar->strng, "Off")) i = 0;
+  if (cmpwrd(pvar->strng, "OFF")) i = 0;
+  if (i<900) pcmn->gsfflg = i;
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(12);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  snprintf(res,11,"%i",i);
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to set gsf private path  */
+
+gaint gsfpath (struct gscmn *pcmn) {
+struct gsvar *pvar;
+char *res;
+gaint ret, i, j;
+
+  pcmn->rres = NULL;
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in gsfpath:  Argument missing\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Copy the path to the gscmn area */
+
+  i = 0;
+  while (*(pvar->strng+i)) i++;
+  if (pcmn->ppath) free (pcmn->ppath);
+  pcmn->ppath = (char *)malloc(i+1);
+  if (pcmn->ppath==NULL) {
+    printf ("Error in gsfpath:  Memory Allocation\n");
+    ret = 1;
+    goto retrn;
+  }
+  j = 0;
+  while (j<i) *(pcmn->ppath+j) = *(pvar->strng+j);
+  *(pcmn->ppath+i) = '\0';
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(3);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  *res = '1';
+  *(res+1) = '\0';
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/*  Routine to do libmf math */
+
+gaint gsfmath (struct gscmn *pcmn, gaint mathflg) {
+struct gsvar *pvar;
+char *res, buf[25],vformat[15];
+char *mathmsg1 = "log";
+char *mathmsg2 = "log10";
+char *mathmsg3 = "cos";
+char *mathmsg4 = "sin";
+char *mathmsg5 = "tan";
+char *mathmsg6 = "atan";
+char *mathmsg7 = "atan2";
+char *mathmsg8 = "sqrt";
+char *mathmsg9 = "abs";
+char *mathmsg10 = "acosh";
+char *mathmsg11 = "asinh";
+char *mathmsg12 = "atanh";
+char *mathmsg13 = "cosh";
+char *mathmsg14 = "sinh";
+char *mathmsg15 = "exp";
+char *mathmsg16 = "fmod";
+char *mathmsg17 = "pow";
+char *mathmsg18 = "sinh";
+char *mathmsg19 = "tanh";
+char *mathmsg20 = "acos";
+char *mathmsg21 = "asin";
+char *mathmsg22 = "format";
+char *mathmsg23 = "nint";
+char *mathmsg24 = "int";
+char *mathmsg25 = "mod";
+char *mathmsg26 = "strlen";
+char *mathmsg=NULL;
+gaint ret, ntype, i, len;
+gaint lwnum;
+gadouble v,v2;
+
+  pcmn->rres = NULL;
+
+  if (mathflg==1) mathmsg = mathmsg1;
+  if (mathflg==2) mathmsg = mathmsg2;
+  if (mathflg==3) mathmsg = mathmsg3;
+  if (mathflg==4) mathmsg = mathmsg4;
+  if (mathflg==5) mathmsg = mathmsg5;
+  if (mathflg==6) mathmsg = mathmsg6;
+  if (mathflg==7) mathmsg = mathmsg7;
+  if (mathflg==8) mathmsg = mathmsg8;
+  if (mathflg==9) mathmsg = mathmsg9;
+  if (mathflg==10) mathmsg = mathmsg10;
+  if (mathflg==11) mathmsg = mathmsg11;
+  if (mathflg==12) mathmsg = mathmsg12;
+  if (mathflg==13) mathmsg = mathmsg13;
+  if (mathflg==14) mathmsg = mathmsg14;
+  if (mathflg==15) mathmsg = mathmsg15;
+  if (mathflg==16) mathmsg = mathmsg16;
+  if (mathflg==17) mathmsg = mathmsg17;
+  if (mathflg==18) mathmsg = mathmsg18;
+  if (mathflg==19) mathmsg = mathmsg19;
+  if (mathflg==20) mathmsg = mathmsg20;
+  if (mathflg==21) mathmsg = mathmsg21;
+  if (mathflg==22) mathmsg = mathmsg22;
+  if (mathflg==23) mathmsg = mathmsg23;
+  if (mathflg==24) mathmsg = mathmsg24;
+  if (mathflg==25) mathmsg = mathmsg25;
+  if (mathflg==26) mathmsg = mathmsg26;
+
+  pvar = pcmn->farg;
+  if (pvar==NULL) {
+    printf ("Error in math_%s:  Argument missing\n",mathmsg);
+    ret = 1;
+    goto retrn;
+  }
+
+  if( !(mathflg == 22 || mathflg == 26) ) {
+    gsnum (pvar->strng, &ntype, &lwnum, &v);
+
+    if (ntype==0) {
+      printf ("Error in math_%s:  Argument not a valid numeric\n",mathmsg);
+      ret = 1;
+      goto retrn;
+    }
+
+  } else {
+    if(mathflg == 22) {
+      if(strlen(pvar->strng) < 15) {
+	strcpy(vformat,pvar->strng);
+      } else {
+	printf ("Error in math_%s:  argument: %s  too long < 15\n",mathmsg,pvar->strng);
+	ret = 1;
+	goto retrn;
+      }
+    }
+  }
+  if (v<=0.0 && (mathflg == 1 || mathflg == 2) ) {  
+    printf ("Error in math_%s:  Argument less than or equal to zero\n",mathmsg);
+    ret = 1;
+    goto retrn;
+  }
+ 
+  if(mathflg == 16) {
+    pvar = pvar->forw;
+    if (pvar==NULL) {
+      printf ("Error in fmod:  2rd argument missing\n");
+      ret = 1;
+      goto retrn;
+    }
+
+    gsnum (pvar->strng, &ntype, &lwnum, &v2);
+    
+    if (ntype == 0) {
+      printf ("Error in fmod:  2rd argument invalid.\n");
+      ret = 1;
+      goto retrn;
+    }
+  }
+
+  if(mathflg == 17) {
+    pvar = pvar->forw;
+    if (pvar==NULL) {
+      printf ("Error in pow:  2rd argument missing\n");
+      ret = 1;
+      goto retrn;
+    }
+
+    gsnum (pvar->strng, &ntype, &lwnum, &v2);
+    
+    if (ntype == 0) {
+      printf ("Error in pow:  2rd argument invalid.\n");
+      ret = 1;
+      goto retrn;
+    }
+  }
+
+  if(mathflg == 7) {
+    pvar = pvar->forw;
+    if (pvar==NULL) {
+      printf ("Error in atan2:  2rd argument missing\n");
+      ret = 1;
+      goto retrn;
+    }
+
+    gsnum (pvar->strng, &ntype, &lwnum, &v2);
+    
+    if (ntype == 0) {
+      printf ("Error in atan2:  2rd argument invalid.\n");
+      ret = 1;
+      goto retrn;
+    }
+  }
+
+  if(mathflg == 25) {
+    pvar = pvar->forw;
+    if (pvar==NULL) {
+      printf ("Error in mod:  2rd argument missing\n");
+      ret = 1;
+      goto retrn;
+    }
+
+    gsnum (pvar->strng, &ntype, &lwnum, &v2);
+    
+    if (ntype == 0) {
+      printf ("Error in mod:  2rd argument invalid.\n");
+      ret = 1;
+      goto retrn;
+    }
+  }
+
+  if(mathflg == 22) {
+    pvar = pvar->forw;
+    if (pvar==NULL) {
+      printf ("Error in format:  2rd argument missing\n");
+      ret = 1;
+      goto retrn;
+    }
+
+    gsnum (pvar->strng, &ntype, &lwnum, &v);
+    
+    if (ntype == 0) {
+      printf ("Error in format:  2rd argument invalid.\n");
+      ret = 1;
+      goto retrn;
+    }
+  }
+
+
+
+  /* Get result */
+
+  if (mathflg==1) v = log(v);
+  if (mathflg==2) v = log10(v);
+  if (mathflg==3) v = cos(v);
+  if (mathflg==4) v = sin(v);
+  if (mathflg==5) v = tan(v);
+  if (mathflg==6) v = atan(v);
+  if (mathflg==7) v = atan2(v,v2);
+  if (mathflg==8) v = sqrt(v);
+  if (mathflg==9) v = fabs(v);
+  if (mathflg==10) v = fabs(v);
+  if (mathflg==11) v = asinh(v);
+  if (mathflg==12) v = atanh(v);
+  if (mathflg==13) v = cosh(v);
+  if (mathflg==14) v = sinh(v);
+  if (mathflg==15) v = exp(v);
+  if (mathflg==16) v = fmod(v,v2);
+  if (mathflg==17) v = pow(v,v2);
+  if (mathflg==18) v = sinh(v);
+  if (mathflg==19) v = tanh(v);
+  if (mathflg==20) v = acos(v);
+  if (mathflg==21) v = asin(v);
+
+
+  if(mathflg == 23) {
+    v=floor(v+0.5);
+  } else if(mathflg == 24) {
+    v=floor(v);
+  } else if(mathflg == 25) {
+    v=floor(fmod(v,v2));
+  } else if(mathflg == 26) {
+    v=strlen(pvar->strng);
+  }
+
+  if(mathflg==22) {
+    snprintf(buf,24,vformat,v);
+  } else {
+    snprintf(buf,24,"%.15g",v);
+  }
+
+
+
+  len = 0;
+  while (buf[len]) len++;
+  len++;
+
+  /* Allocate storage for the result */
+
+  res = (char *)malloc(len);
+  if (res==NULL) {
+    printf ("Error:  Storage allocation error\n");
+    ret = 1;
+    goto retrn;
+  }
+
+  /* Deliver the result and return */
+
+  for (i=0; i<len; i++) *(res+i) = buf[i];
+  ret = 0;
+  pcmn->rres = res;
+
+  /* Release arg storage and return */
+
+retrn:
+
+  gsfrev (pcmn->farg);
+  pcmn->farg = NULL;
+  return (ret);
+}
+
+/* Following functions are related to reading the script file
+   into memory based on the file name and path specification */
+
+/* Open the main script; search the path if needed 
+
+     Rules:  When working with the name of the primary 
+             script, 1st try to open the name provided, as is.
+             If this fails, append .gs (if not there already)
+             and try again.  If this fails, and the file 
+             name provided does not start with a /, then 
+             we try the directories in the GASCRP envvar, 
+             both with the primary name and the .gs extension.
+
+     Code originally by M.Fiorino   */
+
+FILE *gsonam (struct gscmn *pcmn, struct gsfdef *pfdf) {
+FILE *ifile;
+char *uname,*xname,*dname,*lname,*oname;
+char *sdir;
+gaint len;
+
+  uname = NULL;  /* user provided name */
+  xname = NULL;  /* user name plus extension */
+  dname = NULL;  /* path dir name */
+  lname = NULL;  /* path plus uname or xname */
+  oname = NULL;  /* name of file that gets opened */
+  
+  /* First try to open by using the name provided. */
+             
+  uname = gsstad(pcmn->fname,"\0");
+  if (uname==NULL) return(NULL);
+  ifile = fopen(uname,"rb");
+
+  /* If that failed, then try adding a .gs extension,
+     but only if one is not already there */ 
+
+  if (ifile==NULL) {
+    xname = NULL;
+    len = 0;
+    while (*(uname+len)) len++;
+    if (*(uname+len-1)!='s' || *(uname+len-2)!='g' || 
+        *(uname+len-3)!='.' ) { 
+      xname = gsstad(uname,".gs");
+      if (xname==NULL) return(NULL);
+      ifile = fopen(xname,"rb");
+      if (ifile!=NULL) {
+        oname = xname;
+        xname = NULL;
+      }
+    }
+
+    /* If that didn't work, search in the GASCRP path --
+       the path contains blank-delimited directory names */
+
+    if (ifile == NULL && *(uname)!='/' ) {
+
+      sdir = getenv("GASCRP");
+
+      while (sdir!=NULL) {
+        while (gsdelim(*sdir)) sdir++;
+        if (*sdir=='\0') break;
+        dname = gsstcp(sdir);
+        if (dname==NULL) return(NULL);
+        len = 0;              /* add slash to dir name if needed */
+        while (*(dname+len)) len++;
+        if (*(dname+len-1)!='/') {
+          lname = gsstad(dname,"/");
+          if (lname==NULL) return(NULL);
+          free(dname);
+          dname = lname;
+        }
+        lname = gsstad(dname,uname);    /* try uname plus dirname */
+        if (lname==NULL) return(NULL);
+        ifile = fopen(lname,"rb");
+        if (ifile!=NULL) {
+          oname = lname;
+          lname = NULL;
+          break;
+        } else {                        /* try xname plus dirname */
+          free (lname);
+          lname = NULL;
+          if (xname) {
+            lname = gsstad(dname,xname);
+            if (lname==NULL) return(NULL);
+            ifile = fopen(lname,"rb");
+            if (ifile!=NULL) {
+              oname = lname;
+              lname = NULL;
+              break;
+            } else { 
+              free(lname); 
+              lname = NULL;
+            }
+          }
+        }
+        while (*sdir!=' ' && *sdir!='\0') sdir++;   /* Advance */
+        free(dname);
+        dname = NULL;
+      }
+    } 
+  } else {
+    oname = uname; 
+    uname = NULL;
+  }
+
+  if (uname) free(uname);  /* Hopefully set  */
+  if (xname) free(xname);  /*   to null        */
+  if (dname) free(dname);  /*     if assigned    */
+  if (lname) free(lname);  /*       to oname       */
+
+  /* If we opened a file, figure out the prefix */
+
+  if (ifile) {
+    pfdf->name = oname;
+    xname = gsstad(oname,"\0");
+    len = 0;
+    while (*(xname+len)) len++;
+    while (len>0 && *(xname+len)!='/') len--;
+    if (len>0) *(xname+len+1) = '\0';
+    else *(xname) = '\0';
+    pcmn->fprefix = xname;
+  }
+  return (ifile);
+}
+ 
+/*  When working with a .gsf, the function name
+    is appended with .gsf.  Then we first try the
+    same directory that the main script was found
+    in.  If that fails, then we try the search path
+    in GASCRP. */
+
+FILE *gsogsf (struct gscmn *pcmn, struct gsfdef *pfdf, char *pfnc) {
+FILE *ifile;
+char *fname,*tname,*dname,*sdir;
+gaint len,i;
+char nname[20];
+
+  /* Function name is not null terminated -- make a copy that is */
+
+  for (i=0; i<16; i++) nname[i] = *(pfnc+i);
+  nname[16] = ' ';
+  i = 0;
+  while (nname[i] != ' ') i++;
+  nname[i] = '\0';
+
+  fname = gsstad(nname,".gsf");
+  if (fname == NULL) return (NULL);
+
+  /* First try the prefix directory */
+
+  tname = gsstad(pcmn->fprefix,fname);
+  if (tname == NULL) return (NULL);
+  ifile = fopen(tname,"rb");
+  if (ifile) {
+    free (fname);
+    pfdf->name = tname;
+    return (ifile); 
+  }
+  free (tname);
+
+  /* Next try the private path.  The file names are constructed
+     as the prefix plus the private path plus the function name
+     plus the .gsf */
+
+  sdir = pcmn->ppath;
+
+  while (sdir!=NULL) {
+    while (gsdelim(*sdir)) sdir++;
+    if (*sdir=='\0') break;
+    dname = gsstcp(sdir);
+    if (dname==NULL) return(NULL);
+    len = 0;              /* add slash to dir name if needed */
+    while (*(dname+len)) len++;
+    if (*(dname+len-1)!='/') {
+      tname = gsstad(dname,"/");
+      if (tname==NULL) return(NULL);
+      free(dname);
+      dname = tname;
+    }
+    tname = gsstad(dname,fname);  
+    free (dname);
+    dname = gsstad(pcmn->fprefix,tname);  
+    free (tname);
+    ifile = fopen(dname,"rb");
+    if (ifile) {
+      pfdf->name = dname;
+      free (fname);
+      return (ifile);
+    }
+    free (dname);
+    while (*sdir!=' ' && *sdir!='\0') sdir++;   /* Advance */
+  }
+
+  /* If we fall thru, next try the GASCRP path */
+
+  sdir = getenv("GASCRP");
+
+  while (sdir!=NULL) {
+    while (gsdelim(*sdir)) sdir++;
+    if (*sdir=='\0') break;
+    dname = gsstcp(sdir);
+    if (dname==NULL) return(NULL);
+    len = 0;              /* add slash to dir name if needed */
+    while (*(dname+len)) len++;
+    if (*(dname+len-1)!='/') {
+      tname = gsstad(dname,"/");
+      if (tname==NULL) return(NULL);
+      free(dname);
+      dname = tname;
+    }
+    tname = gsstad(dname,fname);
+    free(dname);
+    ifile = fopen(tname,"rb");
+    if (ifile) {
+      pfdf->name = tname;
+      free (fname);
+      return (ifile);
+    }
+    free (tname);
+    while (*sdir!=' ' && *sdir!='\0') sdir++;   /* Advance */
+  }
+  
+  /* If we fall thru, we didn't find anything.  */
+
+  free (fname);
+  return (NULL);
+}
+
+/* Copy a string to a new dynamically allocated area.
+   Copy until a delimiter or null is encountered.
+   Caller is responsible for freeing the storage.  */
+
+char *gsstcp (char *ch) {
+char *res;
+gaint i,len;
+  len = 0;
+  while (!gsdelim(*(ch+len)) && *(ch+len)!='\0') len++;
+  res = (char *)malloc(len+1);
+  if (res==NULL) {
+    printf ("Memory Allocation Error:  Script initialization\n");
+    return (NULL);
+  }
+  i = 0;
+  while (i<len) {
+    *(res+i) = *(ch+i);
+    i++;
+  }
+  *(res+len) = '\0';
+  return (res);
+}
+
+/* Determine if a character is a delimiter for seperating the
+   directory names in the GASCRP path.    To add new 
+   delimiters, put them here. */
+
+gaint gsdelim (char ch) {
+  if (ch==' ') return (1);
+  if (ch==';') return (1);
+  if (ch==',') return (1);
+  if (ch==':') return (1);
+  return (0);
+}
+
+/* Concatentate two strings and make a new string in
+   a dynamically allocated area.  Caller is responsible
+   for freeing the storage.  */
+
+char *gsstad(char *ch1, char *ch2) {
+char *res;
+gaint len,len2,i,j;
+  len = 0;
+  while (*(ch1+len)) len++;
+  len2 = 0;
+  while (*(ch2+len2)) len2++;
+  res = (char *)malloc(len+len2+1);
+  if (res==NULL) {
+    printf ("Memory Allocation Error:  Script initialization\n");
+    return (NULL);
+  }
+  i = 0;
+  while (i<len) {
+    *(res+i) = *(ch1+i);
+    i++;
+  }
+  j = 0;   
+  while (j<len2) {
+    *(res+i) = *(ch2+j);
+    i++; j++;
+  }
+  *(res+i) = '\0';
+  return (res);
+}
diff --git a/src/gsgui.c b/src/gsgui.c
new file mode 100644
index 0000000..8cb95e6
--- /dev/null
+++ b/src/gsgui.c
@@ -0,0 +1,834 @@
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ *   gsgui: - A simple expression analyzer for gagui.
+ *
+ *   REVISION HISTORY:
+ *
+ *   22May97   da Silva   First alpha version.
+ *   10Jun97   da Silva   Added CmdWin() callback.
+ *   06Nov97   da Silva   Fixed small bug in SetWidgetIndex().
+ *   18Feb98   da Silva   Removed "!" as a comment character.
+ *   16Dec07   da Silva   Explicitly adopted GPL.
+
+    Copyright (C) 1997-2007 by Arlindo da Silva <dasilva at opengrads.org>
+    All Rights Reserved.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; using version 2 of the License.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, please consult  
+              
+              http://www.gnu.org/licenses/licenses.html
+
+    or write to the Free Software Foundation, Inc., 59 Temple Place,
+    Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libsx.h"
+#if USEFREQ == 1
+#include "freq.h"
+#endif
+#include "gagui.h"
+
+/* Supported widget types */
+#define OPENDISPLAY     1
+#define SHOWDISPLAY     2
+#define MAKELABEL       3
+#define MAKEMENU        4
+#define MAKEMENUITEM    5
+#define MAKEBUTTON      6
+#define MAINLOOP        7
+#define SETWIDGETPOS    8
+#define SETBGCOLOR      9
+#define SETFGCOLOR      10
+#define MAKETOGGLE      11
+#define GETFONT         12
+#define SETWIDGETFONT   13
+#define MAKEWINDOW      14
+#define CLOSEWINDOW     15
+#define ALLWIDGETFONT   16
+#define ALLFGCOLOR      17
+#define ALLBGCOLOR      18
+#define GETNAMEDCOLOR   19
+#define DEBUGGUI        20
+#define CHDIR           21
+
+/* Widget function table */
+struct Func_Table {
+    char *name;
+    int  func;
+};
+static
+struct Func_Table Widgets[] = {   {"OpenDisplay",   OPENDISPLAY},
+                                  {"ShowDisplay",   SHOWDISPLAY},
+                                  {"MakeLabel",     MAKELABEL},
+                                  {"MakeMenu",      MAKEMENU},
+                                  {"MakeMenuItem",  MAKEMENUITEM},
+                                  {"MakeButton",    MAKEBUTTON},
+                                  {"MainLoop",      MAINLOOP}, 
+                                  {"SetWidgetPos",  SETWIDGETPOS}, 
+                                  {"SetFgColor",    SETFGCOLOR},
+                                  {"SetBgColor",    SETBGCOLOR},
+                                  {"MakeToggle",    MAKETOGGLE},
+                                  {"GetFont",       GETFONT},
+                                  {"SetWidgetFont", SETWIDGETFONT},
+                                  {"MakeWindow",    MAKEWINDOW},
+                                  {"CloseWindow",   CLOSEWINDOW},
+                                  {"AllWidgetFont", ALLWIDGETFONT},
+                                  {"AllFgColor",    ALLFGCOLOR},
+                                  {"AllBgColor",    ALLBGCOLOR},
+                                  {"GetNamedColor", GETNAMEDCOLOR},
+                                  {"Debug",         DEBUGGUI},
+                                  {"chdir",         CHDIR},
+                                  {NULL,           -1} };
+
+
+
+
+/* Callback function table */
+struct CB_Table {
+   char       *name;
+   ButtonCB   func;
+};
+static
+struct CB_Table CallBacks[] = {  {"NULL",     NULL},
+                                 {"Exit",     CB_Exit},
+                                 {"Open",     CB_Open},
+                                 {"Load",     CB_Load},
+                                 {"Cmd",      CB_Cmd},
+                                 {"CmdStr",   CB_CmdStr},
+                                 {"CmdWin",   CB_CmdWin},
+                                 {"CmdLine",  CB_CmdLine},
+                                 {"VarSel",   CB_VarSel},
+                                 {"FileSel",  CB_FileSel},
+                                 {"Display",  CB_Display},
+                                 {"Toggle",   CB_Toggle},
+                                 {"Browse",   CB_Browse},
+                                 {"Edit",     CB_Edit},
+                                 {"CloseWindow", CB_CloseWindow},
+                                 {NULL,       NULL } };
+
+
+/* Internal Macro Tables */ 
+struct Macro_Table{
+   char *name;
+   int  value;
+};
+static
+struct Macro_Table Macros [] = { {"NO_CARE",       NO_CARE},
+                                 {"PLACE_RIGHT",   PLACE_RIGHT},
+                                 {"PLACE_UNDER",   PLACE_UNDER},
+                                 {"FALSE",         FALSE},
+                                 {"TRUE",          TRUE},
+                                 {NULL,            0} };
+
+
+/* scanner specific data */
+
+#define NONE      0            /* Token types */
+#define DELIMITER 1
+#define VARIABLE  2
+#define STRING    3
+#define COMMENT   4
+
+#define NTOKEN  16             /* Maximum number of tokens per line */
+#define LTOKEN  132            /* Maximum length of token */
+static char *prog;             /* holds expression to be analyzed */
+static char token[LTOKEN];     /* current token */
+static char tok_type;          /* token type */
+
+
+/* User defined widgets. TO DO: make this a linked list */
+#define NWIDGETS 512       /* Maximum number of widgets */
+static int iwidgets = -1;  /* index of last entry in user widget table */
+struct User_Widgets {
+    char    name[LTOKEN];  /* short name used by the script */
+    Widget  w;             /* widget data structure */
+    char    data[LTOKEN];  /* data to be passed to callbacks */
+};
+static struct User_Widgets UserWidgets[NWIDGETS];
+
+/* User loaded fonts */
+#define NFONTS 16          /* max number of user fonts allowed  */
+#define LFONTS 80          /* max size of font string name */
+static int ifonts=-1;      /* index of last entry in function table */
+struct User_Fonts {
+    char  name[LFONTS];    /* short name used by the script */
+    XFont font;            /* font data structure */
+};
+static struct User_Fonts UserFonts[NFONTS];
+
+/* User colors */
+#define NCOLORS 32          /* max number of user fonts allowed (>=6) */
+#define LCOLORS 32          /* max size of color string name */
+static int icolors=-1;      /* index of last entry in function table */
+static int FirstColor=1;    /* flag for standard colors creation */
+struct User_Colors {
+    char  name[LCOLORS];    /* short name used by the script */
+    int   color;            /* font data structure */
+};
+static struct User_Colors UserColors[NCOLORS];
+
+/*--------------------------- SCANNER ------------------------------------*/
+
+/*
+ * is_in()  -  Check if char is in string
+ *
+ */
+int
+is_in(char ch, char *s)
+{
+  while(*s) if(*s++==ch) return 1;
+  return 0;
+}
+
+
+/*
+ * iswhite()  -  Look for spaces and tabs 
+ */
+int
+iswhite(char c)
+{
+  if(c == ' ' || c == 9) return 1;
+  return 0;
+}
+			
+
+/*
+ * isdelim()  -  Look for delimiter 
+ */
+int
+isdelim(char c)
+{
+  if(is_in(c,"(,)") || c==0) return 1;
+  return 0;
+}
+
+
+/*
+ *  get_token - return tokens from the input string.
+ *
+ */
+
+void get_token()
+{
+  char *temp;
+  
+  tok_type = NONE;
+  temp = token;
+
+  while(iswhite(*prog)) ++prog;   /* skip over white spaces */
+
+  if(is_in(*prog,"(,)")) {
+    tok_type = DELIMITER;
+    *temp++ = *prog++;            /* advance to next position */
+  }
+  else if(is_in(*prog,"#*")) {
+    tok_type = COMMENT;
+    *temp = '\0';
+    *temp++ = *prog++;            /* advance to next position */
+  }
+  else if(isalpha(*prog)||isdigit(*prog)||is_in(*prog,"-+")) {
+    while(!isdelim(*prog)) *temp++ = *prog++;
+    tok_type = VARIABLE;
+  }
+  else if(is_in(*prog,"\"'")) {
+    ++prog;  /* remove " or ' */
+    while(!isdelim(*prog)) *temp++ = *prog++;
+    tok_type = STRING;
+  }
+
+  /* Note: Variables can start with number, for now, at least */
+
+  *temp = '\0';
+  temp--;
+  while(iswhite(*temp) ) {
+        *temp='\0'; temp--;
+  }
+  if(tok_type==STRING ) {
+     if(*temp=='"'||*temp=='\'') *temp='\0'; /* very forgiving... */
+  }
+
+}
+
+/*-------------------------- USER TABLE MANAGEMENT -----------------------*/
+
+/*
+ * GetGuiFuncIndex() - returns widget function index
+ *
+ */
+int
+GetGuiFuncIndex(char *name)
+{
+   int i, func=-1;
+
+   for(i=0;i<NWIDGETS;i++) {
+       if(Widgets[i].name == NULL) break;
+       if(!strcmp(Widgets[i].name, name)) {
+          func = Widgets[i].func;
+          break;
+       }
+   }
+   return(func);
+}
+
+
+/*
+ * GetCallBackIndex() - returns callback function index
+ *
+ */
+int
+GetCallBackIndex(char *name)
+{
+   int i, index=-1;
+
+   for(i=0;;i++) {
+       if(CallBacks[i].name == NULL) break;
+       if(!strcmp(CallBacks[i].name, name)) {
+          index = i;          
+          break;
+       }
+   }
+   return(index);
+}
+
+/*
+ * GetMacroValue() - returns libsx "macro" values
+ *
+ */
+int
+GetMacroValue(char *name)
+{
+   int i, value=-1;  /* make sure this is not used */
+
+   for(i=0;;i++) {
+       if(Macros[i].name == NULL) break;
+       if(!strcmp(Macros[i].name, name)) {
+          value = Macros[i].value;
+          break;
+       }
+   }
+   return(value);
+}
+
+/*
+ * SetWidgetIndex - creates an entry for a widget name.
+ *
+ */
+
+
+/*
+ * GetWidgetIndex - returns index for a widget name created with 
+ *                  SetWidgetIndex().
+ *
+ */
+int
+GetWidgetIndex(char *name)
+{
+   int i, index=-1;
+   for(i=0;i<=iwidgets;i++) {
+       if(!strcmp(UserWidgets[i].name, name)) {
+          index = i;
+          break;
+       }
+   }
+   return index;
+}
+
+int
+SetWidgetIndex(char *name)
+{
+   int i;
+
+   /* Very first time */
+   if(iwidgets<0) {
+      iwidgets=0;
+      strcpy(UserWidgets[0].name, "NULL");
+      UserWidgets[0].w = (Widget) NULL;  /* need this for SetWidgetPos() */
+   }
+
+   /* If a widget with same name exists, return its index */
+   if ( iwidgets>0 ) {
+        if ( (i=GetWidgetIndex(name)) >= 0 ) return i;
+   }
+
+   iwidgets++;
+   if(iwidgets>NWIDGETS-1) {
+      iwidgets--;
+      printf("GUI Error: too many widgets\n");
+      return -1;
+   } else i = iwidgets;
+   strcpy(UserWidgets[i].name, name);
+   return i;
+}
+
+/*
+ * LoadUserFont() - loads and creates an entry for a font
+ *
+ */
+
+int
+LoadUserFont(char *name,         /* a short name used by the script */ 
+             char *Xfontname)    /* the actual X11 name used for the font */
+{
+   XFont font;
+
+   ifonts++;
+   if(ifonts>NFONTS-1) {
+      ifonts--;
+      printf("GUI Error: too many fonts");
+      return -1;
+   } 
+
+   font = GetFont(Xfontname);
+   if ( font == NULL ) {
+        ifonts--;
+        printf("GUI Error: could not get font %s\n", Xfontname);
+        return -1;
+   }
+   strncpy(UserFonts[ifonts].name, name, LFONTS);
+   UserFonts[ifonts].font = font;
+
+   return ifonts;
+}
+
+
+/*
+ * GetFontIndex - returns index for user fonts created with
+ *                LoadUserFont()
+ */
+int
+GetFontIndex(char *fontname)  /* fontname is a short name
+                                 used by the script */
+{
+   int i, index=-1;
+   for(i=0;i<=ifonts;i++) {
+       if(!strcmp(UserFonts[i].name, fontname)) {
+          index = i;
+          break;
+       }
+   }
+   return index;
+}
+
+
+/*
+ * LoadUserColor() - load named color 
+ *
+ */
+
+int
+LoadUserColor(char *name,         /* a short name used by the script */ 
+              char *colorname)    /* the actual X11 name used for the color */
+{
+   int color;
+
+   if ( FirstColor ) {
+      FirstColor = 0;
+      GetStandardColors();
+      strcpy(UserColors[0].name, "white"  );
+      strcpy(UserColors[1].name, "black"  );
+      strcpy(UserColors[2].name, "red"    );
+      strcpy(UserColors[3].name, "green"  );
+      strcpy(UserColors[4].name, "blue"   );
+      strcpy(UserColors[5].name, "yellow" );
+      UserColors[0].color = WHITE;
+      UserColors[1].color = BLACK;
+      UserColors[2].color = RED;
+      UserColors[3].color = GREEN;
+      UserColors[4].color = BLUE;
+      UserColors[5].color = YELLOW;
+      icolors = 5;
+      if(!name) return;
+   }
+
+   icolors++;
+   if(icolors>NCOLORS-1) {
+      icolors--;
+      printf("GUI Error: too many colors");
+      return -1;
+   } 
+
+   color = GetNamedColor(colorname);
+   if ( color<0 ) {
+        icolors--;
+        printf("GUI Error: could not get color %s\n", colorname);
+        return -1;
+   }
+   strncpy(UserColors[icolors].name, name, LCOLORS);
+   UserColors[icolors].color = color;
+
+   return icolors;
+}
+
+
+/*
+ * GetColorIndex - returns index for user colors created with
+ *                 LoadUserColor()
+ */
+int
+GetColorIndex(char *colorname)  /* colorname is a short name
+                                  used by the script */
+{
+   int i, color=-1;
+
+   if ( FirstColor ) {
+        LoadUserColor(NULL, NULL);
+   }
+
+   for(i=0;i<=icolors;i++) {
+       if(!strcmp(UserColors[i].name, colorname)) {
+          color = UserColors[i].color;
+          break;
+       }
+   }
+   return color;
+}
+
+
+/*----------------------------- GUI INTERPRETER -----------------------------*/
+
+/*
+ *   Custom_GUI()  -  Reads a GUI script and executes it.
+ */
+
+int
+Custom_GUI ( char *fname )
+{
+
+    FILE *script;
+    int  argc;
+    char **argv;
+    char *p;
+    int  Func, i, j, k, m1, m2;
+    int  debug=0;
+
+    /* open script file */
+    script = fopen(fname,"r");
+    if ( script == NULL ) {
+      printf("GUI Error: cannot open GUI script file %s.\n", fname);
+      return 1;
+    }
+
+    /* allocate space to hold script lines & tokens */
+    p = malloc(256*sizeof(char));    
+    argv = (char **) List(NTOKEN,LTOKEN);
+    if(!argv) return 1;
+
+    /* Main loop begins ... */
+    do {
+       
+       /* Read and parse next line */
+       prog = p;
+       if(fgets(p, 256, script)==NULL) break ;
+       argc = -1;
+       do {
+          get_token();
+          if(tok_type==STRING||tok_type==VARIABLE) {
+              argc++;
+              if(argc>=NTOKEN) break;
+              strcpy(argv[argc], token);
+          } else if(tok_type==COMMENT) break;
+       } while(token[0]);
+
+       /* comment or blank line, skip it */
+       if(argc<0) {
+	 if(debug) printf("%s",p);
+	 goto nxtline;  
+       }
+
+       /* if not a GUI function, must be a native GrADS command,
+          go for it */
+       if((Func=GetGuiFuncIndex(argv[0]))<0) {
+           CB_Cmd(NULL,p);
+           goto nxtline;
+       }
+
+       if(debug) printf("%s",p);
+
+       /* Process each widget function */
+       switch(Func) {
+
+
+       case SHOWDISPLAY:
+         ShowDisplay();
+         break;
+
+       case MAINLOOP:
+         MainLoop();
+         break;
+
+       case MAKELABEL:
+	 if (argc!=2) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break;
+         UserWidgets[i].w = MakeLabel(argv[2]);
+         break;
+
+       case MAKEBUTTON:
+	 if (argc!=4) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break;
+         if((j=GetCallBackIndex(argv[3]))<0) break;
+         strcpy(UserWidgets[i].data, argv[4]);
+         UserWidgets[i].w = MakeButton(argv[2], CallBacks[j].func, 
+                                       UserWidgets[i].data);         
+         break;
+
+       case MAKEMENU:
+	 if (argc!=2) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break;
+	 UserWidgets[i].w = MakeMenu( argv[2] );
+	 break;
+
+       case MAKEMENUITEM:
+	 if (argc!=5) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break;
+         if((j=GetWidgetIndex(argv[2]))<0) break;
+         if((k=GetCallBackIndex(argv[4]))<0) break;
+         strcpy(UserWidgets[i].data, argv[5]);
+         UserWidgets[i].w = MakeMenuItem(UserWidgets[j].w, 
+                                 argv[3], CallBacks[k].func, 
+                                 UserWidgets[i].data);         
+	 break;
+
+       case MAKETOGGLE:
+	 if (argc!=6) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break;
+         if((m1=GetMacroValue(argv[3]))<0) break;
+         if((j=GetWidgetIndex(argv[4]))<0) break;
+         if((k=GetCallBackIndex(argv[5]))<0) break;
+         strcpy(UserWidgets[i].data, argv[6]);
+         UserWidgets[i].w = MakeToggle(argv[2], m1, UserWidgets[j].w,
+                            CallBacks[k].func, UserWidgets[i].data);
+         break;          
+
+       case SETWIDGETPOS:
+	 if (argc!=5) break;
+         if((i=GetWidgetIndex(argv[1]))<0) break;
+         if((m1=GetMacroValue(argv[2]))<0) break;
+         if((j=GetWidgetIndex(argv[3]))<0) break;
+         if((m2=GetMacroValue(argv[4]))<0) break;
+         if((k=GetWidgetIndex(argv[5]))<0) break;
+         SetWidgetPos(UserWidgets[i].w, m1, UserWidgets[j].w,
+                                        m2, UserWidgets[k].w );
+         break;
+
+       case SETFGCOLOR:
+	 if (argc!=2) break;
+         if((i=GetWidgetIndex(argv[1]))<0) break;
+         if((m1=GetColorIndex(argv[2]))<0) break;
+         SetFgColor(UserWidgets[i].w, m1);
+         break;
+
+       case ALLFGCOLOR:
+	 if (argc!=1) break;
+         if((m1=GetColorIndex(argv[1]))<0) break;
+         for(i=0; i<=iwidgets; i++ ) {
+             SetFgColor(UserWidgets[i].w, m1);
+         }
+         break;
+
+       case SETBGCOLOR:
+	 if (argc!=2) break;
+         if((i=GetWidgetIndex(argv[1]))<0) break; 
+         if((m1=GetColorIndex(argv[2]))<0) break;
+         SetBgColor(UserWidgets[i].w, m1);
+         break;
+
+       case ALLBGCOLOR:
+	 if (argc!=1) break;
+         if((m1=GetColorIndex(argv[1]))<0) break;
+         for(i=0; i<iwidgets; i++ ) {
+             SetBgColor(UserWidgets[i].w, m1);
+         }
+         break;
+
+       case GETFONT:
+	 if (argc!=2) break;
+         LoadUserFont(argv[1],argv[2]);
+         break;
+
+       case GETNAMEDCOLOR:
+	 if (argc!=2) break;
+         LoadUserColor(argv[1],argv[2]);
+         break;
+
+       case SETWIDGETFONT:
+         if (argc!=2) break;
+         if((i=GetWidgetIndex(argv[1]))<0) break; 
+         if((j=GetFontIndex(argv[2]))<0) break; 
+         SetWidgetFont(UserWidgets[i].w,UserFonts[j].font);
+         break;
+
+       case ALLWIDGETFONT:
+         if (argc!=1) break;
+         if((j=GetFontIndex(argv[1]))<0) break; 
+         for(i=0; i<=iwidgets; i++ ) {
+             SetWidgetFont(UserWidgets[i].w,UserFonts[j].font);
+         }
+         break;
+
+       case MAKEWINDOW:
+         if (argc!=2) break;
+         if((i=SetWidgetIndex(argv[1]))<0) break; 
+	 UserWidgets[i].w = MakeWindow(argv[2], SAME_DISPLAY, 
+                                                NONEXCLUSIVE_WINDOW);
+         break;
+
+       case CLOSEWINDOW:
+         if (argc!=1) break;
+         if((i=GetWidgetIndex(argv[1]))<0) break; 
+         SetCurrentWindow(UserWidgets[i].w);
+         CloseWindow();
+         SetCurrentWindow(ORIGINAL_WINDOW);
+         break;
+
+
+       case DEBUGGUI:
+	 if (argc<1) {
+	    debug = 1 - debug;
+	    break;
+	 } else if ( argc == 1 ) {
+	   if (!strcmp(argv[1], "ON" )  || !strcmp(argv[1], "on" )) debug=1;
+	   if (!strcmp(argv[1], "OFF" ) || !strcmp(argv[1], "off")) debug=0;
+	   break;
+	 }
+         break;
+	 
+       case CHDIR:
+         if (argc!=1) break;
+	 chdir(argv[1]);
+         break;
+
+       }
+ 
+       nxtline:
+         continue;
+
+    } while(*p);
+
+
+    /* close file, deallocate memory */
+    fclose(script);
+    if(p) free(p);
+    Free_List(argv,NTOKEN);
+
+    return 0;
+
+}
+
+
+/*------------------------ OPTIONAL TEST CODE ----------------------------*/
+
+#ifdef TEST
+
+main(int argc, char **argv)
+{
+    Custom_GUI("sample.gui");
+}
+
+/*
+ *   fake callbacks for prototyping
+ */
+
+
+void CB_Load(Widget w, void *data)
+{
+
+  printf("*** Load callback: %s ***\n", data);
+
+}
+
+
+/*
+ * CB_Cmd() - Callback funtion for a generic grads command  button.
+ */
+void CB_Cmd(Widget w, void *data)
+{
+  printf("*** Cmd callback: %s ***\n", data);
+
+}
+
+
+/*
+ *  CB_CmdLine() - Callback funtion for the command line button.
+ */
+void CB_CmdLine(Widget w, void *data)
+{
+  printf("*** CmdLine callback ***\n");
+
+}
+
+
+/*
+ * CB_VarSel() - Callback for selecting a variable.
+ *
+ */
+void CB_VarSel(Widget W, void *data)
+{
+  printf("*** VarSel callback: %s ***\n", data);
+
+}
+
+
+/*
+ * CB_Display() - Callback function for displaying the default variable.
+ *
+ */
+
+void CB_Display(Widget w, void *data)
+{
+  printf("*** Display callback: %s ***\n", data);
+
+}
+
+
+/*
+ * CB_Toggle() - Callback funtion for a generic toggle button.
+ */
+void CB_Toggle(Widget w, void *data)
+{
+  printf("*** Toggle callback: %s ***\n", data);
+
+}
+
+
+/*
+ * CB_FileSel() - Callback for selecting an already open file.
+ *
+ */
+void CB_FileSel(Widget W, void *data)
+{
+  printf("*** FileSel callback: ***\n");
+
+}
+
+/*
+ * CB_CmdStr() - Callback funtion for a generic grads command with user input.
+ */
+void CB_CmdStr(Widget w, void *data)
+{
+  printf("*** CmdStr callback: %s ***\n", data);
+
+}
+
+#endif   /* TEST */
+
+
diff --git a/src/gstmp.c b/src/gstmp.c
new file mode 100644
index 0000000..47b71c1
--- /dev/null
+++ b/src/gstmp.c
@@ -0,0 +1,237 @@
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gs.h"
+
+FILE *gsonam (struct gscmn *, struct gsfdef *);
+int gsgsfrd (struct gscmn *);
+char *gsstcp (char *);
+int gsdelim (char);
+char *gsstad (char *, char *);
+
+/* test some script functions */
+
+char *string = "mytest";
+
+main () {
+FILE *ifile;
+struct gsfdef *pfdf;
+struct gscmn *pcmn;
+int rc;
+
+  pcmn = (struct gscmn *)malloc(sizeof(struct gscmn));
+  pfdf = (struct gsfdef *)malloc(sizeof(struct gsfdef));
+
+  pcmn->fname = string;
+  printf ("qqq p0 %s\n",pcmn->fname);
+  ifile = gsonam(pcmn, pfdf);
+  if (ifile!=NULL) {
+    printf ("oname = -->%s<--\n",pfdf->name);
+    printf ("prefix = -->%s<--\n",pcmn->fprefix);
+  } else {
+    printf ("null\n");
+  }
+}
+
+/* Open the main script; search the path if needed 
+
+     Rules:  When working with the name of the primary 
+             script, 1st try to open the name provided, as is.
+             If this fails, append .gs (if not there already)
+             and try again.  If this fails, and the file 
+             name provided does not start with a /, then 
+             we try the directories in the GASCRP envvar, 
+             both with the primary name and the .gs extension.
+
+     Code originally by M.Fiorino   */
+
+FILE *gsonam (struct gscmn *pcmn, struct gsfdef *pfdf) {
+FILE *ifile;
+char *uname,*xname,*dname,*lname,*oname;
+char *sdir;
+int len;
+
+  uname = NULL;  /* user provided name */
+  xname = NULL;  /* user name plus extension */
+  dname = NULL;  /* path dir name */
+  lname = NULL;  /* path plus uname or xname */
+  oname = NULL;  /* name of file that gets opened */
+  
+  /* First try to open by using the name provided. */
+             
+  uname = gsstad(pcmn->fname,"\0");
+  if (uname==NULL) return(NULL);
+  printf ("qqq p1 -->%s<--- \n",uname);
+  ifile = fopen(uname,"rb");
+
+  /* If that failed, then try adding a .gs extension,
+     but only if one is not already there */ 
+
+  if (ifile==NULL) {
+    xname = NULL;
+    len = 0;
+    while (*(uname+len)) len++;
+    if (*(uname+len-1)!='s' || *(uname+len-2)!='g' || 
+        *(uname+len-3)!='.' ) { 
+      xname = gsstad(uname,".gs");
+      if (xname==NULL) return(NULL);
+      ifile = fopen(xname,"rb");
+      if (ifile!=NULL) {
+        oname = xname;
+        xname = NULL;
+      }
+    }
+
+    /* If that didn't work, search in the GASCRP path --
+       the path contains blank-delimited directory names */
+
+    if (ifile == NULL && *(uname)!='/' ) {
+
+      sdir = getenv("GASCRP");
+      if (sdir) printf ("qqqq -->%s<---\n",sdir);
+
+      while (sdir!=NULL) {
+        while (gsdelim(*sdir)) sdir++;
+        if (*sdir=='\0') break;
+        dname = gsstcp(sdir);
+        if (dname==NULL) return(NULL);
+        len = 0;              /* add slash to dir name if needed */
+        while (*(dname+len)) len++;
+        if (*(dname+len-1)!='/') {
+          lname = gsstad(dname,"/");
+          if (lname==NULL) return(NULL);
+          free(dname);
+          dname = lname;
+        }
+        lname = gsstad(dname,uname);    /* try uname plus dirname */
+        if (lname==NULL) return(NULL);
+        ifile = fopen(lname,"rb");
+        if (ifile!=NULL) {
+          oname = lname;
+          lname = NULL;
+          break;
+        } else {                        /* try xname plus dirname */
+          free (lname);
+          lname = NULL;
+          if (xname) {
+            lname = gsstad(dname,xname);
+            if (lname==NULL) return(NULL);
+            ifile = fopen(lname,"rb");
+            if (ifile!=NULL) {
+              oname = lname;
+              lname = NULL;
+              break;
+            } else { 
+              free(lname); 
+              lname = NULL;
+            }
+          }
+        }
+        while (*sdir!=' ' && *sdir!='\0') sdir++;   /* Advance */
+        free(dname);
+        dname = NULL;
+      }
+    } 
+  } else {
+    oname = uname; 
+    uname = NULL;
+    printf ("qqq p2 file opened \n");
+  }
+
+  if (uname) free(uname);  /* Hopefully set  */
+  if (xname) free(xname);  /*   to null        */
+  if (dname) free(dname);  /*     if assigned    */
+  if (lname) free(lname);  /*       to oname       */
+
+  /* If we opened a file, figure out the prefix */
+
+  if (ifile) {
+    pfdf->name = oname;
+    xname = gsstad(oname,"\0");
+    len = 0;
+    while (*(xname+len)) len++;
+    while (len>0 && *(xname+len)!='/') len--;
+    if (len>0) *(xname+len+1) = '\0';
+    else *(xname) = '\0';
+    pcmn->fprefix = xname;
+  }
+  return (ifile);
+}
+ 
+/*  When working with a gsf, the function name
+    is appended with .gsf.  Then we first try the
+    same directory that the main script was found
+    in.  If that fails, then we try the search path
+    in GASCRP. */
+
+/* Copy a string to a new dynamically allocated area.
+   Copy until a delimiter or null is encountered.
+   Caller is responsible for freeing the storage.  */
+
+char *gsstcp (char *ch) {
+char *res;
+int i,len;
+  len = 0;
+  while (!gsdelim(*(ch+len)) && *(ch+len)!='\0') len++;
+  res = (char *)malloc(len+1);
+  if (res==NULL) {
+    printf ("Memory Allocation Error:  Script initialization\n");
+    return (NULL);
+  }
+  i = 0;
+  while (i<len) {
+    *(res+i) = *(ch+i);
+    i++;
+  }
+  *(res+len) = '\0';
+  return (res);
+}
+
+/* Determine if a character is a delimiter for seperating the
+   directory names in the GASCRP path.    To add new 
+   delimiters, put them here. */
+
+int gsdelim (char ch) {
+  if (ch==' ') return (1);
+  if (ch==';') return (1);
+  if (ch==',') return (1);
+  return (0);
+}
+
+/* Concatentate two strings and make a new string in
+   a dynamically allocated area.  Caller is responsible
+   for freeing the storage.  */
+
+char *gsstad(char *ch1, char *ch2) {
+char *res;
+int len,len2,i,j;
+  len = 0;
+  while (*(ch1+len)) len++;
+  len2 = 0;
+  while (*(ch2+len2)) len2++;
+  printf ("qqq p3 lens = %i %i\n",len,len2);
+  res = (char *)malloc(len+len2+1);
+  if (res==NULL) {
+    printf ("Memory Allocation Error:  Script initialization\n");
+    return (NULL);
+  }
+  i = 0;
+  while (i<len) {
+    *(res+i) = *(ch1+i);
+    i++;
+  }
+  j = 0;   
+  while (j<len2) {
+    *(res+i) = *(ch2+j);
+    i++; j++;
+  }
+  *(res+i) = '\0';
+  return (res);
+}
diff --git a/src/gvt.h b/src/gvt.h
new file mode 100644
index 0000000..3e32a33
--- /dev/null
+++ b/src/gvt.h
@@ -0,0 +1,267 @@
+struct grib_var_table {
+  int id;
+  char name[6] ;
+  char desc[38] ;
+  char units[16] ;
+  } ;
+
+struct grib_var_table vt[256] = {
+
+  { 0 , "undef" , "undef" , "[undef]" },
+  { 1 , "pres" , "Pressure" , "[Pa]" },
+  { 2 , "prmsl" , "Pressure reduced to MSL" , "[Pa]" },
+  { 3 , "ptend" , "Pressure tendency" , "[Pa/s]" },
+  { 4 , "undef" , "undef" , "[undef]" },
+  { 5 , "undef" , "undef" , "[undef]" },
+  { 6 , "gp" , "Geopotential" , "[m**2/s**2]" },
+  { 7 , "hgt" , "Geopotential height" , "[gpm]" },
+  { 8 , "dist" , "Geometric height" , "[m]" },
+  { 9 , "hstdv" , "Standard deviation of height" , "[m]" },
+  { 10 , "hvar" , "Variance of height" , "[m**2]" },
+  { 11 , "tmp" , "Temperature" , "[K]" },
+  { 12 , "vtmp" , "Virtual temperature" , "[K]" },
+  { 13 , "pot" , "Potential temperature" , "[K]" },
+  { 14 , "epot" , "Pseudo-adiabatic potential temperature" , "[K]" },
+  { 15 , "tmax" , "Maximum temperature" , "[K]" },
+  { 16 , "tmin" , "Minimum temperature" , "[K]" },
+  { 17 , "dpt" , "Dew point temperature" , "[K]" },
+  { 18 , "depr" , "Dew point depression" , "[K]" },
+  { 19 , "lapr" , "Lapse rate" , "[K/m]" },
+  { 20 , "visib" , "Visibility" , "[m]" },
+  { 21 , "rdsp1" , "Radar spectra (1)" , "[dimensionless]" },
+  { 22 , "rdsp2" , "Radar spectra (2)" , "[dimensionless]" },
+  { 23 , "rdsp3" , "Radar spectra (3)" , "[dimensionless]" },
+  { 24 , "undef" , "undef" , "[undef]" },
+  { 25 , "tmpa" , "Temperature anomaly" , "[K]" },
+  { 26 , "presa" , "Pressure anomaly" , "[Pa]" },
+  { 27 , "gpa" , "Geopotential height anomaly" , "[gpm]" },
+  { 28 , "wvsp1" , "Wave spectra (1)" , "[dimensionless]" },
+  { 29 , "wvsp2" , "Wave spectra (2)" , "[dimensionless]" },
+  { 30 , "wvsp3" , "Wave spectra (3)" , "[dimensionless]" },
+  { 31 , "wdir" , "Wind direction" , "[degree]" },
+  { 32 , "wind" , "Wind speed" , "[m/s]" },
+  { 33 , "ugrd" , "u wind" , "[m/s]" },
+  { 34 , "vgrd" , "v wind" , "[m/s]" },
+  { 35 , "strm" , "Stream function" , "[m**2/s]" },
+  { 36 , "vpot" , "Velocity potential" , "[m**2/s]" },
+  { 37 , "mntsf" , "Montgomery stream function" , "[m**2/s**2]" },
+  { 38 , "sgcvv" , "Sigma coord. vertical velocity" , "[/s]" },
+  { 39 , "vvel" , "Pressure vertical velocity" , "[Pa/s]" },
+  { 40 , "dzdt" , "Geometric vertical velocity" , "[m/s]" },
+  { 41 , "absv" , "Absolute vorticity" , "[/s]" },
+  { 42 , "absd" , "Absolute divergence" , "[/s]" },
+  { 43 , "relv" , "Relative vorticity" , "[/s]" },
+  { 44 , "reld" , "Relative divergence" , "[/s]" },
+  { 45 , "vucsh" , "Vertical u shear" , "[/s]" },
+  { 46 , "vvcsh" , "Vertical v shear" , "[/s]" },
+  { 47 , "dirc" , "Direction of current" , "[degree]" },
+  { 48 , "spc" , "Speed of current" , "[m/s]" },
+  { 49 , "uogrd" , "u of current" , "[m/s]" },
+  { 50 , "vogrd" , "v of current" , "[m/s]" },
+  { 51 , "spfh" , "Specific humidity" , "[kg/kg]" },
+  { 52 , "rh" , "Relative humidity" , "[percent]" },
+  { 53 , "mixr" , "Humidity mixing ratio" , "[kg/kg]" },
+  { 54 , "pwat" , "Precipitable water" , "[kg/m**2]" },
+  { 55 , "vapp" , "Vapor pressure" , "[Pa]" },
+  { 56 , "satd" , "Saturation deficit" , "[Pa]" },
+  { 57 , "evp" , "Evaporation" , "[kg/m**2]" },
+  { 58 , "cice" , "Cloud Ice" , "[kg/m**2]" },
+  { 59 , "prate" , "Precipitation rate" , "[kg/m**2/s]" },
+  { 60 , "tstm" , "Thunderstorm probability" , "[percent]" },
+  { 61 , "apcp" , "Total precipitation" , "[kg/m**2]" },
+  { 62 , "ncpcp" , "Large scale precipitation" , "[kg/m**2]" },
+  { 63 , "acpcp" , "Convective precipitation" , "[kg/m**2]" },
+  { 64 , "srweq" , "Snowfall rate water equivalent" , "[kg/m**2/s]" },
+  { 65 , "weasd" , "Water equiv. of accum. snow depth" , "[kg/m**2]" },
+  { 66 , "snod" , "Snow depth" , "[m]" },
+  { 67 , "mixht" , "Mixed layer depth" , "[m]" },
+  { 68 , "tthdp" , "Transient thermocline depth" , "[m]" },
+  { 69 , "mthd" , "Main thermocline depth" , "[m]" },
+  { 70 , "mtha" , "Main thermocline anomaly" , "[m]" },
+  { 71 , "tcdc" , "Total cloud cover" , "[percent]" },
+  { 72 , "cdcon" , "Convective cloud cover" , "[percent]" },
+  { 73 , "lcdc" , "Low level cloud cover" , "[percent]" },
+  { 74 , "mcdc" , "Mid level cloud cover" , "[percent]" },
+  { 75 , "hcdc" , "High level cloud cover" , "[percent]" },
+  { 76 , "cwat" , "Cloud water" , "[kg/m**2]" },
+  { 77 , "undef" , "undef" , "[undef]" },
+  { 78 , "snoc" , "Convective snow" , "[kg/m**2]" },
+  { 79 , "snol" , "Large scale snow" , "[kg/m**2]" },
+  { 80 , "wtmp" , "Water temperature" , "[K]" },
+  { 81 , "land" , "Land-sea mask (1=land; 0=sea)" , "[integer]" },
+  { 82 , "dslm" , "Deviation of sea level from mean" , "[m]" },
+  { 83 , "sfcr" , "Surface roughness" , "[m]" },
+  { 84 , "albdo" , "Albedo" , "[percent]" },
+  { 85 , "tsoil" , "Soil temperature" , "[K]" },
+  { 86 , "soilm" , "Soil moisture content" , "[kg/m**2]" },
+  { 87 , "veg" , "Vegetation" , "[percent]" },
+  { 88 , "salty" , "Salinity" , "[kg/kg]" },
+  { 89 , "den" , "Density" , "[kg/m**2]" },
+  { 90 , "runof" , "Runoff" , "[kg/m**2]" },
+  { 91 , "icec" , "Ice concentration (ice=1; no ice=0)" , "[1/0]" },
+  { 92 , "icetk" , "Ice thickness" , "[m]" },
+  { 93 , "diced" , "Direction of ice drift" , "[degree]" },
+  { 94 , "siced" , "Speed of ice drift" , "[m/s]" },
+  { 95 , "uice" , "u of ice drift" , "[m/s]" },
+  { 96 , "vice" , "v of ice drift" , "[m/s]" },
+  { 97 , "iceg" , "Ice growth" , "[m]" },
+  { 98 , "iced" , "Ice divergence" , "[/s]" },
+  { 99 , "snom" , "Snow melt" , "[kg/m**2]" },
+  { 100 , "htsgw" , "Sig height of wind waves and swell" , "[m]" },
+  { 101 , "wvdir" , "Direction of wind waves" , "[degree]" },
+  { 102 , "wvhgt" , "Significant height of wind waves" , "[m]" },
+  { 103 , "wvper" , "Mean period of wind waves" , "[s]" },
+  { 104 , "swdir" , "Direction of swell waves" , "[degree]" },
+  { 105 , "swell" , "Significant height of swell waves" , "[m]" },
+  { 106 , "swper" , "Mean period of swell waves" , "[s]" },
+  { 107 , "dirpw" , "Primary wave direction" , "[degree]" },
+  { 108 , "perpw" , "Primary wave mean period" , "[s]" },
+  { 109 , "dirsw" , "Secondary wave direction" , "[degree]" },
+  { 110 , "persw" , "Secondary wave mean period" , "[s]" },
+  { 111 , "nswrs" , "Net short wave radiation (surface)" , "[W/m**2]" },
+  { 112 , "nlwrs" , "Net long wave radiation (surface)" , "[W/m**2]" },
+  { 113 , "nswrt" , "Net short wave radiation (top)" , "[W/m**2]" },
+  { 114 , "nlwrt" , "Net long wave radiation (top)" , "[W/m**2]" },
+  { 115 , "lwavr" , "Long wave radiation" , "[W/m**2]" },
+  { 116 , "swavr" , "Short wave radiation" , "[W/m**2]" },
+  { 117 , "grad" , "Global radiation" , "[W/m**2]" },
+  { 118 , "undef" , "undef" , "[undef]" },
+  { 119 , "undef" , "undef" , "[undef]" },
+  { 120 , "undef" , "undef" , "[undef]" },
+  { 121 , "lhtfl" , "Latent heat flux" , "[W/m**2]" },
+  { 122 , "shtfl" , "Sensible heat flux" , "[W/m**2]" },
+  { 123 , "blydp" , "Boundary layer dissipation" , "[W/m**2]" },
+  { 124 , "uflx" , "Zonal component of momentum flux" , "[N/m**2]" },
+  { 125 , "vflx" , "Meridional component of momentum flux" , "[N/m**2]" },
+  { 126 , "wmixe" , "Wind mixing energy" , "[J]" },
+  { 127 , "imgd" , "Image data" , "[integer]" },
+  { 128 , "mslsa" , "Mean sea level pressure (Std Atm)" , "[Pa]" },
+  { 129 , "mslma" , "Mean sea level pressure (MAPS)" , "[Pa]" },
+  { 130 , "mslet" , "Mean sea level pressure (ETA model)" , "[Pa]" },
+  { 131 , "lftx" , "Surface lifted index" , "[K]" },
+  { 132 , "4lftx" , "Best (4-layer) lifted index" , "[K]" },
+  { 133 , "kx" , "K index" , "[K]" },
+  { 134 , "sx" , "Sweat index" , "[K]" },
+  { 135 , "mconv" , "Horizontal moisture divergence" , "[kg/kg/s]" },
+  { 136 , "vssh" , "Vertical speed shear" , "[1/s]" },
+  { 137 , "tslsa" , "3-hr pressure tendency" , "[Pa/s]" },
+  { 138 , "bvf2" , "Brunt-Vaisala frequency squared" , "[1/s**2]" },
+  { 139 , "pvmw" , "Potential vorticity (mass-weighted)" , "[1/s/m]" },
+  { 140 , "crain" , "Categorical rain (yes=1;no=0)" , "[non-dim]" },
+  { 141 , "cfrzr" , "Categorical freezing rain (yes=1;no=0)" , "[non-dim]" },
+  { 142 , "cicep" , "Categorical ice pellets (yes=1;no=0)" , "[non-dim]" },
+  { 143 , "csnow" , "Categorical snow (yes=1;no=0)" , "[non-dim]" },
+  { 144 , "soilw" , "Volumetric soil moisture content" , "[fraction]" },
+  { 145 , "pevpr" , "Potential evaporation rate" , "[w/m**/]" },
+  { 146 , "cwork" , "Cloud work function" , "[J/Kg]" },
+  { 147 , "u-gwd" , "Zonal gravity wave stress" , "[N/m**2]" },
+  { 148 , "v-gwd" , "Meridional gravity wave stress" , "[N/m**2]" },
+  { 149 , "pv___" , "Potential vorticity" , "[m**2/s/kg]" },
+  { 150 , "undef" , "undef" , "[undef]" },
+  { 151 , "undef" , "undef" , "[undef]" },
+  { 152 , "undef" , "undef" , "[undef]" },
+  { 153 , "mfxdv" , "Moisture flux divergence" , "[gr/gr*m/s/m]" },
+  { 154 , "undef" , "undef" , "[undef]" },
+  { 155 , "gflux" , "Ground heat flux" , "[W/m**2]" },
+  { 156 , "cin" , "Convective inhibition" , "[J/kg]" },
+  { 157 , "cape" , "Convective Available Potential Energy" , "[J/kg]" },
+  { 158 , "tke" , "Turbulent kinetic energy" , "[J/kg]" },
+  { 159 , "condp" , "Condensation pressure of lifted parcel" , "[Pa]" },
+  { 160 , "csusf" , "Clear sky upward solar flux" , "[W/m**2]" },
+  { 161 , "csdsf" , "Clear sky downward solar flux" , "[W/m**2]" },
+  { 162 , "csulf" , "Clear sky upward long wave flux" , "[W/m**2]" },
+  { 163 , "csdlf" , "Clear sky downward long wave flux" , "[W/m**2]" },
+  { 164 , "cfnsf" , "Cloud forcing net solar flux" , "[W/m**2]" },
+  { 165 , "cfnlf" , "Cloud forcing net long wave flux" , "[W/m**2]" },
+  { 166 , "vbdsf" , "Visible beam downward solar flux" , "[W/m**2]" },
+  { 167 , "vddsf" , "Visible diffuse downward solar flux" , "[W/m**2]" },
+  { 168 , "nbdsf" , "Near IR beam downward solar flux" , "[W/m**2]" },
+  { 169 , "nddsf" , "Near IR diffuse downward solar flux" , "[W/m**2]" },
+  { 170 , "ustr" , "U wind stress" , "[N/m**2]" },
+  { 171 , "vstr" , "V wind stress" , "[N/m**2]" },
+  { 172 , "mflx" , "Momentum flux" , "[N/m**2]" },
+  { 173 , "lmh" , "Mass point model surface" , "[integer]" },
+  { 174 , "lmv" , "Velocity point model surface" , "[integer]" },
+  { 175 , "sglyr" , "Nearby model level" , "[integer]" },
+  { 176 , "nlat" , "Latitude" , "[degree]" },
+  { 177 , "nlon" , "Longitude" , "[degree]" },
+  { 178 , "umas" , "Mass weighted u" , "[gm/m*K*s]" },
+  { 179 , "vmas" , "Mass weighted v" , "[gm/m*K*s]" },
+  { 180 , "undef" , "undef" , "[undef]" },
+  { 181 , "lpsx" , "x-gradient of log pressure" , "[1/m]" },
+  { 182 , "lpsy" , "y-gradient of log pressure" , "[1/m]" },
+  { 183 , "hgtx" , "x-gradient of height" , "[m/m]" },
+  { 184 , "hgty" , "y-gradient of height" , "[m/m]" },
+  { 185 , "stdz" , "Standard deviation of Geop. hgt." , "[m]" },
+  { 186 , "stdu" , "Standard deviation of zonal wind" , "[m/s]" },
+  { 187 , "stdv" , "Standard deviation of meridional wind" , "[m/s]" },
+  { 188 , "stdq" , "Standard deviation of spec. hum." , "[gm/gm]" },
+  { 189 , "stdt" , "Standard deviation of temperature" , "[K]" },
+  { 190 , "cbuw" , "Covariance between u and omega" , "[m/s*Pa/s]" },
+  { 191 , "cbvw" , "Covariance between v and omega" , "[m/s*Pa/s]" },
+  { 192 , "cbuq" , "Covariance between u and specific hum" , "[m/s*gm/gm]" },
+  { 193 , "cbvq" , "Covariance between v and specific hum" , "[m/s*gm/gm]" },
+  { 194 , "cbtw" , "Covariance between T and omega" , "[K*Pa/s]" },
+  { 195 , "cbqw" , "Covariance between spec. hum and omeg" , "[gm/gm*Pa/s]" },
+  { 196 , "cbmzw" , "Covariance between v and u" , "[m**2/s**2]" },
+  { 197 , "cbtzw" , "Covariance between u and T" , "[K*m/s]" },
+  { 198 , "cbtmw" , "Covariance between v and T" , "[K*m/s]" },
+  { 199 , "stdrh" , "Standard deviation of Rel. Hum." , "[percent]" },
+  { 200 , "sdtz" , "Std dev of time tend of geop. hgt" , "[m]" },
+  { 201 , "icwat" , "Ice-free water surface" , "[percent]" },
+  { 202 , "sdtu" , "Std dev of time tend of zonal wind" , "[m/s]" },
+  { 203 , "sdtv" , "Std dev of time tend of merid wind" , "[m/s]" },
+  { 204 , "dswrf" , "Downward solar radiation flux" , "[W/m**2]" },
+  { 205 , "dlwrf" , "Downward long wave radiation flux" , "[W/m**2]" },
+  { 206 , "sdtq" , "Std dev of time tend of spec. hum" , "[gm/gm]" },
+  { 207 , "mstav" , "Moisture availability" , "[percent]" },
+  { 208 , "sfexc" , "Exchange coefficient" , "[kg*m/m**3/s]" },
+  { 209 , "mixly" , "Number of mixed layers next to sfc" , "[integer]" },
+  { 210 , "sdtt" , "Std dev of time tend of temperature" , "[K]" },
+  { 211 , "uswrf" , "Upward solar radiation flux" , "[W/m**2]" },
+  { 212 , "ulwrf" , "Upward long wave radiation flux" , "[W/m**2]" },
+  { 213 , "cdlyr" , "Amount of non-convective cloud" , "[percent]" },
+  { 214 , "cprat" , "Convective precipitation rate" , "[kg/m**2/s]" },
+  { 215 , "ttdia" , "Temperature tendency by all physics" , "[K/s]" },
+  { 216 , "ttrad" , "Temperature tendency by all radiation" , "[K/s]" },
+  { 217 , "ttphy" , "Temperature tendency by nonrad physics" , "[K/s]" },
+  { 218 , "preix" , "Precipitation index" , "[fraction]" },
+  { 219 , "tsd1d" , "Std dev of IR T over 1x1 deg area" , "[K]" },
+  { 220 , "nlsgp" , "Natural log of surface pressure" , "[ln(kPa)]" },
+  { 221 , "sdtrh" , "Std dev of time tend of rel hum" , "[percent]" },
+  { 222 , "5wavh" , "5-wave geopotential height" , "[gpm]" },
+  { 223 , "cwat" , "Plant canopy surface water" , "[kg/m**2]" },
+  { 224 , "pltrs" , "Maximum stomato plant resistance" , "[s/m]" },
+  { 225 , "undef" , "undef" , "[undef]" },
+  { 226 , "bmixl" , "Blackadar's mixing length scale" , "[m]" },
+  { 227 , "amixl" , "Asymptotic mixing length scale" , "[m]" },
+  { 228 , "pevap" , "Potential evaporation" , "[kg/m**2]" },
+  { 229 , "snohf" , "Snow phase-change heat flux" , "[W/m**2]" },
+  { 230 , "undef" , "undef" , "[undef]" },
+  { 231 , "mflux" , "Convective cloud mass flux" , "[Pa/s]" },
+  { 232 , "dtrf" , "Downward total radiation flux" , "[W/m**2]" },
+  { 233 , "utrf" , "Upward total radiation flux" , "[W/m**2]" },
+  { 234 , "bgrun" , "Baseflow-groundwater runoff" , "[kg/m**2]" },
+  { 235 , "ssrun" , "Storm surface runoff" , "[kg/m**2]" },
+  { 236 , "undef" , "undef" , "[undef]" },
+  { 237 , "ozone" , "Total column ozone concentration" , "[Dobson]" },
+  { 238 , "snoc" , "Snow cover" , "[percent]" },
+  { 239 , "snot" , "Snow temperature" , "[K]" },
+  { 240 , "glcr" , "Permanent snow points" , "[mask]" },
+  { 241 , "lrghr" , "Large scale condensation heating rate" , "[K/s]" },
+  { 242 , "cnvhr" , "Deep convective heating rate" , "[K/s]" },
+  { 243 , "cnvmr" , "Deep convective moistening rate" , "[kg/kg/s]" },
+  { 244 , "shahr" , "Shallow convective heating rate" , "[K/s]" },
+  { 245 , "shamr" , "Shallow convective moistening rate" , "[kg/kg/s]" },
+  { 246 , "vdfhr" , "Vertical diffusion heating rate" , "[K/s]" },
+  { 247 , "vdfua" , "Vertical diffusion zonal accel" , "[m/s/s]" },
+  { 248 , "vdfva" , "Vertical diffusion meridional accel" , "[m/s/s]" },
+  { 249 , "vdfmr" , "Vertical diffusion moistening rate" , "[kg/kg/s]" },
+  { 250 , "swhr" , "Solar radiative heating rate" , "[K/s]" },
+  { 251 , "lwhr" , "Longwave radiative heating rate" , "[K/s]" },
+  { 252 , "cd" , "Drag coefficient" , "[dimensionless]" },
+  { 253 , "fricv" , "Friction velocity" , "[m/s]" },
+  { 254 , "ri" , "Richardson number" , "[dimensionless]" },
+  { 255 , "undef" , "undef" , "[undef]" }
+
+} ;
diff --git a/src/gx.h b/src/gx.h
new file mode 100644
index 0000000..9f0c2d1
--- /dev/null
+++ b/src/gx.h
@@ -0,0 +1,489 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+#include <stdlib.h>
+
+/* Installation options for the GX package. */
+
+/* HBUFSZ is the size of the metafile output buffer in
+   number of short integers.  The metafile buffer should be as
+   large as is convenient for the target system.  Frames larger
+   than the buffer will get bufferred into the meta file on disk,
+   when BUFOPT is 1.  Otherwise multiple buffers of size HBUFSZ
+   will be allocated as needed. */
+
+#define HBUFSZ 10000000L 
+#define BUFOPT 0
+#define pi M_PI
+
+/* Default directory containing the stroke and map data sets.
+   User can override this default via setenv GADDIR */
+
+/* static char *datad = "/usr/local/lib/grads"; */
+
+
+/* Option flag.  If 0, map data set is only read once into a
+   dynamically allocated memory area.  The memory is held onto
+   for the next call (about 35K).  If 1, the memory is allocated for
+   each call and the map data set is read each time.             */
+/* Lowres map only */
+
+#define MAPOPT 0
+
+/* Spacing to use for shading to get a 'solid' fill when drawing
+   lines side by side at lineweight 3.  */
+
+#define SDIFF 0.005
+
+/* Structure for setting up map projections.  Used to call
+   map projection routines.                                          */
+
+struct mapprj {
+  gadouble lnmn,lnmx,ltmn,ltmx;        /* Lat,lon limits for projections */
+  gadouble lnref;                      /* Reference longitude            */
+  gadouble ltref1,ltref2;              /* Reference latitudes            */
+  gadouble xmn,xmx,ymn,ymx;            /* Put map in this page area      */
+  gadouble axmn,axmx,aymn,aymx;        /* Actual page area used by proj. */
+};
+
+/* Structure for holding info on displayed widgets. */
+
+struct gobj {
+  gaint type;                 /* Basic type of object. -1 - end of list;
+                                0 - none; 1 - btn; 2 - rbb; 3 = popm */
+  gaint i1,i2,j1,j2;          /* Extent of object */
+  gaint mb;                   /* Mouse button that invokes object */
+  union tobj {
+    struct gbtn *btn;       /* Pointer to button struct */
+    struct grbb *rbb;       /* Pointer to rubber-band struct */
+    struct gdmu *dmu;       /* Pointer to drop menu struct */
+  } iob;
+};
+
+/* Structure for holding information about GrADS button widgets */
+/* Also used for popmenus, which display on the screen the same
+   as buttons */
+
+struct gbtn {
+  gadouble x,y,w,h;              /* Button location, size   */     
+  gaint num;                     /* Button number (-1, unset) */
+  gaint ilo,ihi,jlo,jhi;
+  gaint fc,bc,oc1,oc2,ftc,btc,otc1,otc2;  /* Colors           */
+  gaint thk;                     /* Thickness of outline    */
+  gaint state;                   /* Toggled or not?         */
+  gaint len;                     /* Length of string        */
+  char *ch;                      /* String content of btn   */
+};
+
+/* Structure holds info on rubber-band regions */
+
+struct grbb {
+  gadouble xlo,xhi,ylo,yhi;        /* Rubber band region      */  
+  gaint num;                       /* Region number (-1, unset) */
+  gaint mb;                        /* Mouse button specific   */
+  gaint type;                      /* 0 for box, 1 for line   */
+};
+
+/* Structure for info on drop menus */
+
+struct gdmu {
+  gadouble x,y,w,h;                /* Header button loc,size  */
+  gaint num;                       /* Menu number             */
+  gaint casc;                      /* Anchored?               */
+  gaint ilo,ihi,jlo,jhi;
+  gaint fc,bc,oc1,oc2;             /* Colors of base          */
+  gaint tfc,tbc,toc1,toc2;         /* Colors of selected base */
+  gaint bfc,bbc,boc1,boc2;         /* Colors of box           */
+  gaint soc1,soc2;                 /* Colors of selected item */
+  gaint thk;                       /* Thickness of outlines   */
+  gaint len;                       /* Length of string        */
+  char *ch;                        /* String content of menu  */
+};
+
+/* Structure holds info on dialog */
+
+struct gdlg {
+  gadouble x,y,w,h;                /* Button location, size   */
+  gaint pc,fc,bc,oc;  	  	   /* Colors           	    */
+  gaint th;                        /* Thickness of outline    */
+  gaint len;                       /* Length of string        */
+  gaint nu;                        /* Flag for numeric args   */
+  char *ch;                        /* String content of btn   */
+};
+
+
+/* GrADS event queue. This queue is built as the mouse button
+   is clicked, and is cleared by a GrADS clear event.  Events
+   are removed from the queue via the 'q pos' command.  */
+
+struct gevent {
+  struct gevent *forw;     /* Forward pointer */
+  gadouble x, y;           /* X and Y position of cursor */
+  gaint mbtn;              /* Mouse button pressed */
+  gaint type;              /* Type of event */
+  gaint info[10];          /* Integer info about event */
+  gadouble rinfo[4];       /* info about event */
+};
+
+/* Structure for passing information on map plotting options */
+
+struct mapopt {
+  gadouble lnmin,lnmax,ltmin,ltmax;  /* Plot bounds */
+  gaint dcol,dstl,dthk;              /* Default color, style, thickness */
+  gaint *mcol,*mstl,*mthk;           /* Arrays of map line attributes */
+  char *mpdset;                      /* Map data set name */
+};
+
+/* Structure for passing information on the currently open X Window */
+
+struct xinfo {
+  gaint winid;                 /* Window ID */
+  gaint winx;                  /* Window X position (upper left) */
+  gaint winy;                  /* Window Y position (upper left) */
+  gauint winw;                 /* Window width */ 
+  gauint winh;                 /* Window height */ 
+  gauint winb;                 /* Window border width */
+};
+
+/* Struct for passing contour options */
+
+struct gxcntr {
+  gadouble labsiz;             /* Size of contour label, plotting inches */
+  gaint spline;                /* Spline fit flag - 0 no, 1 yes */
+  gaint ltype;                 /* Label type (off, on, masked, forced */
+  gaint mask;                  /* Label masking flag - 0 no, 1 yes */
+  gaint labcol;                /* Override label color, -1 uses contour color */
+  gaint labwid;                /* Override label width, -1 uses contour width,
+                                         -999 does double plot */
+  gaint ccol;                  /* Contour color */
+  char *label;                 /* Contour label */
+  gadouble val;                /* Contour value */
+  gaint shpflg;                /* flag for shapfiles */
+};
+
+/* Function prototypes for GX library routines  */
+
+/* Functions in gxdev:
+   gxdbgn: Initialize hardware
+   gxdend: Terminate hardware
+   gxdfrm: New frame
+   gxdcol: New color
+   gxadcl: Assign rgb color
+   gxdwid: New line width
+   gxdmov: Move pen
+   gxddrw: Draw
+   gxdrec: Filled rectangle
+   gxdsgl: Set single buffer mode
+   gxddbl: Set doulbe buffer mode
+   gxdswp: Swap buffers
+   gxdfil: Hardware Polygon fill
+   gxdxsz: Resize X Window (X only)
+   gxdbtn: Get pointer pos at mouse btn press
+   gxgrey: Set grey scale
+   gxdbck: Set hardware background/foreground
+   gxrswd: Reset Widget Structures
+   gxrs1wd: Reset one widget
+   gxcpwd: Copy widgets on swap in double buffer mode
+   gxevbn: Handle button press event
+   gxevrb: Handle rubber-band event
+   gxdptn: Set fill pattern
+   gxmaskrec: Set mask for a rectangle
+   gxmaskrq: query mask for a rectangular area
+   gxmaskclear: Clear (unset) mask array
+                                                           */
+
+void gxqdrgb (gaint, gaint *, gaint *, gaint *); /* query default color rgb values */
+void gxdbgn (gadouble, gadouble);
+void gxdbat (void);
+void gxdend (void);
+void gxdfrm (int);
+void gxdcol (int);
+gaint gxdacl (int, int, int, int);
+void gxdwid (int);
+void gxdmov (gadouble, gadouble);
+void gxddrw (gadouble, gadouble);
+void gxdrec (gadouble, gadouble, gadouble, gadouble);
+void gxdsgl (void);
+void gxdbl (void);
+void gxdswp (void);
+void gxdfil (gadouble *, gaint);
+void gxdxsz (int, int);
+void gxgrey (int);
+void gxdbck (int);
+gaint gxdbkq (void);
+void gxdeve (int);
+void gxdbtn (gaint, gadouble *, gadouble *, gaint *, gaint *, gaint *, gadouble *);
+void gxdpbn (int, struct gbtn *, int, int, int);
+void gxdrmu (int, struct gdmu *, int, int);
+void gxdsfn (void);
+void gxdcf (void);
+void gxdrdw (void);
+void gxrdrw (int);
+void gxrswd (int);
+void gxrs1wd (int, int);
+void gxcpwd (void);
+void gxevbn (struct gevent *, int);
+void gxevrb (struct gevent *, int, int, int);
+gaint gxevdm (struct gevent *, int, int, int);
+gaint gxpopdm(struct gdmu *, int, int, int, int);
+void gxdrbb (gaint, gaint, gadouble, gadouble, gadouble, gadouble, gaint);
+char *gxdlg (struct gdlg *);
+void gxdptn (int, int, int);
+void gxdssv (int);
+void gxdssh (int);
+void gxdsfr (int);
+gaint win_data (struct xinfo *);
+void gxmaskrec (gadouble, gadouble, gadouble, gadouble);
+gaint gxmaskrq (gadouble, gadouble, gadouble, gadouble);
+void gxmaskclear (void);
+void dump_back_buffer (char *);
+void dump_front_buffer (char *);
+void gxdgeo (char *);
+int gxheps(char*);
+void gxdimg(gaint *, gaint, gaint, gaint, gaint);
+void gxdgcoord(gadouble, gadouble, gaint *, gaint *);
+
+/* Routines in gxsubs:
+   gxstrt: Initialize graphics output
+   gxend:  Terminate graphics output
+   gxfrme: Start new frame
+   gxcolr: Set color attribute
+   gxacol: Assign new rgb to color number from 16-99
+   gxbckg: Set background color
+   gxqbck: Query background color
+   gxwide: Set line width attribute
+   gxmove: Move to X, Y
+   gxdraw: Draw solid line to X, Y using current color and linewidth
+   gxsdrw: Draw, split into small segments to allow masking
+   gxstyl: Set linestyle
+   gxplot: Move or draw using linestyles
+   gxclip: Set clipping region
+   gxchin: Initialize stroke font
+   gxchpl: Draw character(s)
+   gxtitl: Draw centered title
+   gxvpag: Set up virtual page
+   gxvcon: Do virtual page scaling
+   gxscal: Set up level 1 (linear) scaling
+   gxproj: Set up level 2 (projection) scaling
+   gxgrid: Set up level 3 (grid) scaling
+   gxback: Set up level 1 to level 2 back transform
+   gxconv: Convert coordinates to level 0 (hardware)
+   gxxy2w: Convert level 0 to level 2
+   gxcord: Convert array of coordinates to level 0
+   gxrset: Reset projection or grid level scaling
+   gxrecf: Draw filled rectangle
+   gxqclr: Query current color value
+   gxqwid: Query current line width
+   gxqrgb: Query color rgb values
+   gxqstl: Query current linestyle value
+   gxmark: Draw marker
+   gxfill: Polygon fill
+   bdterp: Clipping Boundry Interpolation
+   gxgsym: Get env var
+   gxgnam: Get full path name
+   gxptrn: Set fill pattern
+                                                                */
+
+void gxstrt (gadouble, gadouble, int, int);
+void gxend (void);
+void gxfrme (int);
+void gxsfrm (void);
+void gxcolr (int);
+gaint gxacol (int, int, int, int);
+void gxbckg (int);
+gaint gxqbck (void);
+void gxwide (int);
+void gxmove (gadouble, gadouble);
+void gxdraw (gadouble, gadouble);
+void gxsdrw (gadouble, gadouble);
+void gxstyl (int);
+void gxplot (gadouble, gadouble, int);
+void gxclip (gadouble, gadouble, gadouble, gadouble);
+void gxtitl (char *, gadouble, gadouble, gadouble, gadouble, gadouble);
+void gxvpag (gadouble, gadouble, gadouble, gadouble, gadouble, gadouble);
+void gxvcon (gadouble, gadouble, gadouble *, gadouble *);
+void gxppvp (gadouble, gadouble, gadouble *, gadouble *);
+void gxscal (gadouble, gadouble, gadouble, gadouble, gadouble, gadouble, gadouble, gadouble);
+void gxproj ( void (*) (gadouble, gadouble, gadouble*, gadouble*) );
+void gxgrid ( void (*) (gadouble, gadouble, gadouble*, gadouble*) );
+void gxback ( void (*) (gadouble, gadouble, gadouble*, gadouble*) );
+void gxconv (gadouble, gadouble, gadouble *, gadouble *, gaint);
+void gxxy2w (gadouble, gadouble, gadouble *, gadouble *); 
+void gxgrmp (gadouble, gadouble, gadouble *, gadouble *);
+void gxcord (gadouble *, gaint, gaint);
+void gxrset (int);
+void gxrecf (gadouble, gadouble, gadouble, gadouble);
+gaint gxqwid (void);
+gaint gxqclr (void);
+void gxqrgb (gaint, gaint *, gaint *, gaint *);
+gaint gxqstl (void);
+void gxmark (gaint, gadouble, gadouble, gadouble);
+void gxfill (gadouble *, gaint);
+void bdterp (gadouble, gadouble, gadouble, gadouble, gadouble *, gadouble *);
+void gxptrn (int, int, int);
+char *gxgsym(char *);
+char *gxgnam(char *);
+
+/* Gxmeta routines handle graphics buffering and metafile output.
+   Routines in gxmeta:
+   gxhopt: Specify buffering option before open
+   gxhnew: Buffering initialization on startup
+   gxhbgn: Enable hardcopy (metafile) output
+   hout0:  Buffer 0 arg metafile command
+   hout1:  Buffer one arg metafile command
+   hout2:  Buffer two arg metafile command
+   hout4:  Buffer four arg metafile command
+   hout2i: Buffer two arg int metafile command
+   hout3i: Buffer three arg int metafile command
+   hout4i: Buffer four arg int metafile command
+   hfull:  Deal with full metafile memory buffer
+   gxhprt: Handle print command (output to metafile)
+   gxhwri: Write buffer to metafile
+   gxhend: Close output metafile
+   gxhfrm: Handle new frame action
+   gxhdrw: Handle redraw operation
+                                           */
+
+void gxhopt (int);
+void gxhnew (gadouble, gadouble, int);
+gaint gxhbgn (char *);
+void hout0 (int);
+void hout1 (int, int);
+void hout2 (int, gadouble, gadouble);
+void hout4 (int, gadouble, gadouble, gadouble, gadouble);
+void hout2i (int, int, int);
+void hout3i (int, int, int, int);
+void hout4i (int, int, int, int, int);
+void hfull (void);
+void gxhprt (char *);
+gaint gxhwri (void *, int);
+void gxhend (void);
+void gxhfrm (int);
+void gxhdrw (int);
+void gxddbl (void);
+
+/* Routines in gxchpl:
+   gxchii: Initialize character plotting
+   gxchdf: Set default font
+   gxchpl: Plot character string
+   gxchln: Determine length (in plotting units) of a string
+   gxchgc: Get character info given character and font
+   gxchrd: Read in a font
+                            */
+void  gxchii (void);
+void  gxchdf (gaint);
+void  gxchpl (char *, gaint, gadouble, gadouble, gadouble, gadouble, gadouble);
+gaint gxchln (char *, gaint, gadouble, gadouble *);
+char *gxchgc (gaint, gaint, gaint *);
+gaint gxchrd (gaint);
+
+/* Routine in gxcntr:
+   gxclmn: Specify minimum distance between labels
+   gxclev: Plot contour at specified value
+   gxcflw: Follow a contour segment
+   gxcspl: Spline fit a contour segment
+   gxclab: Draw buffered contour labels.
+   gxpclab: Plot contour labels, buffered or masked
+   gxqclab: When masked labels, test for label overlap
+   pathln: Find shortest col path through grid box
+   gxcrel: Release storage used by the contouring system
+                                                        */
+void gxclmn (gadouble);
+void gxclev (gadouble *, gaint, gaint, gaint, gaint, gaint, gaint,
+                                    gadouble, char *, struct gxcntr *);
+void gxcflw (gaint, gaint, gaint, gaint);
+gaint gxcspl (gaint, struct gxcntr *);
+void gxclab (gadouble, gaint, gaint);
+void gxpclab (gadouble, gadouble, gadouble, gaint, struct gxcntr *);
+int gxqclab (gadouble, gadouble, gadouble);
+gaint pathln (gadouble, gadouble, gadouble, gadouble);
+void gxcrel (void);
+void gxpclin (void);
+/* Routines in gxshad -- color filled contour routine:
+
+   gxshad -- do color filled contours
+   gxsflw -- Follow shade area boundries
+   spathl -- Calculate col path lengths
+   undcol -- Determine undefined-grid-side col characteristics
+   putxy  -- Buffer current coordinate
+   shdcmp -- Compress contour line
+   shdmax -- Determine max or min interior
+                                                                  */
+void  gxshad (gadouble *, gaint, gaint, gadouble *, gaint *, gaint, char *);
+gaint gxsflw (gaint, gaint, gaint);
+gaint spathl (gadouble, gadouble, gadouble, gadouble);
+gaint undcol (gaint, gaint);
+gaint putxy  (gadouble, gadouble);
+void  shdcmp (void);
+gaint shdmax (void);
+
+/* Routines in gxshad2 -- color filled contours */
+
+void gxshad2 (gadouble *, gaint, gaint, gadouble *, gadouble, gaint *, gaint, char *);
+void s2flags (gadouble *, char *, gaint, gaint, gadouble, gadouble);
+void s2poly (gadouble *,  gaint, gaint, gadouble, gadouble);
+gaint s2follow (gadouble *, gaint, gaint, gadouble, gadouble, gaint, gaint, gaint);
+gaint s2col (gadouble, gaint, gaint);
+void s2ppnt(gadouble,gadouble);
+void s2debug ();
+void gxshad2b (gadouble *, gaint, gaint, gadouble *, gadouble, gaint *, gaint, char *);
+void s2box (gadouble, gadouble, gadouble, gadouble, gadouble, gadouble);
+void s2pdrop (gadouble, gadouble, gaint, gaint);
+void s2outpoly(void);
+gaint s2pathln (gadouble, gadouble, gadouble, gadouble, gadouble);
+void s2frepbuf (void);
+gaint s2bufpoly (gaint);
+void s2setbuf (gaint);
+void s2setdraw (gaint);
+gaint s2polyvert (FILE *);
+
+/* routines in gxstrm:  gxstrm (do streamlines) */
+
+void gxstrm (gadouble *, gadouble *, gadouble *, gaint, gaint, char *, char *, char *,
+	     gaint, gadouble *, gaint *, gaint, gaint, gadouble, gadouble, gaint);
+void strmar (gadouble, gadouble, gadouble, gadouble, gadouble, gaint);
+gaint gxshdc (gadouble *, gaint *, gaint, gadouble);
+
+/* Routines in gxwmap:
+   gxwmap: Draw world map
+   gxnmap: Draw medium res n.am. map
+   gxmout: Output section of world map
+   gxnste: Set up projection scaling for north polar stereographic
+   gxnpst: Scaling routine for north polar stereographic projection
+   gxaarw: Direction adjustment for map projection
+   gxgmap: Medium and hi res map drawer
+   gxhqpt: Plot quadrant of medium or hi res map
+   gxmpoly: Interpolate polygon sides for drawing in non-linear map space
+                                                                  */
+
+void gxrsmapt(void);
+void gxdmap (struct mapopt *);
+void gxwmap (gadouble, gadouble, gadouble, gadouble);
+void gxnmap (gadouble, gadouble, gadouble, gadouble);
+void gxmout (int, gadouble, gadouble, gadouble, gadouble, gadouble);
+int  gxltln (struct mapprj *);
+int  gxscld (struct mapprj *, int, int);
+int  gxnste (struct mapprj *);
+void gxnpst (gadouble, gadouble, gadouble *, gadouble *);
+void gxnrev (gadouble, gadouble, gadouble *, gadouble *);
+int  gxsste (struct mapprj *);
+void gxspst (gadouble, gadouble, gadouble *, gadouble *);
+void gxsrev (gadouble, gadouble, gadouble *, gadouble *);
+gadouble gxaarw (gadouble, gadouble);
+void gxgmap (int, int, gadouble, gadouble, gadouble, gadouble);
+void gxhqpt (int, int, int, gadouble, gadouble, gadouble, gadouble, gadouble);
+int  gxrobi (struct mapprj *);
+void gxrobp (gadouble, gadouble, gadouble *, gadouble *);
+void gxrobb (gadouble, gadouble, gadouble *, gadouble *);
+int  gxmoll (struct mapprj *);
+void gxmollp (gadouble, gadouble, gadouble *, gadouble *);
+void gxmollb (gadouble, gadouble, gadouble *, gadouble *);
+int  gxortg (struct mapprj *);
+void gxortgp (gadouble, gadouble, gadouble *, gadouble *);
+void gxortgb (gadouble, gadouble, gadouble *, gadouble *);
+int  gxlamc (struct mapprj *);
+void gxlamcp (gadouble, gadouble, gadouble *, gadouble *);
+void gxlamcb (gadouble, gadouble, gadouble *, gadouble *);
+gadouble *gxmpoly(gadouble *xy, gaint cnt, gadouble llinc, gaint *newcnt); 
+void gree();
diff --git a/src/gxX.c b/src/gxX.c
new file mode 100644
index 0000000..ff69b67
--- /dev/null
+++ b/src/gxX.c
@@ -0,0 +1,3165 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Include ./configure's header file */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+#include "gatypes.h"
+#include "gx.h"
+#include "bitmaps.h"
+
+/* Following function prototype has to go here since it 
+   depends on X include information, which shouln't go in gx.h */
+
+/*  gxbcol:  Assign best rgb to color number from standard colormap */
+gaint gxbcol (XStandardColormap*, XColor *);
+void set_display_screen (Display *, gaint);
+void Window_Dump(Window,FILE *);
+void Pixmap_Dump(Window, FILE *, gaint, gaint, gaint, gaint);
+
+/* Interface for X11 Release 3  */
+
+/* Device interface level.  Following routines need to be
+   interfaced to the hardware:
+
+   gxdbgn - Initialize graphics output.  Set up any hardware
+            scaling needed, clear the graphics display area,
+            etc.
+   gxdcol - Set hardware color.  The colors should be set up
+            as follows:
+            0 - black;   1 - white    2 - red     3 - green
+            4 - blue     5 - cyan     6 - magenta 7 - yellow
+            8 - orange   9 - purple  10 - yell-grn  11 - lt.blue
+           12 - ora.yell 3 - blu-grn 14 - blu-purp  15 - grey
+            If colors are not available then grey scales can
+            be used, or the call can be a no op.
+   gxdwid - Set hardware line weight.
+   gxdfrm - New frame.  If in single buffer mode, clear the active
+            display.  If in double buffer mode, clear the background
+            buffer.
+   gxdsgl - Initiate single buffer mode.  Normal mode of operation.
+   gxddbl - Initiate double buffer mode, if available.  Both the
+            foreground and background displays should be cleared.
+   gxdswp - Swap buffers when in double buffer mode.  Should take
+            no action if in single buffer mode.
+   gxdrec - Draw a color filled rectangle.
+   gxddrw - Draw a line using current attributes
+   gxdmov - Move to a new point
+   gxdend - Terminate graphics output.
+                                                                  */
+
+static gaint batch=0;                       /* Batch mode? */
+static gaint wchose=0;                      /* Controls technique for wide lines 1= s/w 0 X server*/
+static gaint lcolor,lwidth,owidth;          /* Current attributes */
+static gaint grflg;                         /* Greyscale flag */
+static gaint devbck;                        /* Device background */
+static gadouble xscl,yscl;                  /* Window Scaling */
+static gaint xxx,yyy;                       /* Old position */
+static gadouble xsize, ysize;               /* User specified size */
+static unsigned long cvals[276];            /* Color pixel values */
+static gaint cused[276];                    /* Color is assigned */
+static gaint cmach[276];                    /* Color is matched */
+static gaint dblmode;                       /* single or double buffering */
+static gaint width,height,depth;            /* Window dimensions */
+
+static gaint reds[16] =   {  0,255,250,  0, 30,  0,240,230,240,160,160,  0,230,  0,130,170};
+static gaint greens[16] = {  0,255, 60,220, 60,200,  0,220,130,  0,230,160,175,210,  0,170};
+static gaint blues[16]  = {  0,255, 60,  0,255,200,130, 50, 40,200, 50,255, 45,140,220,170};
+
+static gaint greys[16] = {0,255,215,140,80,110,230,170,200,50,155,95,185,125,65,177};
+static gaint grrev[16] = {0,1,14,3,8,7,9,5,4,6,13,12,11,10,2,15};
+
+/* Various arrays are kept for structures that describe displayed
+   widgets.  This information is kept in static arrays for
+   efficiency reasons -- so the arrays will tend to be in memory
+   together and will be much faster to scan when paging is
+   going on.  A linked list set up would be much easier to code
+   and much cleaner, but at least for now I will stick with
+   the pre-defined arrays.  */
+
+static struct gobj obj[512];    /* Displayed objects */
+static struct gobj obj2[512];   /* Background objects */
+static gaint obnum,obnum2;        /* Current number of objects */
+static struct gbtn btn[256];    /* Current buttons */
+static struct gbtn btn2[256];   /* Background buttons */
+static struct grbb rbb[32];     /* Current rubber-band regions */
+static struct grbb rbb2[32];    /* Background rbb regions */
+static struct gdmu dmu[200];    /* Current dropmenus */
+static struct gdmu dmu2[200];   /* Background dropmenus */
+/* static struct gdlg dlg[1];      /\* Current dialog *\/ */
+
+static struct gevent *evbase;   /* Anchor for GrADS event queue */
+
+/* All stuff passed to Xlib routines as args are put here in
+   static areas since we are not invoking Xlib routines from main*/
+
+static Screen *sptr;
+Display *display=(Display *)NULL;
+static gaint snum;
+static GC gc;
+static XGCValues values;
+static XEvent report;
+Window win=(Window) NULL;    /* used via extern in gagui */
+static Pixmap pmap;
+static Pixmap pmaps[200];
+static XImage *image;
+static Drawable drwbl;
+static char *window_name = "GrADS " GRADS_VERSION "";
+/*char *window_name = "GrADS";*/
+static char *display_name = NULL; 
+static char *icon_name = "GrADS";
+static Pixmap icon_pixmap;
+static XSizeHints size_hints;
+/* static XIconSize *size_list; */
+static gaint argc;
+static char **argv;
+static char *args[4];
+static char *name = "grads";
+static char *dgeom = "500x400+10+10";
+static char *ugeom = NULL;
+static Colormap cmap;
+static XColor cell;
+static XPoint *point;
+static gaint dblmode;                     /* single or double buffering */
+static XFontStruct *font1, *font2, *font3;
+static XFontStruct *font1i, *font2i, *font3i;
+static XSetWindowAttributes xsetw;
+static gaint gfont,cfont;                       /* Font in use by grads */
+static gaint pfilld[200];
+static gaint rstate = 1;              /* Redraw state -- when zero,
+                                      acceptance of X Events is
+                                      blocked. */
+static gaint bsflg;                   /* Backing store enabled or not */
+static gaint excnt;                   /* Count of exposes to skip */
+
+/* Invokes usage of software to generate wide lines (vs Xserver) */
+
+void gxwdln (void) {
+  wchose=1;
+}
+
+/* tell x interface that we are in batch mode */
+
+void gxdbat (void) {
+  batch = 1;
+}
+
+/* Query default color rgb values*/
+
+void gxqdrgb (gaint clr, gaint *r, gaint *g, gaint *b) {
+  if (clr>=0 && clr<16) {
+    *r = reds[clr];
+    *g = greens[clr];
+    *b = blues[clr];
+  } 
+  return;
+}
+
+/* Routine to specify user X stuff (geom string, window name).  Must be
+   called before gxdbgn to have any affect */
+
+void gxdgeo (char *arg) {
+  ugeom = arg;
+}
+
+void gxdbgn (gadouble xsz, gadouble ysz) {
+gaint dw, dh, flag, i, ipos, jpos, border;
+char **flist,*xfnam;
+
+  for (i=0; i<200; i++) pfilld[i] = 0;
+  for (i=0; i<256; i++) cused[i] = 0; 
+  for (i=0; i<256; i++) { btn[i].ch = NULL; btn2[i].ch = NULL; }
+  for (i=0; i<256; i++) { btn[i].num = -1; btn2[i].num = -1; }
+  for (i=0; i<32;  i++) { rbb[i].num = -1; rbb2[i].num = -1; }
+  for (i=0; i<200; i++) { dmu[i].num = -1; dmu2[i].num = -1; }
+  for (i=0; i<512; i++) { obj[i].type = -1; obj2[i].type = -1; }
+  obnum = 0; obnum2 = 0;
+  evbase = NULL;
+  excnt = 0;
+
+  args[0] = name;
+  args[1] = NULL;
+  argv = args;
+  argc = 1;
+
+  xsize = xsz;
+  ysize = ysz;
+  border = 4;
+
+  /* Connect to X server */
+
+  if ( (display=XOpenDisplay(display_name)) == NULL ) {
+    printf("Error in GXSTRT: Unable to connect to X server\n");
+    exit( -1 );
+  }
+
+  /* Get screen size from display structure macro, then figure out
+     proper window size */
+
+  snum = DefaultScreen(display);
+  sptr = DefaultScreenOfDisplay(display);
+  bsflg = 0;
+  if (DoesBackingStore(sptr)) bsflg = 1;
+  cmap = DefaultColormap(display, snum);
+  dw = DisplayWidth(display, snum);
+  dh = DisplayHeight(display, snum);
+  depth = DefaultDepth(display, snum);
+  ipos = 0;
+  jpos = 0;
+
+  /* window sizes are scaled according to the height of display */
+  if ( xsize >= ysize ) {           /* landscape */
+    if (xsize==11.0 && ysize==8.5) {    /* preseve old default */
+      dh = (gaint)((gadouble)dh*0.6);        
+      dw = (gaint)((gadouble)(dh)*xsz/ysz);  
+    } else {
+      dw = (gaint)((gadouble)(dw)*0.6);      
+      dh = (gaint)((gadouble)dw*ysz/xsz);
+    }
+  } else {                          /* portrait */
+    dh = (gaint)((gadouble)dh*0.9);
+    dw = (gaint)((gadouble)(dh)*xsz/ysz);
+  } 
+
+  xscl = (gadouble)(dw)/xsize;
+  yscl = (gadouble)(dh)/ysize;
+
+  size_hints.flags = PPosition | PSize ;
+  if (ugeom) {
+    XGeometry (display, snum, ugeom, dgeom, 4, 1, 1, 0, 0,
+        &ipos, &jpos, &dw, &dh);
+    size_hints.flags = USPosition | USSize ;
+  }
+  size_hints.x = ipos;
+  size_hints.y = jpos;
+  size_hints.width = dw;
+  size_hints.height = dh;
+  width = dw ; /* hoop */
+  height = dh ; /* hoop */
+  xscl = (gadouble) (dw) / xsize ; /* hoop */
+  yscl = (gadouble) (dh) / ysize ; /* hoop */
+
+  /* Create window */
+
+  win = XCreateSimpleWindow(display, RootWindow(display,snum),
+        ipos, jpos, dw, dh, border,
+        WhitePixel(display, snum), BlackPixel(display,snum));
+  devbck = 0;
+
+  /* Set up icon pixmap */
+
+  icon_pixmap = XCreateBitmapFromData(display, win, (char*)icon_bitmap_bits,
+                icon_bitmap_width, icon_bitmap_height);
+
+  /* Set standard properties */
+
+  XSetStandardProperties(display, win, window_name, icon_name,
+       icon_pixmap, argv, argc, &size_hints);
+
+  /* Set colors */
+
+  for (i=0; i<16; i++) {
+    cell.red = reds[i]*256;
+    cell.blue = blues[i]*256;
+    cell.green = greens[i]*256;
+    if (XAllocColor(display, cmap, &cell)) {
+      cvals[i] = cell.pixel;
+    } else {
+      cvals[i] = cvals[1];    /* Assume white and black got allocated */
+    }
+    cused[i] = 1;
+  }
+  for (i=0; i<16; i++) {
+    cell.red = greys[i]*256;
+    cell.blue = greys[i]*256;
+    cell.green = greys[i]*256;
+    if (XAllocColor(display, cmap, &cell)) {
+      cvals[i+256] = cell.pixel;
+    } else {
+      cvals[i+256] = cvals[15];
+    }
+    cused[i+256] = 1;
+  }
+
+  /* Select event types */
+
+  XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
+      ButtonMotionMask | ExposureMask | StructureNotifyMask);
+
+  /* Get a Graphics Context */
+
+  gc = XCreateGC(display, win, 0L, &values);
+  XSetForeground(display, gc, cvals[1]);
+  XSetLineAttributes(display, gc, 0L, LineSolid,
+                     CapButt, JoinBevel);
+  lwidth = 1;
+  owidth = 0;
+  lcolor = 1;
+  grflg = 0;
+
+  /* Display Window */
+
+  XMapWindow(display, win);
+
+  /* We now have to wait for the expose event that indicates our
+     window is up.  Also handle any resizes so we get the scaling
+     right in case it gets changed right away.  We will check again
+     for resizes during frame operations */
+
+#ifndef __CYGWIN32__
+  flag = 1;
+  while (flag)  {
+    XNextEvent(display, &report);
+    switch  (report.type) {
+    case Expose:
+      if (report.xexpose.count != 0) break;
+      else flag = 0;
+      break;
+    case ConfigureNotify:
+      width = report.xconfigure.width;
+      height = report.xconfigure.height;
+      xscl = (gadouble)(width)/xsize;
+      yscl = (gadouble)(height)/ysize;    
+      break;
+    }
+  }
+#endif /* __CYGWIN32__ */
+
+  /* Now ready for drawing, so we can exit. */
+
+  drwbl = win;   /* Initial drawable is the visible window */
+  dblmode = 0;   /* Initially no double buffering mode     */
+
+  xsetw.backing_store = Always;
+  XChangeWindowAttributes (display, win, CWBackingStore, &xsetw);
+
+  /* Set up a font */
+
+  font1 = NULL;
+  font2 = NULL;
+  font3 = NULL;
+  font1i = NULL;
+  font2i = NULL;
+  font3i = NULL;
+
+  xfnam = gxgsym("GAXFS");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-80*", 1, &i);
+  }
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-100*", 1, &i);
+  }
+  if (flist==NULL) {
+    font1 = XLoadQueryFont (display, "fixed");
+  } else {
+    font1 = XLoadQueryFont (display, *flist);
+    if (font1==NULL) printf ("ERROR: Unable to open a basic font!!!\n");
+    XFreeFontNames (flist);
+  }
+
+  xfnam = gxgsym("GAXFSI");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-80*", 1, &i);
+  }
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-100*", 1, &i);
+  }
+  if (flist==NULL) {
+    font1i = XLoadQueryFont (display, "fixed");
+  } else {
+    font1i = XLoadQueryFont (display, *flist);
+    if (font1i==NULL) font1i = font1;
+    XFreeFontNames (flist);
+  }
+
+  xfnam = gxgsym("GAXFM");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-r-normal--~-100*", 1, &i);
+  }
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-120*", 1, &i);
+  }
+  if (flist==NULL) {
+    font2 = font1;
+  } else {
+    font2 = XLoadQueryFont (display, *flist);
+    if (font2==NULL) font2 = font1;
+    XFreeFontNames (flist);
+  }
+  xfnam = gxgsym("GAXFMI");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-o-normal--~-100*", 1, &i);
+  }
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-120*", 1, &i);
+  }
+  if (flist==NULL) {
+    font2i = font1i;
+  } else {
+    font2i = XLoadQueryFont (display, *flist);
+    if (font2i==NULL) font2i = font1i;
+    XFreeFontNames (flist);
+  }
+
+  xfnam = gxgsym("GAXFL");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-r-normal-*-140*", 1, &i);
+  }
+  if (flist==NULL) {
+    font3 = font2;
+  } else {
+    font3 = XLoadQueryFont (display, *flist);
+    if (font3==NULL) font3 = font2;
+    XFreeFontNames (flist);
+  }
+  xfnam = gxgsym("GAXFLI");
+  if (xfnam) flist = XListFonts (display, xfnam, 1, &i);
+  else flist = NULL;
+  if (flist==NULL) {
+    flist = XListFonts (display, "-adobe-helvetica-bold-o-normal-*-140*", 1, &i);
+  }
+  if (flist==NULL) {
+    font3i = font2i;
+  } else {
+    font3i = XLoadQueryFont (display, *flist);
+    if (font3i==NULL) font3i = font2i;
+    XFreeFontNames (flist);
+  }
+  cfont = 0;
+  gxdsfn();
+
+}
+
+void gxgrey (gaint flag) {
+  grflg = flag;
+}
+
+void gxdend (void) {
+  XFreeGC(display, gc);
+  XCloseDisplay(display);
+}
+
+/* Frame action.  Values for action are:
+      0 -- new frame (clear display), wait before clearing.
+      1 -- new frame, no wait.
+      2 -- New frame in double buffer mode.
+      7 -- new frame, but just clear graphics.  Do not clear
+           event queue; redraw widgets.
+      8 -- clear only the event queue.
+      9 -- flush the X request buffer */
+
+void gxdfrm (gaint iact) {
+struct gevent *geve, *geve2;
+gaint i;
+  if (iact==9) {
+    gxdeve(0);
+    XFlush(display);
+    return;
+  }
+  if (iact==0 || iact==1 || iact==7) {
+    XSetForeground(display, gc, cvals[devbck]);
+    XFillRectangle (display, drwbl, gc, 0, 0, width, height);
+    XSetForeground(display, gc, cvals[lcolor]);
+    for (i=0; i<512; i++) obj[i].type = -1;
+    obnum = 0;
+  }
+
+  /* Flush X event queue.  If iact is 7, keep the event info,
+     otherwise discard it. */
+
+  if (iact==7) gxdeve(0);
+  else {
+    while (XCheckMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
+             ButtonMotionMask | KeyPressMask |
+             ExposureMask | StructureNotifyMask, &report)) {
+      if (report.type==ConfigureNotify) {
+        if(width!=report.xconfigure.width||height!=report.xconfigure.height){
+          width = report.xconfigure.width;
+          height = report.xconfigure.height;
+          xscl = (gadouble)(width)/xsize;
+          yscl = (gadouble)(height)/ysize;
+          gxdsfn();
+          if (iact==8) gxdrdw();
+        }
+      }
+    }
+
+    /* Flush GrADS event queue */
+
+    geve = evbase;
+    while (geve) {
+      geve2 = geve->forw;
+      free (geve);
+      geve = geve2;
+    }
+    evbase = NULL;
+  }
+
+  /* Reset all widgets if appropriate. */
+
+  if (iact<7 && iact!=2) gxrswd(0);
+
+  /* Redraw all widgets if appropriate.*/
+
+  if (iact==7) {
+    gxrdrw(0);
+    XFlush(display);
+  }
+}
+
+/* Examine X event queue.  Flag tells us if we should wait for an
+   event.  Any GrADS events (mouse-button presses) are queued.
+   If flag is 2, wait for any event, not just a mouse event.  */
+
+void gxdeve (gaint flag) {
+struct gevent *geve, *geve2;
+gaint i,j,ii,rc,wflg,button,eflg,idm,rdrflg;
+
+  if (flag && evbase) flag = 0;   /* Don't wait if an event stacked */
+  wflg = flag;
+  eflg = 0;
+  rdrflg = 0;
+  while (1) {
+    if (wflg && !rdrflg) {
+      XMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
+         ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
+      rc = 1;
+    } else {
+      rc = XCheckMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
+         ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
+    }
+    if (!rc && rdrflg) {
+      gxdsfn();
+      gxdrdw();
+      rdrflg = 0;
+      continue;
+    }
+    if (!rc) break;
+
+    switch  (report.type) {
+    case Expose:
+      if (excnt>0) excnt--;
+      else if (!bsflg) rdrflg = 1;
+      break;
+    case ButtonPress:
+      geve = (struct gevent *)malloc(sizeof(struct gevent));
+      if (geve==NULL) {
+        printf ("Memory allocation error in event queue!!!!!!\n");
+        eflg = 1;
+        break;
+      }
+      if (evbase==NULL) evbase = geve;
+      else {
+        geve2 = evbase;
+        while (geve2->forw) geve2 = geve2->forw;
+        geve2->forw = geve;
+      }
+      geve->forw = NULL;
+      i = report.xbutton.x;
+      j = report.xbutton.y;
+      button = report.xbutton.button;
+      if (button==Button1) button=1;
+      else if (button==Button2) button=2;
+      else if (button==Button3) button=3;
+      else if (button==Button4) button=4;
+      else if (button==Button5) button=5;
+      geve->mbtn = button;
+      geve->x = xsize*((gadouble)i)/width;
+      geve->y = ysize - ysize*((gadouble)j)/height;
+      geve->type = 0;
+
+      /* Scan to see if point-click event was on one of our
+         widgets.  Handling depends on what is clicked on. */
+
+      ii = 0;
+      while (ii<512 && obj[ii].type>-1) {
+        if (obj[ii].type!=0 && i>obj[ii].i1 && i<obj[ii].i2 &&
+                               j>obj[ii].j1 && j<obj[ii].j2) {
+          if (obj[ii].mb < 0 || obj[ii].mb == button) {
+            if (obj[ii].type==1) gxevbn(geve,ii);
+            else if (obj[ii].type==2) gxevrb(geve,ii,i,j);
+            else if (obj[ii].type==3) {
+              idm = ii;
+              while (idm != -999) idm = gxevdm(geve,idm,i,j);
+            }
+            ii = 100000;           /* Exit loop */
+          }
+        }
+        ii++;
+      }
+      wflg = 0;                  /* Check for more events, but don't
+                                    wait if there aren't any. */
+      break;
+    case ConfigureNotify:
+      if(width!=report.xconfigure.width||height!=report.xconfigure.height){
+        width = report.xconfigure.width;
+        height = report.xconfigure.height;
+        xscl = (gadouble)(width)/xsize;
+        yscl = (gadouble)(height)/ysize;
+        rdrflg = 1;
+        if (flag==2) wflg = 0;
+      }
+      break;
+    }
+    if (eflg) break;
+  }
+  if (rdrflg) {
+    gxdsfn();
+    gxdrdw();
+  }
+}
+
+/* Return info on mouse button press event.  Wait if requested. */
+
+void gxdbtn (gaint flag, gadouble *xpos, gadouble *ypos,
+	     gaint *mbtn, gaint *type, gaint *info, gadouble *rinfo) {
+struct gevent *geve;
+gaint i;
+
+  if (batch) {
+    *xpos = -999.9;
+    *ypos = -999.9;
+    return;
+  }
+  gxdeve(flag);
+  if (evbase==NULL) {
+    *xpos = -999.9;
+    *ypos = -999.9;
+    *mbtn = -1;
+    *type = -1;
+  } else {
+    geve = evbase;
+    *xpos = geve->x;
+    *ypos = geve->y;
+    *mbtn = geve->mbtn;
+    *type = geve->type;
+    for (i=0; i<10; i++) *(info+i) = geve->info[i];
+    for (i=0; i<4; i++) *(rinfo+i) = geve->rinfo[i];
+    evbase = geve->forw;       /* Take even off queue */
+    free(geve);
+  }
+
+}
+
+void gxdcol (gaint clr) {
+  if (clr<0) clr=0;
+  if (clr>255) clr=255;
+  if (devbck) {
+    if (clr==0) clr = 1;
+    else if (clr==1) clr = 0;
+  }
+  if (clr<16 && grflg) {
+    if (devbck) clr = grrev[clr];
+    clr+=256; 
+  }
+  if (!cused[clr] && !cmach[clr]) clr=15; 
+  XSetForeground(display, gc, cvals[clr]);
+  lcolor=clr;
+}
+
+
+/* static void qprint(XStandardColormap* bst);  */
+
+gaint gxdacl (gaint clr, gaint red, gaint green, gaint blue) {
+  XStandardColormap best;
+  gaint screen_num = DefaultScreen(display);
+		
+  if (clr<16 || clr>255) return 1;
+  if (cused[clr]) {
+     XFreeColors(display, cmap, &(cvals[clr]),1,0);
+     cused[clr]=0;
+  }
+  cell.red = red*256;
+  cell.blue = blue*256;
+  cell.green = green*256;
+  cmach[clr] = 0;
+  if (XAllocColor(display, cmap, &cell)) {
+    cvals[clr] = cell.pixel;
+    cused[clr] = 1;
+  } else if (XGetStandardColormap(display, 
+             RootWindow(display,screen_num), &best, XA_RGB_BEST_MAP)) {
+    if (gxbcol(&best, &cell)) {
+      cvals[clr] = cell.pixel;
+      cmach[clr] = 1;
+      printf ("Color Match.  Color number = %i\n",clr);
+    } else {
+      printf ("Color Matching Error.  Color number = %i\n",clr);
+    }
+  } else {
+    printf ("Color Map Allocation Error.  Color number = %i\n",clr);
+  }
+  if (cused[clr] == 0 || cmach[clr] == 1) {
+    return 0;
+  } 
+  return(1);
+}
+
+gaint gxbcol (XStandardColormap* best, XColor * cell) {
+  XColor color, colors[256];
+  unsigned long bestpixel=0;
+  gaint d, i;
+  gaint min;
+ 
+  for (i=0; i<256; i++) {
+    colors[i].pixel = i; 
+  }
+
+  XQueryColors(display, cmap, colors, 256);
+
+  min = 65536;
+
+  for (i=0; i<256; i++) {
+    d = abs(cell->red - colors[i].red)
+      + abs(cell->green - colors[i].green) 
+      + abs(cell->blue - colors[i].blue);
+    if (d<min) { min = d;  bestpixel = i; }
+  }
+
+  if (bestpixel < 256) {
+
+    cell->pixel = bestpixel; 
+    color.pixel = bestpixel; 
+    XQueryColor(display, cmap, &color);
+    return 1;
+
+  } else {
+    return 0;
+  }	
+
+}
+
+void gxdwid (gaint wid){                 /* Set width     */
+gauint lw;
+  lwidth=wid;
+  if (wchose) return;
+  lw = 0;
+  if (lwidth>5) lw=2;
+  if (lwidth>11) lw=3;
+  if (lw != owidth) {
+    XSetLineAttributes(display, gc, lw, LineSolid,
+                     CapButt, JoinBevel);
+  }
+  owidth = lw;
+}
+
+void gxdmov (gadouble x, gadouble y){        /* Move to x,y   */
+  xxx = (gaint)(x*xscl+0.5);
+  yyy = height - (gaint)(y*yscl+0.5);
+}
+
+void gxddrw (gadouble x, gadouble y){        /* Draw to x,y   */
+gaint i, j;
+gaint w,h;
+  i = (gaint)(x*xscl+0.5);
+  j = height - (gaint)(y*yscl+0.5);
+  XDrawLine (display, drwbl, gc, xxx, yyy, i, j);
+  if (wchose && lwidth>5) {
+    w = xxx - i;
+    if (w<0) w = -1*w;
+    h = yyy-j;
+    if (h<0) h = -1*h;
+    if (w<h) {
+      XDrawLine (display, drwbl, gc, xxx-1, yyy, i-1, j);
+      if (lwidth>11) XDrawLine (display, drwbl, gc, xxx+1, yyy, i+1, j);
+    } else {
+      XDrawLine (display, drwbl, gc, xxx, yyy-1, i, j-1);
+      if (lwidth>11) XDrawLine (display, drwbl, gc, xxx, yyy+1, i, j+1);
+    }
+  }
+  xxx = i;
+  yyy = j;
+  if (QLength(display)&&rstate) gxdeve(0);
+}
+
+void gxdrec (gadouble x1, gadouble x2, gadouble y1, gadouble y2) {
+gaint i1,i2,j1,j2;
+
+  i1 = (gaint)(x1*xscl+0.5);
+  j1 = height - (gaint)(y1*yscl+0.5);
+  i2 = (gaint)(x2*xscl+0.5);
+  j2 = height - (gaint)(y2*yscl+0.5);
+  if (i1!=i2 && j1!=j2) {
+    XFillRectangle (display, drwbl, gc, i1, j2, i2-i1, j1-j2);
+  } else {
+    XDrawLine (display, drwbl, gc, i1, j1, i2, j2);
+  }
+  if (QLength(display)&&rstate) gxdeve(0);
+}
+
+void gxdsgl (void) {
+gaint i;
+  if (dblmode) {
+    gxrswd(1);
+    for (i=0; i<512; i++) { obj[i].type=-1; obj2[i].type = -1;}
+    obnum = 0;  obnum2 = 0;
+    XFreePixmap (display, pmap);
+    drwbl = win;
+  }
+  dblmode = 0;
+  return;
+}
+
+void gxddbl (void) {
+gaint i;
+  pmap = XCreatePixmap (display, win, width, height, depth);
+  XSync(display, 0) ; /* hoop */
+  if (pmap==(Pixmap)NULL) {
+    printf ("Error allocating pixmap for animation mode\n");
+    printf ("Animation mode will not be enabled\n");
+    return;
+  }
+  dblmode = 1;
+  drwbl = pmap;
+  XSetForeground(display, gc, cvals[devbck]);
+  XFillRectangle (display, drwbl, gc, 0, 0, width, height);
+  XSetForeground(display, gc, cvals[lcolor]);
+  gxrswd(1);  /* Reset all widgets */
+  for (i=0; i<512; i++) { obj[i].type=-1; obj2[i].type = -1;}
+  obnum = 0;  obnum2 = 0;
+  return;
+}
+
+void dump_back_buffer(filename) 
+    char *filename ; 
+{ 
+    FILE *xwdfile ; 
+
+    if (dblmode) { 
+        set_display_screen(display, snum) ; 
+        xwdfile = fopen(filename, "w") ; 
+	if (!xwdfile) { 
+	    fprintf(stderr, "Couldn't open outxwd argument for writing.\n") ; 
+	    return ; 
+	} 
+        fflush(stderr) ; 
+	Window_Dump(win, xwdfile) ; 
+	Pixmap_Dump(pmap, xwdfile, 0, 0, width, height) ; 
+	fclose(xwdfile) ; 
+    } 
+} 
+
+void dump_front_buffer(filename) 
+    char *filename ; 
+{ 
+    FILE *xwdfile ; 
+
+    set_display_screen(display, snum) ; 
+    xwdfile = fopen(filename, "w") ; 
+    if (!xwdfile) { 
+        fprintf(stderr, "Couldn't open outxwd argument for writing.\n") ; 
+	return ; 
+    } 
+    fflush(stderr) ; 
+    Window_Dump(win, xwdfile) ; 
+    Pixmap_Dump(win, xwdfile, 0, 0, width, height) ; 
+    fclose(xwdfile) ; 
+} 
+
+void gxdswp (void) {
+  if (dblmode) {
+    XCopyArea (display, pmap, win, gc, 0, 0, width, height, 0, 0);
+  }
+  XSetForeground(display, gc, cvals[devbck]);
+  XFillRectangle (display, drwbl, gc, 0, 0, width, height);
+  XSetForeground(display, gc, cvals[lcolor]);
+  gxrswd(0);
+  gxcpwd();
+  gxrswd(2);
+  return;
+}
+
+void gxdfil (gadouble *xy, gaint n) {
+gadouble *pt;
+gaint i;
+XPoint *pnt;
+
+  point = (XPoint *)malloc(sizeof(XPoint)*n);
+  if (point==NULL) {
+    printf ("Error in polygon fill routine gxdfil: \n");
+    printf ("   Unable to allocate enough memory for the request\n");
+    return;
+  }
+  pnt = point;
+  pt = xy;
+  for (i=0; i<n; i++) {
+    pnt->x = (gaint)(*pt*xscl+0.5);
+    pnt->y = height - (gaint)(*(pt+1)*yscl+0.5);
+    pt+=2;
+    pnt++;
+  }
+  XFillPolygon (display, drwbl, gc, point, n, Nonconvex, CoordModeOrigin);
+  free (point);
+  if (QLength(display)&&rstate) gxdeve(0);
+  return;
+}
+
+void gxdxsz (gaint xx, gaint yy) {
+  if (batch) return;
+  XResizeWindow (display, win, xx, yy);
+  gxdeve(2);
+}
+
+/* set hardware background color */
+
+void gxdbck (gaint flg) {
+
+  devbck = flg;
+  if (devbck>1) devbck = 1;
+}
+
+gaint gxdbkq  (void) {
+   return (devbck);
+}
+
+/* Routine to display a button widget */
+/* Flags are cumbersome, sigh....
+      redraw -- indicates the button is being redrawn, probably
+                due to a resize event.  When set, the assumption
+                is that *pbn is NULL and is ignored
+      btnrel -- indicates the button is being redrawn in a new state
+                due to a buttonpress/buttonrelease event.
+      nstat  -- forces the state to go to this new setting.
+                Used for 'redraw button' command.  */
+
+void gxdpbn (gaint bnum, struct gbtn *pbn, gaint redraw, gaint btnrel, gaint nstat) {
+gaint i, j, w, h, ilo, ihi, jlo, jhi, ccc, len;
+struct gbtn *gbb;
+struct gobj *pob=NULL;
+  if (bnum<0 || bnum>255) return;
+  if (dblmode) {
+    gbb = &(btn2[bnum]);
+    if (btnrel) {
+      drwbl = win;
+      gbb = &(btn[bnum]);
+    }
+  } else gbb = &(btn[bnum]);
+  if (!redraw) {
+    *gbb = *pbn;
+    gbb->num = bnum;
+  }
+  if (!redraw || rstate==0) {
+    if (dblmode) {
+      if (obnum2>511) {
+        printf ("Error: Too many widgets on screen\n");
+        return;
+      }
+    } else {
+      if (obnum>511) {
+        printf ("Error: Too many widgets on screen\n");
+        return;
+      }
+    }
+    if (dblmode) {pob = &(obj2[obnum2]); obnum2++;}
+    else {pob = &(obj[obnum]); obnum++;}
+  }
+  if (gbb->num<0) return;
+  if (nstat>-1) gbb->state = nstat;
+  if (redraw>1) {
+    if (pbn->ch) {
+      if (gbb->ch) gree(gbb->ch,"f500");
+      gbb->ch = pbn->ch;
+      gbb->len = pbn->len;
+    }
+    if (redraw==3) {
+      gbb->fc = pbn->fc; gbb->bc = pbn->bc;
+      gbb->oc1 = pbn->oc1; gbb->oc2 = pbn->oc2;
+      gbb->ftc = pbn->ftc; gbb->btc = pbn->btc;
+      gbb->otc1 = pbn->otc1; gbb->otc2 = pbn->otc2;
+    }
+  }
+  i = (gaint)(gbb->x*xscl+0.5);
+  j = height - (gaint)(gbb->y*yscl+0.5);
+  w = (gaint)(gbb->w*xscl+0.5);
+  h = (gaint)(gbb->h*yscl+0.5);
+  w = w - 2;
+  h = h - 2;
+  gbb->ilo = 1 + i - w/2;
+  gbb->jlo = 1 + j - h/2;
+  gbb->ihi = gbb->ilo + w;
+  gbb->jhi = gbb->jlo + h;
+  ilo = gbb->ilo;  ihi = gbb->ihi;
+  jlo = gbb->jlo;  jhi = gbb->jhi;
+  if (gbb->state) ccc = gbb->btc;
+  else ccc = gbb->bc;
+  if (ccc>-1) {
+    gxdcol(ccc);
+    XFillRectangle (display, drwbl, gc, gbb->ilo, gbb->jlo, w, h);
+  }
+  gxdwid(gbb->thk);
+  if (gbb->state) ccc = gbb->otc1;
+  else ccc = gbb->oc1;
+  if (ccc>-1) {
+    gxdcol(ccc);
+    XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
+    XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
+  }
+  if (gbb->state) ccc = gbb->otc2;
+  else ccc = gbb->oc2;
+  if (ccc>-1) {
+    gxdcol(ccc);
+    XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
+    XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
+  }
+  if (gbb->state) ccc = gbb->ftc;
+  else ccc = gbb->fc;
+  if (ccc>-1) {
+    len = 0;
+    while (*(gbb->ch+len)) len++;
+/*    len++;*/
+    gxdcol(ccc);
+    if (gfont==1 && font1) {
+      XSetFont (display, gc, font1->fid);
+      w = XTextWidth(font1, gbb->ch, len);
+      i = i - w/2;
+      j = j + 5*font1->ascent/9;
+    }
+    if (gfont==2 && font2) {
+      XSetFont (display, gc, font2->fid);
+      w = XTextWidth(font2, gbb->ch, len);
+      i = i - w/2;
+      j = j + 5*font2->ascent/9;
+    }
+    if (gfont==3 && font3) {
+      XSetFont (display, gc, font3->fid);
+      w = XTextWidth(font3, gbb->ch, len);
+      i = i - w/2;
+      j = j + 5*font3->ascent/9;
+    }
+    XDrawString(display, drwbl, gc, i, j, gbb->ch, len);
+  }
+  gxdcol(lcolor);
+  if (dblmode && btnrel) drwbl = pmap;
+  if (!redraw || rstate==0) {
+    pob->type = 1;
+    pob->mb = -1;
+    pob->i1 = ilo;  pob->i2 = ihi;
+    pob->j1 = jlo;  pob->j2 = jhi;
+    pob->iob.btn = gbb;
+  }
+  XFlush(display);
+}
+
+/* Routine to display a drop menu widget:
+      redraw -- indicates the button is being redrawn, probably
+                due to a resize event.  When set, the assumption
+                is that *dmu is NULL and is ignored; info for
+                redrawing is obtained from the existing
+                structure list.
+      nstat  -- re-defines the dropmenu.
+                Used for 'redraw dropmenu' command.  */
+
+void gxdrmu (gaint mnum, struct gdmu *pmu, gaint redraw, gaint nstat) {
+gaint i, j, w, h, ilo, ihi, jlo, jhi, len, lw;
+struct gdmu *gmu;
+struct gobj *pob=NULL;
+
+  if (mnum<0 || mnum>199) return;
+  if (dblmode) gmu = &(dmu2[mnum]);
+  else gmu = &(dmu[mnum]);
+  if (!redraw) {
+    *gmu = *pmu;
+    gmu->num = mnum;
+  }
+  if (gmu->num<0) return;
+  if (gmu->casc) return;
+  if (!redraw || rstate==0) {
+    if (dblmode) {
+      if (obnum2>511) {
+        printf ("Error: Too many widgets on screen\n");
+        return;
+      }
+    } else {
+      if (obnum>511) {
+        printf ("Error: Too many widgets on screen\n");
+        return;
+      }
+    }
+    if (dblmode) {pob = &(obj2[obnum2]); obnum2++;}
+    else {pob = &(obj[obnum]); obnum++;}
+  }
+  i = (gaint)(gmu->x*xscl+0.5);
+  j = height - (gaint)(gmu->y*yscl+0.5);
+  w = (gaint)(gmu->w*xscl+0.5);
+  h = (gaint)(gmu->h*yscl+0.5);
+  w = w - 2;
+  h = h - 2;
+  gmu->ilo = 1 + i - w/2;
+  gmu->jlo = 1 + j - h/2;
+  gmu->ihi = gmu->ilo + w;
+  gmu->jhi = gmu->jlo + h;
+  ilo = gmu->ilo;  ihi = gmu->ihi;
+  jlo = gmu->jlo;  jhi = gmu->jhi;
+  if (gmu->bc>-1) {
+    gxdcol(gmu->bc);
+    XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
+  }
+  lw = 1;
+  if (gmu->thk>5) lw = 2;
+  if (gmu->thk>12) lw = 3;
+  gxdwid(1);
+  if (gmu->oc1>-1) {
+    gxdcol(gmu->oc1);
+    XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
+    XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
+  }
+  if (gmu->oc2>-1) {
+    gxdcol(gmu->oc2);
+    XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
+    XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
+  }
+  if (gmu->fc>-1) {
+    len = 0;
+    while (*(gmu->ch+len)) len++;
+/*    len++;*/
+    gxdcol(gmu->fc);
+    if (gfont==1 && font1i) {
+      XSetFont (display, gc, font1i->fid);
+      w = XTextWidth(font1i, gmu->ch, len);
+      i = ilo + font1i->ascent/2;
+      j = j + 5*font1i->ascent/9;
+    }
+    if (gfont==2 && font2i) {
+      XSetFont (display, gc, font2i->fid);
+      w = XTextWidth(font2i, gmu->ch, len);
+      i = ilo + font2i->ascent/2;
+      j = j + 5*font2i->ascent/9;
+    }
+    if (gfont==3 && font3i) {
+      XSetFont (display, gc, font3i->fid);
+      w = XTextWidth(font3i, gmu->ch, len);
+      i = ilo + font3i->ascent/2;
+      j = j + 5*font3i->ascent/9;
+    }
+    XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
+    if (gfont==1 && font1) XSetFont (display, gc, font1->fid);
+    if (gfont==2 && font2) XSetFont (display, gc, font2->fid);
+    if (gfont==3 && font3) XSetFont (display, gc, font3->fid);
+  }
+  gxdcol(lcolor);
+  if (!redraw || rstate==0) {
+    pob->type = 3;
+    pob->mb = -1;
+    pob->i1 = ilo;  pob->i2 = ihi;
+    pob->j1 = jlo;  pob->j2 = jhi;
+    pob->iob.dmu = gmu;
+  }
+  XFlush(display);
+}
+
+/* Select font based on screen size */
+
+void gxdsfn(void) {
+
+  if (width<601 || height<421) {
+    if (gfont!=1) {
+      if (font1) XSetFont (display, gc, font1->fid);
+      gfont = 1;
+    }
+  } else if (width<1001 || height<651) {
+    if (gfont!=2) {
+      if (font2) XSetFont (display, gc, font2->fid);
+      gfont = 2;
+    }
+  } else {
+    if (gfont!=3) {
+      if (font3) XSetFont (display, gc, font3->fid);
+      gfont = 3;
+    }
+  }
+}
+
+
+/* Attempt to redraw when user resizes window */
+
+void gxdrdw (void) {
+int i;
+  rstate = 0;
+  XSetForeground(display, gc, cvals[devbck]);
+  XFillRectangle (display, drwbl, gc, 0, 0, width, height);
+  XSetForeground(display, gc, cvals[lcolor]);
+  for (i=0; i<512; i++) obj[i].type = -1;
+  obnum = 0;
+  if (dblmode) {
+    dblmode = 0;
+    XFreePixmap (display, pmap);
+    pmap = XCreatePixmap (display, win, width, height, depth);
+    if (pmap==(Pixmap)NULL) {
+      printf ("Error allocating pixmap for resize operation\n");
+      printf ("Animation mode will be disabled\n");
+      dblmode = 0;
+      drwbl = win;
+      rstate = 1;
+      return;
+    }
+    drwbl = win;
+    XSetForeground(display, gc, cvals[devbck]);
+    XFillRectangle (display, drwbl, gc, 0, 0, width, height);
+    XFillRectangle (display, pmap, gc, 0, 0, width, height);
+    XSetForeground(display, gc, cvals[lcolor]);
+    for (i=0; i<512; i++) obj2[i].type = -1;
+    obnum2 = 0;
+    gxhdrw(1);
+    gxrdrw(1);
+    dblmode = 1;
+    drwbl = pmap;
+  }
+  gxhdrw(0);
+  gxrdrw(0);
+  rstate = 1;
+}
+
+/* Redraw all widgets.  Flag indicates whether to redraw
+   foreground or background widgets. */
+
+void gxrdrw (int flag) {
+int i;
+  if (flag) {
+    for (i=0; i<256; i++) {
+      if (btn2[i].num>-1) gxdpbn(i, NULL, 1, 0, -1);
+    }
+    for (i=0; i<32; i++) {
+      if (rbb2[i].num>-1) gxdrbb(i, rbb2[i].type,
+            rbb2[i].xlo,rbb2[i].ylo,rbb2[i].xhi,rbb2[i].yhi,rbb2[i].mb);
+    }
+    for (i=0; i<200; i++) {
+      if (dmu2[i].num>-1) gxdrmu(i, NULL, 1, -1);
+    }
+  } else {
+    for (i=0; i<256; i++) {
+      if (btn[i].num>-1) gxdpbn(i, NULL, 1, 0, -1);
+    }
+    for (i=0; i<32; i++) {
+      if (rbb[i].num>-1) gxdrbb(i, rbb[i].type,
+            rbb[i].xlo,rbb[i].ylo,rbb[i].xhi,rbb[i].yhi,rbb[i].mb);
+    }
+    for (i=0; i<200; i++) {
+      if (dmu[i].num>-1) gxdrmu(i, NULL, 1, -1);
+    }
+  }
+}
+
+/* Reset all widgets; release memory as appropriate. */
+/* flag = 0 resets foreground, flag = 1 resets both,
+   flag = 2 resets background only; for after swapping */
+
+void gxrswd(int flag) {
+int i;
+
+  if (flag!=2) {
+    for (i=0; i<256; i++) {
+      if (btn[i].num>-1 && btn[i].ch!=NULL) gree(btn[i].ch,"f501");
+      btn[i].num = -1;
+      btn[i].ch = NULL;
+    }
+    for (i=0; i<200; i++) {
+      if (dmu[i].num>-1 && dmu[i].ch!=NULL) gree(dmu[i].ch,"f502");
+      dmu[i].num = -1;
+      dmu[i].ch = NULL;
+    }
+    for (i=0; i<32; i++) rbb[i].num = -1;
+  }
+
+  if (flag) {
+    for (i=0; i<256; i++) {
+      if (flag!=2) {
+        if (btn2[i].num>-1 && btn2[i].ch!=NULL) gree(btn2[i].ch,"f503");
+      }
+      btn2[i].num = -1;
+      btn2[i].ch = NULL;
+    }
+    for (i=0; i<200; i++) {
+      if (flag!=2) {
+        if (dmu2[i].num>-1 && dmu2[i].ch!=NULL) gree(dmu2[i].ch,"f504");
+      }
+      dmu2[i].num = -1;
+      dmu2[i].ch = NULL;
+    }
+    for (i=0; i<32; i++) rbb2[i].num = -1;
+  }
+}
+
+
+/* Copy all widgets during swap in double buffer mode */
+
+void gxcpwd(void) {
+struct grbb *grb;
+struct gbtn *gbn;
+struct gdmu *gmu;
+int i;
+
+  for (i=0; i<256; i++) {
+    if (btn2[i].num>-1) btn[i] = btn2[i];
+  }
+
+  for (i=0; i<200; i++) {
+    if (dmu2[i].num>-1) dmu[i] = dmu2[i];
+  }
+
+  for (i=0; i<32; i++) {
+    if (rbb2[i].num>-1) rbb[i] = rbb2[i];
+  }
+
+  /* Rebuild list of currently displayed items */
+
+  for (i=0; i<512; i++) obj[i].type = -1;
+  obnum = obnum2;
+  for (i=0; i<obnum; i++) {
+    obj[i] = obj2[i];
+    if (obj[i].type==1) {
+      gbn = obj[i].iob.btn;
+      obj[i].iob.btn = &(btn[gbn->num]);
+    } else if (obj[i].type==2) {
+      grb = obj[i].iob.rbb;
+      obj[i].iob.rbb = &(rbb[grb->num]);
+    } else if (obj[i].type==3) {
+      gmu = obj[i].iob.dmu;
+      obj[i].iob.dmu = &(dmu[gmu->num]);
+    }
+  }
+  for (i=0; i<512; i++) obj2[i].type = -1;
+  obnum2 = 0;
+}
+
+/* Reset a particular widget, given widget type and number */
+/* Assumes arrays are used for holding all the widget info */
+
+void gxrs1wd (int wdtyp, int wdnum) {
+struct grbb *grb;
+struct gbtn *gbn;
+struct gdmu *gmu;
+int ii,jj=0;
+
+  if (wdtyp<1 || wdtyp>3) return;
+  if (wdtyp==1 && (wdnum<0 || wdnum>255)) return;
+  if (wdtyp==2 && (wdnum<0 || wdnum>31)) return;
+  if (wdtyp==3 && (wdnum<0 || wdnum>199)) return;
+
+  /* Remove this widget from the list of displayed items */
+
+  ii = 0;
+  while (ii<512 && obj[ii].type>-1) {
+    if (obj[ii].type!=0 && obj[ii].type==wdtyp) {
+      if (obj[ii].type==1) {
+        gbn = obj[ii].iob.btn;
+        jj = gbn->num;
+      } else if (obj[ii].type==2) {
+        grb = obj[ii].iob.rbb;
+        jj = grb->num;
+      } else if (obj[ii].type==3) {
+        gmu = obj[ii].iob.dmu;
+        jj = gmu->num;
+      }
+      if (jj==wdnum) {
+        obj[ii].type = 0;   /* This should be enough to cause this */
+                            /* widget to be ignored. */
+        ii = 100000;   /* Exit loop */
+      }
+    }
+    ii++;
+  }
+
+  /* Remove this widget from the widget array */
+
+  if (wdtyp==1) {
+    if (btn[wdnum].num>-1 && btn[wdnum].num != wdnum)  {
+       printf ("Logic Error 64 in gxrs1wd\n");
+    }
+    if (btn[wdnum].num>-1 && btn[wdnum].ch!=NULL) gree(btn[wdnum].ch,"f505");
+    btn[wdnum].num = -1;
+    btn[wdnum].ch = NULL;
+  } else if (wdtyp==2) {
+    if (rbb[wdnum].num>-1 && rbb[wdnum].num != wdnum) {
+       printf ("Logic Error 65 in gxrs1wd\n");
+    }
+    rbb[wdnum].num = -1;
+  } else if (wdtyp==3) {
+    if (dmu[wdnum].num>-1 && dmu[wdnum].num != wdnum) {
+       printf ("Logic Error 65 in gxrs1wd\n");
+    }
+    if (dmu[wdnum].num>-1 && dmu[wdnum].ch!=NULL) gree(dmu[wdnum].ch,"f506");
+    dmu[wdnum].num = -1;
+    dmu[wdnum].ch = NULL;
+  }
+}
+
+
+/* Click ocurred over a button object. */
+
+void gxevbn(struct gevent *geve, int iobj) {
+struct gbtn *gbn;
+int jj,c1,c2,i1,i2,j1,j2;
+
+  /* Fill in button specific event info */
+
+  geve->type = 1;
+  gbn = obj[iobj].iob.btn;
+  geve->info[0] = gbn->num;
+
+  jj = gbn->num;
+  if (btn[jj].state) {
+    c1=btn[jj].otc1; c2=btn[jj].otc2;
+    geve->info[1] = 0;
+  } else {
+    c1=btn[jj].oc1; c2=btn[jj].oc2;
+    geve->info[1] = 1;
+  }
+
+  /* Redraw button outline as pressed, if appropriate
+     (ie, if the outline colors are different) */
+
+  i1=btn[jj].ilo; i2=btn[jj].ihi;
+  j1=btn[jj].jlo; j2=btn[jj].jhi;
+  if ( !(btn[jj].state && btn[jj].oc1==btn[jj].otc2 &&
+         btn[jj].oc2==btn[jj].otc1)) {
+    if (c2>-1 && c1>-1) {
+      gxdwid(btn[jj].thk);
+      gxdcol(c2);
+      XDrawLine (display, win, gc, i1, j2, i2, j2);
+      XDrawLine (display, win, gc, i2, j2, i2, j1);
+      gxdcol(c1);
+      XDrawLine (display, win, gc, i2, j1, i1, j1);
+      XDrawLine (display, win, gc, i1, j1, i1, j2);
+      XFlush(display);
+    }
+  }
+
+  /* Wait for button release, and do final redraw
+     of button with new state. */
+
+  while (1) {
+    XMaskEvent(display, ButtonReleaseMask | ButtonMotionMask, &report);
+    if (report.type == ButtonRelease) break;
+  }
+
+  if (btn[jj].state) btn[jj].state=0;
+  else btn[jj].state=1;
+  gxdpbn (jj, NULL, 1, 1, -1);
+  XFlush(display);
+}
+
+/* Click ocurred in a rubber-banded region.  */
+
+void gxevrb(struct gevent *geve, int iobj, int i, int j) {
+struct grbb *grb;
+int i1,i2,j1,j2,i1o,j1o,i2o,j2o,xoflg,typ;
+int ilo,ihi,jlo,jhi;
+
+  i1o = i2o = j1o = j2o = 0;
+  /* Get rest of event info */
+  geve->type = 2;
+  grb = obj[iobj].iob.rbb;
+  geve->info[0] = grb->num;
+  typ = grb->type;
+  ilo = obj[iobj].i1;  ihi = obj[iobj].i2;
+  jlo = obj[iobj].j1;  jhi = obj[iobj].j2;
+
+  /* Set foreground color to something that will show up when Xor'd */
+
+  XSetForeground(display, gc, cvals[0]^cvals[1]);
+  XSetFunction(display, gc, GXxor);
+
+  /* Loop on button motion, waiting for button release */
+
+  xoflg = 0;
+  while (1) {
+    XMaskEvent(display, ButtonReleaseMask|ButtonMotionMask, &report);
+    if (report.type==MotionNotify) {
+      if (xoflg) {
+        if (typ==1)
+           XDrawRectangle(display, win, gc, i1o, j1o, i2o-i1o, j2o-j1o);
+        else XDrawLine (display, win, gc, i1o, j1o, i2o, j2o);
+      }
+      if (i<report.xmotion.x) { i1 = i; i2 = report.xmotion.x; }
+      else { i2 = i; i1 = report.xmotion.x; }
+      if (j<report.xmotion.y) { j1 = j; j2 = report.xmotion.y; }
+      else { j2 = j; j1 = report.xmotion.y; }
+      if (i1<ilo) i1 = ilo; if (i2>ihi) i2 = ihi;
+      if (j1<jlo) j1 = jlo; if (j2>jhi) j2 = jhi;
+      if (typ==1) XDrawRectangle (display, win, gc, i1, j1, i2-i1, j2-j1);
+      else XDrawLine (display, win, gc, i1, j1, i2, j2);
+      i1o=i1; i2o=i2; j1o=j1; j2o=j2; xoflg = 1;
+    } else break;
+  }
+  if (xoflg) {
+    if (typ==1)
+       XDrawRectangle(display, win, gc, i1o, j1o, i2o-i1o, j2o-j1o);
+    else XDrawLine (display, win, gc, i1o, j1o, i2o, j2o);
+  }
+  XSetForeground(display, gc, cvals[lcolor]);
+  XSetFunction(display, gc, GXcopy);
+  XFlush(display);
+  i1 = report.xbutton.x; j1 = report.xbutton.y;
+  if (i1<ilo) i1 = ilo; if (i1>ihi) i1 = ihi;
+  if (j1<jlo) j1 = jlo; if (j1>jhi) j1 = jhi;
+  geve->rinfo[0] = xsize*((gadouble)i1)/width;
+  geve->rinfo[1] = ysize - ysize*((gadouble)j1)/height;
+}
+
+/* Set up a rubber-band region.  */
+
+void gxdrbb (gaint num, gaint type,
+                   gadouble xlo, gadouble ylo, gadouble xhi, gadouble yhi, gaint mbc) {
+struct grbb *prb;
+struct gobj *pob;
+
+  if (num<0 || num>31) return;
+  if (xlo>=xhi) return;
+  if (ylo>=yhi) return;
+
+  if (dblmode) {
+    if (obnum2>511) return;
+    pob = &(obj2[obnum2]); obnum2++;
+    prb = &(rbb2[num]);
+  } else {
+    if (obnum>511) return;
+    pob = &(obj[obnum]); obnum++;
+    prb = &(rbb[num]);
+  }
+
+  pob->type = 2;
+  pob->mb = mbc;
+  pob->i1 = (gaint)(xlo*xscl+0.5);
+  pob->i2 = (gaint)(xhi*xscl+0.5);
+  pob->j1 = height - (gaint)(yhi*yscl+0.5);
+  pob->j2 = height - (gaint)(ylo*yscl+0.5);
+  pob->iob.rbb = prb;
+  prb->num = num;
+  prb->xlo = xlo; prb->xhi = xhi;
+  prb->ylo = ylo; prb->yhi = yhi;
+  prb->type = type;
+  prb->mb = mbc;
+}
+
+/* Handle drop menu.  Create new (temporary) window and
+   put the text in it.  Window is destroyed when the mouse
+   button is released.  */
+
+static int dmrecu,dmi1[4],dmi2[4],dmj1[4],dmj2[4],dmnum[4],dmsel[4],dmcur[4];
+
+int gxevdm(struct gevent *geve, int iobj, int ipos, int jpos) {
+struct gdmu *gmu;
+int i,j,iorig,jorig,ival,ilo,ihi,jlo,jhi,w,h,len,lw;
+
+  geve->type = 3;
+  gmu = obj[iobj].iob.dmu;
+
+  /* Redraw base using toggled colors */
+  i=0;
+  ilo = gmu->ilo; ihi = gmu->ihi;
+  jlo = gmu->jlo; jhi = gmu->jhi;
+  w = ihi - ilo;
+  h = jhi - jlo;
+  j = jlo + h/2 - 1;
+  if (gmu->tbc>-1 && gmu->tfc>-1) {
+    if (gmu->tbc>-1) {
+      gxdcol(gmu->tbc);
+      XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
+    }
+    if (gmu->tfc>-1) {
+      len = 0;
+      while (*(gmu->ch+len)) len++;
+/*    len++;*/
+      gxdcol(gmu->tfc);
+      if (gfont==1 && font1i) {
+        XSetFont (display, gc, font1i->fid);
+        w = XTextWidth(font1i, gmu->ch, len);
+        i = ilo + font1i->ascent/2;
+        j = j + 5*font1i->ascent/9;
+      }
+      if (gfont==2 && font2i) {
+        XSetFont (display, gc, font2i->fid);
+        w = XTextWidth(font2i, gmu->ch, len);
+        i = ilo + font2i->ascent/2;
+        j = j + 5*font2i->ascent/9;
+      }
+      if (gfont==3 && font3i) {
+        XSetFont (display, gc, font3i->fid);
+        w = XTextWidth(font3i, gmu->ch, len);
+        i = ilo + font3i->ascent/2;
+        j = j + 5*font3i->ascent/9;
+      }
+      XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
+    }
+  }
+  gxdwid(1);
+  lw = 1;
+  if (gmu->thk>5) lw = 2;
+  if (gmu->thk>11) lw = 3;
+  if (gmu->toc1>-1) {
+    gxdcol(gmu->toc1);
+    XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
+    XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
+  }
+  if (gmu->toc2>-1) {
+    gxdcol(gmu->toc2);
+    XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
+    XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
+  }
+
+  /* Set up and display first menu */
+
+  iorig = obj[iobj].i1;
+  jorig = obj[iobj].j2;
+
+  dmrecu = -1;
+  for (i=0; i<4; i++) {
+    dmi1[i] = -1; dmi2[i] = -1; dmj1[i] = -1; dmj2[i] = -1;
+    dmnum[i] = -1; dmsel[i] = -1;
+  }
+
+  ival = gxpopdm (gmu, iobj, iorig, iorig, jorig);
+
+  /* Display base in standard colors */
+
+  gxdsfn();
+  w = ihi - ilo;
+  h = jhi - jlo;
+  j = jlo + h/2 - 1;
+  if (gmu->bc>-1 && gmu->fc>-1) {
+    if (gmu->bc>-1) {
+      gxdcol(gmu->bc);
+      XFillRectangle (display, drwbl, gc, ilo, jlo, w+1, h+1);
+    }
+    if (gmu->fc>-1) {
+      len = 0;
+      while (*(gmu->ch+len)) len++;
+/*    len++;*/
+      gxdcol(gmu->fc);
+      if (gfont==1 && font1i) {
+        XSetFont (display, gc, font1i->fid);
+        w = XTextWidth(font1i, gmu->ch, len);
+        i = ilo + font1i->ascent/2;
+        j = j + 5*font1i->ascent/9;
+      }
+      if (gfont==2 && font2i) {
+        XSetFont (display, gc, font2i->fid);
+        w = XTextWidth(font2i, gmu->ch, len);
+        i = ilo + font2i->ascent/2;
+        j = j + 5*font2i->ascent/9;
+      }
+      if (gfont==3 && font3i) {
+        XSetFont (display, gc, font3i->fid);
+        w = XTextWidth(font3i, gmu->ch, len);
+        i = ilo + font3i->ascent/2;
+        j = j + 5*font3i->ascent/9;
+      }
+      XDrawString(display, drwbl, gc, i, j, gmu->ch, len);
+    }
+  }
+  gxdwid(gmu->thk);
+  if (gmu->oc1>-1) {
+    gxdcol(gmu->oc1);
+    XDrawLine (display, drwbl, gc, ilo, jhi, ihi, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jhi-1, ihi-1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jhi-2, ihi-2, jhi-2);
+    XDrawLine (display, drwbl, gc, ihi, jhi, ihi, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jhi-1, ihi-1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jhi-2, ihi-2, jlo+2);
+  }
+  if (gmu->oc2>-1) {
+    gxdcol(gmu->oc2);
+    XDrawLine (display, drwbl, gc, ihi, jlo, ilo, jlo);
+    if (lw>1) XDrawLine (display, drwbl, gc, ihi-1, jlo+1, ilo+1, jlo+1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ihi-2, jlo+2, ilo+2, jlo+2);
+    XDrawLine (display, drwbl, gc, ilo, jlo, ilo, jhi);
+    if (lw>1) XDrawLine (display, drwbl, gc, ilo+1, jlo+1, ilo+1, jhi-1);
+    if (lw>2) XDrawLine (display, drwbl, gc, ilo+2, jlo+2, ilo+2, jhi-2);
+  }
+  XFlush(display);
+  for (i=0; i<4; i++) if (dmsel[i]<0) dmnum[i] = -1;
+  geve->info[0] = dmnum[0];
+  geve->info[1] = dmsel[0];
+  geve->info[2] = dmnum[1];
+  geve->info[3] = dmsel[1];
+  geve->info[4] = dmnum[2];
+  geve->info[5] = dmsel[2];
+  geve->info[6] = dmnum[3];
+  geve->info[7] = dmsel[3];
+  return (ival);
+}
+
+/* pull-down menu */
+
+int gxpopdm(struct gdmu *gmu, int iobj, int porig, int iorig, int jorig) {
+int flag,i,j,cnt,len,maxw,w=0,h=0,absx,absy,enter;
+int item=0,itemold,jmin,jmax,imin,imax,isiz,jsiz,j1,j2,dmflag,ii;
+int pimin=0,pjmin=0,pisiz=0,pjsiz=0,ptrs[200],eflag,lln,cascf,ecnt,itt,itt2;
+unsigned long lw;
+char *ch,ich[5];
+Pixmap tpmap=0;
+Window pop, dummy;
+GC gcp;
+
+  dmrecu++;
+  cnt = 0;
+  ch = gmu->ch;
+  len = 0;
+  i = 0;
+  if (dmrecu==0) {
+    while (*(ch+len)) len++;
+    ch = ch+len+1;
+    i = len+1;
+  }
+  maxw = 0;
+  cascf = 0;
+  while (i<gmu->len) {
+    len = 0;
+    lln = 0;
+    ptrs[cnt] = -1;
+    eflag = 1;
+    while (*(ch+len)) {
+      if (i+len+4<gmu->len && *(ch+len)=='>' &&
+           (*(ch+len+1)>='0' && *(ch+len+1)<='9') &&
+           (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
+            *(ch+len+3)=='>') {
+        ich[0] = *(ch+len+1);
+        ich[1] = *(ch+len+2);
+        ich[2] = '\0';
+        ptrs[cnt] =  atoi(ich);
+        eflag = 0;
+        lln--;
+        cascf = 1;
+      }
+      if (i+len+5<gmu->len && *(ch+len)=='>' &&
+           (*(ch+len+1)>='0' && *(ch+len+1)<='1') &&
+           (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
+           (*(ch+len+3)>='0' && *(ch+len+3)<='9') &&
+            *(ch+len+4)=='>') {
+        ich[0] = *(ch+len+1);
+        ich[1] = *(ch+len+2);
+        ich[2] = *(ch+len+3);
+        ich[3] = '\0';
+        ptrs[cnt] =  atoi(ich);
+        eflag = 0;
+        lln--;
+        cascf = 1;
+      }
+      len++;
+      if (eflag) lln++;
+    }
+    if (gfont==1 && font1i) {
+      w = XTextWidth(font1i, ch, lln);
+      h = font1i->ascent;
+    }
+    if (gfont==2 && font2i) {
+      w = XTextWidth(font2i, ch, lln);
+      h = font2i->ascent;
+    }
+    if (gfont==3 && font3i) {
+      w = XTextWidth(font3i, ch, lln);
+      h = font3i->ascent;
+    }
+    w = w + h;
+    if (w>maxw) maxw = w;
+    ch = ch+len+1;
+    i = i+len+1;
+    cnt++;
+  }
+  if (cascf) {
+    ich[0] = 'x'; ich[1] = 'x'; ich[2] = 'x'; ich[3] = 'x';
+    if (gfont==1 && font1i) w = XTextWidth(font1i, ich, 3);
+    if (gfont==2 && font2i) w = XTextWidth(font2i, ich, 3);
+    if (gfont==3 && font3i) w = XTextWidth(font3i, ich, 3);
+    maxw = maxw + w;
+  }
+  h = h*2;
+  jsiz = h * cnt;
+  isiz = maxw;
+  imin = iorig; imax = imin + isiz;
+  jmin = jorig; jmax = jmin + jsiz;
+  if (imax > width) {
+    if (cascf) imax = iorig - isiz;
+/*    else imax = width;*/
+    else imax = porig;
+    imin = imax - isiz;
+  }
+  if (jmax > height) {
+    jmax = height;
+    jmin = jmax - jsiz;
+  }
+
+  dmi1[dmrecu] = imin; dmi2[dmrecu] = imax;
+  dmj1[dmrecu] = jmin; dmj2[dmrecu] = jmax;
+  dmnum[dmrecu] = gmu->num;
+
+  xsetw.save_under = 1;
+  if (!bsflg) {
+    tpmap = XCreatePixmap (display, win, isiz, jsiz, depth);
+    XSync(display, 0);
+    if (tpmap) {
+       pimin = imin; pjmin = jmin; pisiz = isiz; pjsiz = jsiz;
+       XCopyArea (display, win, tpmap, gc, pimin, pjmin, pisiz, pjsiz, 0, 0);
+    }
+  }
+  pop = XCreateWindow(display, win, imin, jmin, isiz, jsiz, 0,
+        CopyFromParent, CopyFromParent, CopyFromParent,
+        CWSaveUnder, &xsetw);
+  XSelectInput(display, pop, ButtonReleaseMask | ButtonPressMask |
+      ButtonMotionMask | ExposureMask | StructureNotifyMask);
+  gcp = XCreateGC(display, pop, 0L, &values);
+  XSetForeground(display, gcp, cvals[1]);
+  lw = 1;
+  if (gmu->thk>5) lw = 2;
+  if (gmu->thk>11) lw = 3;
+  XSetLineAttributes(display, gcp, lw, LineSolid,
+                     CapButt, JoinBevel);
+  XMapWindow(display, pop);
+  flag = 1;
+  while (flag)  {
+    XMaskEvent(display, ExposureMask | StructureNotifyMask, &report);
+    switch  (report.type) {
+    case Expose:
+      if (report.xexpose.count != 0) break;
+      else flag = 0;
+      break;
+    case ConfigureNotify:
+      break;
+    }
+  }
+  if (gmu->bbc>-1) {
+    XSetForeground(display, gcp, cvals[gmu->bbc]);
+    XFillRectangle (display, pop, gcp, 0, 0, isiz, jsiz);
+  }
+  if (gmu->boc1 > -1) {
+    XSetForeground(display, gcp, cvals[gmu->boc1]);
+    XDrawLine (display, pop, gcp, 0, jsiz-1, isiz-1, jsiz-1);
+    XDrawLine (display, pop, gcp, isiz-1, jsiz-1, isiz-1, 0);
+  }
+  if (gmu->boc2 > -1) {
+    XSetForeground(display, gcp, cvals[gmu->boc2]);
+    XDrawLine (display, pop, gcp, isiz-1, 0, 0, 0);
+    XDrawLine (display, pop, gcp, 0, 0, 0, jsiz-1);
+  }
+  if (gfont==1 && font1i) XSetFont (display, gcp, font1i->fid);
+  if (gfont==2 && font2i) XSetFont (display, gcp, font2i->fid);
+  if (gfont==3 && font3i) XSetFont (display, gcp, font3i->fid);
+  cnt = 0;
+  ch = gmu->ch;
+  len = 0;
+  i=0;
+  if (dmrecu==0) {
+    while (*(ch+len)) len++;
+    ch = ch+len+1;
+    i = len+1;
+  }
+  while (i<gmu->len) {
+    len = 0;
+    lln = 0;
+    eflag = 1;
+    while (*(ch+len)) {
+      if (i+len+4<gmu->len && *(ch+len)=='>' &&
+           (*(ch+len+1)>='0' && *(ch+len+1)<='9') &&
+           (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
+            *(ch+len+3)=='>') {
+        eflag = 0;
+      }
+      if (i+len+5<gmu->len && *(ch+len)=='>' &&
+           (*(ch+len+1)>='0' && *(ch+len+1)<='1') &&
+           (*(ch+len+2)>='0' && *(ch+len+2)<='9') &&
+           (*(ch+len+3)>='0' && *(ch+len+3)<='9') &&
+            *(ch+len+4)=='>') {
+        eflag = 0;
+      }
+      len++;
+      if (eflag) lln++;
+    }
+    if (gfont==1 && font1i) {
+      w = XTextWidth(font1i, ch, lln);
+    }
+    if (gfont==2 && font2i) {
+      w = XTextWidth(font2i, ch, lln);
+    }
+    if (gfont==3 && font3i) {
+      w = XTextWidth(font3i, ch, lln);
+    }
+    j1 = h/4;
+    j2 = (cnt+1)*h - h/3;
+    XSetForeground(display, gcp, cvals[gmu->bfc]);
+    XDrawString(display, pop, gcp, j1, j2, ch, lln);
+    if (ptrs[cnt]>-1) {
+      j1 = h/5;
+      j2 = (cnt+1)*h - h/2;
+      if (gmu->soc2 > -1) {
+        XSetForeground(display, gcp, cvals[gmu->soc2]);
+        XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
+        XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
+      }
+      if (gmu->soc1 > -1) {
+        XSetForeground(display, gcp, cvals[gmu->soc1]);
+        XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
+      }
+    }
+    ch = ch+len+1;
+    i = i+len+1;
+    cnt++;
+  }
+  itemold = -1;
+  enter = 1;
+
+  XTranslateCoordinates (display, win, RootWindow (display, snum), 0, 0,
+			      &absx, &absy, &dummy);
+
+  /* Follow pointer around.  If it lands on another drop-menu
+     header, exit to draw that one instead.  */
+
+  dmflag = -999;
+  ecnt = 0;
+  while (1) {
+    XMaskEvent(display, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, &report);
+    if (report.type == ButtonPress || enter == 1) {
+      i = report.xbutton.x_root;
+      j = report.xbutton.y_root;
+      i -= absx;
+      j -= absy;
+      item = (j-jmin)/h;
+      if (i>imax || i<imin || j>jmax || j<jmin) item = -1;
+      if (item > -1 && ptrs[item] > -1) {
+        j1 = item*h+1;
+        dmcur[dmrecu] = item;
+        itt = ptrs[item];
+        if (dmu[itt].num == itt) {
+          dmflag = gxpopdm( &(dmu[ptrs[item]]), iobj, imin, imax, j1+jmin);
+          if (dmflag != -99) {
+            if (dmsel[dmrecu+1]<1) {
+              item = -2;
+              itemold = -2;
+            }
+          }
+        }
+      }
+      dmflag = -999;
+      itemold = item;
+      if(enter == 1) {
+        enter = 0;
+      } else {
+        break;
+      }
+    }
+    if (report.type == ButtonRelease && item > -1) break;
+    if (report.type == MotionNotify) {
+      i = report.xmotion.x;
+      j = report.xmotion.y;
+      i = report.xmotion.x_root;
+      j = report.xmotion.y_root;
+      i -= absx;
+      j -= absy;
+      if (i>imax || i<imin || j>jmax || j<jmin ) {
+        item = -1;
+        if (dmrecu>0) {
+          for (itt=0; itt<dmrecu; itt++) {
+            if (i>=dmi1[itt] && i<=dmi2[itt] &&
+                j>=dmj1[itt] && j<=dmj2[itt]  ) {
+              itt2 = (j-dmj1[itt])/h;
+              if (itt2 != dmcur[itt]) {
+                dmflag = -99;
+                itt = 999;
+              }
+            }
+          }
+        }
+      }
+      else item = (j-jmin)/h;
+      if (dmflag == -99) {itemold = -1; break; }
+      if (item!=itemold) {
+        if (item>-1) {
+          j1 = item*h+lw; j2 = (item+1)*h-lw-1;
+          if (gmu->soc2 > -1) {
+            XSetForeground(display, gcp, cvals[gmu->soc2]);
+            XDrawLine (display, pop, gcp, lw, j1, lw, j2);
+            XDrawLine (display, pop, gcp, lw, j1, isiz-lw-1, j1);
+          }
+          if (gmu->soc1 > -1) {
+            XSetForeground(display, gcp, cvals[gmu->soc1]);
+            XDrawLine (display, pop, gcp, isiz-lw-1, j1, isiz-lw-1, j2);
+            XDrawLine (display, pop, gcp, lw, j2, isiz-lw-1, j2);
+          }
+          if (ptrs[item]>-1) {
+            j1 = h/5;
+            j2 = (item+1)*h - h/2;
+            if (gmu->soc1 > -1) {
+              XSetForeground(display, gcp, cvals[gmu->soc1]);
+              XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
+              XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
+            }
+            if (gmu->soc2 > -1) {
+              XSetForeground(display, gcp, cvals[gmu->soc2]);
+              XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
+            }
+          }
+          ecnt = 0;
+        }
+        if (itemold>-1) {
+          j1 = itemold*h+lw; j2 = (itemold+1)*h-lw-1;
+          if (gmu->bbc > -1) {
+            XSetForeground(display, gcp, cvals[gmu->bbc]);
+            XDrawLine (display, pop, gcp, lw, j1, lw, j2);
+            XDrawLine (display, pop, gcp, lw, j1, isiz-lw-1, j1);
+            XDrawLine (display, pop, gcp, isiz-lw-1, j1, isiz-lw-1, j2);
+            XDrawLine (display, pop, gcp, lw, j2, isiz-lw-1, j2);
+          }
+          if (ptrs[itemold]>-1) {
+            j1 = h/5;
+            j2 = (itemold+1)*h - h/2;
+            if (gmu->soc2 > -1) {
+              XSetForeground(display, gcp, cvals[gmu->soc2]);
+              XDrawLine (display, pop, gcp, isiz-j1*3, j2+j1, isiz-j1*3, j2-j1);
+              XDrawLine (display, pop, gcp, isiz-j1*3, j2-j1, isiz-j1, j2);
+            }
+            if (gmu->soc1 > -1) {
+              XSetForeground(display, gcp, cvals[gmu->soc1]);
+              XDrawLine (display, pop, gcp, isiz-j1, j2, isiz-j1*3, j2+j1);
+            }
+          }
+          ecnt = 0;
+        }
+      }
+      if (ecnt > 3 && item > -1 && item==itemold && ptrs[item] > -1) {
+        j1 = itemold*h+1;
+        dmcur[dmrecu] = item;
+        itt = ptrs[item];
+        if (dmu[itt].num == itt) {
+          dmflag = gxpopdm( &(dmu[ptrs[item]]), iobj, imin, imax, j1+jmin);
+          if (dmflag != -99) {
+            if (dmsel[dmrecu+1]<1) {
+              item = -2;
+              itemold = -2;
+            }
+            break;
+          }
+          dmflag = -999;
+        }
+      }
+      if (item==itemold) ecnt++;
+      itemold = item;
+      if (item==-1) {
+        ii = 0;
+        while (ii<512 && obj[ii].type>-1) {
+          if (ii != iobj && obj[ii].type==3 &&
+              i>obj[ii].i1 && i<obj[ii].i2 && j>obj[ii].j1 && j<obj[ii].j2) {
+            dmflag = ii;
+            ii = 100000;           /* Exit loop */
+          }
+          ii++;
+        }
+      }
+      if (dmflag > -1) break;
+    }
+  }
+  dmsel[dmrecu] = itemold + 1;
+  if (ptrs[itemold]>-1 && dmsel[dmrecu+1]<0) dmsel[dmrecu] = -1;
+  XUnmapWindow(display,pop);
+  XDestroyWindow(display,pop);
+  if (!bsflg) {
+    if (tpmap) {
+      XCopyArea (display, tpmap, win, gc, 0, 0, pisiz, pjsiz, pimin, pjmin);
+      XFreePixmap (display, tpmap);
+    }
+    excnt++;
+  }
+  XFlush(display);
+  dmrecu--;
+  return (dmflag);
+}
+
+/* Handle dialog box.  A new, temporary window is created,
+   and text input is allowed.  Window is destroyed as soon as
+   the enter key is detected.  */
+
+/* modified 102400 by love to support user settings for window with editing. */
+
+char *gxdlg (struct gdlg *qry) {
+int flag,i,j,cnt,len,w,h=0,rlen,plen,tlen;
+int dflag,cn,c0,c1,c2,i1,i2=0,ii,w1=0,w2=0,cflag,eflag,pflag;
+int jmin,imin,isiz,jsiz,j1,j2;
+int n0,n1,n2,n3,n4,n5,n6,n7,p0,p1,p2,p3,p4,p5,p6,pl=0;
+Time lastBtnDown;
+char *tch,buff[80],*rch,ch[1],*pch;
+KeySym keysym;
+int pimin,pjmin,pisiz,pjsiz;
+Pixmap tpmap=0, wmap=0;
+Window pop;
+GC gcp;
+
+  pch = (char *)malloc(512);
+  if (pch==NULL) {
+    printf ("Memory Allocation Error: Dialog Box\n");
+    return ('\0');
+  }
+  tch = (char *)malloc(512);
+  if (tch==NULL) {
+    printf ("Memory Allocation Error: Dialog Box\n");
+    return ('\0');
+  }
+  rch = (char *)malloc(512);
+  if (rch==NULL) {
+    printf ("Memory Allocation Error: Dialog Box\n");
+    return ('\0');
+  }
+  plen = 0;
+  rlen = 0;
+
+  XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
+      ButtonMotionMask | ExposureMask | StructureNotifyMask);
+
+/* Check for a '|' and split the input string into a prompt and
+   an initial string.  Check for a '\' or '/' to split the line */
+  len = 0;
+  if (qry->ch) while (*(qry->ch+len)) len++;
+  flag = 0;
+  pflag = 0;
+  c0 = 0;
+  c1 = 0;
+  c2 = 0;
+  for (i = 0; i<len; i++) {
+    *(tch-c1+i) = *(qry->ch+i);
+    if ((*(qry->ch+i) == '|' || *(qry->ch+i) == '/') && pflag == 0) {
+      c1 = i + 1; 
+      strcpy(pch,tch);
+      pflag = i;
+    }
+    if (*(qry->ch+i) == '/' && flag == 0) flag = i;
+  }
+  plen = c1;
+  if (*(pch) == '|' || *(pch) == '/') {*(pch) = '\0'; plen = 0;}
+  if (*(pch+pflag) == '|' || *(pch+pflag) == '/') *(pch+pflag) = ' ';
+  *(pch+c1) = '\0';
+  
+/* Define input string */
+  for (i = 0; i<len-c1; i++) { /* find leading blanks and new line indicators */
+    if (*(tch+i) == '/' || *(tch+i) == ' ' || *(tch+i) == '|') continue;
+    else {c2 = i; break;}
+  }
+  for (i = 0; i<len-c2; i++) 	/* remove leading blanks and new line indicators */
+    *(rch+i) =  *(tch+c2+i); 
+  strcpy(tch,rch);
+  tlen = len - c2 - c1;
+  *(tch+tlen) = '\0';
+    
+  if (qry->x<0 &&qry->y<0 &&qry->h<0 &&qry->w<0)
+    dflag = 1;
+  else if (flag)
+    dflag = 2; 
+  else 
+    dflag = 0;
+ 
+  if (pflag && !flag) c0 = c1;
+  if (dflag == 1 ) c0 = 0;
+  
+/* Set width and height of dialog box */
+  if (gfont==1 && font1i) {
+    if (pch) w1 = XTextWidth(font1i, pch, plen);
+    else w1 = 0;
+    h = font1i->ascent;
+  }
+  if (gfont==2 && font2i) {
+    if (pch) w1 = XTextWidth(font2i, pch, plen);
+    else w1 = 0;
+    h = font2i->ascent;
+  }
+  if (gfont==3 && font3i) {
+    if (pch) w1 = XTextWidth(font3i, pch, plen);
+    else w1 = 0;
+    h = font3i->ascent;
+  }
+  if (gfont==1 && font1) {
+    if (tch) w2 = XTextWidth(font1, tch, tlen);
+    else w2 = 0;
+    h = font1->ascent;
+  }
+  if (gfont==2 && font2) {
+    if (tch) w2 = XTextWidth(font2, tch, tlen);
+    else w2 = 0;
+    h = font2->ascent;
+   }
+   if (gfont==3 && font3) {
+    if (tch) w1 = XTextWidth(font3, tch, tlen);
+    else w2 = 0;
+    h = font3->ascent;
+  }
+  if (flag) w = ((w1)>(w2))?(w1):(w2);
+  else w = w1 + w2;
+  if (flag) h = h*1.8;
+
+
+/* Convert box size to pixels */
+  if (qry->h == -1 ) {
+    jsiz = h*5;
+    if (jsiz>height) jsiz = height*3/4;
+  }
+  else jsiz = (int)(qry->h*yscl+0.5);
+  if (qry->h == 0 ) jsiz = h*1.8;
+  
+  if (qry->w == -1 ) isiz = width*2/3;
+  else isiz = (int)(qry->w*xscl+0.5);
+  if (qry->w == 0 ) isiz = w+h*1.5;
+  
+  if (qry->x == -1 ) imin = (width-isiz)/2;
+  else imin = qry->x*xscl+0.5-isiz/2;
+  
+  if (qry->y == -1 ) jmin = (height-jsiz)/2;
+  else jmin = height - (qry->y*yscl+0.5+jsiz/2);
+  pimin = imin; pjmin = jmin; pisiz = isiz; pjsiz = jsiz;
+  
+  xsetw.save_under = 1;
+  if (!bsflg) {
+    wmap = XCreatePixmap (display, win, width, height, depth);
+    XSync(display, 0);
+    if (wmap) {
+       XCopyArea (display, win, wmap, gc, 0, 0, width, height, 0, 0);
+    }
+  }
+  pop = XCreateWindow(display, win, pimin, pjmin, pisiz, pjsiz, 0,
+        CopyFromParent, CopyFromParent, CopyFromParent,
+        CWSaveUnder, &xsetw);
+  XSelectInput(display, pop, ExposureMask | StructureNotifyMask | KeyPressMask);
+  gcp = XCreateGC(display, pop, 0L, &values);
+  if (qry->oc > -1) cn = qry->oc;
+  else cn = 1;
+  XSetForeground(display, gcp, cvals[cn]);
+  XSetLineAttributes(display, gcp, 0L, LineSolid,
+                     CapButt, JoinBevel);
+  XMapWindow(display, pop);
+  flag = 1;
+  while (flag)  {
+    XMaskEvent(display, ExposureMask | StructureNotifyMask, &report);
+    switch  (report.type) {
+    case Expose:
+      if (report.xexpose.count != 0) break;
+      else flag = 0;
+      break;
+    case ConfigureNotify:
+      break;
+    }
+  }
+
+/* Draw dialog box and text */
+  if (dflag == 1 && plen == 0) {
+    plen = tlen;
+    strcpy(pch,tch);
+    tlen = 0;
+    *(tch) = '\0';
+  }
+  if (qry->bc > -1) cn = qry->bc;
+  else cn = 15;
+  XSetForeground(display, gcp, cvals[cn]);
+  XFillRectangle (display, pop, gcp, 0, 0, pisiz, pjsiz);
+  if (qry->oc > -1) cn = qry->oc;
+  else cn = 1;
+  XSetForeground(display, gcp, cvals[cn]);
+  XDrawRectangle (display, pop, gcp, 0, 0, pisiz-1, pjsiz-1);
+  if (qry->th > 5) XDrawRectangle (display, pop, gcp, 1, 1, pisiz-3, pjsiz-3);
+  if (qry->fc > -1) cn = qry->fc;
+  else cn = 0;
+  XSetForeground(display, gcp, cvals[cn]);
+  if (dflag) {
+    if (gfont==1 && font1i) XSetFont (display, gcp, font1i->fid);
+    if (gfont==2 && font2i) XSetFont (display, gcp, font2i->fid);
+    if (gfont==3 && font3i) XSetFont (display, gcp, font3i->fid);
+    i = (isiz-w)/2;
+    if (dflag == 1) {
+      j = h*2;
+    } else {
+      j = jsiz*3/7;
+    }
+    XSetForeground(display, gcp, cvals[0]);
+    if (plen>0) XDrawString(display, pop, gcp, i, j, pch, plen);
+    if (qry->pc > -1) cn = qry->pc;
+    else cn = 1;
+    XSetForeground(display, gcp, cvals[cn]);
+    if (plen>0) XDrawString(display, pop, gcp, i-1, j-1, pch, plen);
+    if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
+    if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
+    if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
+    if (dflag == 1) {
+      j = h*4;
+      j1 = h*2+1;
+      j2 = jsiz-j1-1;
+    } else {
+      j = jsiz*6/7;
+      j1 = jsiz*1/2;
+      j2 = jsiz -j1 -1;
+    }
+    if (qry->fc > -1) cn = qry->fc;
+    else cn = 0;
+    XSetForeground(display, gcp, cvals[cn]);
+    if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
+    if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
+    if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
+    if (tlen>0) XDrawString(display, pop, gcp, i, j, tch, tlen);
+    strcpy(rch,tch);
+    rlen = tlen;
+  } else {
+    if (gfont==1 && font1) XSetFont (display, gcp, font1->fid);
+    if (gfont==2 && font2) XSetFont (display, gcp, font2->fid);
+    if (gfont==3 && font3) XSetFont (display, gcp, font3->fid);
+    j1 = 1;
+    j2 = jsiz -j1 -1;
+    j = (j1+j2+h-1)/2;
+    if (pflag) {
+      i = h/2;
+      strcpy(rch,pch);
+      strcat(rch,tch);
+      rlen = plen + tlen;
+      if (rlen>0) XDrawString(display, pop, gcp, i, j, rch, rlen);
+    } else {
+      i = (isiz-w)/2;
+      if (tlen>0) XDrawString(display, pop, gcp, i, j, tch, tlen);
+      strcpy(rch,tch);
+      rlen = tlen;
+    }    
+  }
+
+  if (!bsflg) {
+    tpmap = XCreatePixmap (display, pop, pisiz, pjsiz, depth);
+    XSync(display, 0);
+    if (tpmap) {
+       XCopyArea (display, pop, tpmap, gc, 0, 0, pisiz, pjsiz, 0, 0);
+    }
+  }
+
+/* Loop on edit session and exit on Enter */
+  c1 = rlen;
+  c2 = rlen;
+  cflag = 0;
+  eflag = 0;
+  for (i=0; i<512; i++) *(tch+i) = '\0';
+  lastBtnDown = 0;
+  while (1) {
+    XMaskEvent(display, ButtonReleaseMask | ButtonPressMask |
+         ButtonMotionMask | KeyPressMask | ExposureMask | StructureNotifyMask, &report);
+   
+/*mf 980112
+  explicit cast of report to make it work on the NERSC j90
+  this is NOT correct for X11R6.3
+mf*/
+
+    if (report.type == NoExpose) continue;
+
+    if (report.type == Expose || report.type == GraphicsExpose) {
+      if (excnt>0) excnt--;
+      if (!bsflg) {
+        if (wmap && report.type == Expose) {
+          XCopyArea (display, wmap, win, gc, 0, 0, width, height, 0, 0);
+        }
+        if (tpmap) {
+          XCopyArea (display, tpmap, pop, gc, 0, 0, pisiz, pjsiz, 0, 0);
+        }
+      }
+      XFlush(display);
+    }
+    if (!bsflg && report.type != Expose && report.type != GraphicsExpose && tpmap) {
+      XFreePixmap (display, tpmap); 
+      tpmap = (Pixmap) NULL;
+    }
+    if (report.type == ButtonPress && report.xbutton.time < lastBtnDown + 300) {
+      c1 = c0;
+      c2 = rlen;
+      i1 = (isiz-w)/2;
+      i2 = (isiz+w)/2;
+      cflag = 1;
+    } else if (report.type == ButtonPress && rlen>0) {
+      i1 = report.xbutton.x - imin;
+      if (2*i1 > isiz-w && 2*i1 < isiz+w) c1 = (i1 - (isiz-w)/2 + 4)*rlen/w;
+      if (2*i1 <= isiz-w) c1 = 0;
+      if (2*i1 >= isiz+w) c1 = rlen; 
+      if (2*i1 <= isiz-w) i1 = (isiz-w)/2; 
+      if (2*i1 >= isiz+w) i1 = (isiz+w)/2; 
+      if (c1 < c0) c1 = c0;
+      c2 = c1;
+      lastBtnDown = report.xbutton.time;
+    } else if ((report.type == ButtonRelease || report.type == MotionNotify) && rlen>0 && cflag==0) {
+      i2 = report.xbutton.x - imin;
+      if (2*i2 > isiz-w && 2*i2 < isiz+w) c2 = (i2 - (isiz-w)/2 + 8)*rlen/w;
+      if (2*i2 <= isiz-w) c2 = c0;
+      if (2*i2 >= isiz+w) c2 = rlen; 
+      if (2*i2 <= isiz-w) i2 = (isiz-w)/2; 
+      if (2*i2 >= isiz+w) i2 = (isiz+w)/2; 
+      if (c2 < c0) c2 = c0;
+      cflag = 0;
+    }
+    if(rlen == 0) {
+      i2 = isiz/2;
+      i1 = isiz/2;
+      c2 = c0;
+      c1 = c0;
+    }
+    if (report.type ==  KeyPress) {
+      cnt = XLookupString((XKeyEvent *)&report,buff,80,&keysym,NULL);
+      if (cnt>0) {
+        if (keysym==XK_Return || keysym==XK_Linefeed) {
+          if (qry->nu == 1) {
+            for (i=0; i<rlen-c0; i++) *(tch+i) = *(rch+c0+i);
+            tlen = rlen-c0;
+            ii = 0;
+            n0=0; n1=0; n2=0; n3=0; n4=0; n5=0; n6=0; n7=0;
+            p0=0; p1=0; p2=0; p3=0; p4=0; p5=0; p6=0;
+            for (i = 0; i<tlen; i++) {
+              if (*(tch+i) == '.') {n1++; p1=i+1;}
+              if (*(tch+i) == '+') {n2++; p2=i+1;}
+              if (*(tch+i) == '-') {n3++; p3=i+1;}
+              if (*(tch+i) == 'e') {n4++; p4=i+1;}
+              if (*(tch+i) == 'E') {n5++; p5=i+1;}
+              if (*(tch+i) >= 'a' && *(tch+i) <= 'z' && *(tch+i) != 'e') n0=1;
+              if (*(tch+i) >= 'A' && *(tch+i) <= 'Z' && *(tch+i) != 'E') n0=1;
+              if (n0==1 && p0==0) p0 = i;
+              if (n0==1) pl =i;
+              if (*(tch+i) == '#') {n6++; p6=i+1;}
+              if (*(tch+i) >= '0' && *(tch+i) <= '9') n7=1;
+            }     
+            if (n1==1 && p1==1) ii = 1; /* require digit before decimal  */    
+            if (n1==1 && p1==2 && p2==1 && n2==1) ii = 1;
+            if (n1==1 && p1==2 && p3==1 && n3==1) ii = 1;  
+            if (n1==1 && p1==2 && p2==p4+1 && n2==2) ii = 1;
+            if (n1==1 && p1==2 && p3==p4+1 && n3==2) ii = 1;  
+            if (n1==1 && p1==2 && p2==p5+1 && n2==2) ii = 1;
+            if (n1==1 && p1==2 && p3==p5+1 && n3==2) ii = 1;  
+            if (n1>1) ii = 2; /* too many decimal points */
+            if (n2>=1 && p2>p4+1 && n4==1) ii = 3; /* misplaced + sign in exponent */
+            if (n2>=1 && p2>p5+1 && n5==1) ii = 3;
+            if (n3>=1 && p3>p4+1 && n4==1) ii = 4; /* misplaced - sign in exponent */
+            if (n3>=1 && p3>p5+1 && n5==1) ii = 4;           
+            if (n2>=1 && p2>1 && n4+n5==0) ii = 5; /* misplaced + sign in number */
+            if (n2>=1 && p2>1 && p2<p4 && n4==1) ii = 5;
+            if (n2>=1 && p2>1 && p2<p5 && n5==1) ii = 5;            
+            if (n3>=1 && p3>1 && n4+n5==0) ii = 6; /* misplaced - sign in number */
+            if (n3>=1 && p3>1 && p3<p4 && n4==1) ii = 6;
+            if (n3>=1 && p3>1 && p3<p5 && n5==1) ii = 6;
+            if (n1==1 && p1>p4 && n4==1) ii = 7; /* decimal in exponent */
+            if (n1==1 && p1>p5 && n5==1) ii = 7;            
+            if (n4>0 && p4==tlen) ii = 8; /* missing exponent value */
+            if (n5>0 && p5==tlen) ii = 8;
+            if (n4>0 && p4==tlen-1 && p2==tlen) ii = 8;
+            if (n5>0 && p5==tlen-1 && p2==tlen) ii = 8;
+            if (n4>0 && p4==tlen-1 && p3==tlen) ii = 8;
+            if (n5>0 && p5==tlen-1 && p3==tlen) ii = 8;
+            if (n7==0) ii = 9; /* missing number value */
+            if (n4>0 && p4==1) ii = 9;
+            if (n5>0 && p5==1) ii = 9;
+            if (n4>0 && p4==2 && p1==1) ii = 9;
+            if (n5>0 && p5==2 && p1==1) ii = 9;
+            if (n4>0 && p4==2 && p2==1) ii = 9;
+            if (n5>0 && p5==2 && p2==1) ii = 9;
+            if (n4>0 && p4==2 && p3==1) ii = 9;
+            if (n5>0 && p5==2 && p3==1) ii = 9;
+            if (n2>2) ii = 10; /* too many '+' signs */
+            if (n3>2) ii = 11; /* too many '-' signs */
+            if (n4+n5>1) ii = 12; /* too many exponent symbols */
+            if (n6>0) ii = 13; /* # sign still present, number not entered */
+            if (n0>0) ii = 14; /* number includes an alpha char */
+            if (ii>1) { /* calculate error indices to highlight */
+              eflag = 1;
+              if (ii==2) {c1 = p1-1; c2 = p1;}
+              if (ii==3) {c1 = p2-1; c2 = p2;}
+              if (ii==4) {c1 = p3-1; c2 = p3;}
+              if (ii==5) {c1 = p2-1; c2 = p2;}
+              if (ii==6) {c1 = p3-1; c2 = p3;}
+              if (ii==7) {c1 = p1-1; c2 = p1;}
+              if (ii==8) {c1 = tlen; c2 = tlen+1; 
+                 *(tch+tlen)='#'; *(tch+tlen+1)='\0'; tlen++;}
+              if (ii==9) {c1 = 0; c2 = 1; 
+                  strcpy(rch,tch); *(tch)='#'; 
+                 for (i=1; i<tlen+1; i++) *(tch+i) = *(rch+i-1); 
+                 *(tch+tlen+1) = '\0';}
+              if (ii==10) {c1 = p2-1; c2 = p2;}
+              if (ii==11) {c1 = p3-1; c2 = p3;}
+              if (ii==12) {
+                if (p5>p4) {c1 = p5-1; c2 = p5;}
+                else {c1 = p4-1; c2 = p4;}
+              }
+              if (ii==13) {c1 = p6-1; c2 = p6;}
+              if (ii==14) {c1 = p0-1; c2 = pl+1;}
+              rlen = tlen+c0;
+              if (pflag && !dflag) {
+                c1 += plen; c2 += plen;
+                strcpy(rch,tch);
+                strcpy(tch,pch);
+                strcat(tch,rch);
+                rlen = strlen(tch);
+              } 
+              strcpy(rch,tch);
+            
+            } else {
+              eflag = 0;
+               if (ii==1) { /* insert zero digit before decimal  */ 
+                strcpy(rch,tch);
+                tlen++;
+                ii = 0;
+                for (i=0; i<tlen; i++) {
+                  if (i==p1-1) {
+                    *(tch+i) = '0';
+                    i++;
+                  }
+                  *(tch+i) = *(rch+ii);
+                  ii++;
+                }
+                *(tch+tlen) = '\0';
+              }
+              rlen = tlen+c0;
+              if (pflag && !dflag) {
+                strcpy(rch,tch);
+                strcpy(tch,pch);
+                strcat(tch,rch);
+              }
+              strcpy(rch,tch);
+            
+              break;
+            }           
+          } else break;
+        }
+        if (keysym==XK_BackSpace && c1>c0) {
+          strcpy(tch,rch);
+          ii = 0;
+          for (i=c0; i<rlen; i++) {
+            if (i == c1-1 && c1 == c2) continue;
+            if (i >= c1 && i < c2) continue;
+            *(rch+ii) = *(tch+i);
+            ii++;
+          }
+          rlen = ii;
+          if (pflag && !dflag) {strcpy(tch,pch); strcat(tch,rch); strcpy(rch,tch); rlen+=plen;}
+          *(rch+rlen) = '\0';
+          c1--;
+          c2 = c1;
+        }
+        if (keysym==XK_Delete) {
+          strcpy(tch,rch);
+          ii = 0;
+          for (i=c0; i<rlen; i++) {
+            if (i == c1 && c1 == c2) continue;
+            if (i >= c1 && i < c2) continue;
+            *(rch+ii) = *(tch+i);
+            ii++;
+          }
+          rlen = ii;
+          if (pflag && !dflag) {strcpy(tch,pch); strcat(tch,rch); strcpy(rch,tch); rlen+=plen;}
+          if (c1==rlen &&c1>0) c1--;
+          *(rch+rlen) = '\0';
+          c2 = c1;
+        }
+        if (keysym>=XK_space && keysym<=XK_asciitilde) {
+          if (qry->nu == 1) {
+            *(ch) = buff[0];
+            if ((*ch>='0' && *ch<='9') || *ch=='+' || *ch=='-' || *ch=='.' || *ch=='e' || *ch=='E') ;
+            else continue;
+          }
+          strcpy(tch,rch);
+          rlen += c1-c2+1;
+          ii = 0;
+          for (i=0; i<rlen; i++) {
+            if (i == c1) {
+              *(rch+c1) = buff[0];
+              i++;
+              ii += c2-c1;
+            }
+            *(rch+i) = *(tch+ii);
+            ii++;
+          }
+          c1++;
+          *(rch+rlen) = '\0';
+          c2 = c1;
+        }
+        for (i=0; i<512; i++) *(tch+i) = '\0';
+      }
+      if ((keysym==XK_KP_Left  ||keysym==XK_Left) && c1>c0) {if (c1==c2) c2--; c1--;}
+      if ((keysym==XK_KP_Right ||keysym==XK_Right) && c1<rlen) {if (c1==c2) c2++; c1++;}
+      if ((keysym==XK_KP_Down  ||keysym==XK_Down) && c2>c1) c2--; 
+      if ((keysym==XK_KP_Up    ||keysym==XK_Up) && c2<rlen) c2++;
+    }
+    if (rlen>=0 && c1>=c2) {
+      if (qry->bc > -1) cn = qry->bc;
+      else cn = 15;
+      XSetForeground(display, gcp, cvals[cn]);
+      XFillRectangle (display, pop, gcp, 2, j1+1, isiz-4, j2-2);
+      if (qry->fc > -1) cn = qry->fc;
+      else cn = 0;
+      XSetForeground(display, gcp, cvals[cn]);
+      if (gfont==1 && font1) w = XTextWidth(font1, rch, rlen);
+      if (gfont==2 && font2) w = XTextWidth(font2, rch, rlen);
+      if (gfont==3 && font3) w = XTextWidth(font3, rch, rlen);
+      if (w+h < isiz) i = (isiz-w)/2;
+      else i = isiz-w-h/2;
+      if (pflag && !dflag && w+h < isiz) i = h/2;
+      if (c1>0) strncpy(tch,rch, (size_t) c1);
+      *(tch+c1) = '\0';
+      if (gfont==1 && font1) w1 = XTextWidth(font1, tch, c1);
+      if (gfont==2 && font2) w1 = XTextWidth(font2, tch, c1);
+      if (gfont==3 && font3) w1 = XTextWidth(font3, tch, c1);
+      ii = i+w1;
+      if (ii<=0) {
+        i=-w1;
+        XDrawString(display, pop, gcp, i, j, rch, rlen);
+        XDrawString(display, pop, gcp, i, j, "|", 1);
+      } else {
+        XDrawString(display, pop, gcp, i, j, rch, rlen);
+        XDrawString(display, pop, gcp, ii, j, "|", 1);
+      }
+    }
+    if(c1<c2) {
+      if (gfont==1 && font1) w = XTextWidth(font1, rch, rlen);
+      if (gfont==2 && font2) w = XTextWidth(font2, rch, rlen);
+      if (gfont==3 && font3) w = XTextWidth(font3, rch, rlen);
+      if (w+h < isiz) i = (isiz-w)/2;
+      else i = isiz-w-h/2;
+      if (pflag && !dflag && w+h < isiz) i = h/2;
+      
+      if (c1>0) strncpy(tch,rch, (size_t) c1);
+      *(tch+c1) = '\0';
+      if (gfont==1 && font1) w1 = XTextWidth(font1, tch, c1);
+      if (gfont==2 && font2) w1 = XTextWidth(font2, tch, c1);
+      if (gfont==3 && font3) w1 = XTextWidth(font3, tch, c1);
+      if (qry->bc > -1) cn = qry->bc;
+      else cn = 15;
+      XSetForeground(display, gcp, cvals[cn]);
+      XFillRectangle (display, pop, gcp, 2, j1+1, isiz-4, j2-2);
+      if (qry->fc > -1) cn = qry->fc;
+      else cn = 0;
+      XSetForeground(display, gcp, cvals[cn]);
+      XDrawString(display, pop, gcp, i, j, tch, c1);
+      
+      for (ii=0; ii<c2-c1; ii++) *(tch+ii) = *(rch+ii+c1);
+      *(tch+c2-c1) = '\0';
+      if (gfont==1 && font1) w2 = XTextWidth(font1, tch, c2-c1);
+      if (gfont==2 && font2) w2 = XTextWidth(font2, tch, c2-c1);
+      if (gfont==3 && font3) w2 = XTextWidth(font3, tch, c2-c1);
+      i += w1;     
+      if (qry->fc > -1) cn = qry->fc;
+      else cn = 0;
+      if (eflag) cn = 2;
+      XSetForeground(display, gcp, cvals[cn]);
+      XFillRectangle (display, pop, gcp, i, j1+1, w2, j2-2);
+      if (qry->bc > -1) cn = qry->bc;
+      else cn = 15;
+      XSetForeground(display, gcp, cvals[cn]);
+      XDrawString(display, pop, gcp, i, j, tch, c2-c1);
+      
+      for (ii=0; ii<rlen-c2; ii++) *(tch+ii) = *(rch+ii+c2);
+      *(tch+rlen-c2) = '\0';
+      i += w2;
+      if (qry->bc > -1) cn = qry->bc;
+      else cn = 15;
+      XSetForeground(display, gcp, cvals[cn]);
+      XFillRectangle (display, pop, gcp, i, j1+1, isiz-i2, j2-2);
+      if (qry->fc > -1) cn = qry->fc;
+      else cn = 0;
+      XSetForeground(display, gcp, cvals[cn]);
+      XDrawString(display, pop, gcp, i, j, tch, rlen-c2);
+      
+      if (qry->oc > -1) cn = qry->oc;
+      else cn = 1;
+      XSetForeground(display, gcp, cvals[cn]);
+      XDrawRectangle (display, pop, gcp, 0, 0, isiz-1, jsiz-1);
+      if (qry->th > 5) XDrawRectangle (display, pop, gcp, 1, 1, isiz-3, jsiz-3);
+    }
+    for (i=0; i<512; i++) *(tch+i) = '\0';
+
+    if (!bsflg && report.type != Expose && report.type != GraphicsExpose && !tpmap) {
+      tpmap = XCreatePixmap (display, pop, pisiz, pjsiz, depth);
+      XSync(display, 0);
+      if (tpmap) {
+         XCopyArea (display, pop, tpmap, gc, 0, 0, pisiz, pjsiz, 0, 0);
+      }
+    }
+  }
+
+/* Restore original screen */
+  XUnmapWindow(display,pop);
+  XDestroyWindow(display,pop);
+  gxdsfn();
+  XSelectInput(display, win, ButtonReleaseMask | ButtonPressMask |
+      ButtonMotionMask | ExposureMask | StructureNotifyMask);
+  if (!bsflg) {
+    if (wmap) {
+      XCopyArea (display, wmap, win, gc, 0, 0, width, height, 0, 0);
+      XFreePixmap (display, wmap);
+    }
+    if (tpmap) {
+      XFreePixmap (display, tpmap);
+    }
+    excnt++;
+  }
+  XFlush(display);
+  
+/* Remove '+' signs */
+  if (qry->nu == 1) {
+    strcpy(tch,rch);
+    ii = 0;
+    for (i=0; i<rlen; i++) {
+      if (*(rch+i)  == '+') continue;
+      *(rch+ii) = *(tch+i);
+      ii++;
+    }
+    rlen = ii;
+  } 
+/* Trim prompt string */
+  if (pflag && !dflag) {
+    strcpy(tch,rch);
+    ii = 0;
+    for (i=c0; i<rlen; i++) {
+      *(rch+ii) = *(tch+i);
+      ii++;
+    }
+    rlen = ii;
+  }
+  *(rch+rlen) = '\n';
+  *(rch+rlen+1) = '\0';
+  return (rch);
+}
+
+/* Screen save and show operation */
+/* Save from displayed window.  Do show operation to current
+   window display, sometimes background */
+
+void gxdssv (int frame) {
+  if (batch) {
+    printf("Error: the screen command does not work in batch mode\n");
+    return;
+  }
+  if (frame<0 || frame>199) return;
+  if (!pfilld[frame]) {
+    pmaps[frame] = XCreatePixmap (display, win, width, height, depth);
+    if (pmaps[frame]==(Pixmap)NULL) {
+      printf ("Error allocating pixmap for screen save operation\n");
+      printf ("Screen will not be saved\n");
+      return;
+    }
+    pfilld[frame] = 1;
+  }
+  XCopyArea (display, win, pmaps[frame], gc, 0, 0, width, height, 0, 0);
+}
+
+void gxdssh (int cnt) {
+  if (batch) {
+    printf("Error: the screen command does not work in batch mode\n");
+    return;
+  }
+  if (cnt<0 || cnt>199) return;
+  if (pfilld[cnt]) XCopyArea (display, pmaps[cnt], drwbl, gc, 0, 0, width, height, 0, 0);
+}
+
+void gxdsfr (int frame) {
+  if (batch) {
+    printf("Error: the screen command does not work in batch mode\n");
+    return;
+  }
+  if (frame<0 || frame>199) return;
+  if (pfilld[frame]) {
+    XFreePixmap (display, pmaps[frame]);
+    pfilld[frame] = 0;
+  }
+}
+
+/* Routine to install stipple pixmaps to provide pattern fills for
+   recf and polyf.  Choices include solid, dot, line and open.
+   Check and line density can be controlled as well as line angle. */
+
+void gxdptn (int typ, int den, int ang) {
+unsigned char *bitmap_bits;
+int bitmap_width, bitmap_height;
+Pixmap stipple_pixmap;
+
+  if (typ==0) {
+    bitmap_bits = open_bitmap_bits;
+    bitmap_width = open_bitmap_width;
+    bitmap_height = open_bitmap_height;
+  }
+  else if (typ==1) {
+    XSetFillStyle (display, gc, FillSolid);
+    return;
+  }
+  else if (typ==2) {
+    if (den==6) {
+      bitmap_bits = dot_6_bitmap_bits;
+      bitmap_width = dot_6_bitmap_width;
+      bitmap_height = dot_6_bitmap_height;
+    }
+    else if (den==5) {
+      bitmap_bits = dot_5_bitmap_bits;
+      bitmap_width = dot_5_bitmap_width;
+      bitmap_height = dot_5_bitmap_height;
+    }
+    else if (den==4) {
+      bitmap_bits = dot_4_bitmap_bits;
+      bitmap_width = dot_4_bitmap_width;
+      bitmap_height = dot_4_bitmap_height;
+    }
+    else if (den==3) {
+      bitmap_bits = dot_3_bitmap_bits;
+      bitmap_width = dot_3_bitmap_width;
+      bitmap_height = dot_3_bitmap_height;
+    }
+    else if (den==2) {
+      bitmap_bits = dot_2_bitmap_bits;
+      bitmap_width = dot_2_bitmap_width;
+      bitmap_height = dot_2_bitmap_height;
+    }
+    else if (den==1) {
+      bitmap_bits = dot_1_bitmap_bits;
+      bitmap_width = dot_1_bitmap_width;
+      bitmap_height = dot_1_bitmap_height;
+    }
+    else {
+      printf ("Error in density specification: density = %d\n",den);
+      return;
+    }
+  }
+  else if (typ==3) {
+    if (ang==0) {
+      if (den==5) {
+        bitmap_bits = line_0_5_bitmap_bits;
+        bitmap_width = line_0_5_bitmap_width;
+        bitmap_height = line_0_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_0_4_bitmap_bits;
+        bitmap_width = line_0_4_bitmap_width;
+        bitmap_height = line_0_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_0_3_bitmap_bits;
+        bitmap_width = line_0_3_bitmap_width;
+        bitmap_height = line_0_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_0_2_bitmap_bits;
+        bitmap_width = line_0_2_bitmap_width;
+        bitmap_height = line_0_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_0_1_bitmap_bits;
+        bitmap_width = line_0_1_bitmap_width;
+        bitmap_height = line_0_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==30) {
+      if (den==5) {
+        bitmap_bits = line_30_5_bitmap_bits;
+        bitmap_width = line_30_5_bitmap_width;
+        bitmap_height = line_30_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_30_4_bitmap_bits;
+        bitmap_width = line_30_4_bitmap_width;
+        bitmap_height = line_30_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_30_3_bitmap_bits;
+        bitmap_width = line_30_3_bitmap_width;
+        bitmap_height = line_30_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_30_2_bitmap_bits;
+        bitmap_width = line_30_2_bitmap_width;
+        bitmap_height = line_30_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_30_1_bitmap_bits;
+        bitmap_width = line_30_1_bitmap_width;
+        bitmap_height = line_30_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==45) {
+      if (den==5) {
+        bitmap_bits = line_45_5_bitmap_bits;
+        bitmap_width = line_45_5_bitmap_width;
+        bitmap_height = line_45_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_45_4_bitmap_bits;
+        bitmap_width = line_45_4_bitmap_width;
+        bitmap_height = line_45_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_45_3_bitmap_bits;
+        bitmap_width = line_45_3_bitmap_width;
+        bitmap_height = line_45_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_45_2_bitmap_bits;
+        bitmap_width = line_45_2_bitmap_width;
+        bitmap_height = line_45_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_45_1_bitmap_bits;
+        bitmap_width = line_45_1_bitmap_width;
+        bitmap_height = line_45_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==60) {
+      if (den==5) {
+        bitmap_bits = line_60_5_bitmap_bits;
+        bitmap_width = line_60_5_bitmap_width;
+        bitmap_height = line_60_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_60_4_bitmap_bits;
+        bitmap_width = line_60_4_bitmap_width;
+        bitmap_height = line_60_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_60_3_bitmap_bits;
+        bitmap_width = line_60_3_bitmap_width;
+        bitmap_height = line_60_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_60_2_bitmap_bits;
+        bitmap_width = line_60_2_bitmap_width;
+        bitmap_height = line_60_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_60_1_bitmap_bits;
+        bitmap_width = line_60_1_bitmap_width;
+        bitmap_height = line_60_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==-30) {
+      if (den==5) {
+        bitmap_bits = line_120_5_bitmap_bits;
+        bitmap_width = line_120_5_bitmap_width;
+        bitmap_height = line_120_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_120_4_bitmap_bits;
+        bitmap_width = line_120_4_bitmap_width;
+        bitmap_height = line_120_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_120_3_bitmap_bits;
+        bitmap_width = line_120_3_bitmap_width;
+        bitmap_height = line_120_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_120_2_bitmap_bits;
+        bitmap_width = line_120_2_bitmap_width;
+        bitmap_height = line_120_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_120_1_bitmap_bits;
+        bitmap_width = line_120_1_bitmap_width;
+        bitmap_height = line_120_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==-45) {
+      if (den==5) {
+        bitmap_bits = line_135_5_bitmap_bits;
+        bitmap_width = line_135_5_bitmap_width;
+        bitmap_height = line_135_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_135_4_bitmap_bits;
+        bitmap_width = line_135_4_bitmap_width;
+        bitmap_height = line_135_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_135_3_bitmap_bits;
+        bitmap_width = line_135_3_bitmap_width;
+        bitmap_height = line_135_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_135_2_bitmap_bits;
+        bitmap_width = line_135_2_bitmap_width;
+        bitmap_height = line_135_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_135_1_bitmap_bits;
+        bitmap_width = line_135_1_bitmap_width;
+        bitmap_height = line_135_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==-60) {
+      if (den==5) {
+        bitmap_bits = line_150_5_bitmap_bits;
+        bitmap_width = line_150_5_bitmap_width;
+        bitmap_height = line_150_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_150_4_bitmap_bits;
+        bitmap_width = line_150_4_bitmap_width;
+        bitmap_height = line_150_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_150_3_bitmap_bits;
+        bitmap_width = line_150_3_bitmap_width;
+        bitmap_height = line_150_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_150_2_bitmap_bits;
+        bitmap_width = line_150_2_bitmap_width;
+        bitmap_height = line_150_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_150_1_bitmap_bits;
+        bitmap_width = line_150_1_bitmap_width;
+        bitmap_height = line_150_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else if (ang==90||ang==-90) {
+      if (den==5) {
+        bitmap_bits = line_90_5_bitmap_bits;
+        bitmap_width = line_90_5_bitmap_width;
+        bitmap_height = line_90_5_bitmap_height;
+      }
+      else if (den==4) {
+        bitmap_bits = line_90_4_bitmap_bits;
+        bitmap_width = line_90_4_bitmap_width;
+        bitmap_height = line_90_4_bitmap_height;
+      }
+      else if (den==3) {
+        bitmap_bits = line_90_3_bitmap_bits;
+        bitmap_width = line_90_3_bitmap_width;
+        bitmap_height = line_90_3_bitmap_height;
+      }
+      else if (den==2) {
+        bitmap_bits = line_90_2_bitmap_bits;
+        bitmap_width = line_90_2_bitmap_width;
+        bitmap_height = line_90_2_bitmap_height;
+      }
+      else if (den==1) {
+        bitmap_bits = line_90_1_bitmap_bits;
+        bitmap_width = line_90_1_bitmap_width;
+        bitmap_height = line_90_1_bitmap_height;
+      }
+      else {
+        printf ("Error in density specification: density = %d\n",den);
+        return;
+      }
+    }
+    else {
+      printf ("Error in angle specification: angle = %d\n",ang);
+      return;
+    }
+  }
+  else {
+    printf ("Error in fill specification: type = %d\n",typ);
+    return;
+  }
+
+  if (typ>1) {
+    stipple_pixmap = XCreateBitmapFromData(display, win, (char*)bitmap_bits,
+		     bitmap_width, bitmap_height);
+    XSetStipple(display, gc, stipple_pixmap);
+    XSetFillStyle(display, gc, FillStippled);
+  }
+}
+
+/*gl 980114 - function to save window info gl*/
+/*
+ * int
+ * win_data ---  Saves current window information 
+ */
+
+int win_data (struct xinfo *xinf) {
+  int absx, absy;
+  Window dummy;
+  XWindowAttributes result;
+
+  if (display == (Display *) NULL || win == (Window) NULL) return 0;
+  if (!XGetWindowAttributes (display, win, &result) ) return 0;
+  if (!XTranslateCoordinates (display, win, RootWindow (display, snum), 0, 0,
+			      &absx, &absy, &dummy) ) return 0;
+  xinf->winid=(int)win;
+  xinf->winw=result.width;  
+  xinf->winh=result.height;  
+  xinf->winb=result.border_width;
+  xinf->winx=absx;  
+  xinf->winy=absy;  
+  return 1;
+}
+ 
+/* Given x,y page location, return screen pixel location */
+
+void gxdgcoord (gadouble x, gadouble y, gaint *i, gaint *j) {
+  if (batch) {
+    *i = -999;
+    *j = -999;
+    return;
+  }
+  *i = (gaint)(x*xscl+0.5);
+  *j = height - (gaint)(y*yscl+0.5);
+}
+
+void gxdimg(gaint *im, gaint imin, gaint jmin, gaint isiz, gaint jsiz) {
+int i,j,col;
+
+  if (batch) return;
+
+  image = XGetImage(display, drwbl, imin, jmin, isiz, jsiz, AllPlanes, XYPixmap);
+  if (image==NULL) {
+    printf ("Unable to allocate image file for gxout imap. \n");
+    return;
+  }
+
+  for (j=0; j<jsiz; j++) {
+    for (i=0; i<isiz; i++) {
+       col = *(im+j*isiz+i);
+       if (col<255) XPutPixel(image,i,j,cvals[col]);
+    }
+  }
+  XPutImage(display, drwbl, gc, image, 0, 0, imin, jmin, isiz, jsiz);
+  XDestroyImage(image);
+}
diff --git a/src/gxchpl.c b/src/gxchpl.c
new file mode 100644
index 0000000..34f3dbe
--- /dev/null
+++ b/src/gxchpl.c
@@ -0,0 +1,310 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+/* Plot character strings using the Hershey fonts */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+#include <stdio.h>
+#include <math.h>
+#include "gatypes.h"
+#include "gx.h"
+
+static char *fch[10];     /* Pointers to font data once it is read in */
+static gaint *foff[10];   /* Pointers to character offsets */
+static gaint *flen[10];   /* Pointers to character lengths */
+static gaint dfont;       /* Default font */
+void gree();
+
+/* Initialize */
+
+void gxchii (void) {
+gaint i;
+  for (i=0; i<10; i++) fch[i] = NULL;
+  dfont = 0;
+}
+
+/* Change default font */
+
+void gxchdf (gaint df) {
+  if (df<0 || df>9) return;
+  dfont = df;
+}
+
+/* Plot character string */
+
+void gxchpl (char *chrs, int len, gadouble x, gadouble y, gadouble height, gadouble width, gadouble angle) {
+gadouble xc,yc,xscl,yscl,xs,ys,w,d,ang,rx,ry,yoff;
+gaint i,fn,ic,jc,cnt,ipen,supsub;
+char *cdat;
+
+  xscl = width/21.0;
+  yscl = height/22.0;
+  fn = dfont;
+  angle = angle*M_PI/180;
+  supsub = 0;
+  while (*chrs!='\0' && len>0) {
+    while (*chrs=='`') {
+      if (*(chrs+1)>='0' && *(chrs+1)<='9') {
+        fn = (gaint)*(chrs+1) - 48;
+        chrs+=2;
+        len-=2;
+      } else if (*(chrs+1)=='a') {
+        supsub = 1;
+        chrs+=2; len-=2;
+      } else if (*(chrs+1)=='b') {
+        supsub = 2;
+        chrs+=2; len-=2;
+      } else if (*(chrs+1)=='n') {
+        supsub = 0;
+        chrs+=2; len-=2;
+      } else break;
+    }
+    if (*chrs!='\0' && len>0) {
+      if (angle==0.0) {           /* Fast path for ang=0 */
+        cdat = gxchgc ( (gaint)*(chrs), fn, &cnt);
+        if (cdat==NULL) return;
+        ic = (gaint)(*(cdat+3)) - 82;
+        jc = (gaint)(*(cdat+4)) - 82;
+        if (supsub) {
+          xs = xscl*0.45; ys = yscl*0.45;
+          if (supsub==1) yoff = height*0.35;
+          else yoff = -1.0*height*0.42;
+        } else {
+          xs = xscl; ys = yscl; yoff = 0.0;
+        }
+        w = (gadouble)(jc-ic) * xs * 1.05;
+        xc= x + w/2.0;
+        yc = y + height*0.42 + yoff;
+        cdat += 5;
+        ipen = 3;
+        for (i=1; i<cnt; i++) {
+          ic = (gaint)*cdat;
+          jc = (gaint)*(cdat+1);
+          if (ic==32) ipen = 3;
+          else {
+            ic = ic - 82;
+            jc = jc - 82;
+            rx = xc + ((gadouble)ic)*xs;
+            ry = yc - ((gadouble)jc)*ys;
+            if (ipen==3) gxmove (rx,ry);
+            else gxdraw (rx,ry);
+            ipen = 2;
+          }
+          cdat += 2;
+        }
+        x = x + w;
+        chrs++; len--;
+      } else {
+        cdat = gxchgc ( (gaint)*(chrs), fn, &cnt);
+        if (cdat==NULL) return;
+        ic = (gaint)(*(cdat+3)) - 82;
+        jc = (gaint)(*(cdat+4)) - 82;
+        if (supsub) {
+          xs = xscl*0.45; ys = yscl*0.45;
+          if (supsub==1) yoff = height*0.35;
+          else yoff = -1.0*height*0.42;
+        } else {
+          xs = xscl; ys = yscl; yoff = 0.0;
+        }
+        w = (gadouble)(jc-ic) * xs * 1.05;
+        d = hypot(w/2.0,height*0.42+yoff);
+        ang = atan2(height*0.42+yoff,w/2.0)+angle;
+        xc = x + d*cos(ang);
+        yc = y + d*sin(ang);
+        cdat += 5;
+        ipen = 3;
+        for (i=1; i<cnt; i++) {
+          ic = (gaint)*cdat;
+          jc = (gaint)*(cdat+1);
+          if (ic==32) ipen = 3;
+          else {
+            ic = ic - 82;
+            jc = jc - 82;
+            rx = ((gadouble)ic)*xs;
+            ry = -1.0*((gadouble)jc)*ys;
+            if (rx==0.0 && ry==0.0) {
+              d = 0.0; ang = 0.0;
+            } else {
+              d = hypot(rx,ry);
+              ang = atan2(ry,rx)+angle;
+            }
+            rx = xc + d*cos(ang);
+            ry = yc + d*sin(ang);
+            if (ipen==3) gxmove (rx,ry);
+            else gxdraw (rx,ry);
+            ipen = 2;
+          }
+          cdat += 2;
+        }
+        x = x + w*cos(angle);
+        y = y + w*sin(angle);
+        chrs++; len--;
+      }
+    }
+  }
+}
+
+/* Figure out the length of a character string, without
+   plotting it */
+
+gaint gxchln (char *chrs, gaint len, gadouble width, gadouble *w) {
+int fn,ic,jc,supsub;
+gadouble xscl,xs;
+char *cdat;
+
+  *w = 0.0;
+  xscl = width/21.0;
+  fn = dfont;
+  supsub = 0;
+  while (*chrs!='\0' && len>0) {
+    while (*chrs=='`') {
+      if (*(chrs+1)>='0' && *(chrs+1)<='9') {
+        fn = (gaint)*(chrs+1) - 48;
+        chrs+=2;
+        len-=2;
+      } else if (*(chrs+1)=='a') {
+        supsub = 1;
+        chrs+=2; len-=2;
+      } else if (*(chrs+1)=='b') {
+        supsub = 2;
+        chrs+=2; len-=2;
+      } else if (*(chrs+1)=='n') {
+        supsub = 0;
+        chrs+=2; len-=2;
+      } else break;
+    }
+    cdat = gxchgc ((gaint)*(chrs), fn, &ic);
+    if (cdat==NULL) return(1);
+    ic = (gaint)(*(cdat+3)) - 82;
+    jc = (gaint)(*(cdat+4)) - 82;
+    if (supsub) xs = xscl*0.45;
+    else xs = xscl;
+    *w = *w + (gadouble)(jc-ic) * xs * 1.05;
+    chrs++; len--;
+  }
+  return 0;
+}
+
+/* Get location and length of particular character info
+   for particular font */
+
+char * gxchgc (int ch, int fn, int *cnt) {
+int *clen, *coff, rc;
+char *fdat;
+
+  if (fch[fn]==NULL) {
+    rc = gxchrd (fn);
+    if (rc) return(NULL);
+  }
+  clen = flen[fn];
+  coff = foff[fn];
+  fdat = fch[fn];
+  if (ch<32 || ch>127) ch=32;
+  ch = ch - 32;
+  *cnt = *(clen+ch);
+  return (fdat + *(coff+ch));
+}
+
+/* Read in a font file */
+
+int gxchrd (int fn) {
+FILE *ifile;
+gaint i,j,rc,tlen,*coff,*clen,flag;
+char buff[20],*fname,*fdat;
+
+  snprintf(buff,19,"font%i.dat",fn);
+
+  ifile = NULL;
+  fname = gxgnam(buff);
+  if (fname!=NULL) ifile = fopen(fname,"rb");
+  if (ifile==NULL) {
+    ifile = fopen(buff,"rb");
+    if (ifile==NULL) {
+      printf ("Error opening stroke character data set \n");
+      if (fname!=NULL) {
+        printf ("  Data set names = %s ; %s\n",fname,buff);
+        gree (fname,"f295");
+      }
+      return(1);
+    }
+  }
+  gree(fname,"f296");
+
+  fseek(ifile,0L,2);
+  tlen = ftell(ifile);
+  fseek(ifile,0L,0);
+
+  fdat = (char *)malloc(tlen+1);
+  if (fdat==NULL) {
+    printf ("Error reading font data:  Memory allocation error\n");
+    return(1);
+  }
+  coff = (gaint *)malloc(sizeof(gaint)*95);
+  if (coff==NULL) {
+    printf ("Error reading font data:  Memory allocation error\n");
+    free (fdat);
+    return(1);
+  }
+  clen = (gaint *)malloc(sizeof(gaint)*95);
+  if (clen==NULL) {
+    printf ("Error reading font data:  Memory allocation error\n");
+    free (fdat);
+    return(1);
+  }
+
+  rc = fread(fdat,1,tlen,ifile);
+  if (rc!=tlen) {
+    printf ("Error reading font data: I/O Error\n");
+    return(1);
+  }
+  *(fdat+tlen) = '\0';
+
+  /* Determine the locations of the start of each character */
+
+  i = 0;
+  j = 1;
+  *(coff) = 0;
+  flag = 0;
+  while (*(fdat+i)) {
+    if (*(fdat+i)<' ') {
+      flag = 1;
+    } else {
+      if (flag) {
+        *(coff+j) = i;
+        j++;
+      }
+      flag = 0;
+    }
+    i++;
+  }
+
+  /* Determine the count on each character */
+
+  for (i=0; i<95; i++) {
+    for (j=0; j<3; j++) buff[j] = *(fdat+*(coff+i)+j);
+    buff[3] = '\0';
+    sscanf (buff,"%i",&rc);
+    *(clen+i) = rc;
+  }
+
+  flen[fn] = clen;
+  foff[fn] = coff;
+  fch[fn] = fdat;
+
+  return(0);
+}
diff --git a/src/gxcntr.c b/src/gxcntr.c
new file mode 100644
index 0000000..bf76043
--- /dev/null
+++ b/src/gxcntr.c
@@ -0,0 +1,1107 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* qqq resolve gxdraw vs gxsdrw issue for cterp off */
+/* qqq clip labels and masking outside of parea */
+/* qqq error(mem) handling */
+
+/* Authored by B. Doty */
+/* Add labeling with masking 10/2008  B. Doty */
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "gatypes.h"
+#include "gx.h"
+
+/* function prototype */
+void *galloc(size_t,char *);
+void gree();
+char *intprs (char *, gaint *);
+char *getdbl (char *, gadouble *);
+gaint gxclvert (FILE *);
+gaint dequal(gadouble, gadouble, gadouble);
+
+/* For buffering contour lines, when label masking is in use */
+
+struct gxclbuf {
+  struct gxclbuf *fpclbuf;       /* Forward pointer */
+  gaint len;                     /* Number of contour points */
+  gaint color,style,width,sfit;  /* Output options for this line */
+  gadouble *lxy;                 /* Line points, x,y number len */
+  gadouble val;                  /* contour level value */
+};
+
+#if USESHP==1
+#include "shapefil.h"
+/* Structure that contains dBase field metadata */
+struct dbfld {
+  struct dbfld *next;           /* Address of next data base field */
+  DBFFieldType type;            /* string, integer, double, or logical */
+  char name[12];                /* library interface limits length to 11 charaters */
+  gaint len;                    /* for type string: width of string
+				   for type int and double: total number of digits */
+  gaint prec; 			/* for type double: used with len for format string %len.prec */
+  gaint index;                  /* index value (for identifying this field in a list of fields) */
+  gaint flag;                   /* 0==static fiels (same for all shapes), 1==dynamic (varies w/ shape) */
+  void *value;                  /* field value */
+};
+gaint gxshplin (SHPHandle, DBFHandle, struct dbfld *);
+#endif
+
+static struct gxclbuf *clbufanch=NULL;  /* Anchor for contour line buffering for masking */
+static struct gxclbuf *clbuflast=NULL;  /* Last clbuf struct in chain */
+static char pout[512];                  /* Build strings for KML here */
+
+/* Contour labels get buffered here when not using label masking  */
+
+#define LABMAX 200
+static gadouble gxlabx[LABMAX];
+static gadouble gxlaby[LABMAX];
+static gadouble gxlabs[LABMAX];
+static char gxlabv[LABMAX] [24];
+static gaint gxlabc[LABMAX];
+static gaint gxlabn=0;
+static gadouble ldmin=2.5;    /* Minimum distance between labels */
+
+/* Common values for the contouring routines.                        */
+
+static short *lwk=NULL;                   /* Pntr to flag work area     */
+static gaint lwksiz=0;                    /* Size of flag work area     */
+static gadouble *fwk=NULL;                /* Pntr to X,Y coord buffer   */
+static gaint fwksiz=0;                    /* Size of coord buffer       */
+static gaint fwkmid;                      /* fwk midpoint               */
+static gadouble *xystrt, *xyend;          /* Pntrs into the fwk buffer  */
+static gaint iss,iww,jww;                 /* Grid row lengths           */
+static gadouble vv;                       /* Value being contoured      */
+static gadouble *rr;                      /* Start of grid              */
+
+static char clabel [24];                  /* Label for current contour  */
+
+void gxclmn (gadouble dis) {
+  if (dis>0.1) ldmin = dis;
+} 
+
+/* GXCLEV draws contours at a specified contour level and locates
+   labels for that contour level.  The labels are buffered into
+   the label buffer for later output.
+
+   Contours are drawn through the grid pointed at by r, row length is,
+   number of rows js, row start and end ib and ie, column start
+   and end jb and je.  The contour is drawn at value V, and undefined
+   values u are ignored.  Note that min value for ib or jb is 1.     */
+
+/* Label types:  0 - none, 1 - at slope=0, 2 - forced  */
+
+void gxclev (gadouble *r, gaint is, gaint js, gaint ib, gaint ie, gaint jb,
+   gaint je, gadouble v, char *u, struct gxcntr *pcntr) {
+
+gadouble *p1,*p2,*p4;
+gaint i,j,iw,jw,rc;
+short *l1,*l2;
+char *p1u,*p2u,*p4u;
+size_t sz;
+
+
+/* Figure out in advance what grid sides the contour passes
+   through for this grid box.  We will actually draw the contours
+   later.  Doing the tests in advance saves some calculations.
+   Note that a border of flags is left unset all around the grid
+   boundry.  This avoids having to test for the grid boundries
+   when we are following a contour.                                  */
+
+strcpy (clabel,pcntr->label);          /* Label for this contour     */
+
+iw=is+2; jw=js+2;                      /* Dimensions of flag grid    */
+iww=iw; jww=jw; iss=is;                /* Set shared values          */
+vv=v; rr=r;                            /* Set more shared values     */
+
+/* Obtain storage for flag work area and coord buffer -- if we don't
+   already have enough storage allocated for these.                  */
+
+if (lwksiz<iw*jw*2) {                  /* If storage inadaquate then */
+  if (lwk!=NULL) {                     /* If storage is allocated... */
+    gree (lwk,"c1");                        /* Release it.                */
+    gree (fwk,"c2");
+    lwk = NULL; fwk = NULL;
+  }
+  lwksiz = iw*jw*2;                    /* Size of lwk flag area      */
+  sz = lwksiz*sizeof(short);
+  lwk = (short *)galloc(sz,"lwk");  /* Allocate flag work area */
+  if (lwk==NULL) {
+    printf ("Error in GXCLEV: Unable to allocate storage \n");
+    return;
+  }
+  fwksiz = (iw+1)*(jw+1);              /* Size of coord pair buffer */
+  if (fwksiz<500) fwksiz=500;          /* Insure big enough for small grids */
+  sz = fwksiz*sizeof(gadouble);
+  fwk = (gadouble *)galloc(sz,"fwk");    /* Allocate fwk   */
+  if (lwk==NULL) {
+    printf ("Error in GXCLEV: Unable to allocate storage \n");
+    gree (lwk,"c3");
+    lwk = NULL;
+    return;
+  }
+  fwkmid = fwksiz/2;                   /* fwk midpoint              */
+}
+
+/* Set up the flags */
+
+for (l1=lwk; l1<lwk+iw*jw*2; l1++) *l1=0;  /* Clear flags            */
+
+for (j=jb;j<je;j++){                   /* Loop through the rows      */
+  p1=r+is*(j-1)+ib-1;                  /* Set grid pointers to corner ...  */
+  p2=p1+1; p4=p1+is;                   /*   values at start of row         */
+  p1u=u+is*(j-1)+ib-1;                 /* Set undef pointers to corner ... */
+  p2u=p1u+1; p4u=p1u+is;               /*   values at start of row         */
+  l1=lwk+iw*j+ib; l2=l1+iw*jw;         /* Pointers to flags          */
+  for (i=ib;i<ie;i++){                 /* Loop through a row         */
+                                       /* Cntr pass through bottom?  */
+    if (((*p1<=v&&*p2>v)||(*p1>v&&*p2<=v))&&*p1u!=0&&*p2u!=0) *l1=1;
+                                       /* Cntr pass through left?    */
+    if (((*p1<=v&&*p4>v)||(*p1>v&&*p4<=v))&&*p1u!=0&&*p4u!=0) *l2=1;
+    p1++;p2++;p4++;l1++;l2++;          /* Bump pntrs through the row */
+    p1u++;p2u++;p4u++;                 /* Bump undef pntrs through the row */
+  }
+  if (((*p1<=v&&*p4>v)||(*p1>v&&*p4<=v))&&*p1u!=0&&*p4u!=0) *l2=1;
+}
+
+p1=r+is*(je-1)+ib-1;                   /* Set grid pntrs to corner values  */
+p2=p1+1; p4=p1+is;                     /*   at start of last row           */
+p1u=u+is*(je-1)+ib-1;                   /* Set undef pntrs to corner values */
+p2u=p1u+1; p4u=p1u+is;                     /*   at start of last row           */
+l1=lwk+iw*je+ib;                       /* Flag pointers              */
+for (i=ib;i<ie;i++) {                  /* Loop through the last row  */
+                                       /* Check top of grid          */
+  if (((*p1<=v&&*p2>v)||(*p1>v&&*p2<=v))&&*p1u!=0&&*p2u!=0) *l1=1;
+  p1++;p2++;p4++;l1++;                 /* Incr pntrs through the row */
+  p1u++;p2u++;p4u++;                   /* Incr undef pntrs through the row */
+}
+
+/* Look for a grid side that has a contour passing through it that
+   has not yet been drawn.  Follow it in both directions.
+   The X,Y coord pairs will be put in the floating point buffer,
+   starting from the middle of the buffer.                           */
+
+for (j=jb;j<je;j++){                   /* Loop through the rows      */
+  l1=lwk+iw*j+ib; l2=l1+iw*jw;         /* Pointers to flags          */
+  for (i=ib;i<ie;i++){                 /* Loop through a row         */
+    if (*l1) {                         /* Do we got one?             */
+      gxcflw (i,j,1,2);                /* Follow it                  */
+      gxcflw (i,j-1,3,-2);             /* Follow it the other way    */
+      rc = gxcspl(0,pcntr);            /* Output it                  */
+      if (rc) goto merr;
+    }
+    if (*l2) {                         /* Do we got one?             */
+      gxcflw (i,j,4,2);                /* Follow it                  */
+      gxcflw (i-1,j,2,-2);             /* Follow it the other way    */
+      rc = gxcspl(0,pcntr);            /* Output it                  */
+      if (rc) goto merr;
+    }
+    l1++; l2++;
+  }
+}
+
+/* Short (two point) lines in  upper right corner may hae been missed */
+
+l1 = lwk+iw*je+ie-1;                   /* Upper right corner flags   */
+l2 = lwk+iw*jw+iw*(je-1)+ie;
+if (*l1 && *l2) {
+  gxcflw (ie,je-1,4,2);                /* Follow it one way */
+  xystrt = fwk + fwkmid;               /* Terminate other direction */
+  rc = gxcspl(0,pcntr);                /* Output it */
+  if (rc) goto merr;
+}
+
+return;
+
+merr:
+  printf ("Error in line contouring: Memory allocation for Label Buffering\n");
+  return;
+}
+
+void gxcflw (gaint i, gaint j, gaint iside, gaint dr) {
+
+/* Follow a contour to the end.  i and j are the grid location
+   of the start of the contour.  is is the side on which we are
+   entering the grid box.  dr is the direction in which we should
+   fill the output buffer.  Other needed values are external.        */
+
+/* The grid box:
+
+     p4      side 3     p3
+        x ------------ x
+        |              |
+ side 4 |              | side 2
+        |              |
+        |              |
+        x ------------ x
+      p1    side 1      p2
+                                                                     */
+
+short *l1,*l2,*l3,*l4;                 /* Flags for each box side    */
+gadouble *p1,*p2,*p3,*p4;              /* Grid points for a box      */
+gaint isave,jsave;                     /* Save initial grid postn    */
+gadouble *xy,*xyllim, *xyulim;         /* Buffer position and limits */ 
+
+
+isave=i; jsave=j;
+p1=rr+iss*(j-1)+i-1;                   /* Set pntrs to corner values */
+p2=p1+1; p4=p1+iss; p3=p4+1;
+l1=lwk+iww*j+i; l4=l1+iww*jww;         /* Pointers to flags          */
+l2=l4+1; l3=l1+iww;
+xy = fwk + fwkmid;                     /* Start in middle of buffer  */
+xyllim = fwk+6;                        /* Buffer limits              */
+xyulim = fwk+(fwksiz-6);
+
+if (iside==1) goto side1;              /* Jump in based on side      */
+if (iside==2) goto side2;
+if (iside==3) goto side3;
+goto side4;
+
+/* Calculate exit point in the current grid box, then move to the
+   next grid box based on the exit side.                             */
+
+side1:                                 /* Exit side 1; Enter side 3  */
+*xy = i + (vv-*p1)/(*p2-*p1);          /* Calculate exit point       */
+*(xy+1) = j;
+*l1 = 0;                               /* Indicate we were here      */
+xy+=dr;                                /* Move buffer pntr           */
+if ((xy<xyllim)||(xy>xyulim)) goto done;   /* Don't exceed buffer    */
+l3=l1; l1-=iww; l4-=iww; l2=l4+1;      /* Move pntrs to lower box    */
+p4=p1; p3=p2; p1-=iss; p2-=iss;
+j--;
+if (*l1 && *l2 && *l4) {               /* Handle col point           */
+  if (pathln(*p1, *p2, *p3, *p4)) goto side4;
+  else goto side2;
+}
+if (*l4) goto side4;                   /* Find exit point            */
+if (*l1) goto side1;
+if (*l2) goto side2;
+goto done;                             /* If no exit point, then done*/
+
+side2:                                 /* Exit side 2; Enter side 4  */
+*xy = i + 1.0;                         /* Calculate exit point       */
+*(xy+1) = j + (vv-*p2)/(*p3-*p2);
+*l2 = 0;                               /* Indicate we were here      */
+xy+=dr;                                /* Move buffer pntr           */
+if ((xy<xyllim)||(xy>xyulim)) goto done;   /* Don't exceed buffer    */
+l4=l2; l1++; l2++; l3++;               /* Move pntrs to right box    */
+p1=p2; p4=p3; p2++; p3++;
+i++;
+if (*l1 && *l2 && *l3) {               /* Handle col point           */
+  if (pathln(*p1, *p2, *p3, *p4)) goto side3;
+  else goto side1;
+}
+if (*l1) goto side1;                   /* Find exit point            */
+if (*l2) goto side2;
+if (*l3) goto side3;
+goto done;                             /* If no exit point, then done*/
+
+side3:                                 /* Exit side 3; Enter side 1  */
+*xy = i + (vv-*p4)/(*p3-*p4);          /* Calculate exit point       */
+*(xy+1) = j + 1.0;
+*l3 = 0;                               /* Indicate we were here      */
+xy+=dr;                                /* Move buffer pntr           */
+if ((xy<xyllim)||(xy>xyulim)) goto done;   /* Don't exceed buffer    */
+l1=l3; l4+=iww; l3+=iww; l2=l4+1;      /* Move pntrs to upper box    */
+p1=p4; p2=p3; p3+=iss; p4+=iss;
+j++;
+if (*l2 && *l3 && *l4) {               /* Handle col point           */
+  if (pathln(*p1, *p2, *p3, *p4)) goto side2;
+  else goto side4;
+}
+if (*l2) goto side2;                   /* Find exit point            */
+if (*l3) goto side3;
+if (*l4) goto side4;
+goto done;                             /* If no exit point, then done*/
+
+side4:                                 /* Exit side 4; Enter side 2  */
+*xy = i;                               /* Calculate exit point       */
+*(xy+1) = j + (vv-*p1)/(*p4-*p1);
+*l4 = 0;                               /* Indicate we were here      */
+xy+=dr;                                /* Move buffer pntr           */
+if ((xy<xyllim)||(xy>xyulim)) goto done;   /* Don't exceed buffer    */
+l2=l4; l1--; l3--; l4--;               /* Move pntrs to upper box    */
+p2=p1; p3=p4; p1--; p4--;
+i--;
+if (*l3 && *l4 && *l1) {               /* Handle col point           */
+  if (pathln(*p1, *p2, *p3, *p4)) goto side1;
+  else goto side3;
+}
+if (*l3) goto side3;                   /* Find exit point            */
+if (*l4) goto side4;
+if (*l1) goto side1;
+
+done:
+
+if ((i==isave)&&(j==jsave)) {          /* Closed contour?            */
+  *xy = *(fwk+fwkmid);                 /* Close it off               */
+  *(xy+1) = *(fwk+fwkmid+1);
+  xy+=dr;
+}
+
+if (dr<0) 
+  xystrt=xy+2; 
+else 
+  xyend=xy-2;  /* Set final buffer pntrs   */
+return;
+}
+
+/* Calculate shortest combined path length through a col point.
+   Return true if shortest path is side 1/2,3/4, else false.         */
+
+gaint pathln (gadouble p1, gadouble p2, gadouble p3, gadouble p4) {
+gadouble v1,v2,v3,v4,d1,d2;
+
+  v1 = (vv-p1)/(p2-p1);
+  v2 = (vv-p2)/(p3-p2);
+  v3 = (vv-p4)/(p3-p4);
+  v4 = (vv-p1)/(p4-p1);
+  d1 = hypot(1.0-v1, v2) + hypot(1.0-v4, v3);
+  d2 = hypot(v1, v4) + hypot(1.0-v2, 1.0-v3);
+  if (d2<d1) return (0);
+  return (1);
+}
+
+gaint gxcspl (gaint frombuf, struct gxcntr *pcntr) {
+
+/* This subroutine does the curve fitting for the GX contouring
+   package.  The X,Y point pairs have been placed in a floating
+   point buffer.  *xystrt points to the start of the points in
+   the buffer (namely, the first X,Y pair in the buffer).  *xyend
+   points to end of the buffer -- the last X in the line (ie, the
+   start of the last X,Y pair).
+
+   To handle the end point conditions more easily, there must be
+   enough room left in the buffer to hold one X,Y pair before
+   the start of the line, and one X,Y pair after the end.
+
+   The points are fitted with a psuedo cubic spline curve.
+   (The slopes are arbitrarily chosen).  An intermediate point is
+   output every del grid units.  */
+
+
+struct gxclbuf *pclbuf; 
+gadouble *x0,*x1,*x2,*x3,*y0,*y1,*y2,*y3;
+gadouble sx1,sx2,sy1,sy2,d0,d1,d2,xt1,xt2,yt1,yt2;
+gadouble t,t2,t3,tint,x,y,ax,bx,ay,by;
+gadouble del,kurv,cmax,dacum,dcmin,c1,c2;
+gadouble mslope,tslope,xlb=0.0,ylb=0.0;
+gaint i,icls,nump=0,labflg;
+gadouble *xy;
+size_t sz;
+
+if (pcntr->ltype==2) dacum=2.0;
+else dacum=1.0;             /* Accumulated length between labels */
+dcmin=ldmin;         /* Minimum distance between labels                */
+labflg=0;          /* Contour not labelled yet   */
+mslope=1000.0;     /* Minimum slope of contour line */
+
+del=0.05;                              /* Iteration distance         */
+if (frombuf) del=0.02;
+kurv=0.5;                              /* Curviness (0 to 1)         */
+cmax=0.7;                              /* Limit curviness            */
+
+icls=0;                                /* Is it a closed contour?    */
+if ( (*xystrt==*xyend) && (*(xystrt+1)==*(xyend+1)) ) icls=1;
+
+/* Convert contour coordinates to plotting inches.  We will do
+   our spline fit and assign labels in this lower level coordinate
+   space to insure readability.    */
+
+if (!frombuf) {
+  nump=xyend-xystrt;
+  nump=(nump+2)/2;
+  gxcord (xystrt, nump, 3);
+}
+
+
+
+/* If using label masking, buffer the lines, and output the labels. */
+
+if (pcntr->mask && !frombuf) {
+
+  /* Allocate and chain a clbuf */
+
+  sz = sizeof(struct gxclbuf);
+  pclbuf = (struct gxclbuf *) galloc(sz,"pclbuf"); 
+  if (pclbuf==NULL) return (1);
+  if (clbufanch==NULL) clbufanch = pclbuf;
+  else clbuflast->fpclbuf = pclbuf;
+  clbuflast = pclbuf;
+  pclbuf->fpclbuf = NULL;
+
+  /* Allocate space for the line points */
+
+  pclbuf->len = nump; 
+  sz = sizeof(gadouble)*nump*2;
+  pclbuf->lxy = (gadouble *) galloc(sz,"pclbufxy");
+  if (pclbuf->lxy==NULL) return(1);
+
+  /* Copy the line points and line info */
+
+  for (i=0;i<nump*2;i++) *(pclbuf->lxy+i) = *(xystrt+i); 
+  pclbuf->color = gxqclr();
+  pclbuf->style = gxqstl();
+  pclbuf->width = gxqwid();
+  pclbuf->sfit = pcntr->spline;
+  pclbuf->val = pcntr->val;
+
+  /* Plot labels and set mask */
+
+  if (pcntr->ltype && clabel[0]) {
+    for (xy=xystrt+2; xy<xyend-1; xy+=2) {
+      dacum += hypot(*xy-*(xy-2),*(xy+1)-*(xy-1));
+      /* c1 = (thisY - prevY) * (nextY - thisY) */
+      if (dequal(*(xy+1),*(xy-1),1e-12)==0 || dequal(*(xy+3),*(xy+1),1e-12)==0) 
+	c1 = 0.0; 
+      else 
+	c1 = (*(xy+1)-*(xy-1))*(*(xy+3)-*(xy+1));
+      /* c2 = abs(thisY - prevY) + abs(nextY - thisY) */
+      if ( dequal(*(xy+1),*(xy-1),1e-12)==0 ) {
+	if ( dequal(*(xy+3),*(xy+1),1e-12)==0 ) {
+	  /* thisY = prevY = nextY. Check if true for X coords too */
+	  if (dequal(*(xy),*(xy-2),1e-12)==0 && dequal(*(xy+2),*(xy),1e-12)==0 ) {
+	    /* Duplicate point. Set c2 artificially high so label is not drawn */
+	    c2 = 99;  
+	  }
+	  else
+	    c2 = 0.0;
+	}
+	else 
+	  c2 = fabs(*(xy+3)-*(xy+1));
+      }
+      else {
+	if ( dequal(*(xy+3),*(xy+1),1e-12)==0 )
+	  c2 = fabs(*(xy+1)-*(xy-1));
+	else 
+	  c2 = fabs(*(xy+1)-*(xy-1)) + fabs(*(xy+3)-*(xy+1));
+      }
+      /* Plot the label... 
+	 if slope is zero or has changed sign, 
+	 if contour doesn't bend too much,
+	 and if not too close to another label */
+      if ( c1<=0.0 && c2<0.02 && dacum>dcmin ){
+        if (!gxqclab (*xy,*(xy+1),pcntr->labsiz)) {
+          if (pcntr->shpflg==0) gxpclab (*xy,*(xy+1),0.0,gxqclr(),pcntr);
+          dacum=0.0;
+        }
+      }
+    }
+    dacum += hypot(*xyend-*(xyend-2),*(xyend+1)-*(xyend-1));
+    /* for closed contours, check the joining point */
+    if (icls) {
+      /* c1 = (endY - secondY) * (prevY - endY) */
+      if (dequal(*(xyend+1),*(xystrt+3),1e-12)==0 || 
+	  dequal(*(xyend-1),*(xyend+1),1e-12)==0 ) 
+	c1=0.0;
+      else 
+	c1 = (*(xyend+1)-*(xystrt+3))*(*(xyend-1)-*(xyend+1));
+      /* c2 = abs(endY - prevY) + abs(secondY - endY) */
+      if (dequal(*(xyend+1),*(xyend-1),1e-12)==0) {
+	if (dequal(*(xystrt+3),*(xyend+1),1e-12)==0) {
+	  /* thisY = prevY = nextY  
+	     Duplicate point. Set c2 artificially high so label is not drawn */
+	  c2 = 99;  
+	}
+	else 
+	  c2 = fabs(*(xystrt+3)-*(xyend+1));
+      }
+      else {
+	if (dequal(*(xystrt+3),*(xyend+1),1e-12)==0)
+	  c2 = fabs(*(xyend+1)-*(xyend-1));
+	else 
+	  c2 = fabs(*(xyend+1)-*(xyend-1)) + fabs(*(xystrt+3)-*(xyend+1));
+      }
+      /* same criteria apply as for non-closed contours */
+      if (c1<=0.0 && c2<0.02 && dacum>dcmin){
+        if (!gxqclab (*xy,*(xy+1),pcntr->labsiz)) {
+          if (pcntr->shpflg==0) gxpclab (*xyend,*(xyend+1),0.0,gxqclr(),pcntr);
+        }
+      }
+    }
+  }
+
+  return(0);
+}
+
+/* If specified, do not do the cubic spline fit, just output the
+   contour sides, determine label locations, and return.        */
+
+if (pcntr->spline==0) {
+  if (pcntr->mask==1) gxplot (*xystrt, *(xystrt+1), 3);
+  else gxplot (*xystrt, *(xystrt+1), 3);
+  for (xy=xystrt+2; xy<xyend-1; xy+=2) {
+    gxplot (*xy, *(xy+1), 2);
+    if (!frombuf) {
+      dacum += hypot(*xy-*(xy-2),*(xy+1)-*(xy-1));
+      if ((*(xy+1)-*(xy-1))*(*(xy+3)-*(xy+1))<0.0 &&
+                                  gxlabn<LABMAX && dacum>dcmin ){
+        if (clabel[0]) {
+          gxlabx[gxlabn]=(*xy);
+          gxlaby[gxlabn]=(*(xy+1));
+          gxlabs[gxlabn]=0.0;
+          strcpy (gxlabv[gxlabn],clabel);
+          gxlabc[gxlabn] = gxqclr();
+          gxlabn++;
+        }
+        dacum=0.0;
+      }
+    }
+  }
+  gxplot (*xyend, *(xyend+1), 2);
+  if (!frombuf) {
+    dacum += hypot(*xyend-*(xyend-2),*(xyend+1)-*(xyend-1));
+    if (icls) {
+      if ((*(xyend+1)-*(xystrt+3))*(*(xyend-1)-*(xyend+1))<0.0 &&
+                                    gxlabn<LABMAX && dacum>dcmin ){
+        if (clabel[0]) {
+          gxlabx[gxlabn]=(*xyend);
+          gxlaby[gxlabn]=(*(xyend+1));
+          gxlabs[gxlabn]=0.0;
+          strcpy (gxlabv[gxlabn],clabel);
+          gxlabc[gxlabn] = gxqclr();
+          gxlabn++;
+        }
+      }
+    }
+  }
+  return (0);
+}
+
+/*  We handle end points by assigning a shadow point just beyond
+    the start and end of the line.  This is a bit tricky since we
+    have to make sure we ignore any points that are too close
+    together.  If the contour is open, we extend the line straigth
+    out one more increment.  If the contour is closed, we extend the
+    line by wrapping it to the other end.  This ensures that a
+    closed contour will have a smooth curve fit at our artificial
+    boundry.                                                         */
+
+x3=xyend; y3=xyend+1;                  /* Point to last X,Y          */
+x2=x3; y2=y3;
+do {                                   /* Loop to find prior point   */
+  x2-=2; y2-=2;                        /* Check next prior point     */
+  if (x2<xystrt) goto exit;            /* No valid line to draw      */
+  d2 = hypot ((*x3-*x2), (*y3-*y2));   /* Get distance               */
+} while (d2<0.01);                     /* Loop til distance is big   */
+
+x0=xystrt; y0=xystrt+1;                /* Point to first X,Y         */
+x1=x0; y1=y0;
+do {                                   /* Loop to find next point    */
+  x1+=2; y1+=2;                        /* Point to next X,Y          */
+  if (x1>xyend) goto exit;             /* Exit if no valid line      */
+  d1 = hypot ((*x1-*x0), (*y1-*y0));   /* Distance to next point     */
+} while (d1<0.01);                     /* Keep looping til d1 is big */
+
+if (icls) {                            /* Select shadow points       */
+  *(xystrt-2) = *x2;                   /* Wrap for closed contour    */
+  *(xystrt-1) = *y2;
+  *(xyend+2)  = *x1;
+  *(xyend+3)  = *y1;
+}
+else {
+  *(xystrt-2) = *x0 + (*x0 - *x1);     /* Linear for open contour    */
+  *(xystrt-1) = *y0 + (*y0 - *y1);
+  *(xyend+2)  = *x3 + (*x3 - *x2);
+  *(xyend+3)  = *y3 + (*y3 - *y2);
+}
+/* We have extended the line on either end.  We can now loop through
+   the points in the line.  First set up the loop.                   */
+
+x2=x1; x1=x0; x0=xystrt-2; x3=x2;      /* Init pointers to coords    */
+y2=y1; y1=y0; y0=xystrt-1; y3=y2;
+
+d0 = hypot ((*x1-*x0), (*y1-*y0));     /* Init distances             */
+d1 = hypot ((*x2-*x1), (*y2-*y1));
+
+xt1 = (*x1-*x0)/d0 + (*x2-*x1)/d1;     /* Partial slope calculation  */
+yt1 = (*y1-*y0)/d0 + (*y2-*y1)/d1;
+xt1 *= kurv;                           /* Curviness factor           */
+yt1 *= kurv;
+
+gxplot (*x1,*y1,3);                    /* Start output with pen up   */
+
+/* Loop through the various points in the line                       */
+
+x3+=2; y3+=2; 
+while (x3 < xyend+3) {                 /* Loop to end of the line    */
+
+  d2 = hypot ((*x3-*x2),(*y3-*y2));    /* Distance to next point     */
+  while (d2<0.01 && x3<xyend+3) {      /* Skip points too close      */
+    x3+=2; y3+=2;                      /* Check next point           */
+    d2 = hypot ((*x3-*x2),(*y3-*y2));  /* Distance to next point     */
+  }
+  if (x3 >= xyend+3) break;            /* Went too far?              */
+
+  if (!frombuf) {
+
+    dacum+=d1;                         /* Total dist. from last labl */
+
+    if (pcntr->ltype && ((*y2-*y1)*(*y3-*y2)<0.0) && gxlabn<LABMAX && dacum>dcmin){
+      if (clabel[0]) {
+        gxlabx[gxlabn]=(*x2);
+        gxlaby[gxlabn]=(*y2);
+        gxlabs[gxlabn]=0.0;
+        strcpy (gxlabv[gxlabn],clabel);
+        gxlabc[gxlabn] = gxqclr();
+        gxlabn++;
+        labflg=1;
+      }
+      dacum=0.0;
+    }
+    if (pcntr->ltype==2 && !labflg && gxlabn<LABMAX && x2!=xyend) {
+      if (*x1 < *x2 && *x2 < *x3) {
+        tslope = atan2(*y3-*y1, *x3-*x1);
+        if (fabs(mslope) > fabs(tslope)) {
+          mslope = tslope;
+          xlb = *x2;
+          ylb = *y2;
+        }
+      } else if (*x1 > *x2 && *x2 > *x3 ) {
+        tslope = atan2(*y1-*y3, *x1-*x3);
+        if (fabs(mslope) > fabs(tslope)) {
+          mslope = tslope;
+          xlb = *x2;
+          ylb = *y2;
+        }
+      }
+    }
+  }
+
+  xt2 = (*x2-*x1)/d1 + (*x3-*x2)/d2;   /* Partial slope calculation  */
+  yt2 = (*y2-*y1)/d1 + (*y3-*y2)/d2;
+  xt2 *= kurv;                         /* Curviness factor           */
+  yt2 *= kurv;
+
+  if (d1>cmax) t=cmax; else t=d1;      /* Limit curviness            */
+  sx1 = xt1*t;                         /* Calculate slopes           */
+  sx2 = xt2*t;
+  sy1 = yt1*t;
+  sy2 = yt2*t;
+
+                                       /* Calculate Cubic Coeffic.   */
+  ax = sx1 + sx2 + 2.0*(*x1) - 2.0*(*x2);
+  bx = 3.0*(*x2) - sx2 - 2.0*sx1 - 3.0*(*x1);
+  ay = sy1 + sy2 + 2.0*(*y1) - 2.0*(*y2);
+  by = 3.0*(*y2) - sy2 - 2.0*sy1 - 3.0*(*y1);
+
+  tint=del/d1;                         /* How much to increment      */
+
+  for (t=0.0; t<1.0; t+=tint) {        /* Increment this segment     */
+    t2=t*t; t3=t2*t;                   /* Get square and cube        */
+    x = ax*t3 + bx*t2 + sx1*t + *x1;   /* Get x value on curve       */
+    y = ay*t3 + by*t2 + sy1*t + *y1;   /* Get y value on curve       */
+    gxplot (x,y,2);                    /* Output the point           */
+  }
+  d0=d1; d1=d2; xt1=xt2; yt1=yt2;      /* Carry calcs forward        */
+  x0=x1; x1=x2; x2=x3;                 /* Update pointers            */
+  y0=y1; y1=y2; y2=y3;
+  x3+=2; y3+=2;  
+}
+gxplot (*xyend,*(xyend+1),2);          /* Last point                 */
+
+if (!frombuf && pcntr->ltype==2 && !labflg && gxlabn<LABMAX && fabs(mslope)<2.0) {
+  if (clabel[0]) {
+    gxlabx[gxlabn]=xlb;
+    gxlaby[gxlabn]=ylb;
+    gxlabs[gxlabn]=mslope;
+    strcpy (gxlabv[gxlabn],clabel);
+    gxlabc[gxlabn] = gxqclr();
+    gxlabn++;
+  }
+}
+
+exit:                                  /* No line here, just exit    */
+return(0);
+}
+
+/* When label masking is not in use, this routine gets called after the 
+   contour lines are drawn to plot the labels.  A rectangle with the background
+   color is drawn before the label to blank beneath the label.  If label
+   masking is in use, this routine should not be called.  */
+
+void gxclab (gadouble csize, gaint flag, gaint colflg) {
+gadouble x,y,xy[10],xd1,xd2,yd1,yd2,w,h,buff;
+gaint i,lablen,colr,bcol,fcol;
+
+if (!flag) { gxlabn=0; return; }
+colr = gxqclr();
+for (i=0; i<gxlabn; i++ ) {
+  lablen=strlen(gxlabv[i]);
+  bcol = gxqbck();
+  h = csize*1.2;                     /* set label height */
+  w = 0.2;
+  gxchln (gxlabv[i],lablen,csize,&w);  /* get label width */
+  if (gxlabs[i]==0.0) {              /* contour label is not rotated */
+    x = gxlabx[i] - (w/2.0);         /* adjust reference point */
+    y = gxlaby[i] - (h/2.0);
+    gxcolr (bcol);
+    buff=h*0.2;     /* add a buffer above and below the string, already padded in X */
+    gxrecf (x, x+w, y-buff, y+h+buff);   /* draw the background rectangle,  */
+    if (colflg>-1) fcol = colflg;
+    else fcol = gxlabc[i];
+    if (fcol==gxqbck()) {
+      if (gxqbck()==0) gxcolr(1);
+      else gxcolr(0);
+    }
+    else gxcolr (fcol);
+    gxchpl (gxlabv[i],lablen,x,y,h,csize,0.0);  /* draw the label */
+  } else {                           /* contour label is rotated */
+    xd1 = (h/2.0)*sin(gxlabs[i]);
+    xd2 = (w/2.0)*cos(gxlabs[i]);
+    yd1 = (h/2.0)*cos(gxlabs[i]);
+    yd2 = (w/2.0)*sin(gxlabs[i]);
+    x = gxlabx[i] - xd2 + xd1;       /* adjust reference point */
+    y = gxlaby[i] - yd2 - yd1;
+    xd1 = (h/2.0*1.6)*sin(gxlabs[i]);
+    xd2 = 1.1*(w/2.0)*cos(gxlabs[i]);
+    yd1 = (h/2.0*1.6)*cos(gxlabs[i]);
+    yd2 = 1.1*(w/2.0)*sin(gxlabs[i]);
+    xy[0] = gxlabx[i] - xd2 + xd1;   /* rotated background rectangle => polygon */
+    xy[1] = gxlaby[i] - yd2 - yd1;
+    xy[2] = gxlabx[i] - xd2 - xd1;
+    xy[3] = gxlaby[i] - yd2 + yd1;
+    xy[4] = gxlabx[i] + xd2 - xd1;
+    xy[5] = gxlaby[i] + yd2 + yd1;
+    xy[6] = gxlabx[i] + xd2 + xd1;
+    xy[7] = gxlaby[i] + yd2 - yd1;
+    xy[8] = xy[0];
+    xy[9] = xy[1];
+    gxcolr (bcol);
+    gxfill (xy,5);
+    if (colflg>-1) fcol = colflg;
+    else fcol = gxlabc[i];
+    if (fcol==gxqbck()) {
+      if (gxqbck()==0) gxcolr(1);
+      else gxcolr(0);
+    }
+    else gxcolr (fcol);
+    gxchpl (gxlabv[i],lablen,x,y,h,csize,gxlabs[i]*180/M_PI)  /* draw the label */;
+  }
+}
+gxcolr (colr);
+gxlabn=0;
+}
+
+/* When label masking is in use, this routine is called to plot all the 
+   contour lines after the contour labels have been plotted and their masking
+   regions set.  Thus the contour lines drawn will not overlay the labels.  */
+
+void gxpclin (void) {
+gaint i,rc;
+struct gxclbuf *pclbuf, *p2;
+struct gxcntr lcntr;
+
+  /* Set up gxcntr struct appropriately -- most values are dummy */
+  lcntr.labsiz = 0.5;
+  lcntr.ltype = 0;
+  lcntr.mask = 1;
+  lcntr.labcol = 1;
+  lcntr.ccol = 1;
+  lcntr.label = NULL;
+
+  /* Copy the lines into fwk, dump the lines,
+     release storage, return.  fwk should be guaranteed big enough for the 
+     largest line we have, and shouldn't have been release via gxcrel at
+     this point. */
+
+  pclbuf = clbufanch;
+  while (pclbuf) { 
+    if (pclbuf->lxy) {
+      xystrt = fwk+2;  
+      xyend = xystrt + 2*(pclbuf->len-1);
+      for (i=0; i<2*pclbuf->len; i++) *(xystrt+i) = *(pclbuf->lxy+i); 
+      gxcolr (pclbuf->color);
+      gxstyl (pclbuf->style);
+      gxwide (pclbuf->width); 
+      lcntr.spline = pclbuf->sfit;
+      rc = gxcspl(1,&lcntr);
+    }
+    pclbuf = pclbuf->fpclbuf;
+  }
+  pclbuf = clbufanch;
+  while (pclbuf) {
+    p2 = pclbuf->fpclbuf;
+    if (pclbuf->lxy) gree (pclbuf->lxy,"c5");
+    gree (pclbuf,"c6");
+    pclbuf = p2;
+  }
+  clbufanch = NULL;
+  clbuflast = NULL;
+  return;
+}
+
+/* When gxout shape is in use, this routine is called to dump all the 
+   contour vertices to the shapefile
+   For each contour in the buffer: 
+     get the vertex x/y coordinates, 
+     convert them to lon/lat, 
+     write out the coordinates to the shapefile,
+     release storage and return. 
+   Returns -1 on error, otherwise returns number of shapes written to file.
+*/
+#if USESHP==1
+gaint gxshplin (SHPHandle sfid, DBFHandle dbfid, struct dbfld *dbanch) {
+gaint i,rc,ival;
+struct dbfld *fld;
+struct gxclbuf *pclbuf=NULL, *p2;
+gaint shpid,*pstart=NULL,nParts,nFields;
+SHPObject *shp;
+gadouble x,y,*lons=NULL,*lats=NULL,*vals=NULL,lon,lat,val,dval;
+ 
+ nParts = 1;
+ nFields = 1;
+ pstart = (gaint*)galloc(nParts*sizeof(gaint),"pstart");
+ *pstart = 0;
+ shpid=0;
+ pclbuf = clbufanch;
+ if (pclbuf==NULL) {
+   snprintf(pout,511,"Error in gxshplin: contour buffer is empty\n");
+   gaprnt(0,pout);
+   rc = -1; 
+   goto cleanup;
+ }
+ while (pclbuf) { 
+   if (pclbuf->lxy) {
+     /* allocate memory for lons and lats of the vertices in contour line */
+     if ((lons = (gadouble*)galloc (pclbuf->len*sizeof(gadouble),"shplons"))==NULL) {
+       snprintf(pout,511,"Error in gxshplin: unable to allocate memory for lon array\n");
+       gaprnt(0,pout);
+       rc = -1;
+       goto cleanup;
+     }
+     if ((lats = (gadouble*)galloc (pclbuf->len*sizeof(gadouble),"shplats"))==NULL) {
+       snprintf(pout,511,"Error in gxshplin: unable to allocate memory for lat array\n");
+       gaprnt(0,pout);
+       rc = -1;
+       goto cleanup;
+     }
+     if ((vals = (gadouble*)galloc (pclbuf->len*sizeof(gadouble),"shpvals"))==NULL) {
+       snprintf(pout,511,"Error in gxshplin: unable to allocate memory for val array\n");
+       gaprnt(0,pout);
+       rc = -1;
+       goto cleanup;
+     }
+     /* get x,y values and convert them to lon,lat */
+     for (i=0; i<pclbuf->len; i++) {
+       x = *(pclbuf->lxy+(2*i)); 
+       y = *(pclbuf->lxy+(2*i+1)); 
+       gxxy2w (x,y,&lon,&lat);
+       *(lons+i) = lon;
+       *(lats+i) = lat;
+       *(vals+i) = pclbuf->val;
+     }
+     /* create the shape, write it out, then release it */
+     shp = SHPCreateObject (SHPT_ARCM,shpid,nParts,pstart,NULL,pclbuf->len,lons,lats,NULL,vals);
+     i = SHPWriteObject(sfid,-1,shp);
+     SHPDestroyObject(shp);
+     if (i!=shpid) {
+       snprintf(pout,511,"Error in gxshplin: SHPWriteObject returned %d, shpid=%d\n",i,shpid);
+       gaprnt(0,pout);
+       rc = -1;
+       goto cleanup;
+     }
+     gree(lons,"c10"); lons=NULL;
+     gree(lats,"c11"); lats=NULL;
+     gree(vals,"c12"); vals=NULL;
+     /* write out the attribute fields for this shape */
+     fld = dbanch;           /* point to the first one */
+     while (fld != NULL) {
+       if (fld->flag==0) {   /* static fields */
+	 if (fld->type==FTString) {
+	   DBFWriteStringAttribute (dbfid,shpid,fld->index,(const char *)fld->value);
+	 } else if (fld->type==FTInteger) {
+	   intprs(fld->value,&ival);
+	   DBFWriteIntegerAttribute (dbfid,shpid,fld->index,ival);
+	 } else if (fld->type==FTDouble) {
+	   getdbl(fld->value,&dval);
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,dval);
+	 }
+       }
+       else {                /* dynamic fields */
+	 if (strcmp(fld->name,"CNTR_VALUE")==0) {
+	   val = pclbuf->val;
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+	 }
+       }
+       fld = fld->next;      /* advance to next field */
+     }
+     shpid++;
+   }
+   pclbuf = pclbuf->fpclbuf;
+ }
+ /* if no errors, return the number of contour lines written to the file */
+ rc = shpid;
+ 
+ cleanup:
+ if (lons) gree (lons,"c7");
+ if (lats) gree (lats,"c8");
+ if (vals) gree (vals,"c8");
+ if (pstart) gree (pstart,"c9");
+ /* release the memory in the contour buffer */
+ pclbuf = clbufanch;
+ while (pclbuf) {
+   p2 = pclbuf->fpclbuf;
+   if (pclbuf->lxy) gree (pclbuf->lxy,"c5");
+   gree (pclbuf,"c6");
+   pclbuf = p2;
+ }
+ clbufanch = NULL;
+ clbuflast = NULL;
+ return (rc);
+}
+#endif
+
+/* Routine to write out contour line vertices to a KML file. 
+   For each contour in the buffer: 
+     get the vertex x/y coordinates, 
+     convert them to lon/lat, 
+     write out the coordinates to the kmlfile,
+     release storage and return. 
+   Returns -1 on error, otherwise the number of contours written. 
+*/
+gaint gxclvert (FILE *kmlfp)  {
+struct gxclbuf *pclbuf,*p2;
+ gadouble lon,lat,x,y;  
+ gaint i,j,c,err;
+ err=0;
+ c=0;
+ pclbuf = clbufanch;
+ while (pclbuf) { 
+   if (pclbuf->lxy) {
+     /* write out headers for each contour */
+     snprintf(pout,511,"    <Placemark>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+     snprintf(pout,511,"      <styleUrl>#%d</styleUrl>\n",pclbuf->color);
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=2; goto cleanup;}
+     snprintf(pout,511,"      <name>%g</name>\n",pclbuf->val);
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=3; goto cleanup;}
+     snprintf(pout,511,"      <LineString>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=4; goto cleanup;}
+     snprintf(pout,511,"        <altitudeMode>clampToGround</altitudeMode>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=5; goto cleanup;}
+     snprintf(pout,511,"        <tessellate>1</tessellate>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=6; goto cleanup;}
+     snprintf(pout,511,"        <coordinates>\n          ");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=7; goto cleanup;}
+     /* get x,y values and convert them to lon,lat */
+     j=1;
+     for (i=0; i<pclbuf->len; i++) {
+       x = *(pclbuf->lxy+(2*i)); 
+       y = *(pclbuf->lxy+(2*i+1)); 
+       gxxy2w (x,y,&lon,&lat);
+       if (lat>90)  lat = 90;
+       if (lat<-90) lat = -90;
+       snprintf(pout,511,"%g,%g,0 ",lon,lat); 
+       if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=8; goto cleanup;}
+       if (j==6 || i==(pclbuf->len-1)) { 
+	 if (j==6) snprintf(pout,511,"\n          "); 
+	 else snprintf(pout,511,"\n"); 
+	 if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=9; goto cleanup;}
+	 j=0;
+       }
+       j++;
+     }
+     /* write out footers for each contour */
+     snprintf(pout,511,"        </coordinates>\n      </LineString>\n    </Placemark>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=10; goto cleanup;}
+     c++;
+   }
+   pclbuf = pclbuf->fpclbuf;
+ }
+ cleanup:
+ /* release the memory in the contour buffer */
+ pclbuf = clbufanch;
+ while (pclbuf) {
+   p2 = pclbuf->fpclbuf;
+   if (pclbuf->lxy) gree (pclbuf->lxy,"c5");
+   gree (pclbuf,"c6");
+   pclbuf = p2;
+ }
+ clbufanch = NULL;
+ clbuflast = NULL;
+ if (err) return (-1);
+ else return (c);
+}
+
+
+
+/* Plot contour labels when label masking is in use. 
+   Currently, rot is assumed to be zero.  */
+
+void gxpclab (gadouble xpos, gadouble ypos, gadouble rot, gaint ccol, struct gxcntr *pcntr) {
+  gadouble x,y,w,h,csize,buff;
+  gaint lablen,bcol,fcol,scol,swid;
+
+  csize = pcntr->labsiz;
+  lablen = strlen(clabel);
+  bcol = gxqbck();
+  h = csize*1.2;                          /* set label height */
+  w = 0.2;
+  gxchln (clabel,lablen,csize,&w);        /* get label width */
+  buff=h*0.05;                            /* set a small buffer around the label */
+  x = xpos-(w/2.0);                       /* adjust reference point */
+  y = ypos-(h/2.0);
+  scol = gxqclr();
+  if (pcntr->labcol > -1) fcol = pcntr->labcol;
+  else fcol = ccol;
+  gxcolr (fcol);
+  swid = gxqwid();
+  /* if contour label thickness is set to -999, then we draw a fat version of the label
+     in the background color and then overlay a thin version of the label in desired color. 
+     This will only work with hershey fonts, since the boldness of cairo fonts is not
+     controlled by the thickness setting for contour labels. */
+  if (pcntr->labwid > -1) gxwide(pcntr->labwid);
+  if (pcntr->labwid == -999) {
+    /* invoke settings for fat background label */
+     gxwide(12); gxcolr(bcol);
+  }
+  /* draw the label */
+  gxchpl (clabel,lablen,x,y,h,csize,0.0);
+  if (pcntr->labwid == -999) {
+    /* overlay a thin label in foreground color */
+    gxwide(1); gxcolr(fcol);
+    gxchpl (clabel,lablen,x,y,h,csize,0.0);
+  }
+  gxmaskrec (x-buff, x+w+buff, y-buff, y+h+buff);
+  gxcolr (scol);
+  gxwide (swid);
+}
+
+/* query if the contour label will overlay another, if using masking */
+
+int gxqclab (gadouble xpos, gadouble ypos, gadouble csize) {
+gadouble lablen,x,y,w,h,buff;
+gaint rc;
+  lablen=strlen(clabel);
+  w = 0.2;
+  h = csize*1.2;            /* height scaled by 1.2 for consistency with other labels */
+  gxchln (clabel,lablen,csize,&w);
+  x = xpos-(w/2.0);
+  y = ypos-(h/2.0);
+  buff=h*0.2;                            /* set a buffer around the label */
+  /* area to check is a bit (0.02) smaller than the actual mask */
+  rc = gxmaskrq (x-buff+0.02, x+w+buff-0.02, y-buff+0.02, y+h+buff-0.02);
+  return (rc);
+}
+
+/*  Release storage used by the contouring package  */
+
+void gxcrel (void) {
+  if (lwk!=NULL) {
+    gree (lwk,"c7"); lwk = NULL; 
+  }
+  if (fwk!=NULL) {
+    gree (fwk,"c8"); fwk = NULL;
+  }
+  lwksiz = 0; fwksiz = 0;
+}
diff --git a/src/gxdxwd.c b/src/gxdxwd.c
new file mode 100644
index 0000000..c265959
--- /dev/null
+++ b/src/gxdxwd.c
@@ -0,0 +1,391 @@
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <X11/Xmu/WinUtil.h>
+#include "gatypes.h"
+#define FEEP_VOLUME 0
+
+/* Window_Dump: dump a window to a file which must already be open for writing. */
+
+#include "X11/XWDFile.h"
+
+#ifdef __alpha
+#define NON_STANDARD_XCOLOR_SIZE 4
+#endif
+
+#undef NON_STANDARD_XCOLOR_SIZE
+
+#ifdef NON_STANDARD_XCOLOR_SIZE
+#define My_XColor_size 12
+#else
+#define My_XColor_size sizeof(XColor)
+#endif
+
+void _swaplong  (register char *,register unsigned);
+void _swapshort (register char *,register unsigned);
+gaint Get_XColors (XWindowAttributes *, XColor **);
+gaint Image_Size (XImage *);
+void outl(char *,char *,char *,char *,char *,char *,char *,char *);
+void Window_Dump(Window,FILE *);
+void set_display_screen (Display *, gaint);
+
+static gaint format = ZPixmap;
+static Bool nobdrs = True;
+static Bool on_root = False;
+static Bool debug = False;
+static Bool use_installed = False;
+static long add_pixel_value = 0;
+
+static Display *dpy;                          /* The current display */
+static gaint screen;                            /* The current screen */
+
+void set_display_screen(d,s)
+Display *d;                                 
+gaint s;   
+{
+ dpy =d;
+ screen=s;
+}    
+
+void Pixmap_Dump(window, out,x, y, width, height)
+     Window window;
+     FILE *out;
+     gaint x, y, width, height;
+{
+    XImage *image;
+    unsigned buffer_size;
+
+    image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format);  
+    buffer_size = Image_Size(image);
+    (void) fwrite(image->data, (gaint) buffer_size, 1, out);  
+    if (debug)    fprintf(stderr,"scritti %d bytes immagine\n",buffer_size);
+}                            
+
+void Window_Dump(window, out)
+     Window window;
+     FILE *out;
+{
+    unsigned long swaptest = 1;
+    XColor *colors;
+    unsigned buffer_size;
+    gaint win_name_size;
+    gaint header_size;
+    gaint ncolors, i;
+    char *win_name;
+    Bool got_win_name;
+    XWindowAttributes win_info;
+    XImage *image;
+    gaint absx, absy, x, y;
+    unsigned width, height;
+    gaint dwidth, dheight;
+    gaint bw;
+    Window dummywin;
+    XWDFileHeader header;
+
+    
+    /*
+     * Get the parameters of the window being dumped.
+     */
+    if (debug) fprintf(stderr,"xwd: Getting target window information.\n");
+    if(!XGetWindowAttributes(dpy, window, &win_info)) 
+      { fprintf(stderr,"Can't get target window attributes."); exit(1); }
+
+    /* handle any frame window */
+    if (!XTranslateCoordinates (dpy, window, RootWindow (dpy, screen), 0, 0,
+				&absx, &absy, &dummywin)) {
+	fprintf (stderr, 
+		  "unable to translate window coordinates (%d,%d)\n",
+		 absx, absy);
+	exit (1);
+    }
+    win_info.x = absx;
+    win_info.y = absy;
+    width = win_info.width;
+    height = win_info.height;
+    bw = 0;
+
+    if (!nobdrs) {
+	absx -= win_info.border_width;
+	absy -= win_info.border_width;
+	bw = win_info.border_width;
+	width += (2 * bw);
+	height += (2 * bw);
+    }
+    dwidth = DisplayWidth (dpy, screen);
+    dheight = DisplayHeight (dpy, screen);
+
+
+    /* clip to window */
+    if (absx < 0) width += absx, absx = 0;
+    if (absy < 0) height += absy, absy = 0;
+    if (absx + width > dwidth) width = dwidth - absx;
+    if (absy + height > dheight) height = dheight - absy;
+
+    XFetchName(dpy, window, &win_name);
+    if (!win_name || !win_name[0]) {
+	win_name = "xwdump";
+	got_win_name = False;
+    } else {
+	got_win_name = True;
+    }
+
+    /* sizeof(char) is included for the null string terminator. */
+    win_name_size = strlen(win_name) + sizeof(char);
+
+    /*
+     * Snarf the pixmap with XGetImage.
+     */
+
+    x = absx - win_info.x;
+    y = absy - win_info.y;
+
+    if (on_root)
+	image = XGetImage (dpy, RootWindow(dpy, screen), absx, absy, width, height, AllPlanes, format);
+    else
+	image = XGetImage (dpy, window, x, y, width, height, AllPlanes, format);
+
+    if (!image) {
+	fprintf (stderr, "unable to get image at %dx%d+%d+%d\n",
+		 width, height, x, y);
+	exit (1);
+    }
+
+    if (add_pixel_value != 0) XAddPixel (image, add_pixel_value);
+
+    /*
+     * Determine the pixmap size.
+     */
+    buffer_size = Image_Size(image);
+    ncolors = Get_XColors(&win_info, &colors);
+
+    /*
+     * Inform the user that the image has been retrieved.
+     */
+    XBell(dpy, FEEP_VOLUME);
+    XBell(dpy, FEEP_VOLUME);
+    XFlush(dpy);
+
+    /*
+     * Calculate header size.
+     */
+    header_size = sizeof(header) + win_name_size;
+    if (debug) fprintf(stderr,"header_size= %ld win_name_size= %d \n",sizeof(header),win_name_size);
+    if (debug) fprintf(stderr,"x rs %d y res %d size pix %d\n",image->width,image->height,image->depth);
+
+    /*
+     * Write out header information.
+     */
+    header.header_size = (CARD32) header_size;
+    header.file_version = (CARD32) XWD_FILE_VERSION;
+    header.pixmap_format = (CARD32) format;
+    header.pixmap_depth = (CARD32) image->depth;
+    header.pixmap_width = (CARD32) image->width;
+    header.pixmap_height = (CARD32) image->height;
+    header.xoffset = (CARD32) image->xoffset;
+    header.byte_order = (CARD32) image->byte_order;
+    header.bitmap_unit = (CARD32) image->bitmap_unit;
+    header.bitmap_bit_order = (CARD32) image->bitmap_bit_order;
+    header.bitmap_pad = (CARD32) image->bitmap_pad;
+    header.bits_per_pixel = (CARD32) image->bits_per_pixel;
+    header.bytes_per_line = (CARD32) image->bytes_per_line;
+    header.visual_class = (CARD32) win_info.visual->class;
+    header.red_mask = (CARD32) win_info.visual->red_mask;
+    header.green_mask = (CARD32) win_info.visual->green_mask;
+    header.blue_mask = (CARD32) win_info.visual->blue_mask;
+    header.bits_per_rgb = (CARD32) win_info.visual->bits_per_rgb;
+    header.colormap_entries = (CARD32) win_info.visual->map_entries;
+    header.ncolors = ncolors;
+    header.window_width = (CARD32) win_info.width;
+    header.window_height = (CARD32) win_info.height;
+    header.window_x = absx;
+    header.window_y = absy;
+    header.window_bdrwidth = (CARD32) win_info.border_width;
+
+    if (*(char *) &swaptest) {
+	_swaplong((char *) &header, sizeof(header));
+	for (i = 0; i < ncolors; i++) {
+	    _swaplong((char *) &colors[i].pixel, sizeof(long));
+	    _swapshort((char *) &colors[i].red, 3 * sizeof(short));
+	}
+    }
+
+    (void) fwrite((char *)&header, sizeof(header), 1, out);
+    (void) fwrite(win_name, win_name_size, 1, out);
+
+    /*
+     * Write out the color maps, if any
+     */
+#ifdef NON_STANDARD_XCOLOR_SIZE
+    {
+     XColor *pt;
+     for(pt=colors; pt < colors + ncolors; pt++)
+       fwrite((((char *) pt) + NON_STANDARD_XCOLOR_SIZE),My_XColor_size,1, out);
+    }
+#else
+    (void) fwrite((char *) colors, My_XColor_size, ncolors, out);
+#endif
+
+    if(ncolors > 0) free(colors);         /* free the color buffer */
+    if (got_win_name) XFree(win_name);    /* free window name string */
+    XDestroyImage(image);                 /* free image */
+}
+
+/* Report the syntax for calling xwd. */
+/* changed from usage() to Usage() to avoid PC/X11e conflict */
+gaint Usage() 
+{
+    fprintf (stderr,"old usage of xwd\n");
+    exit(1);
+}
+
+
+/* Error - Fatal xwd error */
+extern gaint errno;
+
+gaint Error(string)
+	char *string;	/* Error description string. */
+{
+	fflush(stdout);
+	fprintf(stderr, "xwd: Error => %s\n", string);
+	fflush(stderr);
+
+	if (errno != 0) {
+	  perror("xwd");
+	  fprintf(stderr,"\n");
+	}
+	exit(1);
+}
+
+
+/*
+ * Determine the pixmap size.
+ */
+
+gaint Image_Size(image)
+     XImage *image;
+{
+    if (image->format != ZPixmap)
+      return(image->bytes_per_line * image->height * image->depth);
+
+    return(image->bytes_per_line * image->height);
+}
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/*
+ * Get the XColors of all pixels in image - returns # of colors
+ */
+gaint Get_XColors(win_info, colors)
+     XWindowAttributes *win_info;
+     XColor **colors;
+{
+    gaint i, ncolors;
+    Colormap cmap = win_info->colormap;
+
+    if (use_installed)
+	/* assume the visual will be OK ... */
+	cmap = XListInstalledColormaps(dpy, win_info->root, &i)[0];
+    if (!cmap)
+	return(0);
+
+    ncolors = win_info->visual->map_entries;
+    if (!(*colors = (XColor *) malloc (sizeof(XColor) * ncolors)))
+      {fprintf(stderr,"Out of memory!"); exit(-1); }
+
+    if (win_info->visual->class == DirectColor ||
+	win_info->visual->class == TrueColor) {
+	gaPixel red, green, blue, red1, green1, blue1;
+
+	red = green = blue = 0;
+	red1 = lowbit(win_info->visual->red_mask);
+	green1 = lowbit(win_info->visual->green_mask);
+	blue1 = lowbit(win_info->visual->blue_mask);
+	for (i=0; i<ncolors; i++) {
+	  (*colors)[i].pixel = red|green|blue;
+	  (*colors)[i].pad = 0;
+	  red += red1;
+	  if (red > win_info->visual->red_mask)
+	    red = 0;
+	  green += green1;
+	  if (green > win_info->visual->green_mask)
+	    green = 0;
+	  blue += blue1;
+	  if (blue > win_info->visual->blue_mask)
+	    blue = 0;
+	}
+    } else {
+	for (i=0; i<ncolors; i++) {
+	  (*colors)[i].pixel = i;
+	  (*colors)[i].pad = 0;
+	}
+    }
+
+    XQueryColors(dpy, cmap, *colors, ncolors);
+    
+    return(ncolors);
+}
+
+void _swapshort (bp, n)
+    register char *bp;
+    register unsigned n;
+{
+    register char c;
+    register char *ep = bp + n;
+
+    while (bp < ep) {
+	c = *bp;
+	*bp = *(bp + 1);
+	bp++;
+	*bp++ = c;
+    }
+}
+
+void _swaplong (bp, n)
+    register char *bp;
+    register unsigned n;
+{
+    register char c;
+    register char *ep = bp + n;
+    register char *sp;
+
+    while (bp < ep) {
+	sp = bp + 3;
+	c = *sp;
+	*sp = *bp;
+	*bp++ = c;
+	sp = bp + 1;
+	c = *sp;
+	*sp = *bp;
+	*bp++ = c;
+	bp += 2;
+    }
+}
+
+/*
+ * outl: a debugging routine.  Flushes stdout then prints a message on stderr
+ *       and flushes stderr.  Used to print messages when past certain points
+ *       in code so we can tell where we are.  Outl may be invoked like
+ *       printf with up to 7 arguments.
+ */
+/* VARARGS1 */
+void outl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
+     char *msg;
+     char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
+{
+	fflush(stdout);
+	fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+	fprintf(stderr, "\n");
+	fflush(stderr);
+}
diff --git a/src/gxeps.c b/src/gxeps.c
new file mode 100644
index 0000000..4af58a0
--- /dev/null
+++ b/src/gxeps.c
@@ -0,0 +1,1775 @@
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/***********************************************************
+ * GXEPS a grads metafile to PostScript converter
+ * Copyright (c) 1999 - 2001 Matthias Munnich
+ *
+ * I regard gxeps as freeware as long as proper credit is given.
+ * As I often read lengthy copyright notices I adjusted
+ * one which seemed fitting. Here it goes:
+ * * Permission has been granted to copy and distribute gxeps in any 
+ * context, including a commercial application, provided that this notice 
+ * is present in user-accessible supporting documentation.
+ * 
+ * This does not affect your ownership of the derived work itself, and 
+ * the intent
+ * is to assure proper credit for the authors of gxeps, not to interfere
+ * with your productive use of gxeps. If you have questions, ask. 
+ * "Derived works" includes all programs that utilize gxeps.
+ * Credit must be given in user-accessible documentation.
+ * 
+ * Permission to use, copy, modify, and distribute this software and its 
+ * documentation for any purpose and without fee is hereby granted, provided 
+ * that the above copyright notice appear in all copies and that both that 
+ * copyright notice and this permission notice appear in supporting 
+ * documentation.  This software is provided "as is" without express or 
+ * implied warranty.
+ * 
+ * Matthias Munnich mailto:munnich at atmos.ucla.edu
+ * ==================================================
+ *
+ *   $Log: gxeps.c,v $
+ *   Revision 1.13  2009/05/06 14:13:43  jma
+ *   additional mods for the 255 colors
+ *
+ *   Revision 1.12  2009/04/30 15:25:31  jma
+ *   changed max number of colors from 99 to 255
+ *
+ *   Revision 1.11  2009/01/05 12:48:24  jma
+ *   changed
+ *   #include <config.h>
+ *   to
+ *   #include "config.h"
+ *
+ *   Revision 1.10  2008/11/07 19:03:55  jma
+ *   removed all the #ifdefs for PRINT_EPS
+ *   this is now permanently enabled so you can
+ *   create postcript files using 'print' without 'enable print'
+ *
+ *   Revision 1.9  2008/01/23 13:04:49  jma
+ *   removed files, no more support of USEIMG
+ *
+ *   Revision 1.8  2007/09/13 13:58:42  jma
+ *   First and incomplete stab at double precision data handling and undef mask.
+ *   Compiles with few warnings on OSX, checked in now for testing on linux.
+ *
+ *   Revision 1.7  2007/05/31 15:45:28  jma
+ *   Changes to the configure system -- updated for dods 3.4 as the default. 
+ *   Some other minor changes to src files to add #include statements to remove compiler warnings.
+ *
+ *   Revision 1.6  2004/02/27 14:42:11  administrator
+ *   Changes to RGB color settings in gxps.c and gxeps.c to match the colors in
+ *   gxX.c, gxhpng.c, and the documentation. This should make image and postscript
+ *   ouput look just like the graphical display.
+ *
+ *   Revision 1.5  2003/11/10 21:27:39  jma
+ *   Fix to gxeps.c to add graylines (-G option) which fixes hardcopy output from basemap.gs
+ *
+ *   Revision 1.4  2003/04/04 01:52:30  joew
+ *   Mod from Matthias Munnich:
+ *
+ *   -DMM_NEW_PROMPT
+ *       - The grads prompt is changed to "ga[command number]> ", e.g., "ga[17]> ".
+ *
+ *   -DMM_READLINE Enhanced READLINE.
+ *   Command line enhancements:
+ *       - New "history" or "his" command:
+ *         "his[tory] [-sqx] [first] [last] [filename]" writes commands "first" to "last"
+ *         in the command history buffer to file "filename".
+ *         "his[tory] -r filename" reads commands from file "filename" into the command
+ *         history buffer.
+ *
+ *          Options:
+ *           -s  Write history in script syntax (quoted).
+ *           -x  Write history unquoted for "exec" command.
+ *           -q  Write quitely.
+ *           -r  Read history from file.
+ *
+ *         For files with extension ".gs" the history is written quoted (option "-s").
+ *         Examples:
+ *            "ga[17]> his" list the current command history.
+ *            "ga[17]> his 17 27 foo.gs" writes quoted commands 17 through 27 to file
+ *            foo.gs so that ga[17]> foo will reproduce the current state.
+ *
+ *       - New startup option "-H [history_log_file]":
+ *         At startup the last 256 commands in history_log_file are read into the command
+ *         history buffer.  When GrADS is terminated the new history is written to
+ *         history_log_file.
+ *         The default history_log_file is $HOME/.grads.log. (This may need adjustment
+ *         for Windows).
+ *
+ *       - New "repeat" or "r" command: r[epeat] [start] stop
+ *         Examples:
+ *         "ga[17]> r 21"  repeats command number 21. "ga[17]> r 20 30" repeats commands
+ *         20 to 30 skipping r commands to avoid infinite loops.
+ *
+ *   Revision 1.3  2003/04/03 19:46:27  joew
+ *   Mod from Matthias Munnich: improved EPS output
+ *
+ *   Revision 1.6  2001/12/17 23:37:15  munnich
+ *   Symbol fonts are now always drawn. To this end the string information
+ *   where moved to command -15 (begin string).
+ *
+ *   Revision 1.5  2001/12/07 00:40:42  munnich
+ *   Fixed bugs with gxheps.
+ *
+ *   Revision 1.4  2001/12/04 05:37:53  munnich
+ *   Incorporated gxeps into the print command. If printing is
+ *   not yet "enabled" the print command now uses gxeps code
+ *   to directly produce EPS files. Most of the standard gxeps
+ *   options are valid. Help is given via ga-> print -h or any
+ *   invalid option.
+ *   Affected files: Makefile, gauser.c, gx.h, gxmeta.c
+ *
+ *   Also changed the map drawing to use polygons if clip is hard.
+ *   Affected: gxwmap.c
+ *   RCS file: /long/munnich/CVSROOT/grads/cola/src/Makefile.in,v
+ *   RCS file: /long/munnich/CVSROOT/grads/cola/src/gauser.c,v
+ *   RCS file: /long/munnich/CVSROOT/grads/cola/src/gx.h,v
+ *   cvs diff: gxeps.c is a new entry, no comparison available
+ *   RCS file: /long/munnich/CVSROOT/grads/cola/src/gxmeta.c,v
+ *   RCS file: /long/munnich/CVSROOT/grads/cola/src/gxwmap.c,v
+ *
+ *   Revision 0.94  2001/12/02 06:22:59  munnich
+ *   gxeps.c
+ *
+ *   Revision 0.93  2001/12/02 06:20:55  munnich
+ *   Fixed Filled rectangle bug for RSCALE != 2
+ *
+ *   Revision 0.92  2001/11/24 04:48:25  munnich
+ *   Added clipboundary to bounding box computation.
+ *   Added meta file draw line command (-13) to search for Polygons.
+ *   Took care that the gsave/grestore pairs in clipping match at the end.
+ *
+ *   Revision 0.91  2001/11/22 02:17:23  munnich
+ *   Back to 1000dpi resolution due to visible roundoff errors.
+ *   Added IsoLatin1 support for PostScript level 2.
+ *   Made PS Level 2 default.
+ *
+ *   Revision 0.90  2001/11/21 07:03:28  munnich
+ *   Fixed a hardware clipping bug.
+ *
+ *   Revision 0.88  2001/04/19 01:55:35  munnich
+ *   Fixed a bug in rotated strings.-- 
+ *   of grads as well.
+ *
+ *   Revision 0.87  2001/03/08 21:57:23  munnich
+ *   Introduced hardware clipping, line styles, polygon and line drawing.
+ *   Use hardware clipping to cut contour lines for labels.
+ *   Right now smoothing of contours is disabled.
+ *   To be done:
+ *   1. Enable smoothing of contours.
+ *   2. Make hardware clipping and line style a setting
+ *      which can be changed by something like
+ *      set clip hard/soft
+ *      set style hard/soft
+ *   3. Disgard overlapping lables (an old "bug").
+ *
+ *   Revision 0.86  2001/03/08 21:21:22  munnich
+ *   Added support for new metafile commands:
+ *   (*) -13    draw a polygon
+ *   (*) -14    draw a line
+ *   (*) -17    set line style (dashes)
+ *   (*) -18    set/change clipping region
+ *
+ *   Revision 0.85  2001/02/01 21:23:45  munnich
+ *   1. Another change to the memory reallocation for large polygons.
+ *   Now it should always works.
+ *   2. New macro PSFONTS to enable PostScript font support.
+ *   3. Input can now come from stdin by using option -i -.
+ *
+ *   Revision 0.84  2001/01/27 06:57:04  munnich
+ *   Fixed coordinate line thicknes bug.
+ *
+ *   Revision 0.83  2000/10/13 16:36:01  munnich
+ *   Another bug fix related user defined colors.
+ *
+ *   Revision 0.82  2000/10/12 22:33:52  munnich
+ *   Fixed a bug related to user defined colors and black&white mode.
+ *
+ *   Revision 0.81  2000/09/20 22:51:42  munnich
+ *   Fixed rotated strings
+ *
+ *   Revision 0.80  2000/09/15 19:19:24  munnich
+ *   Implemented "-g" option for true 8.5'' x 11'' inch output size.
+ *
+ *   Revision 0.79  2000/09/05 01:33:13  munnich
+ *   Back to old scaling for letter paper.
+ *
+ *   Revision 0.78  2000/08/25 20:54:30  munnich
+ *   Back to version 0.76. V0.77 was broken.
+ *
+ *   Revision 0.76  2000/06/02 23:45:10  munnich
+ *   *** empty log message ***
+ *
+ *   Revision 0.75  2000/06/02 23:23:52  munnich
+ *   Fixed Orientation comment.
+ *
+ *   Revision 0.74  2000/04/03 17:28:54  munnich
+ *   Fixed 2 bugs:
+ *   (i) gsave was not bracketed with a grestore when
+ *   neither options -L nor -n were used.
+ *   (ii) Undefined colors are now set to gray (no. 15).
+ *
+ *   There is also a rudimentary font support in gxeps.c.
+ *   This only comes into affect when a new metafile format is
+ *   introduced.  Everthing should be backward compatible.
+ *
+ *   Revision 0.73  1998/11/30 10:13:57  m211033
+ *   Fixed a 2 bug: Lineswidth and colors can know
+ *   change within a polygon. This bug only occurred with
+ *   colored streamline plots.
+ *
+ *   Changed the line breaking method for polygons.
+ *
+ *   Revision 0.72  1997/12/08 14:16:15  m211033
+ *   Added the -R option which suppresses the rotation
+ *   for landscape metafiles.
+ *
+ *   Revision 0.71  1997/11/05 17:26:41  m211033
+ *   Added a compile option NEVER_CTL_D which disables
+ *   the -d option for DEFAULT_CTL_D 0, i.e. no ^D is added in
+ *   any case.
+ *
+ *   Revision 0.70  1997/04/15 15:14:37  m211033
+ *   Added a BORDER macro that controls the
+ *   added white space (in points) around the graph
+ *   for the bounding box comment.
+ *
+ * Revision 0.69  1997/04/09  14:38:39  m211033
+ * Black background now as large as the bounding box.
+ * BoundingBox corrected for black background.
+ *
+ *   Revision 0.68  1996/11/22 14:10:45  m211033
+ *   BoundingBox takes filled rectangulars into account.
+ *
+ * Revision 0.67  96/11/19  16:46:19  m211033
+ * Two bugs were fixed:
+ * (i) with DEFAULT_CTL_D 1 the -d option didn't work.
+ * (ii) Color change now leads to a flush of stored lines
+ *     (Before sometimes a line was drawn in a invisible color.)
+ * 
+ * Revision 0.66  96/10/23  12:50:26  m211033
+ * Fixed the data type of file position.
+ * 
+ * Revision 0.65  1996/06/26  15:20:29  m211033
+ * Inserted a gsave to match the grestore.
+ * This fixes an annotation bug.
+ * Resolution is reduce to 500dpi since Version 0.64.
+ *
+ * Revision 0.64  1996/05/15  10:17:00  m211033
+ * The cut of filled line did not work. No the old method
+ * is used untill drawline and fillline is rewritten for
+ * the use of reversepath.
+ * Filline now also looks for colinear lines.
+ *
+ * Revision 0.63  1996/04/26  19:32:57  m211033
+ * Got rid off the error prone reallocation for saved point.
+ *
+ * Revision 0.62  96/04/26  19:08:25  m211033
+ * Fixed another bug with multible plots in one metafile.
+ * 
+ * Revision 0.61  1996/04/26  17:16:57  m211033
+ * Now it tries to find straight lines in polygons.
+ *
+ * Revision 0.6  96/04/26  16:15:45  m211033
+ * Tries to find dashed lines to make the EPS output
+ * more compact. Unnecessary return(0) in while(1) eliminated.
+ * 
+ *
+ ***********************************************************/
+          /* default PS-level */
+#define PS_LEVEL 2
+          /* set this to 1 for default a4 paper */
+#define DEFAULTA4 0
+     /* default add control-D at end-of-file (some printer may need this) */
+#define DEFAULT_CTL_D 0
+   /* if NEVER_CTL_D is defined ^D will never be added (disables -d Option) */
+#define NEVER_CTL_D
+#define BORDER 10
+
+/* PS font support */
+#define PSFONTS 
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+
+#define max(A, B) ((A) > (B) ? (A) : (B))
+#define min(A, B) ((A) < (B) ? (A) : (B))
+
+
+/* Some scales for letter paper */
+/* RSCALE: resolution scale */
+#define RSCALE 1
+/* #define LETSCALE 0.1314 */
+#define LETSCALE 0.0657 * RSCALE
+#define LETXOFF 30
+#define LETYOFF 45
+/* GrADS scaling 8.'' x 11'' */
+#define GASCALE 0.144 
+/* Some scales for a4 paper */
+#define A4SCALE 0.1134 
+#define A4XOFF 71
+#define A4YOFF 109
+/* default file extensions */
+#define IN_EXT "gm"
+#define OUT_EXT "eps"
+
+#define PNMAX 512
+/* maximum string size */
+#define STRSIZ 300
+#ifdef OLD__GNUC__
+#define fpos_t long
+#endif
+
+/* is also defined in gxhpng.c */
+struct point {short x; short y;};
+struct point bblow, bbhigh;     /* BoundingBox */
+struct point cliplow, cliphigh; /* Clipping Box */
+struct options {                /* command line options (flags) */
+  short pscale, color, ctl_d, comment, pslevel,
+    tstamp, reverse, rotate, verbose, label, font,
+    history, graylines;
+};
+FILE *infile, *outfile;
+fpos_t bboxpos,pagespos,pagepos,blackpos; /* output file position of boundingbox and page # comments */
+void boundbox(struct point* pnt); /* compute bounding box */
+void printbbox(short opscale,short landscape,struct options *o);  /* print bounding box to PS-file */
+int print_options(char *argv[]); /* print command line options */
+void drawline(struct point pnts[],short *pcnt,
+	      short lcolor,short *colold,short *lastfill,short flush); /* draw a polygon */
+int SaveLine(struct point pnts[],struct point dline[]);
+void PrintDashLine(struct point dline[]);
+short CheckDashLine(struct point pnts[],struct point dline[]);
+void SetDline(struct point pnts[],struct point dline[]);
+short CheckExpandDashLine(struct point pnts[],struct point dline[]);
+int parse_arg(int argc,char *argv[],struct options *o,char **fin, char **fout); /* parse command line */
+int openfiles(char **fin, char **fout, short verbose); /* Open files */
+void fillline(struct point pnts[],short pcnt); /* fill a polygon */
+void initepsf(short landscape,int argc,char *argv[],char *fout,struct options *o); /* write PS-file header */
+void init_newpage(short landscape,char *fout,struct options *o); /* New page header */
+void setjust(short *opts, short *justx, short *justy);
+int gxheps(char*);
+void getwrd (char *, char *, int);
+int gxeps(int , char **);
+
+#ifndef GXHEPS
+#define RDSTREAM(var,num)  fread (var , sizeof(short), num, infile);
+#define MAIN main
+#else
+#define MAIN gxeps
+#define RDSTREAM(var,num)  var=poi; poi+=num;
+char *nxtwrd (char *); 
+
+/* --------------------- Wrapper for gxeps -------------------------- */
+int gxheps(char *com) {
+  char *args,**argv; 
+  int argc=0;
+  char *cmd,*ch;
+  int i,rc;
+
+  cmd=com;
+
+  while( ((cmd=nxtwrd(cmd)) != NULL)) {
+    argc++; 
+  }
+
+  argc+=1;
+
+  argv=(char **) malloc(argc*sizeof(char **));
+  args=(char *) malloc( (strlen(com)+5) *sizeof(char));
+  for(i=0;i<argc;i++) argv[i]=NULL;
+
+  /* copy words in com into args and assign pointers to each word */
+  cmd=com;
+  /* copy command (print) */
+  i=0;
+  ch=args;
+  getwrd(ch,cmd,256);
+  argv[i]=ch;
+  ch+=strlen(ch)+1; 
+  
+  /* copy gxeps options */ 
+  while(++i<argc) {
+    cmd=nxtwrd(cmd);
+    getwrd(ch,cmd,256); 
+    argv[i]=ch;
+    ch+=strlen(ch)+1;
+  }
+
+#ifdef DEBUG_EPS
+  printf(" GXHEPS:\n");
+  printf("argc = %d\n",argc);
+  for(i=0;i<argc;i++)
+      printf("argv[%d]= >%s<\n",i,argv[i]);
+  printf("Calling gxeps...\n");
+#endif
+  rc=gxeps(argc, argv);
+  rc=0;
+  free(argv);
+  free(args);
+  return (rc);
+}
+
+#endif
+
+/* --------------------------------------------------------------------------------- */
+int MAIN (int argc, char *argv[])  {
+   short cmd,coldef[256],lcolor=0, colold=-1, wold=-1, landscape=0, npnmax=1, lastfill=0;
+   short oldstyle=0;
+   struct point *pnts, *pnts2;            /* points of a polygon */
+   struct options o;                      /* command line options */
+   int nodraw=0;                          /* skip draw commands (for string drawing) */
+   int pnmax=PNMAX;                        /* maximum length of a polygon */
+   register int  i,j, ii,jj;
+   short pcnt,pcntSave,fcnt=0,filflg=0;
+   float red,blue,green;
+   char *fin=NULL,*fout=NULL;              /* file names */
+   char str[STRSIZ+50]; /* I hope nobody writes longer lines */
+   short justx,justy; /* justification in % */
+#ifndef GXHEPS
+   fpos_t infile_pos;
+   char string[STRSIZ]; /* I hope nobody writes longer lines */
+   short opts[8];
+#else
+   char *string;
+   short *opts;
+  int cnt,flag,fflag,ib;
+  short *poi,*pend;
+#endif
+   o.pscale=DEFAULTA4;                                           /* default options */
+#ifdef NEVER_CTL_D
+   o.ctl_d=0;
+#else
+   o.ctl_d=DEFAULT_CTL_D;
+#endif
+#ifdef PSFONTS
+   o.font=1;
+#else
+   o.font=0;
+#endif
+   o.reverse=o.verbose=o.comment=o.tstamp=o.label=0;
+   o.history=1;
+   o.rotate=o.color=1;
+   o.pslevel=PS_LEVEL;
+   o.graylines=0;
+   landscape=0;
+   bblow.x=1200;bblow.y=1200;
+   bbhigh.x=0; bbhigh.y=0;
+   pnts=(struct point *) malloc(pnmax*sizeof(struct point)); /* initial maximal polygon size */
+
+  for(i=0;i<16;i++) coldef[i]=1;          /* Initialize defined color flag*/
+  for(i=16;i<=255;i++) coldef[i]=0;
+
+  if(parse_arg(argc,argv,&o,&fin,&fout))
+    return(1);     /* Parse command line arguments */
+  if(openfiles(&fin,&fout,o.verbose))
+    return(1);                  /* open files */
+
+  /* Translate the file */
+
+#ifdef GXHEPS  
+  /*  Set up pointers into current meta buffer list */
+
+  if (dbmode && pntf==0) {
+    lens2[pnt2-1] = hpnt-hbuff;
+    cnt = pnt2; flag = 1;
+  } else {
+    lens[pnt-1] = hpnt-hbuff;
+    cnt = pnt; flag = 0;
+  }
+  fflag = 0;
+
+    /* Initialization (cmd ==-1) not in buffer. we do it here */
+
+    landscape= (yrsize<xrsize);  /* ysize < xsize : landscape */
+    if(o.rotate && landscape) o.rotate=1; /* no -R option and */
+    else o.rotate=0; 
+    
+    initepsf(landscape,argc,argv,fout,&o);
+    colold=-1;
+    init_newpage(landscape,fout,&o);
+    pcnt = 0;
+
+  for (ib=0; ib<cnt; ib++) {
+    if (flag) {
+      poi = bufs2[ib];
+      pend = poi + lens2[ib];
+    } else { 
+      poi = bufs[ib];
+      pend = poi + lens[ib];
+    } 
+
+    while (poi<pend) {
+    cmd= *poi; poi++;
+#else 
+      /* gxeps utility */
+  fcnt = 1;
+  while (1) {
+    fread (&cmd , sizeof(short), 1, infile);
+#endif
+
+    if (cmd==-11) {				/* Draw to */
+      /*      fread (opts, sizeof(short), 2, infile); */
+      RDSTREAM(opts,2)
+      if(nodraw) {
+	pnts[pcnt+1].x=opts[0]/RSCALE;
+	pnts[pcnt+1].y=opts[1]/RSCALE;
+	boundbox(&pnts[pcnt+1]);
+	if (lcolor != colold)  {
+	  fprintf(outfile,"c%i ",lcolor);
+	  colold=lcolor;
+	}
+	continue;
+      }
+      pnts[++pcnt].x=opts[0]/RSCALE;
+      pnts[pcnt].y=opts[1]/RSCALE;
+      boundbox(&pnts[pcnt]);
+      if (pcnt%(pnmax/4)==(pnmax/4)-1){
+        if (!filflg) {   /* flush pnts to keep vector counts small */
+	  drawline(pnts,&pcnt,lcolor,&colold,&lastfill,-1);
+          pnts[0].x=opts[0]/RSCALE;
+	  pnts[0].y=opts[1]/RSCALE;
+        } else if(pcnt==pnmax-1) { /* increase pnmax to hold more points */
+	  pnmax =PNMAX* ++npnmax;
+	  pnts2=(struct point *) malloc(pnmax*sizeof(struct point)); /* new memory array */
+	  memcpy(pnts2,pnts,pnmax*sizeof(struct point));    /* copy saved pnts to new array */
+	  free(pnts);
+	  pnts=pnts2;
+	  if(o.verbose)
+	    printf("     Memory allocation for polygons increased to %i points.\n",pnmax);
+        }
+      }
+    }
+    else if (cmd==-10){				/* Move to */
+      /*      fread ( opts, sizeof(short), 2, infile); */
+      RDSTREAM(opts,2)
+      if (pcnt) {
+	if( (pnts[pcnt].x==opts[0]/RSCALE) && (pnts[pcnt].y==opts[1]/RSCALE) ) {
+	  continue;
+	}
+	drawline(pnts,&pcnt,lcolor,&colold,&lastfill,0);
+      }
+      pnts[pcnt].x=opts[0]/RSCALE;
+      pnts[pcnt].y=opts[1]/RSCALE;
+      boundbox(&pnts[pcnt]);
+      if(nodraw) continue;
+    }
+    else if (cmd==-4) {				/* Set line width */
+      if (pcnt) {
+	pcntSave=pcnt;
+	drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+	pnts[pcnt].x=pnts[pcntSave].x;
+	pnts[pcnt].y=pnts[pcntSave].y;
+      } else
+	drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+      /*       fread (opts, sizeof(short), 2, infile); */
+      RDSTREAM(opts,2)
+      i = opts[0];
+      if (i>12) i=12;
+      else if (i<1) i=1;
+      if(--i!=wold){
+	fprintf(outfile,"w%i ",i);
+	wold=i;
+      }
+    }
+    else if (cmd==-3) {				/* Set color */
+      if (pcnt) {
+	pcntSave=pcnt;
+	drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+	pnts[pcnt].x=pnts[pcntSave].x;
+	pnts[pcnt].y=pnts[pcntSave].y;
+      }
+      /*      fread (opts, sizeof(short), 1, infile); */
+      RDSTREAM(opts,1)
+      lcolor = opts[0];
+      /********      printf("New lcol#=%i\n",lcolor); */
+      if (lcolor<0) lcolor=0;
+      if (lcolor>255) lcolor=255; 
+      if (!(coldef[lcolor])) lcolor=15;
+      /*      if (nodraw) fprintf(outfile,"c%i ",lcolor); */
+      fprintf(outfile,"c%i ",lcolor);
+    }
+    else if (cmd==-7){				/* Start fill */
+      /*       fread (opts, sizeof(short), 1, infile); */
+      RDSTREAM(opts,1)
+      filflg = 1;
+      /* if(o.verbose) fprintf(outfile, "%%Fflag\n"); */
+    }
+    else if (cmd==-8){				/* End fill */
+      if (pcnt) { 
+	  if (lcolor != colold || lastfill==0)  {
+	  fprintf(outfile,"g%i ",lcolor);
+	  colold=lcolor;
+	  }
+        fillline(pnts,pcnt); pcnt=0;
+        filflg = 0;
+	lastfill=1;
+      }
+    }
+    else if (cmd==-6){				/* Rectangle fill */
+      if (pcnt) {drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);}
+      /*       fread (opts, sizeof(short), 4, infile); */
+      RDSTREAM(opts,4)
+      if (lcolor != colold || lastfill==0)  {
+	fprintf(outfile,"g%i ",lcolor);
+	colold=lcolor;
+      }
+      for(i=0;i<4;i++) opts[i]/=RSCALE;
+      pnts[0].x=opts[0];
+      pnts[0].y=opts[2];
+      pnts[1].x=opts[1];
+      pnts[1].y=opts[3];
+      boundbox(&pnts[0]);
+      boundbox(&pnts[1]);
+      fprintf(outfile,"%i %i %i %i B\n",
+	      opts[0],opts[2],opts[1]-opts[0],opts[3]-opts[2]);
+      lastfill=1;
+    }
+    else if (cmd==-9) {				/* End of plotting */
+      /*  fsetpos(outfile,&pagepos); */
+	fprintf (outfile,"%%%%Trailer\n%%%%EOF\n");
+	/*  if(!o.reverse) printbbox(o.pscale,landscape); */
+	/*  if(o.verbose) printf("BBox without offset: %i %i %i %i \n",
+                           bblow.x, bblow.y, bbhigh.x, bbhigh.y); */
+      if (o.ctl_d) fprintf (outfile,"%c%c",(char)4,'\n');
+      if(o.verbose) printf ("     Number of pages = %i\n",fcnt);
+#ifdef GXHEPS
+      fsetpos(outfile,&pagespos);
+      printf("WARNING: command -9 in plot buffer.\n");
+#endif
+      fprintf(outfile,"%i",fcnt);
+      fclose (outfile);
+      return(0);
+    }
+    else if (cmd==-1) {				/* Start of plotting */
+      /*       fread (opts, sizeof(short), 2, infile); */
+      RDSTREAM(opts,2);
+      landscape= (opts[1]<opts[0]);  /* ysize < xsize : landscape */
+      if(o.rotate && landscape) o.rotate=1; /* no -R option and */
+      else o.rotate=0; 
+      
+      initepsf(landscape,argc,argv,fout,&o);
+      colold=-1;
+      init_newpage(landscape,fout,&o);
+      pcnt = 0;
+    }
+    else if (cmd==-2) {				/* New Page */
+      if (pcnt) drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+      fprintf(outfile,"C0\n");
+#ifdef DEBUG_EPS
+     fprintf(outfile,
+     " %i %i moveto %i %i lineto %i %i lineto %i %i lineto closepath stroke\n ",
+     bblow.x,bblow.y,bblow.x, bbhigh.y,bbhigh.x,bbhigh.y,bbhigh.x,bblow.y);
+#endif
+      fprintf (outfile,"showpage\n");
+      printbbox(o.pscale,landscape,&o);
+#ifndef GXHEPS
+      fgetpos(infile,&infile_pos);
+      /*       fread (&cmd , sizeof(short), 1, infile);  */
+      RDSTREAM(&cmd,1)
+      fsetpos(infile,&infile_pos);
+#endif
+      if (cmd != -9) {  /* if next command is not end_of_plotting */
+      ++fcnt;
+      fprintf (outfile,"\n%%%%Page: %i %i\n",fcnt,fcnt); /* print %%Page: for the last page */
+#ifndef GXHEPS
+         fprintf(outfile,"%%%%BoundingBox: ");
+         fgetpos(outfile, &bboxpos);
+         fprintf(outfile,"                  \n");
+#else
+         fprintf(outfile,"%%%%BoundingBox: (atend)\n");
+#endif
+         bblow.x=1200;bblow.y=1200;
+         bbhigh.x=0; bbhigh.y=0;
+	 colold=-1;
+         init_newpage(landscape,fout,&o);
+      }
+    }
+    else if (cmd==-5){				/* Define new color */
+      /*       fread (opts, sizeof(short), 4, infile); */
+      RDSTREAM(opts,4);
+      i = opts[0];
+      if (i>15 && i<=255) {
+          green = ((float)(opts[2]))/255.0;
+          if (green<0.0) green=0.0;
+          if (green>1.0) green=1.0;
+          red = ((float)opts[1])/255.0;
+          if (red<0.0) red=0.0;
+          if (red>1.0) red=1.0;
+          blue = ((float)opts[3])/255.0;
+          if (blue<0.0) blue=0.0;
+          if (blue>1.0) blue=1.0;
+          fprintf(outfile,"blackwhite \n");
+	  /* (b/w: mapped into grey scale via green intensity) */
+	  if(o.graylines)
+	    fprintf(outfile,"  {/g%i {%.5g g} bdef /c%i {%.5g g} bdef}\n",i,1.0-green,i,1.0-green);
+	  else
+	    fprintf(outfile,"  {/g%i {%.5g g} bdef /c%i {g1} bdef}\n",i,1.0-green,i);
+	  fprintf(outfile,"  {/c%i {%.5g %.5g %.5g c} bdef\n",i,red,green,blue);
+          fprintf(outfile,"/g%i {c%i} def}\n ifelse\n",i,i);
+	  coldef[i]=1;
+      }
+    }
+      /*  -13 draw a polygon.  It has 2*siz+1 args. */
+      else if (cmd==-13) {
+	/* 	fread (opts, sizeof(short), 1, infile); */
+	RDSTREAM(opts,1)
+	i=opts[0]/2; /* i: # points in polygon */
+	/* 	fprintf(outfile,"%% polygon of %d points, opts[0]=%d\n",i,opts[0]); */
+	pnts2=(struct point *) malloc(i*sizeof(struct point));
+#ifndef GXHEPS
+	fread (pnts2, sizeof(struct point), i, infile);
+#else
+        pnts2=(struct point *) poi; poi+=2*i;
+#endif
+	jj=0;
+	for(ii=i-1;ii>0; ii--){
+	  jj+=fprintf(outfile,"%d %d ",(pnts2[ii].x-pnts2[ii-1].x)/RSCALE,
+		      (pnts2[ii].y-pnts2[ii-1].y)/RSCALE);
+	  if(jj>70) {
+	    jj=0;
+	    fprintf(outfile,"\n");
+	  }
+	}
+	fprintf(outfile,"%d %d%s%d S\n",pnts2->x/RSCALE,pnts2->y/RSCALE,(jj>70) ? "\n" : " ", --i);
+	/*	if(jj>70) fprintf(outfile,"\n");
+		fprintf(outfile,"%d S\n",--i); */
+      }
+  
+
+      /* -14 is draw a line  It has four float args. */ 
+ 
+    else if (cmd==-14) {
+      /*      fread (opts, sizeof(short), 4, infile); */
+      RDSTREAM(opts,4)
+      if(pcnt) { /* Check if we can add this secment to the stored polygon..*/
+	if( (pnts[pcnt].x==opts[0]/RSCALE) && (pnts[pcnt].y==opts[1]/RSCALE) ){
+	  pnts[++pcnt].x=opts[2]/RSCALE;
+	  pnts[pcnt].y=opts[3]/RSCALE;
+	  boundbox(&pnts[pcnt]);
+	  if (pcnt%(pnmax/4)==(pnmax/4)-1){
+	    drawline(pnts,&pcnt,lcolor,&colold,&lastfill,-1);
+	    pnts[0].x=opts[2]/RSCALE;
+	    pnts[0].y=opts[3]/RSCALE;
+	  }
+	} else 	if( (pnts[pcnt].x==opts[2]/RSCALE) && (pnts[pcnt].y==opts[3]/RSCALE) ){
+	  pnts[++pcnt].x=opts[0]/RSCALE;
+	  pnts[pcnt].y=opts[1]/RSCALE;
+	  boundbox(&pnts[pcnt]);
+	  if (pcnt%(pnmax/4)==(pnmax/4)-1){
+	    drawline(pnts,&pcnt,lcolor,&colold,&lastfill,-1);
+	    pnts[0].x=opts[0]/RSCALE;
+	    pnts[0].y=opts[1]/RSCALE;
+    }
+	} else {
+	  drawline(pnts,&pcnt,lcolor,&colold,&lastfill,0);
+	}
+      } else {
+	pnts[pcnt].x=opts[0]/RSCALE;
+	pnts[pcnt].y=opts[1]/RSCALE;
+	boundbox(&pnts[pcnt]);
+	pnts[++pcnt].x=opts[2]/RSCALE;
+	pnts[pcnt].y=opts[3]/RSCALE;
+	boundbox(&pnts[pcnt]);
+/*       fprintf(outfile," %d %d %d %d L\n", */
+/* 	      (opts[2]-opts[0])/RSCALE,(opts[3]-opts[1])/RSCALE,opts[0]/RSCALE,opts[1]/RSCALE); */
+/*       boundbox((struct point *)&opts[0]); */
+/*       boundbox((struct point *)&opts[2]); */
+      }
+    }
+    else if (cmd==-15) {		/* Begin  Char. String drawing */
+      /*  if (pcnt) drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1); */
+      /*       fread (opts, sizeof(short), 8, infile); */
+      RDSTREAM(opts,8)
+                  /* opts[0]=len,   opts[1]=x, opts[2]=y, opts[3]=height,
+                   * opts[4]=width, opts[5]=angle, opts[6]=font number
+                   * opts[7]=justification
+                   */
+      if(opts[0]>=STRSIZ) {
+	printf("String too long. Recompile with bigger STRSIZ.\n");
+	return(1);
+      }
+#ifndef GXHEPS
+      fread(string,sizeof(short),(opts[0])/sizeof(short)+2,infile);
+#else
+      string=(char *) poi; 
+      poi+= (int) (opts[0])/sizeof(short)+2;
+#endif
+      i=j=0;
+      do { /* quote parentheses */
+	if(string[i]=='(' || string[i]==')' ) {
+	  str[j++]='\\';
+	  str[j++]=string[i++];
+	} else
+	  str[j++]=string[i++];
+      }  while(string[i]!='\0');
+      str[j]='\0';
+      
+      if((opts[6] != 3) && o.font) nodraw=1;
+      if(!nodraw) fprintf(outfile,"%% String: ");
+      setjust(opts,&justx,&justy);
+      if(opts[7] == 1) {
+      fprintf(outfile,"(%s) %d %d %d %d %d %d LS\n",
+                  str,opts[6],opts[4]*85/50/RSCALE,opts[3]*75/50/RSCALE,
+	         (int)((float)opts[5]/64.),opts[1]/RSCALE,opts[2]/RSCALE);
+	
+      } else {
+
+		fprintf(outfile,"(%s) %d %d %d %d %d %d %d %d JS\n",
+			str,opts[6],opts[4]*85/50/RSCALE,opts[3]*75/50/RSCALE,
+			(int)((float)opts[5]/64.),opts[1]/RSCALE,opts[2]/RSCALE,justx,justy);
+	      
+      }
+      if(!nodraw) fprintf(outfile,"%% String begin{\n");
+    }
+    else if (cmd==-16) {		/* End string  drawing */
+      if (pcnt) drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+      if(nodraw) {
+      nodraw=0;
+      } else {
+	fprintf(outfile,"\n%%} String end\n");
+      }
+    }
+
+      /* -17 indicates linestyle.  One arg; style number.  */
+  
+      else if (cmd==-17) {
+	/* 	fread (opts, sizeof(short), 1, infile); */
+	RDSTREAM(opts,1)
+	if(oldstyle != opts[0]) {
+	  if (pcnt) {drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);} 
+	  if(opts[0]>0 && opts[0]<9)
+	    fprintf(outfile,"s%d ",opts[0]);
+	  else
+	    fprintf(outfile,"s1 %%s%d\n",opts[0]);
+	  oldstyle=opts[0];
+	}
+    }
+
+      /* -18 Change clipping region: has 5 args  */
+  
+      else if (cmd==-18) {
+	/* 	fread (opts, sizeof(short), 5, infile); */
+	RDSTREAM(opts,5)
+
+	if(opts[0]==0) {
+	  fprintf(outfile,"C0\n");
+	  cliplow.x=0;cliplow.y=0;cliphigh.x=11000;cliphigh.y=11000;
+	}
+	else if(opts[0]==1) { /* clip exterior of rectangle */
+	  fprintf(outfile,"%d %d %d %d C1\n",opts[1]/RSCALE,opts[3]/RSCALE,
+		  (opts[2]-opts[1])/RSCALE,(opts[4]-opts[3])/RSCALE);
+	  cliplow.x=opts[1]/RSCALE;
+	  cliplow.y=opts[3]/RSCALE;
+	  cliphigh.x=opts[2]/RSCALE;
+	  cliphigh.y=opts[4]/RSCALE;
+ 	}
+	else if(opts[0]==2) /* add interior of rectangle to clipping*/
+	  fprintf(outfile,"%d %d %d %d C2\n",opts[1]/RSCALE,opts[4]/RSCALE,
+		  (opts[2]-opts[1])/RSCALE,(opts[3]-opts[4])/RSCALE);
+      }
+
+    else if (cmd==-20) {		/* Draw button -- ignore */
+      /*       fread (opts, sizeof(short), 1, infile); */
+      RDSTREAM(opts,1)
+    }
+    else {
+       printf ("   Fatal error: Invalid command \"%i\" found in metafile\"%s\".\n",cmd,fin);
+       printf ("   Is \"%s\" really a GrADS (v1.5 or higher) metafile?\n",fin);
+      return(1);
+    }
+  }
+#ifdef GXHEPS
+    }
+    /* Commands -2 (new page) and -9 (end plot) not in buffer *
+     *  We need to do it now */
+    
+    /* cmd == -2  New page  + -9 end of plotting*/
+    if (pcnt) drawline(pnts,&pcnt,lcolor,&colold,&lastfill,1);
+    fprintf (outfile,"showpage\n");
+    fprintf (outfile,"%%%%Trailer\n");
+    fprintf(outfile,"%%%%BoundingBox: ");
+    printbbox(o.pscale,landscape,&o);
+    fprintf (outfile,"\n%%%%EOF\n");
+    fprintf(outfile,"\n");
+    if (o.ctl_d) fprintf (outfile,"%c%c",(char)4,'\n');
+    fclose (outfile);
+    if(fout != NULL) printf("  EPS file written to %s\n",fout);
+    return(0);
+#endif
+}
+/* --------------------------------------------------------------------------------- */
+
+void initepsf(short landscape,int argc,char *argv[],char *fout,struct options *o){
+       char *gr[16] =  {                      /* default greys */
+                  "1", "0", "0.16", "0.46", "0.7", "0.58", "0.1", "0.34",
+                  "0.22", "0.82", "0.4", "0.64", "0.28", "0.52", "0.76", "0.5"
+             };
+       char * col[16] = {          /* colors */
+		"1.00 1.00 1.00",  /* white */
+		"0.00 0.00 0.00",  /* black */
+		"0.98 0.24 0.24",  /* red */
+		"0.00 0.86 0.00",  /* green */
+		"0.12 0.24 1.00",  /* blue */
+		"0.00 0.78 0.78",  /* cyan */
+		"0.94 0.00 0.51",  /* magenta */
+		"0.90 0.86 0.19",  /* yellow */
+		"0.94 0.51 0.16",  /* orange */
+		"0.63 0.00 0.78",  /* purple */
+		"0.63 0.90 0.19",  /* yellow/green */
+		"0.00 0.63 1.00",  /* med. blue */
+		"0.90 0.69 0.18",  /* dark yellow */
+		"0.00 0.82 0.55",  /* aqua */
+		"0.51 0.00 0.86",  /* dark purple */
+		"0.67 0.67 0.67"   /* grey */
+};
+      char *widths[12] = {                      /* widths */
+	 "4 w","7 w","10 w","14 w","17 w","20 w",
+                "24 w","27 w","31 w","34 w","38 w","41 w"
+	/*   "1 w","3 w","5 w","7 w","9 w","10 w",
+	     "12 w","14 w","15 w","17 w","19 w","21 w"  RSCALE=2 widths */
+             };
+      int i;
+      char buf[256];
+      time_t thetime=time(NULL);
+      if(o->pslevel>1) fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-1.2\n");
+      else             fprintf(outfile, "%%!PS-Adobe-1.0 EPSF-1.2\n");
+#ifndef GXHEPS
+      fprintf(outfile,"%%%%BoundingBox: ");
+      fgetpos(outfile, &bboxpos);
+      fprintf(outfile,"                    \n");
+#else
+         fprintf(outfile,"%%%%BoundingBox: (atend)\n");
+#endif
+      if(getenv("USER"))
+	fprintf(outfile,"%%%%For: %s\n",getenv("USER"));
+      fprintf(outfile,
+              "%%%%Creator: gxeps $Revision: 1.13 $\n"
+              "%%%%Title: %s\n"
+              "%%%%CreationDate: %s"
+              "%%%%Pages: ",fout,ctime(&thetime));
+#ifndef GXHEPS
+      fgetpos(outfile, &pagespos);
+#endif
+      if(o->pscale !=2) {
+	fprintf(outfile,"    \n%%%%PageOrder: Ascend\n%%%%PaperSize: ");
+	if(o->pscale==1) fprintf(outfile, "A4\n");
+	else      fprintf(outfile, "Letter\n");
+      }
+      if(landscape) fprintf(outfile, "%%%%PageOrientation: Landscape\n");
+      else      fprintf(outfile, "%%%%PageOrientation: Portrait\n");
+      /*       fprintf(outfile,"%%%%DocumentFonts: "); */
+      /*      if(o->tstamp||o->label) fprintf(outfile,"Helvetica"); */
+      fprintf(outfile,"\n%%GxepsCommandLine: ");
+      for(i=0;i<argc;i++) fprintf(outfile," %s",argv[i]);
+      fprintf(outfile,"\n");
+      if(getenv("HOST"))
+	fprintf(outfile,"%%Host: %s\n",getenv("HOST"));
+      if(getenv("PWD"))
+	fprintf(outfile,"%%PWD: %s\n",getenv("PWD"));
+      if(o->comment) {			/* get user comments */
+         fprintf(outfile,"\n%%BeginUserComments\n");
+         printf("%s%s","Comments to plot=?",
+               " (Period (.) on a single line to finish)\n");
+        while(1) {
+          fgets(buf,130,stdin);
+          if(buf[0]=='.' && buf[1]=='\n') break;
+          fprintf(outfile,"%% %s",buf);
+        }
+         fprintf(outfile,"%%EndUserComments\n");
+      }
+#ifdef GXHEPS
+#if READLINE == 1
+     if(o->history) {
+       fprintf(outfile,"%%BeginGradsCommandHistory\n");
+       fclose(outfile);
+       strcpy(buf,"his -q ");
+       gahistory("his",strncat(buf,fout,255), NULL);
+       outfile=fopen(fout,"a");
+       fprintf(outfile,"%%EndGradsCommandHistory\n");
+      }
+#endif
+#endif
+      fprintf(outfile,"%%%%EndComments\n");
+      fprintf(outfile,"%s",
+                      "\n%%BeginProlog\n");
+      fprintf(outfile,"%%Change the following (values: true, false) to get color or b/w output\n");
+      fprintf(outfile,"/blackwhite {%s} def\n",
+	      (o->color) ? "false" : "true");
+      fprintf(outfile,"%s",
+	              "/clipOn {false} def\n"
+	              "/bdef {bind def} bind def\n"
+	              "/edef {exch def} bind def\n"
+                      "/in {72 mul} bdef\n"
+                      "/cm {in 2.54 div} bdef\n"
+                      "/c {setrgbcolor} bdef\n"
+                      "/g {setgray} bdef\n"
+                      "/w {setlinewidth} bdef\n"
+                      "/L {moveto rlineto stroke} bdef\n"
+                      "/D {5 -1 roll 0 setdash L []0 setdash} bdef %% dashed line\n"
+                      "/P {% Lay out a polygon\n"
+                      "    % usage: x_n y_n x_n-1 y_n-1 ... x_0 y_0 n P\n"
+                      "    3 1 roll moveto {rlineto} repeat} bdef\n"
+                      "/F {P fill} bdef %Fill a polygon\n"
+                      "/S {P stroke} bdef %Draw a polygon\n"
+                      "/gxfonts {%Usage: <font#> gxfonts\n"
+                      "    [/Helvetica /Times-Roman /Times-Italic /Symbol /Helvetica-Bold /Times-Bold] \n"
+                      "     exch get findfont} bdef\n"
+                      "/sfont {%Usage: <font#> <width> <height> sfont\n"
+                      "     /szy edef /szx edef gxfonts [szx 0 0 szy 0 0 ] makefont setfont} def\n"
+                      "/LS % Left alligned string\n" 
+                      "{ % Usage: <string> <font#> <width> <height> <angle> <pos_x> <pos_y>\n"
+                      "   gsave translate rotate sfont 0 0 moveto show grestore\n"
+                      "} def\n"
+                      "/RS % Right alligned string\n" 
+                      "{ % Usage: <string> <font#> <width> <height> <angle> <pos_x> <pos_y>\n"
+                      "   gsave translate rotate sfont 0 0 moveto dup stringwith pop \n"
+                      "   0 sub rmoveto show grestore\n"
+                      "} def\n"
+		      "/JS % General justified string \n"
+		      "{ %Usage: <string> <font#> <width> <height> "
+		      "<angle> <pos_x> <pos_y> <justx> <justy> JS\n"
+		      " % (Note: justx, justy in percent: e.g., justx=50 => x-centered)\n"
+		      "   /jy edef /jx edef gsave translate rotate sfont 0 0 moveto dup stringwidth\n"
+		      "   jy mul 0.01 neg mul exch jx mul 0.01 mul neg exch rmoveto show grestore\n} def\n"
+		      );
+if(o->pslevel>1){
+         fprintf(outfile,"%s",
+                      "/B {rectfill} bdef %Fill a box, usage: xlow ylow width height B\n");
+         fprintf(outfile,"%s",
+                      "/iso_reencode { % Usage: <Font> iso_reencode\n"
+                      "  dup /isoname exch def findfont\n"
+                      "  dup length dict begin\n"
+                      "  { 1 index /FID ne\n"
+                      "      {def}\n"
+                      "      {pop pop}\n"
+                      "      ifelse\n"
+                      "  } forall\n"
+                      "  /Encoding ISOLatin1Encoding def\n"
+                      "  currentdict end\n"
+                      "  isoname exch definefont pop\n"
+		      "} def\n"
+		      "[/Helvetica /Times-Roman /Times-Italic /Helvetica-Bold /Times-Bold]\n"
+                      "   {iso_reencode} forall\n");
+      }
+      else { 
+         fprintf(outfile,"%s",
+                      "/B { %Fill a box, usage: xlow ylow width height B\n"
+                      "     /height exch def /width exch def moveto width 0 rlineto\n"
+                      "     0 height rlineto width neg 0 rlineto closepath fill} bdef \n");
+      }
+         fprintf(outfile,"%s",
+                      "/BL { %layout a box, usage: xlow ylow width height BL\n"
+                      "     /height exch def /width exch def moveto width 0 rlineto\n"
+                      "     0 height rlineto width neg 0 rlineto closepath} bdef \n");
+         fprintf(outfile,"%s","/G {gsave} bdef /R {grestore} bdef\n");
+/*          fprintf(outfile,"%s", */
+/*                       "/C { %Clip a box, usage: xlow ylow width height C\n" */
+/*                       "  clippath BL  clip newpath} bdef \n"); */
+         fprintf(outfile,"%s", 
+                      "/C0 { %Reset clip path\n"  
+                      "     clipOn {grestore /clipOn {false} def} if} def\n"
+                      "/C1 { %Reset clipping to a box. Usage: xlow ylow width height C\n" 
+                      "      clipOn {grestore} if gsave /clipOn {true} def\n"
+		      "      BL eoclip newpath } bdef\n" 
+                      "/C2 {%Add clip inside a box to current clipping.  Usage: xlow ylow width height C \n"
+                      "      clipOn not {gsave /clipOn {true} def} if\n"
+                      "     clippath BL eoclip newpath } bdef\n");
+
+
+      fprintf(outfile,"\n%%Define line widths\n");
+      for (i=0;i<12;i++) fprintf(outfile,"/w%i {%s} bdef\n",i,widths[i]);
+
+      fprintf(outfile,"\n%%Define dashes\n");
+      fprintf(outfile,"/s0 {[] 0 setdash} bdef\n");
+      fprintf(outfile,"/s1 {[] 0 setdash} bdef\n");
+      fprintf(outfile,"/s2 {[125 60] 0 setdash} bdef\n");
+      fprintf(outfile,"/s3 {[60 60] 0 setdash} bdef\n");
+      fprintf(outfile,"/s4 {[125 60 60 60] 0 setdash} bdef\n");
+      fprintf(outfile,"/s5 {[10 40] 0 setdash} bdef\n");
+      fprintf(outfile,"/s6 {[75 60] 0 setdash} bdef\n");
+      fprintf(outfile,"/s7 {[125 40 15 15 15 40] 0 setdash} bdef\n");
+      fprintf(outfile,"/s8 {[15 80] 0 setdash} bdef\n");
+      
+
+      fprintf(outfile,"\n%%Define colors:\n");
+      if (o->reverse) {                       /* switch black and white colors */
+          fprintf(outfile,"/c0 {%s g} bdef %%black and white reversed\n",gr[1]);
+          fprintf(outfile,"/c1 {%s g} bdef\n",gr[0]);
+      } else {
+          for (i=0;i<2;i++) fprintf(outfile,"/c%i {%s g} bdef\n",i,gr[i]);
+      }
+      for (i=2;i<16;i++) fprintf(outfile,"/c%i {%s c} bdef\n",i,col[i]);
+
+      fprintf(outfile,"\n%%Define grays:\n");
+      if (o->reverse) {                       /* switch black and white */
+          fprintf(outfile,"/g0 {%s g} bdef %%black and white reversed\n",gr[1]);
+          fprintf(outfile,"/g1 {%s g} bdef\n",gr[0]);
+      } else {
+          for (i=0;i<2;i++) fprintf(outfile,"/g%i {%s g} bdef\n",i,gr[i]);
+      }
+      for (i=2;i<16;i++) fprintf(outfile,"/g%i {%s g} bdef\n",i,gr[i]);
+      fprintf(outfile,"\nblackwhite\n");
+      fprintf(outfile,"{ %%Black&white output: re-define line colors black, fill colors gray... \n  ");
+      for (i=1;i<16;i++) fprintf(outfile,"/c%i {g1} def%s",i,(((i+1)%5)==0) ? "\n  " : " ");
+      fprintf(outfile,"}\n{ %%Color output: undefine fill-colors... \n  ");
+      for (i=0;i<16;i++) fprintf(outfile,"/g%i {c%i} def%s",i,i,(((i+1)%5)==0) ? "\n  " : " ");
+      fprintf(outfile,"\n} ifelse\n");
+      
+
+      fprintf(outfile,"%%%%EndProlog\n\n%%%%BeginSetup\n");
+      fprintf(outfile,"1 setlinecap 1 setlinejoin\n%%%%EndSetup\n");
+#ifndef GXHEPS
+      fgetpos(outfile,&pagepos);
+#endif
+      fprintf(outfile,"%%%%Page: 1 1\n");
+      return;
+}
+/* --------------------------------------------------------------------------------- */
+
+void init_newpage(short landscape,char *fout,struct options *o){
+      int i;
+      char buf[130];
+      time_t thetime=time(NULL);
+      struct tm *ltime=localtime(&thetime);
+#ifndef GXHEPS
+      if (o->reverse) {
+        fgetpos(outfile, &blackpos);
+        fprintf(outfile,"                              %% black background\n");
+      }
+#endif
+      if(o->tstamp||o->label) fprintf(outfile,"gsave\n");
+      if(o->pscale==1) { /* A4 paper */
+        if (o->rotate) {
+	  fprintf(outfile,"21 cm 0 translate 90 rotate\n"); /* landscape mode */
+          fprintf(outfile,"%i %i translate %%move origin slightly in\n",A4YOFF, A4XOFF);
+	} else {
+          fprintf(outfile,"%i %i translate %%move origin slightly in\n",A4XOFF, A4YOFF);
+	}
+	fprintf(outfile,"%f %f scale  %% Units: 1000 = 2 cm\n",A4SCALE, A4SCALE);
+      } else if (o->pscale==0){ /* Letter paper */
+        if (o->rotate) {
+	  fprintf(outfile,"8.5 in 0 translate 90 rotate %% landscape\n");
+          fprintf(outfile,"%i %i translate %%move origin slightly in\n",LETYOFF,LETXOFF);
+	} else {
+          fprintf(outfile,"%i %i translate %%move origin slightly in\n",LETXOFF,LETYOFF);
+	}
+	fprintf(outfile,"%f %f scale  %%Units: 1000 = .9125 inch\n",LETSCALE, LETSCALE);
+      } else if (o->pscale==2){ /* GrADS 8.5''x 11' scaling */
+        if (o->rotate) 
+	  fprintf(outfile,"8.5 in 0 translate 90 rotate %% landscape\n");
+	fprintf(outfile,"%f %f scale  %%Units: 1000 = .9125 inch\n",GASCALE, GASCALE);
+      }
+      if(landscape)
+	fprintf(outfile,"0 0 %d %d BL clip newpath %% Initial clipping.\n",
+			    11000/RSCALE, 8500/RSCALE);
+      else
+	fprintf(outfile,"0 0 %d %d BL clip newpath %% Initial clipping.\n",
+			    8500/RSCALE, 11000/RSCALE);
+	
+      fprintf(outfile,"c1\n");
+      if(o->tstamp||o->label) {
+	fprintf(outfile,"matrix currentmatrix %% store CTM\n");
+        fprintf(outfile,"grestore\nc1 /Helvetica findfont 8 scalefont setfont\n");
+	if(o->pscale) fprintf(outfile,"1 cm 28.5 cm translate 0 0 moveto\n");
+	else     fprintf(outfile,"0.3 in 0.5 in translate 0 0 moveto\n");
+	if(o->tstamp) {
+          strftime(buf,130,"%c",ltime);
+	  fprintf(outfile,"(%s,  %s) show %%file and time stamp\n", fout,buf);
+	}
+        if(o->label) {			/* get user label */
+          fprintf(outfile,"\n\n%%BeginUserLabel\n");
+          printf("   %s%s","Label to print on the plot=?"," (Period (.) on a single line to finish)\n");
+          while(1) {
+            fgets(buf,130,stdin);
+            if(buf[0]=='.' && buf[1]=='\n') break;
+            fprintf(outfile,"0 -7 translate 0 0 moveto (");
+	    for (i=0;i<strlen(buf)-1;i++){
+	      if(buf[i]=='(' || buf[i]==')'|| buf[i]=='\\') fprintf(outfile,"%c",'\\'); 
+              fprintf(outfile,"%c",buf[i]);
+            }
+	    fprintf(outfile,") show\n");
+          }
+          fprintf(outfile,"%%EndUserLabel\n");
+        }
+        fprintf(outfile,"setmatrix %% restore CTM\n");
+      }
+      return;
+}
+/* --------------------------------------------------------------------------------- */
+
+void drawline(struct point pnts[],short *pcnt,
+	      short lcolor,short *colold,short *lastfill,short flush){
+   register int i,im,j,colum;
+   static short LastLine=0;
+   static short firstcall=1;
+   static struct point *dline;
+   long dx,dy,dx1,dy1;
+
+   /* flush=1; mm debugging */
+
+   if(firstcall) {
+      dline=(struct point *) malloc(4*sizeof(struct point)); 
+      firstcall=0;
+   }
+   if(*pcnt==1) {
+      if (LastLine==2){ /* there is a saved dashed line */
+	     if ((LastLine=CheckExpandDashLine(pnts,dline))==2) {
+	        dline[1].x=pnts[1].x; dline[1].y=pnts[1].y;
+	     } else { /*  Dashed Line  not expandable => print dashed line */
+	        PrintDashLine(dline);
+		LastLine=SaveLine(pnts,dline);
+	     }
+      } else if (LastLine==1) { /* there is a saved non-dashed line */
+            if((LastLine=CheckDashLine(pnts,dline))==2) {                 
+	        SetDline(pnts,dline);
+            } else { /* Not New LastLine */
+	        PrintDashLine(dline);
+		LastLine=SaveLine(pnts,dline);
+	    }
+      } else { /* no last line saved */
+         if (lcolor != (*colold) || (*lastfill) ) {
+             fprintf(outfile,"c%i ",lcolor);
+             *lastfill=0;
+             *colold=lcolor;
+         }
+	    LastLine=SaveLine(pnts,dline);
+      }
+      if(flush){ 
+   if ( lcolor != (*colold) || (*lastfill) )  {
+     fprintf(outfile,"c%i ",lcolor);
+     *lastfill=0;
+     *colold=lcolor;
+   }
+	 PrintDashLine(dline);
+	 LastLine=0;
+      }
+   } else { 
+        if(LastLine) PrintDashLine(dline);
+	if(*pcnt>1){
+           if ( lcolor != (*colold) || (*lastfill) ) {
+                fprintf(outfile,"c%i ",lcolor);
+                *lastfill=0;
+                *colold=lcolor;
+           }
+	   dx=(long)(pnts[*pcnt].x- pnts[(*pcnt)-1].x);
+	   dy=(long)(pnts[*pcnt].y- pnts[(*pcnt)-1].y);
+	   j=0;
+	   colum=1;
+           for(i=(*pcnt)-1;i>0;i--) {
+              im=i-1;
+	      dx1=(long)(pnts[i].x-pnts[im].x);
+	      dy1=(long)(pnts[i].y-pnts[im].y);
+	      if (((dx==0&&dy==0) || (dx*dy1==dx1*dy)) && !((dx==0&&dx1!=0) || (dy==0&&dy1!=0)) ) {
+		 dx+=dx1;
+		 dy+=dy1;
+		 (*pcnt)--;
+	      } else {
+		             /* if old and new line directions disagree */
+		 colum+=fprintf(outfile,"%ld %ld",dx,dy);
+                 if (colum>=70) {
+		     fprintf(outfile,"%c",'\n');
+		     colum=1;
+		 } else 
+		     colum+=fprintf(outfile,"%c",' ');
+		 dx=dx1;
+		 dy=dy1;
+	      }
+           }
+	   fprintf(outfile,"%ld %ld",dx,dy);
+                 if (colum>=60) {
+		     fprintf(outfile,"%c",'\n');
+		     colum=1;
+		 } else 
+		     colum+=fprintf(outfile,"%c",' ');
+           colum+=fprintf(outfile,"%i %i ",pnts[0].x,pnts[0].y);
+	   if(flush==-1) fprintf(outfile,"%i P\n",*pcnt);
+	   else
+	     if(*pcnt==1) fprintf(outfile,"L\n");
+	     else fprintf(outfile,"%i S\n",*pcnt);
+	}
+	LastLine=0;
+   } 
+   *pcnt=0;
+}
+/* --------------------------------------------------------------------------------- */
+int SaveLine(struct point pnts[],struct point dline[]){
+  dline[0].x=pnts[0].x;
+  dline[0].y=pnts[0].y;
+  dline[1].x=pnts[1].x;
+  dline[1].y=pnts[1].y;
+  dline[2].x=pnts[0].x;
+  dline[2].y=pnts[0].y;
+  dline[3].x=pnts[0].x;
+  dline[3].y=pnts[0].y;
+  return 1;
+}
+/* --------------------------------------------------------------------------------- */
+void PrintDashLine(struct point dline[]){
+  short SolidLine,dxsolid,dysolid,dxskip,dyskip;
+  dxsolid=dline[2].x-dline[0].x;
+  dysolid=dline[2].y-dline[0].y;
+  dxskip=dline[3].x-dline[2].x;
+  dyskip=dline[3].y-dline[2].y;
+  SolidLine= ((dxsolid==0)&&(dysolid==0)&&(dxskip==0)&&(dyskip==0));
+  if(!SolidLine) fprintf(outfile,"[%i %i] ",
+	      (short) (sqrt((float) dxsolid*dxsolid+(float) dysolid*dysolid)+0.5),
+	      (short) (sqrt((float) dxskip*dxskip+(float) dyskip*dyskip)+0.5));
+  fprintf(outfile,"%i %i %i %i %c\n",dline[1].x-dline[0].x,dline[1].y-dline[0].y,
+	  dline[0].x,dline[0].y,SolidLine ? 'L' : 'D');
+  return;
+}
+/* --------------------------------------------------------------------------------- */
+short CheckDashLine(struct point pnts[],struct point dline[]){
+  short dx,dy;
+  dx=pnts[1].x-pnts[0].x;
+  if (dx!=dline[1].x-dline[0].x) return 1; /* delta x disagree */
+  dy=pnts[1].y-pnts[0].y;
+  if (dy!=dline[1].y-dline[0].y) return 1; /* delta y disagree */
+  if((int) dx *(pnts[0].y-dline[1].y) !=(int) (pnts[0].x-dline[1].x)*dy)
+      return 1;  /* line directions disagree */
+  else return 2;
+}
+/* --------------------------------------------------------------------------------- */
+short CheckExpandDashLine(struct point pnts[],struct point dline[]){
+  if( (dline[3].x-dline[2].x!=pnts[0].x-dline[1].x) ||
+      (dline[3].y-dline[2].y!=pnts[0].y-dline[1].y) ||
+      (dline[2].x-dline[0].x!=pnts[1].x-pnts[0].x)  ||
+      (dline[2].y-dline[0].y!=pnts[1].y-pnts[0].y)    )return 1;
+  else return 2;
+}
+/* --------------------------------------------------------------------------------- */
+void SetDline(struct point pnts[],struct point dline[]){
+  dline[2].x=dline[1].x;
+  dline[2].y=dline[1].y;
+  dline[3].x=pnts[0].x;
+  dline[3].y=pnts[0].y;
+  dline[1].x=pnts[1].x;
+  dline[1].y=pnts[1].y;
+  return;
+  }
+/* --------------------------------------------------------------------------------- */
+void fillline(struct point pnts[],short pcnt){
+   register int i,im;
+   /* check if the polygon is a rectangel: */
+   if(pcnt==4 &&  pnts[0].x==pnts[1].x && pnts[2].x==pnts[3].x &&
+	     pnts[1].y==pnts[2].y && pnts[0].y==pnts[3].y) {
+      fprintf(outfile,"%i %i %i %i B\n",
+	      pnts[0].x,pnts[0].y,pnts[2].x-pnts[0].x,pnts[2].y-pnts[0].y);
+   } else if(pcnt==4 && pnts[0].y==pnts[1].y && pnts[2].y==pnts[3].y &&
+	     pnts[1].x==pnts[2].x && pnts[0].x==pnts[3].x) {
+      fprintf(outfile,"%i %i %i %i B\n",
+	      pnts[0].x,pnts[0].y,pnts[2].x-pnts[0].x,pnts[2].y-pnts[0].y);
+   } else {
+     long dx,dy,dx1,dy1;
+     int j,colum;
+	   dx=(long)(pnts[pcnt].x- pnts[(pcnt)-1].x);
+	   dy=(long)(pnts[pcnt].y- pnts[(pcnt)-1].y);
+	   j=0;
+	   colum=1;
+           for(i=(pcnt)-1;i>0;i--){
+              im=i-1;
+	      dx1=(long)(pnts[i].x-pnts[im].x);
+	      dy1=(long)(pnts[i].y-pnts[im].y);
+	      if (((dx1==0&&dy1==0) ||
+		   (dx*dy1==dx1*dy)) && !((dx==0&&dx1!=0)||(dy==0&&dy1!=0)) ) {
+		 dx+=dx1;
+		 dy+=dy1;
+		 (pcnt)--;
+	      } else {      /* if old and new line directions disagree */
+		 colum+=fprintf(outfile,"%ld %ld",dx,dy);
+                 /* (j++%10==9) ? fprintf(outfile,"%c",'\n') : fprintf(outfile,"%c",' '); */
+                 if (colum>=70) {
+		     fprintf(outfile,"%c",'\n');
+		     colum=1;
+		 } else 
+		     colum+=fprintf(outfile,"%c",' ');
+		 dx=dx1;
+		 dy=dy1;
+	      }
+           }
+	   if(colum>=60)
+	       fprintf(outfile,"%ld %ld\n%i %i %i F\n",dx,dy,pnts[0].x,pnts[0].y,pcnt);
+	   else
+               fprintf(outfile,"%ld %ld %i %i %i F\n",dx,dy,pnts[0].x,pnts[0].y,pcnt);
+   }
+}
+/* --------------------------------------------------------------------------------- */
+
+void boundbox(struct point* pnts){  /* compute bounding box */
+  /*  Does not work because of clipping to the outside 
+   *  For now, let's not take clipping into account
+   *  *** TO BE FIXED ***
+  if((cliplow.x<bblow.x) && (pnts->x<bblow.x)) bblow.x=max(pnts->x,cliplow.x);
+  if((cliplow.y<bblow.y) && (pnts->y<bblow.y)) bblow.y=max(pnts->y,cliplow.y);
+  if((cliphigh.x>bbhigh.x) && (pnts->x>bbhigh.x)) bbhigh.x=min(pnts->x,cliphigh.x);
+  if((cliphigh.y>bbhigh.y) && (pnts->y>bbhigh.y)) bbhigh.y=min(pnts->y,cliphigh.y);
+  */
+     if(pnts->x<bblow.x) bblow.x=pnts->x;
+     if(pnts->y<bblow.y) bblow.y=pnts->y;
+    if(pnts->x>bbhigh.x) bbhigh.x=pnts->x;
+     if(pnts->y>bbhigh.y) bbhigh.y=pnts->y;
+     return;
+}
+/* --------------------------------------------------------------------------------- */
+void printbbox(short pscale,short landscape,struct options *o){
+#ifndef GXHEPS
+     fsetpos(outfile, &bboxpos);
+#endif
+     if(pscale) {
+        bblow.x= ( (float) bblow.x) *A4SCALE;
+        bbhigh.x= ((float) bbhigh.x)*A4SCALE;
+        bblow.y= ((float) bblow.y)*A4SCALE;
+        bbhigh.y= ((float) bbhigh.y)*A4SCALE;
+        if(o->rotate==0) {
+          fprintf(outfile,"%i %i %i %i",
+               bblow.x+A4XOFF-BORDER,bblow.y+A4YOFF-BORDER,bbhigh.x+A4XOFF+BORDER,
+		  bbhigh.y+A4YOFF+BORDER);
+#ifndef GXHEPS
+	  if(o->reverse) {
+            fsetpos(outfile, &blackpos);
+            fprintf(outfile,"0 g %i %i %i %i B 1 g ",
+               bblow.x+A4XOFF-BORDER,bblow.y+A4YOFF-BORDER,bbhigh.x-bblow.x+2*BORDER,
+		    bbhigh.y-bblow.y+2*BORDER);
+	  }
+#endif
+        } else {
+           fprintf(outfile,"%i %i %i %i",
+              595-bbhigh.y-A4XOFF-BORDER,bblow.x+A4YOFF-BORDER,612-bblow.y-A4XOFF+BORDER,
+		   bbhigh.x+A4YOFF+BORDER);
+#ifndef GXHEPS
+	  if(o->reverse) {
+            fsetpos(outfile, &blackpos);
+            fprintf(outfile,"0 g %i %i %i %i B 1 g ",
+		  595-bbhigh.y-A4XOFF-BORDER,bblow.x+A4YOFF-BORDER,bbhigh.y-bblow.y+2*BORDER,
+		    bbhigh.x-bblow.x+2*BORDER); 
+	  }
+#endif
+	}
+     } else {
+        bblow.x= ((float) bblow.x)*LETSCALE;
+        bbhigh.x= ((float) bbhigh.x)*LETSCALE;
+        bblow.y= ((float) bblow.y)*LETSCALE;
+        bbhigh.y= ((float) bbhigh.y)*LETSCALE;
+        if(o->rotate==0){
+           fprintf(outfile,"%i %i %i %i",
+               bblow.x+LETXOFF-BORDER,bblow.y+LETYOFF-BORDER,bbhigh.x+LETXOFF+BORDER,
+		   bbhigh.y+LETYOFF+BORDER);
+#ifndef GXHEPS
+	  if(o->reverse) {
+            fsetpos(outfile, &blackpos);
+            fprintf(outfile,"0 g %i %i %i %i B 1 g ",
+               bblow.x+LETXOFF-BORDER,bblow.y+LETYOFF-BORDER,bbhigh.x-bblow.x+2*BORDER,
+		    bbhigh.y-bblow.y+2*BORDER);
+	  }
+#endif
+	} else {
+           fprintf(outfile,"%i %i %i %i",
+              612-bbhigh.y-LETXOFF-BORDER,bblow.x+LETYOFF-BORDER,612-bblow.y-LETXOFF+BORDER,
+		   bbhigh.x+LETYOFF+BORDER);
+#ifndef GXHEPS
+	  if(o->reverse) {
+            fsetpos(outfile, &blackpos);
+            fprintf(outfile,"0 g %i %i %i %i B 1 g ",
+		      612-bbhigh.y-LETXOFF-BORDER,bblow.x+LETYOFF-BORDER,
+		    bbhigh.y-bblow.y+2*BORDER,bbhigh.x-bblow.x+2*BORDER); 
+	  }
+#endif
+	}
+     }
+#ifndef GXEPS       
+     fseek(outfile,0L,2); 
+#endif
+}
+/* --------------------------------------------------------------------------------- */
+
+
+int parse_arg(int argc,char *argv[],struct options *o,char **fin, char **fout){
+     register int i,j;
+     i = 1;
+#ifndef GXHEPS
+     if(argc==1) return(print_options(argv));
+#endif
+
+     for (i=1;i<argc;i++) {
+
+     if (*(argv[i])=='-') {  /* parse options */
+       j = 0;
+       while (*(argv[i]+(++j))) {
+         if      (*(argv[i]+j)=='a') o->pscale = 1;
+         else if (*(argv[i]+j)=='1') o->pslevel = 1;
+         else if (*(argv[i]+j)=='2') o->pslevel = 2;
+	 else if (*(argv[i]+j)=='b') o->color = 0;
+         else if (*(argv[i]+j)=='c') o->color = 1;
+#ifdef NEVER_CTL_D
+         else if (*(argv[i]+j)=='d') ;
+#else
+         else if (*(argv[i]+j)=='d') o->ctl_d = !o->ctl_d;
+#endif
+#ifdef PSFONTS
+         else if (*(argv[i]+j)=='f') o->font =0;
+#endif
+         else if (*(argv[i]+j)=='g') o->pscale = 2;
+	 else if (*(argv[i]+j)=='G') o->graylines = 1;
+	 else if (*(argv[i]+j)=='h') return (print_options(argv));
+	 else if (*(argv[i]+j)=='H') o->history = 0;
+         else if (*(argv[i]+j)=='i') {*fin = argv[++i];break;}
+         else if (*(argv[i]+j)=='l') o->pscale = 0;
+         else if (*(argv[i]+j)=='L') o->label = 1;
+         else if (*(argv[i]+j)=='n') o->comment = 1;
+         else if (*(argv[i]+j)=='o') {*fout = argv[++i];break;}
+         else if (*(argv[i]+j)=='r') o->reverse = 1;
+         else if (*(argv[i]+j)=='R') o->rotate = 0;
+         else if (*(argv[i]+j)=='s') o->tstamp = 1;
+         else if (*(argv[i]+j)=='v') o->verbose = 1;
+         else { 
+	   fprintf(stderr,"Unknown option: %s\n\n",argv[i]);
+	   print_options(argv);
+	     return(1);
+	 }
+       }
+     }
+    else  /* No command line "-" */
+#ifdef GXHEPS
+	 *fout = argv[i];
+#else
+      *fin=argv[i];
+#endif
+  }
+#ifdef GXHEPS
+     if(*fout==NULL)
+       *fout="grads.eps";
+#endif     
+     return(0);
+}
+/* --------------------------------------------------------------------------------- */
+
+int print_options(char *argv[]){
+#ifndef GXHEPS	       
+	       /* printf("   This is gxeps $Revision: 1.13 $\n"); */
+	       printf("   This is gxeps Version: GRADS_VERSION\n");
+#endif
+#ifdef NEVER_CTL_D
+       fprintf(stderr,"   %s%s%s","Usage: ",argv[0],
+#ifndef GXHEPS	       
+	   " [-abcfghiLlnRrsv -i <in_file>[."  IN_EXT
+#else
+	   " [-abcfghiLlnRrsv"
+#endif 
+           "] -o <out_file>] [<in_file>[."IN_EXT"]].\n");
+#else
+       fprintf(stderr,"%s%s%s","Usage: ",argv[0],
+	   " [-acdifhLlnRrsv -i <in_file>[."  IN_EXT
+           "] -o <out_file>] [<in_file>[."IN_EXT"]].\n");
+#endif
+       fprintf(stderr,"Options:\n");
+       fprintf(stderr,"     -1   PostScript Level 1 output.\n");
+       fprintf(stderr,"     -2   PostScript Level 2 output  (default).\n");
+       fprintf(stderr,"     -a   A4 paper.\n");
+       fprintf(stderr,"     -b   Black & white output.\n");
+       fprintf(stderr,"     -c   Color output (default).\n");
+#ifndef NEVER_CTL_D
+       if(DEFAULT_CTL_D)  fprintf(stderr,"     -d   Do not add Control-D at end.\n");
+       else fprintf(stderr,"     -d   Add Control-D at end.\n");
+#endif
+#ifdef PSFONTS
+       fprintf(stderr,"     -f   Do not use PostScript fonts.\n");
+#endif
+       fprintf(stderr,"     -g   True 8.5'' x 11'' output (GrADS scaling).\n");
+       fprintf(stderr,"     -G   Use gray lines in black & white mode (default: all black).\n");
+#ifdef GXHEPS
+       fprintf(stderr,"     -H   Do not include GrADS command history in output.\n");
+#endif
+       fprintf(stderr,"     -h   Help.\n");
+#ifndef GXHEPS	       
+       fprintf(stderr,"     -i   <in_file>[."IN_EXT"], '-' = stdin.\n");
+#endif
+       fprintf(stderr,"     -l   letter paper\n");
+       fprintf(stderr,"     -L   Ask for a label to be printed on the plot.\n");
+       fprintf(stderr,"     -n   Ask for a note to include in postscript file header.\n");
+       fprintf(stderr,"     -o   <out_file> (default: basename(in_file)."OUT_EXT", '-' = stdout).\n");
+#ifndef GXHEPS	       
+       fprintf(stderr,"     -R   Do not rotate landscape metafiles.\n");
+#endif
+       fprintf(stderr,"     -r   Black background.\n");
+       fprintf(stderr,"     -s   Add a file & time stamp.\n");
+       fprintf(stderr,"     -v   Verbose.\n\n");
+       fprintf(stderr,"For more information visit http://www.bol.ucla.edu/~munnich/grads/gxeps.html.\n");
+     return(8);
+     }
+/* --------------------------------------------------------------------------------- */
+
+int openfiles(char **fin, char **fout,short verbose){ /* Open files */
+
+#ifndef GXHEPS
+  int i;
+  if (*fin==NULL) {
+    *fin = (char *) malloc(sizeof(char)*150);
+     fgets(*fin,150,stdin);
+     printf("   Read infile = %s\n",*fin);
+  }
+  if(strcmp(*fin,"-")==0) infile=stdin;
+  else infile = fopen(*fin ,"rb");
+  if (infile == NULL) {
+    *fin=strcat(*fin,"."IN_EXT);
+    infile = fopen(*fin,"rb");
+    if (infile == NULL) {
+      (*fin)[strlen(*fin)-3]='\0';
+      printf ("Input file %s[."IN_EXT"] not found.\n",*fin);
+      return(1);
+    }
+  }
+  /* setvbuf(infile,NULL,_IOFBF,(size_t) 524288L); */
+  if (*fout==NULL) {
+    *fout = (char *) malloc(sizeof(char)*150);
+    strcpy(*fout,*fin);
+    for (i=strlen(*fout)-1;i>=0;i--) {
+      if((*fout)[i]=='.') {strcpy((*fout)+i+1,OUT_EXT);
+	break;
+      }
+      if(i==0){strcpy((*fout)+strlen(*fout),"."OUT_EXT);}
+    }
+  }
+#endif
+  if(strcmp(*fout,"-")==0) outfile=stdout;
+  else outfile = fopen(*fout,"w");
+  if (outfile==NULL) {
+    printf ("Error opening output file %s \n",*fout);
+    return(1);
+  }
+  if(verbose) {
+    printf("\n   Gxeps $Revision: 1.13 $\n");
+#ifndef GXHEPS
+    printf("     Input file  = %s\n",*fin);
+#endif
+    if(strcmp(*fout,"-")==0) printf("output to stdout\n");
+    else printf("     Output file = %s\n",*fout);
+  }
+  /* setvbuf(outfile,NULL,_IOFBF,(size_t) 524288L); */
+  return(0);
+}
+/* --------------------------------------------------------------------------------- */
+void setjust(short *opts, short *justx, short *justy)
+{	/* 
+	 * Set justification
+	 * for just>9 an addition border of size height is
+	 * added. This is mainly used for axis labels who initial
+	 * position touched the axis.
+	 */
+	short just,wid;
+	struct point pnt;
+
+	just=opts[7];
+	/*  Remember:
+	 *  xpos=opts[1];
+	 *  ypos=opts[2];
+	 *  height=opts[3].
+	 */
+	if(just==2) {
+		*justx=50;
+		*justy=0;
+	} else if (just==3) {
+		*justx=100;
+		*justy=0;
+	} else if (just==4) {
+		*justx=0;
+		*justy=50;
+	} else if (just==5) {
+		*justx=50;
+		*justy=50;
+	} else if (just==6) {
+		if(opts[5]/64==90) {
+			*justx=50;
+			*justy=100;
+		} else {
+			*justx=100;
+			*justy=50;
+		}
+	} else if (just==7) {
+		*justx=0;
+		*justy=100;
+	} else if (just==8) {
+		*justx=50;
+		*justy=100;
+	} else if (just==9) {
+		*justx=100;
+		*justy=100;
+	} else if (just==11) { /* title, x-axis label top */
+		*justx=50;
+		*justy=100;
+		opts[2]+=opts[3];
+	} else if (just==12) { /* y-axis label left */
+		*justx=100;
+		*justy=50;
+		opts[1]-=opts[3];
+		opts[2]-=opts[3]/2;
+	} else if (just==13) { /* yaxis label right */
+		*justx=0;
+		*justy=50;
+		opts[1]+=opts[3]; 
+		opts[2]-=opts[3]/2;
+	} else if (just==14) { /* title or x-axis label */
+		*justx=50;
+		*justy=100;
+		opts[2]-=2*opts[3];
+	}
+	/* Guess new bounding box
+	 * 
+	 * We dont know the exact string width 
+	 * and guess it to be height * strlen * 3/4
+	 */
+
+	wid=opts[3]*opts[0]*3/4; 
+	/* lower left */
+	pnt.x=opts[1]-wid * *justx/100;
+	pnt.y=opts[2]-opts[3]**justy/100;
+	boundbox(&pnt);
+	/* lower right */
+	pnt.x=opts[1]+wid*(100 - *justx)/100;
+	boundbox(&pnt);
+	/* upper right */
+	pnt.y=opts[2]+opts[3]*(100 - *justy)/100;
+	boundbox(&pnt);
+	/* upper left */
+	pnt.x=opts[1]-wid * *justx/100;
+	boundbox(&pnt);
+  return;
+}
+/* --------------------------------------------------------------------------------- */
+/*
+/Helvetica findfont
+dup length dict begin
+  { 1 index /FID ne
+      {def}
+      {pop pop}
+    ifelse
+  }
+/Encoding ISOLatin1Encoding def
+  currentdict
+end
+/Helvetica-ISOLatin1 exch definefont pop
+
+/iso_reencode { 
+  dup findfont
+  dup length dict begin
+  { 1 index /FID ne
+      {def}
+      {pop pop}
+      ifelse
+  } forall
+  /Encoding ISOLatin1Encoding def
+  currentdict end
+  exch definefont pop 
+} def
+ */
+/* --------------------------------------------------------------------------------- */
diff --git a/src/gxgif.c b/src/gxgif.c
new file mode 100644
index 0000000..cec4ceb
--- /dev/null
+++ b/src/gxgif.c
@@ -0,0 +1,2683 @@
+/***********************************************************
+ *
+ * GXGIF: a grads metafile to GIF converter.
+ * Written by Matthias Muennich 
+ *
+ *   $Log: gxgif.c,v $
+ *   Revision 1.5  2009/04/30 15:25:31  jma
+ *   changed max number of colors from 99 to 255
+ *
+ *   Revision 1.4  2009/01/05 12:48:24  jma
+ *   changed
+ *   #include <config.h>
+ *   to
+ *   #include "config.h"
+ *
+ *   Revision 1.3  2003/06/24 21:31:08  joew
+ *   put conditionals around #include malloc.h, for Mac OS X
+ *
+ *   Revision 1.2  2002/10/28 19:08:33  joew
+ *   Preliminary change for 'autonconfiscation' of GrADS: added a conditional
+ *   #include "config.h" to each C file. The GNU configure script generates a unique config.h for each platform in place of -D arguments to the compiler.
+ *   The include is only done when GNU configure is used.
+ *
+ *   Revision 1.1.1.1  2002/06/27 19:44:05  cvsadmin
+ *   initial GrADS CVS import - release 1.8sl10
+ *
+ *   Revision 1.1.1.1  2001/10/18 02:00:54  Administrator
+ *   Initial repository: v1.8SL8 plus slight MSDOS mods
+ *
+ *   Revision 0.4  1997/12/19 10:43:56  m211033
+ *   Added a version statement in verbose mode.
+ *
+ *   Revision 0.3  1997/12/04 10:08:26  m211033
+ *   Copied the subroutines used from gd1.2 into gxgif.c
+ *   to make the code independent of the gd library.
+ *   Added an option "-h" for horizontal filling of polygons
+ *   (=> horizontal spurious lines).
+ *   Fixed the output file names for more that 1 image.
+ *   Fixed the "-r" option.
+ *
+ *   Revision 0.2  1997/02/25 13:30:35  m211033
+ *   Added support for different line thicknesses and
+ *   cleaned up the code.
+ *
+ *   Revision 0.1  1997/02/21 15:20:51  m211033
+ *   different line width are not yet supported.
+ *   The gdImageFilledPolygon routine gives wrong height
+ *   when filling horizontally. This led to flaud horizontal
+ *   lines in the GIF file. I rewrote it switching x and y
+ *   coordinates. The lines disappeared. Now vertical lines
+ *   may show up. For a fix we have to wait for a better
+ *   version on gdImageFilledPolygon.
+ *   No black and white mode is available right now.
+ *
+ *
+ *
+ ***********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+/*  #include "gd.h" */
+static char rcsid[] = "$Id: gxgif.c,v 1.5 2009/04/30 15:25:31 jma Exp $";
+
+/* ---------------------------- begin gd.h -------------------------------------- */
+#ifndef GD_H
+#define GD_H 1
+
+/* gd.h: declarations file for the gifdraw module.
+
+	Written by Tom Boutell, 5/94.
+	Copyright 1994, Cold Spring Harbor Labs.
+	Permission granted to use this code in any fashion provided
+	that this notice is retained and any alterations are
+	labeled as such. It is requested, but not required, that
+	you share extensions to this module with us so that we
+	can incorporate them into new versions. */
+
+/* stdio is needed for file I/O. */
+#include <stdio.h>
+
+/* This can't be changed, it's part of the GIF specification. */
+
+#define gdMaxColors 256
+
+/* Image type. See functions below; you will not need to change
+	the elements directly. Use the provided macros to
+	access sx, sy, the color table, and colorsTotal for 
+	read-only purposes. */
+
+typedef struct gdImageStruct {
+	unsigned char ** pixels;
+	int sx;
+	int sy;
+	int colorsTotal;
+	int red[gdMaxColors];
+	int green[gdMaxColors];
+	int blue[gdMaxColors]; 
+	int open[gdMaxColors];
+	int transparent;
+	int *polyInts;
+	int polyAllocated;
+	struct gdImageStruct *brush;
+	struct gdImageStruct *tile;	
+	int brushColorMap[gdMaxColors];
+	int tileColorMap[gdMaxColors];
+	int styleLength;
+	int stylePos;
+	int *style;
+	int interlace;
+} gdImage;
+
+typedef gdImage * gdImagePtr;
+
+typedef struct {
+	/* # of characters in font */
+	int nchars;
+	/* First character is numbered... (usually 32 = space) */
+	int offset;
+	/* Character width and height */
+	int w;
+	int h;
+	/* Font data; array of characters, one row after another.
+		Easily included in code, also easily loaded from
+		data files. */
+	char *data;
+} gdFont;
+
+/* Text functions take these. */
+typedef gdFont *gdFontPtr;
+
+/* For backwards compatibility only. Use gdImageSetStyle()
+	for MUCH more flexible line drawing. Also see
+	gdImageSetBrush(). */
+#define gdDashSize 4
+
+/* Special colors. */
+
+#define gdStyled (-2)
+#define gdBrushed (-3)
+#define gdStyledBrushed (-4)
+#define gdTiled (-5)
+
+/* NOT the same as the transparent color index.
+	This is used in line styles only. */
+#define gdTransparent (-6)
+
+/* Functions to manipulate images. */
+
+gdImagePtr gdImageCreate(int sx, int sy);
+gdImagePtr gdImageCreateFromGif(FILE *fd);
+gdImagePtr gdImageCreateFromGd(FILE *in);
+gdImagePtr gdImageCreateFromXbm(FILE *fd);
+void gdImageDestroy(gdImagePtr im);
+void gdImageSetPixel(gdImagePtr im, int x, int y, int color);
+int gdImageGetPixel(gdImagePtr im, int x, int y);
+void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+/* For backwards compatibility only. Use gdImageSetStyle()
+	for much more flexible line drawing. */
+void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+/* Corners specified (not width and height). Upper left first, lower right
+ 	second. */
+void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+/* Solid bar. Upper left corner first, lower right corner second. */
+void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
+int gdImageBoundsSafe(gdImagePtr im, int x, int y);
+void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
+void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, char c, int color);
+void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, char *s, int color);
+void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, char *s, int color);
+
+/* Point type for use in polygon drawing. */
+
+typedef struct {
+	int x, y;
+} gdPoint, *gdPointPtr;
+
+void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c);
+void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c);
+
+int gdImageColorAllocate(gdImagePtr im, int r, int g, int b);
+int gdImageColorClosest(gdImagePtr im, int r, int g, int b);
+int gdImageColorExact(gdImagePtr im, int r, int g, int b);
+void gdImageColorDeallocate(gdImagePtr im, int color);
+void gdImageColorTransparent(gdImagePtr im, int color);
+void gdImageGif(gdImagePtr im, FILE *out);
+void gdImageGd(gdImagePtr im, FILE *out);
+void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color);
+void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color);
+void gdImageFill(gdImagePtr im, int x, int y, int color);
+void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h);
+/* Stretches or shrinks to fit, as needed */
+void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);
+void gdImageSetBrush(gdImagePtr im, gdImagePtr brush);
+void gdImageSetTile(gdImagePtr im, gdImagePtr tile);
+void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels);
+/* On or off (1 or 0) */
+void gdImageInterlace(gdImagePtr im, int interlaceArg);
+
+/* Macros to access information about images. READ ONLY. Changing
+	these values will NOT have the desired result. */
+#define gdImageSX(im) ((im)->sx)
+#define gdImageSY(im) ((im)->sy)
+#define gdImageColorsTotal(im) ((im)->colorsTotal)
+#define gdImageRed(im, c) ((im)->red[(c)])
+#define gdImageGreen(im, c) ((im)->green[(c)])
+#define gdImageBlue(im, c) ((im)->blue[(c)])
+#define gdImageGetTransparent(im) ((im)->transparent)
+#define gdImageGetInterlaced(im) ((im)->interlace)
+#endif
+
+/* ---------------------------- end gd.h -------------------------------------- */
+
+
+
+/* default file extensions */
+#define IN_EXT "gm"
+#define OUT_EXT "gif"
+
+/* default size of the graph */
+#define SX 550
+#define SY 425
+
+/* PNMAX: maximal points in polygons */
+#define PNMAX 4096
+#ifdef __GNUC__
+#define fpos_t long
+#endif 
+
+/* ---------------------------- global vars -------------------------------------- */
+
+struct options {int reverse, fillx, verbose, sx, sy;}; /* command line options (flags) */
+FILE *infile, *outfile;
+gdImagePtr im,w[12];
+int cidx[13][100];  /* color index table [0][*]: filling, [1-12][*] brush images */
+int r[100]={0, 255, 240,   0,  31,   0, 220, 230, 240, 161, 161,   0, 230,   0, 110, 125},
+    g[100]={0, 255,   0, 220,  61, 199,   0, 220, 130,   0, 230, 161, 176, 209,   0, 125},
+    b[100]={0, 255,   0,   0, 250, 199,  99,  51,  41, 199,  51, 230,  46, 140, 220, 125};
+
+/* ---------------------------- prototypes --------------------------------------- */
+
+void printOptions(char *argv[]); /* print command line options */
+void drawLine(gdPoint pnts[],short *pcnt,int wd,int color); /* draw a polygon */
+void parseArg(int argc,char *argv[],struct options *o,char **fin, char **fout); /* parse command line */
+void openFiles(char **fin, char **fout, short verbose); /* Open files */
+void defBGround(gdImagePtr im,short reverse); /* set background */
+
+/* changed gd-library routines */
+void gdImagePolygonUnclosed(gdImagePtr im, gdPointPtr p, int n, int c);
+void gdImageFilledPolygonx(gdImagePtr im, gdPointPtr p, int n, int c);
+extern int gdCompareInt(const void *a, const void *b);
+
+/* --------------------------------------------------------------------------------- */
+int main (int argc, char *argv[])  {
+   short cmd,opts[4], rotate=0;
+   int col=0, wd=0;
+   int sx=SX,sy=SY,sh,lly,ury;
+   short coldef[100];
+   float blowx,blowy;
+   gdPoint pnts[PNMAX];                    /* points of a polygon */
+   struct options o;                      /* command line options */
+   register int  i,j;
+   short pcnt,fcnt;
+   char *fin=NULL,*fout=NULL,*fout_new=NULL;              /* file names */
+   fpos_t infile_pos;
+   short width[12] = {                      /* width (units: .001 inch) */
+               2 ,7 ,10 ,14 ,17 ,20 ,
+	       24 ,27 ,31 ,34 ,38 ,41 };
+
+   o.reverse=o.verbose=o.fillx=o.sx=o.sy=0;
+   for(i=0;i<13;i++)
+     for(j=0;j<100;j++) cidx[i][j]=-1;
+   for(i=0;i<16;i++) coldef[i]=1;
+   for(i=16;i<100;i++) coldef[i]=0;
+
+  parseArg(argc,argv,&o,&fin,&fout);     /* Parse command line arguments */
+  openFiles(&fin,&fout,o.verbose);                  /* open files */
+
+  /* Translate metafile */
+
+  fcnt = 1;
+  while (1) {
+    fread (&cmd, sizeof(short), 1, infile);
+
+    if (cmd==-11){				/* Draw to */
+      fread (opts, sizeof(short), 2, infile);
+      pnts[++pcnt].x=opts[0]*blowx;
+      pnts[pcnt].y= sy-opts[1]*blowy;
+    }
+    else if (cmd==-10){				/* Move to */
+      if (pcnt) drawLine(pnts,&pcnt,wd,col);
+      fread ((char *) opts, sizeof(short), 2, infile);
+      pnts[pcnt].x=opts[0]*blowx;
+      pnts[pcnt].y= sy-opts[1]*blowy;
+    }
+    else if (cmd==-4) {				/* Set line width */
+      if (pcnt) drawLine(pnts,&pcnt,wd,col);
+      fread ((char *)opts, sizeof(short), 2, infile);
+      i = opts[0];
+      if (i>12) i=12;
+      else if (i<1) i=1;
+      wd=width[i-1]*blowx+1;
+    }
+    else if (cmd==-3) {				/* Set color */
+      if (pcnt) drawLine(pnts,&pcnt,wd,col);
+      fread ((char *)opts, sizeof(short), 1, infile);
+      col = opts[0];
+      if (col<0) col=0;
+      if (col>255) col=255; 
+      if (!(coldef[i])) col=15;
+      if(o.reverse){
+	  if(col==1) col=0;
+	  else if(col==0) col=1;
+      }
+    }
+    else if (cmd==-7){				/* Start fill */
+      fread ((char *)opts, sizeof(short), 1, infile);
+    }
+    else if (cmd==-8){				/* End fill */
+      if (pcnt>1)
+        if(cidx[0][col]<0){
+	  cidx[0][col]=gdImageColorAllocate(im, r[col],g[col],b[col]);
+	}
+        if(o.fillx) gdImageFilledPolygon(im, pnts, ++pcnt, cidx[0][col]);
+        else gdImageFilledPolygonx(im, pnts, ++pcnt, cidx[0][col]);
+        pcnt=0;
+    }
+    else if (cmd==-6){				/* Rectangle fill */
+      if (pcnt) drawLine(pnts,&pcnt,wd,col);
+      fread ((char *)opts, sizeof(short), 4, infile);
+      lly=sy-opts[2]*blowy;
+      ury=sy-opts[3]*blowy;
+        if(cidx[0][col]<0)
+	  cidx[0][col]=gdImageColorAllocate(im, r[col],g[col],b[col]);
+      gdImageFilledRectangle(im, (int) opts[0]*blowx,ury,
+			     (int) opts[1]*blowx,lly, cidx[0][col]);
+    }
+    else if (cmd==-9) {				/* End of plotting */
+      if(o.verbose) printf ("Number of pages = %i\n",fcnt);
+      /*       gdImageInterlace(im, 1); */
+      gdImageGif(im, outfile);
+      fclose(outfile);
+      gdImageDestroy(im);
+      return(0);
+    }
+    else if (cmd==-1) {				/* Start of plotting */
+      fread ((char *)opts, sizeof(short), 2, infile);
+      if(opts[0]<opts[1]) {sh=sx; sx=sy; sy=sh;}
+      if(o.sx) {
+          sx=o.sx;
+         if(o.sy==0) sy=sx *(opts[1]/100)/(opts[0]/100);
+      }
+      if(o.sy) {
+          sy=o.sy;
+          if(o.sx==0) sx=sy*(opts[0]/100)/(opts[1]/100);
+      }
+      blowx=(float)sx/(float)opts[0];  /* picture size in metafile: opts[0] x opts[1] */ 
+      blowy=(float)sy/(float)opts[1];
+      if(o.verbose) printf("Image size: %d x %d pixels\n",sx,sy);
+
+      for (i=0;i<=width[11]*blowx;i++)
+	  w[i] = gdImageCreate(i+1,i+1);
+      im = gdImageCreate(sx,sy);
+      defBGround(im,o.reverse);
+      col=1;
+      pcnt = 0;
+    }
+    else if (cmd==-2) {				/* New Page */
+      if (pcnt) drawLine(pnts,&pcnt,wd,col);
+      /* gdImageInterlace(im, 1); */
+      gdImageGif(im, outfile);
+      fclose(outfile);
+      gdImageDestroy(im);
+      for (i=0;i<=width[11]*blowx;i++)
+	  gdImageDestroy(w[i]);
+      fgetpos(infile,&infile_pos);
+      fread (&cmd , sizeof(short), 1, infile); 
+      fsetpos(infile,&infile_pos);
+      if (cmd != -9) {  /* if next command is not end_of_plotting */
+	  if(fout_new==NULL){
+             fout[strlen(fout)-4]='\0';
+             fout_new = (char *) malloc(sizeof(char)*150);
+	  }
+          strcpy(fout_new,fout);
+	  sprintf(fout_new+strlen(fout_new), "_%d",++fcnt);
+          strcpy((fout_new)+strlen(fout_new),"."OUT_EXT);
+          if(o.verbose) printf ("New GIF-file:%s\n",fout_new);
+          outfile = fopen(fout_new,"wb");
+#ifdef NOTDEF
+	  strcpy(fout+strlen(fout),"1");
+          outfile = fopen(fout,"wb");
+#endif
+          for (i=0;i<=width[11]*blowx;i++)
+	      w[i] = gdImageCreate(i+1,i+1);
+          im = gdImageCreate(sx,sy);
+          defBGround(im,o.reverse);
+          col=1;
+          pcnt = 0;
+      }
+      else return(0);
+    }
+    else if (cmd==-5){				/* Define new color */
+      fread ((char *)opts, sizeof(short), 4, infile);
+      i = opts[0];
+      if (i>15 && i<100) {
+	  r[i]=opts[1];
+	  g[i]=opts[2];
+	  b[i]=opts[3];
+	  coldef[i]=1;
+      }
+    }
+    else if (cmd==-20) {		/* Draw button -- ignore */
+      fread ((char *)opts, sizeof(short), 1, infile);
+    }
+    else {
+       printf ("Fatal error: Invalid command \"%i\" found in metafile\"%s\".\n",cmd,fin);
+       printf ("Is \"%s\" really a GrADS (v1.5 or higher) metafile?\n",fin);
+      return(1);
+    }
+  }
+}
+/* --------------------------------------------------------------------------------- */
+/* --------------------------------------------------------------------------------- */
+
+void defBGround(gdImagePtr im, short reverse){
+    if(reverse) 
+         cidx[0][1]=gdImageColorAllocate(im, 255, 255, 255); /* white background */
+    else
+         cidx[0][0]=gdImageColorAllocate(im, 0, 0, 0);       /* black background */
+    return;
+}
+
+/* --------------------------------------------------------------------------------- */
+
+void drawLine(gdPoint pnts[],short *pcnt,int wd, int col){
+    if(cidx[wd][col]<0)
+      cidx[wd][col]=gdImageColorAllocate(w[wd-1],r[col],g[col],b[col]);
+    gdImageFilledRectangle(w[wd-1],0,0,wd,wd, cidx[wd][col]);
+    gdImageSetBrush(im, w[wd-1]);
+    if(*pcnt>1) gdImagePolygonUnclosed(im, pnts, (*pcnt)+1, gdBrushed);
+    else gdImageLine(im, pnts[0].x, pnts[0].y,pnts[1].x,pnts[1].y,gdBrushed);
+   *pcnt=0;
+   return;
+}
+/* --------------------------------------------------------------------------------- */
+void parseArg(int argc,char *argv[],struct options *o,char **fin, char **fout){
+     register int i,j;
+     if(argc==1) printOptions(argv);
+     for (i=1;i<argc;i++) {
+       if (*(argv[i])=='-') {  /* parse options */
+         j = 0;
+         while (*(argv[i]+(++j))) {
+           if (*(argv[i]+j)=='i') {*fin = argv[++i];break;}
+           else if (*(argv[i]+j)=='h') o->fillx = 1;
+           else if (*(argv[i]+j)=='o') {*fout = argv[++i];break;}
+           else if (*(argv[i]+j)=='r') o->reverse = 1;
+           else if (*(argv[i]+j)=='x') {
+	     sscanf(argv[++i],"%d",&(o->sx));break;
+	   }
+           else if (*(argv[i]+j)=='y') {
+	     sscanf(argv[++i],"%d",&(o->sy));break;
+	   }
+           else if (*(argv[i]+j)=='v') {
+	       o->verbose = 1;
+	       printf("This is gxgif $Revision: 1.5 $, $Date: 2009/04/30 15:25:31 $\n");
+	   }
+           else { 
+	     fprintf(stderr,"Unknown option: %s\n\n",argv[i]);
+	     printOptions(argv);
+	     exit(1);
+	   }
+         }
+       }
+      else  /* No command line "-" */
+        *fin=argv[i];
+    }
+    return;
+}
+/* --------------------------------------------------------------------------------- */
+
+void printOptions(char *argv[]){
+       fprintf(stderr,"%s%s%s","Usage: ",argv[0],
+	   " [-hrv -x <pixels> -y <pixels> -i <in_file>[."  IN_EXT
+           "] -o <out_file>] [<in_file>[."IN_EXT"]].\n");
+       fprintf(stderr,"Options:\n");
+       fprintf(stderr,"     -i   <in_file>[."IN_EXT"].\n");;
+       fprintf(stderr,"     -h   Fill polygons horizontally.\n");
+       fprintf(stderr,"     -o   <out_file> (default: basename(in_file)."OUT_EXT", '-' = stdout).\n");
+       fprintf(stderr,"     -r   Black background.\n");
+       fprintf(stderr,"     -v   Verbose.\n");
+       fprintf(stderr,"     -x <pixels>  # pixels horizontally.\n");
+       fprintf(stderr,"     -y <pixels>  # pixels vertically.\n");
+     exit(8);
+     }
+/* --------------------------------------------------------------------------------- */
+
+void openFiles(char **fin, char **fout,short verbose){ /* Open files */
+  int i;
+
+  if (*fin==NULL) {
+    *fin = (char *) malloc(sizeof(char)*150);
+     fgets(*fin,150,stdin);
+     printf("read infile = %s\n",*fin);
+  }
+  infile = fopen(*fin ,"rb");
+  if (infile == NULL) {
+    *fin=strcat(*fin,"."IN_EXT);
+    infile = fopen(*fin,"rb");
+    if (infile == NULL) {
+      (*fin)[strlen(*fin)-3]='\0';
+      printf ("Input file %s[."IN_EXT"] not found.\n",*fin);
+      exit(1);
+    }
+  }
+  if (*fout==NULL) {
+    *fout = (char *) malloc(sizeof(char)*150);
+    strcpy(*fout,*fin);
+    for (i=strlen(*fout)-1;i>=0;i--) {
+      if((*fout)[i]=='.') {strcpy((*fout)+i+1,OUT_EXT);
+	break;
+      }
+      if(i==0){strcpy((*fout)+strlen(*fout),"."OUT_EXT);}
+    }
+  }
+  if(strcmp(*fout,"-")==0) outfile=stdout;
+  else outfile = fopen(*fout,"wb");
+  if (outfile==NULL) {
+    printf ("Error opening output file %s \n",*fout);
+    exit(1);
+  }
+  if(verbose) {
+    printf("GrADS metafile: %s\n",*fin);
+    if(strcmp(*fout,"-")==0) printf("output to stdout\n");
+    else printf("GIF-file: %s\n",*fout);
+  }
+  return;
+}
+/* --------------------------------------------------------------------------------- */
+void gdImagePolygonUnclosed(gdImagePtr im, gdPointPtr p, int n, int c)
+{
+        int i;
+        int lx, ly;
+        if (!n) {
+                return;
+        }
+        lx = p->x;
+        ly = p->y;
+        /* gdImageLine(im, lx, ly, p[n-1].x, p[n-1].y, c); */
+        for (i=1; (i < n); i++) {
+                p++;
+                gdImageLine(im, lx, ly, p->x, p->y, c);
+                lx = p->x;
+                ly = p->y;
+        }
+}       
+
+/* --------------------------------------------------------------------------------- */
+	
+void gdImageFilledPolygonx(gdImagePtr im, gdPointPtr p, int n, int c)
+{
+	int i;
+	int x;
+	int x1, x2;
+	int ints;
+	if (!n) {
+		return;
+	}
+	if (!im->polyAllocated) {
+		im->polyInts = (int *) malloc(sizeof(int) * n);
+		im->polyAllocated = n;
+	}		
+	if (im->polyAllocated < n) {
+		while (im->polyAllocated < n) {
+			im->polyAllocated *= 2;
+		}	
+		im->polyInts = (int *) realloc(im->polyInts,
+			sizeof(int) * im->polyAllocated);
+	}
+	x1 = p[0].x;
+	x2 = p[0].x;
+	for (i=1; (i < n); i++) {
+		if (p[i].x < x1) {
+			x1 = p[i].x;
+		}
+		if (p[i].x > x2) {
+			x2 = p[i].x;
+		}
+	}
+	for (x=x1; (x <= x2); x++) {
+		int interLast = 0;
+		int dirLast = 0;
+		int interFirst = 1;
+		ints = 0;
+		for (i=0; (i <= n); i++) {
+			int y1, y2;
+			int x1, x2;
+			int dir;
+			int ind1, ind2;
+			int lastInd1 = 0;
+			if ((i == n) || (!i)) {
+				ind1 = n-1;
+				ind2 = 0;
+			} else {
+				ind1 = i-1;
+				ind2 = i;
+			}
+			x1 = p[ind1].x;
+			x2 = p[ind2].x;
+			if (x1 < x2) {
+				x1 = p[ind1].x;
+				x2 = p[ind2].x;
+				y1 = p[ind1].y;
+				y2 = p[ind2].y;
+				dir = -1;
+			} else if (x1 > x2) {
+				x2 = p[ind1].x;
+				x1 = p[ind2].x;
+				y2 = p[ind1].y;
+				y1 = p[ind2].y;
+				dir = 1;
+			} else {
+				/* Horizontal; just draw it */
+				gdImageLine(im, 
+					 x1, p[ind1].y, 
+					x1, p[ind2].y, 
+					c);
+				continue;
+			}
+			if ((x >= x1) && (x <= x2)) {
+				int inter = 
+					(x-x1) * (y2-y1) / (x2-x1) + y1;
+				/* Only count intersections once
+					except at maxima and minima. Also, 
+					if two consecutive intersections are
+					endpoints of the same horizontal line
+					that is not at a maxima or minima,	
+					discard the leftmost of the two. */
+				if (!interFirst) {
+					if ((p[ind1].x == p[lastInd1].x) &&
+						(p[ind1].y != p[lastInd1].y)) {
+						if (dir == dirLast) {
+							if (inter > interLast) {
+								/* Replace the old one */
+								im->polyInts[ints] = inter;
+							} else {
+								/* Discard this one */
+							}	
+							continue;
+						}
+					}
+					if (inter == interLast) {
+						if (dir == dirLast) {
+							continue;
+						}
+					}
+				} 
+				if (i > 0) {
+					im->polyInts[ints++] = inter;
+				}
+				lastInd1 = i;
+				dirLast = dir;
+				interLast = inter;
+				interFirst = 0;
+			}
+		}
+		qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
+		for (i=0; (i < (ints-1)); i+=2) {
+			gdImageLine(im, x, im->polyInts[i],
+				 x, im->polyInts[i+1],  c);
+		}
+	}
+}
+/* ---------------------------- begin gd.c -------------------------------------- */
+static void gdImageBrushApply(gdImagePtr im, int x, int y);
+static void gdImageTileApply(gdImagePtr im, int x, int y);
+
+gdImagePtr gdImageCreate(int sx, int sy)
+{
+	int i;
+	gdImagePtr im;
+	im = (gdImage *) malloc(sizeof(gdImage));
+	im->pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx);
+	im->polyInts = 0;
+	im->polyAllocated = 0;
+	im->brush = 0;
+	im->tile = 0;
+	im->style = 0;
+	for (i=0; (i<sx); i++) {
+		im->pixels[i] = (unsigned char *) calloc(
+			sy, sizeof(unsigned char));
+	}	
+	im->sx = sx;
+	im->sy = sy;
+	im->colorsTotal = 0;
+	im->transparent = (-1);
+	im->interlace = 0;
+	return im;
+}
+
+void gdImageDestroy(gdImagePtr im)
+{
+	int i;
+	for (i=0; (i<im->sx); i++) {
+		free(im->pixels[i]);
+	}	
+	free(im->pixels);
+	if (im->polyInts) {
+			free(im->polyInts);
+	}
+	if (im->style) {
+		free(im->style);
+	}
+	free(im);
+}
+
+int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
+{
+	int i;
+	long rd, gd, bd;
+	int ct = (-1);
+	long mindist = 0;
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		long dist;
+		if (im->open[i]) {
+			continue;
+		}
+		rd = (im->red[i] - r);	
+		gd = (im->green[i] - g);
+		bd = (im->blue[i] - b);
+		dist = rd * rd + gd * gd + bd * bd;
+		if ((i == 0) || (dist < mindist)) {
+			mindist = dist;	
+			ct = i;
+		}
+	}
+	return ct;
+}
+
+int gdImageColorExact(gdImagePtr im, int r, int g, int b)
+{
+	int i;
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		if (im->open[i]) {
+			continue;
+		}
+		if ((im->red[i] == r) && 
+			(im->green[i] == g) &&
+			(im->blue[i] == b)) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
+{
+	int i;
+	int ct = (-1);
+	for (i=0; (i<(im->colorsTotal)); i++) {
+		if (im->open[i]) {
+			ct = i;
+			break;
+		}
+	}	
+	if (ct == (-1)) {
+		ct = im->colorsTotal;
+		if (ct == gdMaxColors) {
+			return -1;
+		}
+		im->colorsTotal++;
+	}
+	im->red[ct] = r;
+	im->green[ct] = g;
+	im->blue[ct] = b;
+	im->open[ct] = 0;
+	return ct;
+}
+
+void gdImageColorDeallocate(gdImagePtr im, int color)
+{
+	/* Mark it open. */
+	im->open[color] = 1;
+}
+
+void gdImageColorTransparent(gdImagePtr im, int color)
+{
+	im->transparent = color;
+}
+
+void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
+{
+	int p;
+	switch(color) {
+		case gdStyled:
+		if (!im->style) {
+			/* Refuse to draw if no style is set. */
+			return;
+		} else {
+			p = im->style[im->stylePos++];
+		}
+		if (p != (gdTransparent)) {
+			gdImageSetPixel(im, x, y, p);
+		}
+		im->stylePos = im->stylePos %  im->styleLength;
+		break;
+		case gdStyledBrushed:
+		if (!im->style) {
+			/* Refuse to draw if no style is set. */
+			return;
+		}
+		p = im->style[im->stylePos++];
+		if ((p != gdTransparent) && (p != 0)) {
+			gdImageSetPixel(im, x, y, gdBrushed);
+		}
+		im->stylePos = im->stylePos %  im->styleLength;
+		break;
+		case gdBrushed:
+		gdImageBrushApply(im, x, y);
+		break;
+		case gdTiled:
+		gdImageTileApply(im, x, y);
+		break;
+		default:
+		if (gdImageBoundsSafe(im, x, y)) {
+			 im->pixels[x][y] = color;
+		}
+		break;
+	}
+}
+
+static void gdImageBrushApply(gdImagePtr im, int x, int y)
+{
+	int lx, ly;
+	int hy;
+	int hx;
+	int x1, y1, x2, y2;
+	int srcx, srcy;
+	if (!im->brush) {
+		return;
+	}
+	hy = gdImageSY(im->brush)/2;
+	y1 = y - hy;
+	y2 = y1 + gdImageSY(im->brush);	
+	hx = gdImageSX(im->brush)/2;
+	x1 = x - hx;
+	x2 = x1 + gdImageSX(im->brush);
+	srcy = 0;
+	for (ly = y1; (ly < y2); ly++) {
+		srcx = 0;
+		for (lx = x1; (lx < x2); lx++) {
+			int p;
+			p = gdImageGetPixel(im->brush, srcx, srcy);
+			/* Allow for non-square brushes! */
+			if (p != gdImageGetTransparent(im->brush)) {
+				gdImageSetPixel(im, lx, ly,
+					im->brushColorMap[p]);
+			}
+			srcx++;
+		}
+		srcy++;
+	}	
+}		
+
+static void gdImageTileApply(gdImagePtr im, int x, int y)
+{
+	int srcx, srcy;
+	int p;
+	if (!im->tile) {
+		return;
+	}
+	srcx = x % gdImageSX(im->tile);
+	srcy = y % gdImageSY(im->tile);
+	p = gdImageGetPixel(im->tile, srcx, srcy);
+	/* Allow for transparency */
+	if (p != gdImageGetTransparent(im->tile)) {
+		gdImageSetPixel(im, x, y,
+			im->tileColorMap[p]);
+	}
+}		
+
+int gdImageGetPixel(gdImagePtr im, int x, int y)
+{
+	if (gdImageBoundsSafe(im, x, y)) {
+		return im->pixels[x][y];
+	} else {
+		return 0;
+	}
+}
+
+/* Bresenham as presented in Foley & Van Dam */
+
+void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+{
+	int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
+	dx = abs(x2-x1);
+	dy = abs(y2-y1);
+	if (dy <= dx) {
+		d = 2*dy - dx;
+		incr1 = 2*dy;
+		incr2 = 2 * (dy - dx);
+		if (x1 > x2) {
+			x = x2;
+			y = y2;
+			ydirflag = (-1);
+			xend = x1;
+		} else {
+			x = x1;
+			y = y1;
+			ydirflag = 1;
+			xend = x2;
+		}
+		gdImageSetPixel(im, x, y, color);
+		if (((y2 - y1) * ydirflag) > 0) {
+			while (x < xend) {
+				x++;
+				if (d <0) {
+					d+=incr1;
+				} else {
+					y++;
+					d+=incr2;
+				}
+				gdImageSetPixel(im, x, y, color);
+			}
+		} else {
+			while (x < xend) {
+				x++;
+				if (d <0) {
+					d+=incr1;
+				} else {
+					y--;
+					d+=incr2;
+				}
+				gdImageSetPixel(im, x, y, color);
+			}
+		}		
+	} else {
+		d = 2*dx - dy;
+		incr1 = 2*dx;
+		incr2 = 2 * (dx - dy);
+		if (y1 > y2) {
+			y = y2;
+			x = x2;
+			yend = y1;
+			xdirflag = (-1);
+		} else {
+			y = y1;
+			x = x1;
+			yend = y2;
+			xdirflag = 1;
+		}
+		gdImageSetPixel(im, x, y, color);
+		if (((x2 - x1) * xdirflag) > 0) {
+			while (y < yend) {
+				y++;
+				if (d <0) {
+					d+=incr1;
+				} else {
+					x++;
+					d+=incr2;
+				}
+				gdImageSetPixel(im, x, y, color);
+			}
+		} else {
+			while (y < yend) {
+				y++;
+				if (d <0) {
+					d+=incr1;
+				} else {
+					x--;
+					d+=incr2;
+				}
+				gdImageSetPixel(im, x, y, color);
+			}
+		}
+	}
+}
+
+
+int gdImageBoundsSafe(gdImagePtr im, int x, int y)
+{
+	return (!(((y < 0) || (y >= im->sy)) ||
+		((x < 0) || (x >= im->sx))));
+}
+
+
+/* Code drawn from ppmtogif.c, from the pbmplus package
+**
+** Based on GIFENCOD by David Rowley <mgardi at watdscu.waterloo.edu>. A
+** Lempel-Zim compression based on "compress".
+**
+** Modified by Marcel Wijkstra <wijkstra at fwi.uva.nl>
+**
+** Copyright (C) 1989 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+**
+** The Graphics Interchange Format(c) is the Copyright property of
+** CompuServe Incorporated.  GIF(sm) is a Service Mark property of
+** CompuServe Incorporated.
+*/
+
+/*
+ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
+ */
+typedef int             code_int;
+
+#ifdef SIGNED_COMPARE_SLOW
+typedef unsigned long int count_int;
+typedef unsigned short int count_short;
+#else /*SIGNED_COMPARE_SLOW*/
+typedef long int          count_int;
+#endif /*SIGNED_COMPARE_SLOW*/
+
+static int colorstobpp(int colors);
+static void BumpPixel (void);
+static int GIFNextPixel (gdImagePtr im);
+static void GIFEncode (FILE *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
+static void Putword (int w, FILE *fp);
+static void compress (int init_bits, FILE *outfile, gdImagePtr im);
+static void output (code_int code);
+static void cl_block (void);
+static void cl_hash (register count_int hsize);
+static void char_init (void);
+static void char_out (int c);
+static void flush_char (void);
+/* Allows for reuse */
+static void init_statics(void);
+
+void gdImageGif(gdImagePtr im, FILE *out)
+{
+	int interlace, transparent, BitsPerPixel;
+	interlace = im->interlace;
+	transparent = im->transparent;
+
+	BitsPerPixel = colorstobpp(im->colorsTotal);
+	/* Clear any old values in statics strewn through the GIF code */
+	init_statics();
+	/* All set, let's do it. */
+	GIFEncode(
+		out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
+		im->red, im->green, im->blue, im);
+}
+
+static int
+colorstobpp(int colors)
+{
+    int bpp = 0;
+
+    if ( colors <= 2 )
+        bpp = 1;
+    else if ( colors <= 4 )
+        bpp = 2;
+    else if ( colors <= 8 )
+        bpp = 3;
+    else if ( colors <= 16 )
+        bpp = 4;
+    else if ( colors <= 32 )
+        bpp = 5;
+    else if ( colors <= 64 )
+        bpp = 6;
+    else if ( colors <= 128 )
+        bpp = 7;
+    else if ( colors <= 256 )
+        bpp = 8;
+    return bpp;
+    }
+
+/*****************************************************************************
+ *
+ * GIFENCODE.C    - GIF Image compression interface
+ *
+ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
+ *            BitsPerPixel, Red, Green, Blue, gdImagePtr )
+ *
+ *****************************************************************************/
+
+#define TRUE 1
+#define FALSE 0
+
+static int Width, Height;
+static int curx, cury;
+static long CountDown;
+static int Pass = 0;
+static int Interlace;
+
+/*
+ * Bump the 'curx' and 'cury' to point to the next pixel
+ */
+static void
+BumpPixel(void)
+{
+        /*
+         * Bump the current X position
+         */
+        ++curx;
+
+        /*
+         * If we are at the end of a scan line, set curx back to the beginning
+         * If we are interlaced, bump the cury to the appropriate spot,
+         * otherwise, just increment it.
+         */
+        if( curx == Width ) {
+                curx = 0;
+
+                if( !Interlace )
+                        ++cury;
+                else {
+                     switch( Pass ) {
+
+                       case 0:
+                          cury += 8;
+                          if( cury >= Height ) {
+                                ++Pass;
+                                cury = 4;
+                          }
+                          break;
+
+                       case 1:
+                          cury += 8;
+                          if( cury >= Height ) {
+                                ++Pass;
+                                cury = 2;
+                          }
+                          break;
+
+                       case 2:
+                          cury += 4;
+                          if( cury >= Height ) {
+                             ++Pass;
+                             cury = 1;
+                          }
+                          break;
+
+                       case 3:
+                          cury += 2;
+                          break;
+                        }
+                }
+        }
+}
+
+/*
+ * Return the next pixel from the image
+ */
+static int
+GIFNextPixel(gdImagePtr im)
+{
+        int r;
+
+        if( CountDown == 0 )
+                return EOF;
+
+        --CountDown;
+
+        r = gdImageGetPixel(im, curx, cury);
+
+        BumpPixel();
+
+        return r;
+}
+
+/* public */
+
+static void
+GIFEncode(FILE *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
+{
+        int B;
+        int RWidth, RHeight;
+        int LeftOfs, TopOfs;
+        int Resolution;
+        int ColorMapSize;
+        int InitCodeSize;
+        int i;
+
+        Interlace = GInterlace;
+
+        ColorMapSize = 1 << BitsPerPixel;
+
+        RWidth = Width = GWidth;
+        RHeight = Height = GHeight;
+        LeftOfs = TopOfs = 0;
+
+        Resolution = BitsPerPixel;
+
+        /*
+         * Calculate number of bits we are expecting
+         */
+        CountDown = (long)Width * (long)Height;
+
+        /*
+         * Indicate which pass we are on (if interlace)
+         */
+        Pass = 0;
+
+        /*
+         * The initial code size
+         */
+        if( BitsPerPixel <= 1 )
+                InitCodeSize = 2;
+        else
+                InitCodeSize = BitsPerPixel;
+
+        /*
+         * Set up the current x and y position
+         */
+        curx = cury = 0;
+
+        /*
+         * Write the Magic header
+         */
+        fwrite( Transparent < 0 ? "GIF87a" : "GIF89a", 1, 6, fp );
+
+        /*
+         * Write out the screen width and height
+         */
+        Putword( RWidth, fp );
+        Putword( RHeight, fp );
+
+        /*
+         * Indicate that there is a global colour map
+         */
+        B = 0x80;       /* Yes, there is a color map */
+
+        /*
+         * OR in the resolution
+         */
+        B |= (Resolution - 1) << 5;
+
+        /*
+         * OR in the Bits per Pixel
+         */
+        B |= (BitsPerPixel - 1);
+
+        /*
+         * Write it out
+         */
+        fputc( B, fp );
+
+        /*
+         * Write out the Background colour
+         */
+        fputc( Background, fp );
+
+        /*
+         * Byte of 0's (future expansion)
+         */
+        fputc( 0, fp );
+
+        /*
+         * Write out the Global Colour Map
+         */
+        for( i=0; i<ColorMapSize; ++i ) {
+                fputc( Red[i], fp );
+                fputc( Green[i], fp );
+                fputc( Blue[i], fp );
+        }
+
+	/*
+	 * Write out extension for transparent colour index, if necessary.
+	 */
+	if ( Transparent >= 0 ) {
+	    fputc( '!', fp );
+	    fputc( 0xf9, fp );
+	    fputc( 4, fp );
+	    fputc( 1, fp );
+	    fputc( 0, fp );
+	    fputc( 0, fp );
+	    fputc( (unsigned char) Transparent, fp );
+	    fputc( 0, fp );
+	}
+
+        /*
+         * Write an Image separator
+         */
+        fputc( ',', fp );
+
+        /*
+         * Write the Image header
+         */
+
+        Putword( LeftOfs, fp );
+        Putword( TopOfs, fp );
+        Putword( Width, fp );
+        Putword( Height, fp );
+
+        /*
+         * Write out whether or not the image is interlaced
+         */
+        if( Interlace )
+                fputc( 0x40, fp );
+        else
+                fputc( 0x00, fp );
+
+        /*
+         * Write out the initial code size
+         */
+        fputc( InitCodeSize, fp );
+
+        /*
+         * Go and actually compress the data
+         */
+        compress( InitCodeSize+1, fp, im );
+
+        /*
+         * Write out a Zero-length packet (to end the series)
+         */
+        fputc( 0, fp );
+
+        /*
+         * Write the GIF file terminator
+         */
+        fputc( ';', fp );
+}
+
+/*
+ * Write out a word to the GIF file
+ */
+static void
+Putword(int w, FILE *fp)
+{
+        fputc( w & 0xff, fp );
+        fputc( (w / 256) & 0xff, fp );
+}
+
+
+/***************************************************************************
+ *
+ *  GIFCOMPR.C       - GIF Image compression routines
+ *
+ *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
+ *  David Rowley (mgardi at watdcsu.waterloo.edu)
+ *
+ ***************************************************************************/
+
+/*
+ * General DEFINEs
+ */
+
+#define GIFBITS    12
+
+#define HSIZE  5003            /* 80% occupancy */
+
+#ifdef NO_UCHAR
+ typedef char   char_type;
+#else /*NO_UCHAR*/
+ typedef        unsigned char   char_type;
+#endif /*NO_UCHAR*/
+
+/*
+ *
+ * GIF Image compression - modified 'compress'
+ *
+ * Based on: compress.c - File compression ala IEEE Computer, June 1984.
+ *
+ * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
+ *              Jim McKie               (decvax!mcvax!jim)
+ *              Steve Davies            (decvax!vax135!petsd!peora!srd)
+ *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
+ *              James A. Woods          (decvax!ihnp4!ames!jaw)
+ *              Joe Orost               (decvax!vax135!petsd!joe)
+ *
+ */
+#include <ctype.h>
+
+#define ARGVAL() (*++(*argv) || (--argc && *++argv))
+
+static int n_bits;                        /* number of bits/code */
+static int maxbits = GIFBITS;                /* user settable max # bits/code */
+static code_int maxcode;                  /* maximum code, given n_bits */
+static code_int maxmaxcode = (code_int)1 << GIFBITS; /* should NEVER generate this code */
+#ifdef COMPATIBLE               /* But wrong! */
+# define MAXCODE(n_bits)        ((code_int) 1 << (n_bits) - 1)
+#else /*COMPATIBLE*/
+# define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)
+#endif /*COMPATIBLE*/
+
+static count_int htab [HSIZE];
+static unsigned short codetab [HSIZE];
+#define HashTabOf(i)       htab[i]
+#define CodeTabOf(i)    codetab[i]
+
+static code_int hsize = HSIZE;                 /* for dynamic table sizing */
+
+/*
+ * To save much memory, we overlay the table used by compress() with those
+ * used by decompress().  The tab_prefix table is the same size and type
+ * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We
+ * get this from the beginning of htab.  The output stack uses the rest
+ * of htab, and contains characters.  There is plenty of room for any
+ * possible stack (stack used to be 8000 characters).
+ */
+
+#define tab_prefixof(i) CodeTabOf(i)
+#define tab_suffixof(i)        ((char_type*)(htab))[i]
+#define de_stack               ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
+
+static code_int free_ent = 0;                  /* first unused entry */
+
+/*
+ * block compression parameters -- after all codes are used up,
+ * and compression rate changes, start over.
+ */
+static int clear_flg = 0;
+
+static int offset;
+static long int in_count = 1;            /* length of input */
+static long int out_count = 0;           /* # of codes output (for debugging) */
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm:  use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination.  We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe.  Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation.  Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills.  The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor.  Late addition:  construct the table according to
+ * file size for noticeable speed improvement on small files.  Please direct
+ * questions about this implementation to ames!jaw.
+ */
+
+static int g_init_bits;
+static FILE* g_outfile;
+
+static int ClearCode;
+static int EOFCode;
+
+static void
+compress(int init_bits, FILE *outfile, gdImagePtr im)
+{
+    register long fcode;
+    register code_int i /* = 0 */;
+    register int c;
+    register code_int ent;
+    register code_int disp;
+    register code_int hsize_reg;
+    register int hshift;
+
+    /*
+     * Set up the globals:  g_init_bits - initial number of bits
+     *                      g_outfile   - pointer to output file
+     */
+    g_init_bits = init_bits;
+    g_outfile = outfile;
+
+    /*
+     * Set up the necessary values
+     */
+    offset = 0;
+    out_count = 0;
+    clear_flg = 0;
+    in_count = 1;
+    maxcode = MAXCODE(n_bits = g_init_bits);
+
+    ClearCode = (1 << (init_bits - 1));
+    EOFCode = ClearCode + 1;
+    free_ent = ClearCode + 2;
+
+    char_init();
+
+    ent = GIFNextPixel( im );
+
+    hshift = 0;
+    for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
+        ++hshift;
+    hshift = 8 - hshift;                /* set hash code range bound */
+
+    hsize_reg = hsize;
+    cl_hash( (count_int) hsize_reg);            /* clear hash table */
+
+    output( (code_int)ClearCode );
+
+#ifdef SIGNED_COMPARE_SLOW
+    while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {
+#else /*SIGNED_COMPARE_SLOW*/
+    while ( (c = GIFNextPixel( im )) != EOF ) {  /* } */
+#endif /*SIGNED_COMPARE_SLOW*/
+
+        ++in_count;
+
+        fcode = (long) (((long) c << maxbits) + ent);
+        i = (((code_int)c << hshift) ^ ent);    /* xor hashing */
+
+        if ( HashTabOf (i) == fcode ) {
+            ent = CodeTabOf (i);
+            continue;
+        } else if ( (long)HashTabOf (i) < 0 )      /* empty slot */
+            goto nomatch;
+        disp = hsize_reg - i;           /* secondary hash (after G. Knott) */
+        if ( i == 0 )
+            disp = 1;
+probe:
+        if ( (i -= disp) < 0 )
+            i += hsize_reg;
+
+        if ( HashTabOf (i) == fcode ) {
+            ent = CodeTabOf (i);
+            continue;
+        }
+        if ( (long)HashTabOf (i) > 0 )
+            goto probe;
+nomatch:
+        output ( (code_int) ent );
+        ++out_count;
+        ent = c;
+#ifdef SIGNED_COMPARE_SLOW
+        if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
+#else /*SIGNED_COMPARE_SLOW*/
+        if ( free_ent < maxmaxcode ) {  /* } */
+#endif /*SIGNED_COMPARE_SLOW*/
+            CodeTabOf (i) = free_ent++; /* code -> hashtable */
+            HashTabOf (i) = fcode;
+        } else
+                cl_block();
+    }
+    /*
+     * Put out the final code.
+     */
+    output( (code_int)ent );
+    ++out_count;
+    output( (code_int) EOFCode );
+}
+
+/*****************************************************************
+ * TAG( output )
+ *
+ * Output the given code.
+ * Inputs:
+ *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
+ *              that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ *      Outputs code to the file.
+ * Assumptions:
+ *      Chars are 8 bits long.
+ * Algorithm:
+ *      Maintain a GIFBITS character long buffer (so that 8 codes will
+ * fit in it exactly).  Use the VAX insv instruction to insert each
+ * code in turn.  When the buffer fills up empty it and start over.
+ */
+
+static unsigned long cur_accum = 0;
+static int cur_bits = 0;
+
+static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
+                                  0x001F, 0x003F, 0x007F, 0x00FF,
+                                  0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+                                  0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
+
+static void
+output(code_int code)
+{
+    cur_accum &= masks[ cur_bits ];
+
+    if( cur_bits > 0 )
+        cur_accum |= ((long)code << cur_bits);
+    else
+        cur_accum = code;
+
+    cur_bits += n_bits;
+
+    while( cur_bits >= 8 ) {
+        char_out( (unsigned int)(cur_accum & 0xff) );
+        cur_accum >>= 8;
+        cur_bits -= 8;
+    }
+
+    /*
+     * If the next entry is going to be too big for the code size,
+     * then increase it, if possible.
+     */
+   if ( free_ent > maxcode || clear_flg ) {
+
+            if( clear_flg ) {
+
+                maxcode = MAXCODE (n_bits = g_init_bits);
+                clear_flg = 0;
+
+            } else {
+
+                ++n_bits;
+                if ( n_bits == maxbits )
+                    maxcode = maxmaxcode;
+                else
+                    maxcode = MAXCODE(n_bits);
+            }
+        }
+
+    if( code == EOFCode ) {
+        /*
+         * At EOF, write the rest of the buffer.
+         */
+        while( cur_bits > 0 ) {
+                char_out( (unsigned int)(cur_accum & 0xff) );
+                cur_accum >>= 8;
+                cur_bits -= 8;
+        }
+
+        flush_char();
+
+        fflush( g_outfile );
+
+        if( ferror( g_outfile ) )
+		return;
+    }
+}
+
+/*
+ * Clear out the hash table
+ */
+static void
+cl_block (void)             /* table clear for block compress */
+{
+
+        cl_hash ( (count_int) hsize );
+        free_ent = ClearCode + 2;
+        clear_flg = 1;
+
+        output( (code_int)ClearCode );
+}
+
+static void
+cl_hash(register count_int hsize)          /* reset code table */
+                         
+{
+
+        register count_int *htab_p = htab+hsize;
+
+        register long i;
+        register long m1 = -1;
+
+        i = hsize - 16;
+        do {                            /* might use Sys V memset(3) here */
+                *(htab_p-16) = m1;
+                *(htab_p-15) = m1;
+                *(htab_p-14) = m1;
+                *(htab_p-13) = m1;
+                *(htab_p-12) = m1;
+                *(htab_p-11) = m1;
+                *(htab_p-10) = m1;
+                *(htab_p-9) = m1;
+                *(htab_p-8) = m1;
+                *(htab_p-7) = m1;
+                *(htab_p-6) = m1;
+                *(htab_p-5) = m1;
+                *(htab_p-4) = m1;
+                *(htab_p-3) = m1;
+                *(htab_p-2) = m1;
+                *(htab_p-1) = m1;
+                htab_p -= 16;
+        } while ((i -= 16) >= 0);
+
+        for ( i += 16; i > 0; --i )
+                *--htab_p = m1;
+}
+
+/******************************************************************************
+ *
+ * GIF Specific routines
+ *
+ ******************************************************************************/
+
+/*
+ * Number of characters so far in this 'packet'
+ */
+static int a_count;
+
+/*
+ * Set up the 'byte output' routine
+ */
+static void
+char_init(void)
+{
+        a_count = 0;
+}
+
+/*
+ * Define the storage for the packet accumulator
+ */
+static char accum[ 256 ];
+
+/*
+ * Add a character to the end of the current packet, and if it is 254
+ * characters, flush the packet to disk.
+ */
+static void
+char_out(int c)
+{
+        accum[ a_count++ ] = c;
+        if( a_count >= 254 )
+                flush_char();
+}
+
+/*
+ * Flush the packet to disk, and reset the accumulator
+ */
+static void
+flush_char(void)
+{
+        if( a_count > 0 ) {
+                fputc( a_count, g_outfile );
+                fwrite( accum, 1, a_count, g_outfile );
+                a_count = 0;
+        }
+}
+
+static void init_statics(void) {
+	/* Some of these are properly initialized later. What I'm doing
+		here is making sure code that depends on C's initialization
+		of statics doesn't break when the code gets called more
+		than once. */
+	Width = 0;
+	Height = 0;
+	curx = 0;
+	cury = 0;
+	CountDown = 0;
+	Pass = 0;
+	Interlace = 0;
+	a_count = 0;
+	cur_accum = 0;
+	cur_bits = 0;
+	g_init_bits = 0;
+	g_outfile = 0;
+	ClearCode = 0;
+	EOFCode = 0;
+	free_ent = 0;
+	clear_flg = 0;
+	offset = 0;
+	in_count = 1;
+	out_count = 0;	
+	hsize = HSIZE;
+	n_bits = 0;
+	maxbits = GIFBITS;
+	maxcode = 0;
+	maxmaxcode = (code_int)1 << GIFBITS;
+}
+
+
+/* +-------------------------------------------------------------------+ */
+/* | Copyright 1990, 1991, 1993, David Koblas.  (koblas at netcom.com)    | */
+/* |   Permission to use, copy, modify, and distribute this software   | */
+/* |   and its documentation for any purpose and without fee is hereby | */
+/* |   granted, provided that the above copyright notice appear in all | */
+/* |   copies and that both that copyright notice and this permission  | */
+/* |   notice appear in supporting documentation.  This software is    | */
+/* |   provided "as is" without express or implied warranty.           | */
+/* +-------------------------------------------------------------------+ */
+
+
+#define        MAXCOLORMAPSIZE         256
+
+#define        TRUE    1
+#define        FALSE   0
+
+#define CM_RED         0
+#define CM_GREEN       1
+#define CM_BLUE                2
+
+#define        MAX_LWZ_BITS            12
+
+#define INTERLACE              0x40
+#define LOCALCOLORMAP  0x80
+#define BitSet(byte, bit)      (((byte) & (bit)) == (bit))
+
+#define        ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
+
+#define LM_to_uint(a,b)                        (((b)<<8)|(a))
+
+/* We may eventually want to use this information, but def it out for now */
+#if 0
+static struct {
+       unsigned int    Width;
+       unsigned int    Height;
+       unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
+       unsigned int    BitPixel;
+       unsigned int    ColorResolution;
+       unsigned int    Background;
+       unsigned int    AspectRatio;
+} GifScreen;
+#endif
+
+static struct {
+       int     transparent;
+       int     delayTime;
+       int     inputFlag;
+       int     disposal;
+} Gif89 = { -1, -1, -1, 0 };
+
+static int ReadColorMap (FILE *fd, int number, unsigned char (*buffer)[256]);
+static int DoExtension (FILE *fd, int label, int *Transparent);
+static int GetDataBlock (FILE *fd, unsigned char *buf);
+static int GetCode (FILE *fd, int code_size, int flag);
+static int LWZReadByte (FILE *fd, int flag, int input_code_size);
+static void ReadImage (gdImagePtr im, FILE *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int ignore);
+
+int ZeroDataBlock;
+
+gdImagePtr
+gdImageCreateFromGif(FILE *fd)
+{
+       int imageNumber;
+       int BitPixel;
+       int ColorResolution;
+       int Background;
+       int AspectRatio;
+       int Transparent = (-1);
+       unsigned char   buf[16];
+       unsigned char   c;
+       unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
+       unsigned char   localColorMap[3][MAXCOLORMAPSIZE];
+       int             imw, imh;
+       int             useGlobalColormap;
+       int             bitPixel;
+       int             imageCount = 0;
+       char            version[4];
+       gdImagePtr im = 0;
+       ZeroDataBlock = FALSE;
+
+       imageNumber = 1;
+       if (! ReadOK(fd,buf,6)) {
+		return 0;
+	}
+       if (strncmp((char *)buf,"GIF",3) != 0) {
+		return 0;
+	}
+       strncpy(version, (char *)buf + 3, 3);
+       version[3] = '\0';
+
+       if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
+		return 0;
+	}
+       if (! ReadOK(fd,buf,7)) {
+		return 0;
+	}
+       BitPixel        = 2<<(buf[4]&0x07);
+       ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
+       Background      = buf[5];
+       AspectRatio     = buf[6];
+
+       if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
+               if (ReadColorMap(fd, BitPixel, ColorMap)) {
+			return 0;
+		}
+       }
+       for (;;) {
+               if (! ReadOK(fd,&c,1)) {
+                       return 0;
+               }
+               if (c == ';') {         /* GIF terminator */
+                       int i;
+                       if (imageCount < imageNumber) {
+                               return 0;
+                       }
+                       /* Terminator before any image was declared! */
+                       if (!im) {
+                              return 0;
+                       }
+		       /* Check for open colors at the end, so
+                          we can reduce colorsTotal and ultimately
+                          BitsPerPixel */
+                       for (i=((im->colorsTotal-1)); (i>=0); i--) {
+                               if (im->open[i]) {
+                                       im->colorsTotal--;
+                               } else {
+                                       break;
+                               }
+                       } 
+                       return im;
+               }
+
+               if (c == '!') {         /* Extension */
+                       if (! ReadOK(fd,&c,1)) {
+                               return 0;
+                       }
+                       DoExtension(fd, c, &Transparent);
+                       continue;
+               }
+
+               if (c != ',') {         /* Not a valid start character */
+                       continue;
+               }
+
+               ++imageCount;
+
+               if (! ReadOK(fd,buf,9)) {
+	               return 0;
+               }
+
+               useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
+
+               bitPixel = 1<<((buf[8]&0x07)+1);
+
+               imw = LM_to_uint(buf[4],buf[5]);
+               imh = LM_to_uint(buf[6],buf[7]);
+	       if (!(im = gdImageCreate(imw, imh))) {
+			 return 0;
+	       }
+               im->interlace = BitSet(buf[8], INTERLACE);
+               if (! useGlobalColormap) {
+                       if (ReadColorMap(fd, bitPixel, localColorMap)) { 
+                                 return 0;
+                       }
+                       ReadImage(im, fd, imw, imh, localColorMap, 
+                                 BitSet(buf[8], INTERLACE), 
+                                 imageCount != imageNumber);
+               } else {
+                       ReadImage(im, fd, imw, imh,
+                                 ColorMap, 
+                                 BitSet(buf[8], INTERLACE), 
+                                 imageCount != imageNumber);
+               }
+               if (Transparent != (-1)) {
+                       gdImageColorTransparent(im, Transparent);
+               }	   
+       }
+}
+
+static int
+ReadColorMap(FILE *fd, int number, unsigned char (*buffer)[256])
+{
+       int             i;
+       unsigned char   rgb[3];
+
+
+       for (i = 0; i < number; ++i) {
+               if (! ReadOK(fd, rgb, sizeof(rgb))) {
+                       return TRUE;
+               }
+               buffer[CM_RED][i] = rgb[0] ;
+               buffer[CM_GREEN][i] = rgb[1] ;
+               buffer[CM_BLUE][i] = rgb[2] ;
+       }
+
+
+       return FALSE;
+}
+
+static int
+DoExtension(FILE *fd, int label, int *Transparent)
+{
+       static unsigned char     buf[256];
+
+       switch (label) {
+       case 0xf9:              /* Graphic Control Extension */
+               (void) GetDataBlock(fd, (unsigned char*) buf);
+               Gif89.disposal    = (buf[0] >> 2) & 0x7;
+               Gif89.inputFlag   = (buf[0] >> 1) & 0x1;
+               Gif89.delayTime   = LM_to_uint(buf[1],buf[2]);
+               if ((buf[0] & 0x1) != 0)
+                       *Transparent = buf[3];
+
+               while (GetDataBlock(fd, (unsigned char*) buf) != 0)
+                       ;
+               return FALSE;
+       default:
+               break;
+       }
+       while (GetDataBlock(fd, (unsigned char*) buf) != 0)
+               ;
+
+       return FALSE;
+}
+
+static int
+GetDataBlock(FILE *fd, unsigned char *buf)
+{
+       unsigned char   count;
+
+       if (! ReadOK(fd,&count,1)) {
+               return -1;
+       }
+
+       ZeroDataBlock = count == 0;
+
+       if ((count != 0) && (! ReadOK(fd, buf, count))) {
+               return -1;
+       }
+
+       return count;
+}
+
+static int
+GetCode(FILE *fd, int code_size, int flag)
+{
+       static unsigned char    buf[280];
+       static int              curbit, lastbit, done, last_byte;
+       int                     i, j, ret;
+       unsigned char           count;
+
+       if (flag) {
+               curbit = 0;
+               lastbit = 0;
+               done = FALSE;
+               return 0;
+       }
+
+       if ( (curbit+code_size) >= lastbit) {
+               if (done) {
+                       if (curbit >= lastbit) {
+                                /* Oh well */
+                       }                        
+                       return -1;
+               }
+               buf[0] = buf[last_byte-2];
+               buf[1] = buf[last_byte-1];
+
+               if ((count = GetDataBlock(fd, &buf[2])) == 0)
+                       done = TRUE;
+
+               last_byte = 2 + count;
+               curbit = (curbit - lastbit) + 16;
+               lastbit = (2+count)*8 ;
+       }
+
+       ret = 0;
+       for (i = curbit, j = 0; j < code_size; ++i, ++j)
+               ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+
+       curbit += code_size;
+
+       return ret;
+}
+
+static int
+LWZReadByte(FILE *fd, int flag, int input_code_size)
+{
+       static int      fresh = FALSE;
+       int             code, incode;
+       static int      code_size, set_code_size;
+       static int      max_code, max_code_size;
+       static int      firstcode, oldcode;
+       static int      clear_code, end_code;
+       static int      table[2][(1<< MAX_LWZ_BITS)];
+       static int      stack[(1<<(MAX_LWZ_BITS))*2], *sp;
+       register int    i;
+
+       if (flag) {
+               set_code_size = input_code_size;
+               code_size = set_code_size+1;
+               clear_code = 1 << set_code_size ;
+               end_code = clear_code + 1;
+               max_code_size = 2*clear_code;
+               max_code = clear_code+2;
+
+               GetCode(fd, 0, TRUE);
+               
+               fresh = TRUE;
+
+               for (i = 0; i < clear_code; ++i) {
+                       table[0][i] = 0;
+                       table[1][i] = i;
+               }
+               for (; i < (1<<MAX_LWZ_BITS); ++i)
+                       table[0][i] = table[1][0] = 0;
+
+               sp = stack;
+
+               return 0;
+       } else if (fresh) {
+               fresh = FALSE;
+               do {
+                       firstcode = oldcode =
+                               GetCode(fd, code_size, FALSE);
+               } while (firstcode == clear_code);
+               return firstcode;
+       }
+
+       if (sp > stack)
+               return *--sp;
+
+       while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
+               if (code == clear_code) {
+                       for (i = 0; i < clear_code; ++i) {
+                               table[0][i] = 0;
+                               table[1][i] = i;
+                       }
+                       for (; i < (1<<MAX_LWZ_BITS); ++i)
+                               table[0][i] = table[1][i] = 0;
+                       code_size = set_code_size+1;
+                       max_code_size = 2*clear_code;
+                       max_code = clear_code+2;
+                       sp = stack;
+                       firstcode = oldcode =
+                                       GetCode(fd, code_size, FALSE);
+                       return firstcode;
+               } else if (code == end_code) {
+                       int             count;
+                       unsigned char   buf[260];
+
+                       if (ZeroDataBlock)
+                               return -2;
+
+                       while ((count = GetDataBlock(fd, buf)) > 0)
+                               ;
+
+                       if (count != 0)
+                       return -2;
+               }
+
+               incode = code;
+
+               if (code >= max_code) {
+                       *sp++ = firstcode;
+                       code = oldcode;
+               }
+
+               while (code >= clear_code) {
+                       *sp++ = table[1][code];
+                       if (code == table[0][code]) {
+                               /* Oh well */
+                       }
+                       code = table[0][code];
+               }
+
+               *sp++ = firstcode = table[1][code];
+
+               if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
+                       table[0][code] = oldcode;
+                       table[1][code] = firstcode;
+                       ++max_code;
+                       if ((max_code >= max_code_size) &&
+                               (max_code_size < (1<<MAX_LWZ_BITS))) {
+                               max_code_size *= 2;
+                               ++code_size;
+                       }
+               }
+
+               oldcode = incode;
+
+               if (sp > stack)
+                       return *--sp;
+       }
+       return code;
+}
+
+static void
+ReadImage(gdImagePtr im, FILE *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int ignore)
+{
+       unsigned char   c;      
+       int             v;
+       int             xpos = 0, ypos = 0, pass = 0;
+       int i;
+       /* Stash the color map into the image */
+       for (i=0; (i<gdMaxColors); i++) {
+               im->red[i] = cmap[CM_RED][i];	
+               im->green[i] = cmap[CM_GREEN][i];	
+               im->blue[i] = cmap[CM_BLUE][i];	
+               im->open[i] = 1;
+       }
+       /* Many (perhaps most) of these colors will remain marked open. */
+       im->colorsTotal = gdMaxColors;
+       /*
+       **  Initialize the Compression routines
+       */
+       if (! ReadOK(fd,&c,1)) {
+               return; 
+       }
+       if (LWZReadByte(fd, TRUE, c) < 0) {
+               return;
+       }
+
+       /*
+       **  If this is an "uninteresting picture" ignore it.
+       */
+       if (ignore) {
+               while (LWZReadByte(fd, FALSE, c) >= 0)
+                       ;
+               return;
+       }
+
+       while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
+               /* This how we recognize which colors are actually used. */
+               if (im->open[v]) {
+                       im->open[v] = 0;
+               }
+               gdImageSetPixel(im, xpos, ypos, v);
+               ++xpos;
+               if (xpos == len) {
+                       xpos = 0;
+                       if (interlace) {
+                               switch (pass) {
+                               case 0:
+                               case 1:
+                                       ypos += 8; break;
+                               case 2:
+                                       ypos += 4; break;
+                               case 3:
+                                       ypos += 2; break;
+                               }
+
+                               if (ypos >= height) {
+                                       ++pass;
+                                       switch (pass) {
+                                       case 1:
+                                               ypos = 4; break;
+                                       case 2:
+                                               ypos = 2; break;
+                                       case 3:
+                                               ypos = 1; break;
+                                       default:
+                                               goto fini;
+                                       }
+                               }
+                       } else {
+                               ++ypos;
+                       }
+               }
+               if (ypos >= height)
+                       break;
+       }
+
+fini:
+       if (LWZReadByte(fd,FALSE,c)>=0) {
+               /* Ignore extra */
+       }
+}
+
+void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+{
+	gdImageLine(im, x1, y1, x2, y1, color);		
+	gdImageLine(im, x1, y2, x2, y2, color);		
+	gdImageLine(im, x1, y1, x1, y2, color);
+	gdImageLine(im, x2, y1, x2, y2, color);
+}
+
+void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+{
+	int x, y;
+	for (y=y1; (y<=y2); y++) {
+		for (x=x1; (x<=x2); x++) {
+			gdImageSetPixel(im, x, y, color);
+		}
+	}
+}
+
+int gdGetWord(int *result, FILE *in)
+{
+	int r;
+	r = getc(in);
+	if (r == EOF) {
+		return 0;
+	}
+	*result = r << 8;
+	r = getc(in);	
+	if (r == EOF) {
+		return 0;
+	}
+	*result += r;
+	return 1;
+}
+
+void gdPutWord(int w, FILE *out)
+{
+	putc((unsigned char)(w >> 8), out);
+	putc((unsigned char)(w & 0xFF), out);
+}
+
+int gdGetByte(int *result, FILE *in)
+{
+	int r;
+	r = getc(in);
+	if (r == EOF) {
+		return 0;
+	}
+	*result = r;
+	return 1;
+}
+
+gdImagePtr gdImageCreateFromGd(FILE *in)
+{
+	int sx, sy;
+	int x, y;
+	int i;
+	gdImagePtr im;
+	if (!gdGetWord(&sx, in)) {
+		goto fail1;
+	}
+	if (!gdGetWord(&sy, in)) {
+		goto fail1;
+	}
+	im = gdImageCreate(sx, sy);
+	if (!gdGetByte(&im->colorsTotal, in)) {
+		goto fail2;
+	}
+	if (!gdGetWord(&im->transparent, in)) {
+		goto fail2;
+	}
+	if (im->transparent == 257) {
+		im->transparent = (-1);
+	}
+	for (i=0; (i<gdMaxColors); i++) {
+		if (!gdGetByte(&im->red[i], in)) {
+			goto fail2;
+		}
+		if (!gdGetByte(&im->green[i], in)) {
+			goto fail2;
+		}
+		if (!gdGetByte(&im->blue[i], in)) {
+			goto fail2;
+		}
+	}	
+	for (y=0; (y<sy); y++) {
+		for (x=0; (x<sx); x++) {	
+			int ch;
+			ch = getc(in);
+			if (ch == EOF) {
+				gdImageDestroy(im);
+				return 0;
+			}
+			im->pixels[x][y] = ch;
+		}
+	}
+	return im;
+fail2:
+	gdImageDestroy(im);
+fail1:
+	return 0;
+}
+	
+void gdImageGd(gdImagePtr im, FILE *out)
+{
+	int x, y;
+	int i;
+	int trans;
+	gdPutWord(im->sx, out);
+	gdPutWord(im->sy, out);
+	putc((unsigned char)im->colorsTotal, out);
+	trans = im->transparent;
+	if (trans == (-1)) {
+		trans = 257;
+	}	
+	gdPutWord(trans, out);
+	for (i=0; (i<gdMaxColors); i++) {
+		putc((unsigned char)im->red[i], out);
+		putc((unsigned char)im->green[i], out);	
+		putc((unsigned char)im->blue[i], out);	
+	}
+	for (y=0; (y < im->sy); y++) {	
+		for (x=0; (x < im->sx); x++) {	
+			putc((unsigned char)im->pixels[x][y], out);
+		}
+	}
+}
+
+gdImagePtr
+gdImageCreateFromXbm(FILE *fd)
+{
+	gdImagePtr im;	
+	int bit;
+	int w, h;
+	int bytes;
+	int ch;
+	int i, x, y;
+	char *sp;
+	char s[161];
+	if (!fgets(s, 160, fd)) {
+		return 0;
+	}
+	sp = &s[0];
+	/* Skip #define */
+	sp = strchr(sp, ' ');
+	if (!sp) {
+		return 0;
+	}
+	/* Skip width label */
+	sp++;
+	sp = strchr(sp, ' ');
+	if (!sp) {
+		return 0;
+	}
+	/* Get width */
+	w = atoi(sp + 1);
+	if (!w) {
+		return 0;
+	}
+	if (!fgets(s, 160, fd)) {
+		return 0;
+	}
+	sp = s;
+	/* Skip #define */
+	sp = strchr(sp, ' ');
+	if (!sp) {
+		return 0;
+	}
+	/* Skip height label */
+	sp++;
+	sp = strchr(sp, ' ');
+	if (!sp) {
+		return 0;
+	}
+	/* Get height */
+	h = atoi(sp + 1);
+	if (!h) {
+		return 0;
+	}
+	/* Skip declaration line */
+	if (!fgets(s, 160, fd)) {
+		return 0;
+	}
+	bytes = (w * h / 8) + 1;
+	im = gdImageCreate(w, h);
+	gdImageColorAllocate(im, 255, 255, 255);
+	gdImageColorAllocate(im, 0, 0, 0);
+	x = 0;
+	y = 0;
+	for (i=0; (i < bytes); i++) {
+		char h[3];
+		int b;
+		/* Skip spaces, commas, CRs, 0x */
+		while(1) {
+			ch = getc(fd);
+			if (ch == EOF) {
+				goto fail;
+			}
+			if (ch == 'x') {
+				break;
+			}	
+		}
+		/* Get hex value */
+		ch = getc(fd);
+		if (ch == EOF) {
+			goto fail;
+		}
+		h[0] = ch;
+		ch = getc(fd);
+		if (ch == EOF) {
+			goto fail;
+		}
+		h[1] = ch;
+		h[2] = '\0';
+		sscanf(h, "%x", &b);		
+		for (bit = 1; (bit <= 128); (bit = bit << 1)) {
+			gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);	
+			if (x == im->sx) {
+				x = 0;
+				y++;
+				if (y == im->sy) {
+					return im;
+				}
+				/* Fix 8/8/95 */
+				break;
+			}
+		}
+	}
+	/* Shouldn't happen */
+	fprintf(stderr, "Error: bug in gdImageCreateFromXbm!\n");
+	return 0;
+fail:
+	gdImageDestroy(im);
+	return 0;
+}
+
+void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c)
+{
+	int i;
+	int lx, ly;
+	if (!n) {
+		return;
+	}
+	lx = p->x;
+	ly = p->y;
+	gdImageLine(im, lx, ly, p[n-1].x, p[n-1].y, c);
+	for (i=1; (i < n); i++) {
+		p++;
+		gdImageLine(im, lx, ly, p->x, p->y, c);
+		lx = p->x;
+		ly = p->y;
+	}
+}	
+	
+int gdCompareInt(const void *a, const void *b);
+	
+void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
+{
+	int i;
+	int y;
+	int y1, y2;
+	int ints;
+	if (!n) {
+		return;
+	}
+	if (!im->polyAllocated) {
+		im->polyInts = (int *) malloc(sizeof(int) * n);
+		im->polyAllocated = n;
+	}		
+	if (im->polyAllocated < n) {
+		while (im->polyAllocated < n) {
+			im->polyAllocated *= 2;
+		}	
+		im->polyInts = (int *) realloc(im->polyInts,
+			sizeof(int) * im->polyAllocated);
+	}
+	y1 = p[0].y;
+	y2 = p[0].y;
+	for (i=1; (i < n); i++) {
+		if (p[i].y < y1) {
+			y1 = p[i].y;
+		}
+		if (p[i].y > y2) {
+			y2 = p[i].y;
+		}
+	}
+	for (y=y1; (y <= y2); y++) {
+		int interLast = 0;
+		int dirLast = 0;
+		int interFirst = 1;
+		ints = 0;
+		for (i=0; (i <= n); i++) {
+			int x1, x2;
+			int y1, y2;
+			int dir;
+			int ind1, ind2;
+			int lastInd1 = 0;
+			if ((i == n) || (!i)) {
+				ind1 = n-1;
+				ind2 = 0;
+			} else {
+				ind1 = i-1;
+				ind2 = i;
+			}
+			y1 = p[ind1].y;
+			y2 = p[ind2].y;
+			if (y1 < y2) {
+				y1 = p[ind1].y;
+				y2 = p[ind2].y;
+				x1 = p[ind1].x;
+				x2 = p[ind2].x;
+				dir = -1;
+			} else if (y1 > y2) {
+				y2 = p[ind1].y;
+				y1 = p[ind2].y;
+				x2 = p[ind1].x;
+				x1 = p[ind2].x;
+				dir = 1;
+			} else {
+				/* Horizontal; just draw it */
+				gdImageLine(im, 
+					p[ind1].x, y1, 
+					p[ind2].x, y1,
+					c);
+				continue;
+			}
+			if ((y >= y1) && (y <= y2)) {
+				int inter = 
+					(y-y1) * (x2-x1) / (y2-y1) + x1;
+				/* Only count intersections once
+					except at maxima and minima. Also, 
+					if two consecutive intersections are
+					endpoints of the same horizontal line
+					that is not at a maxima or minima,	
+					discard the leftmost of the two. */
+				if (!interFirst) {
+					if ((p[ind1].y == p[lastInd1].y) &&
+						(p[ind1].x != p[lastInd1].x)) {
+						if (dir == dirLast) {
+							if (inter > interLast) {
+								/* Replace the old one */
+								im->polyInts[ints] = inter;
+							} else {
+								/* Discard this one */
+							}	
+							continue;
+						}
+					}
+					if (inter == interLast) {
+						if (dir == dirLast) {
+							continue;
+						}
+					}
+				} 
+				if (i > 0) {
+					im->polyInts[ints++] = inter;
+				}
+				lastInd1 = i;
+				dirLast = dir;
+				interLast = inter;
+				interFirst = 0;
+			}
+		}
+		qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
+		for (i=0; (i < (ints-1)); i+=2) {
+			gdImageLine(im, im->polyInts[i], y,
+				im->polyInts[i+1], y, c);
+		}
+	}
+}
+	
+int gdCompareInt(const void *a, const void *b)
+{
+	return (*(const int *)a) - (*(const int *)b);
+}
+
+void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels)
+{
+	if (im->style) {
+		free(im->style);
+	}
+	im->style = (int *) 
+		malloc(sizeof(int) * noOfPixels);
+	memcpy(im->style, style, sizeof(int) * noOfPixels);
+	im->styleLength = noOfPixels;
+	im->stylePos = 0;
+}
+
+void gdImageSetBrush(gdImagePtr im, gdImagePtr brush)
+{
+	int i;
+	im->brush = brush;
+	for (i=0; (i < gdImageColorsTotal(brush)); i++) {
+		int index;
+		index = gdImageColorExact(im, 
+			gdImageRed(brush, i),
+			gdImageGreen(brush, i),
+			gdImageBlue(brush, i));
+		if (index == (-1)) {
+			index = gdImageColorAllocate(im,
+				gdImageRed(brush, i),
+				gdImageGreen(brush, i),
+				gdImageBlue(brush, i));
+			if (index == (-1)) {
+				index = gdImageColorClosest(im,
+					gdImageRed(brush, i),
+					gdImageGreen(brush, i),
+					gdImageBlue(brush, i));
+			}
+		}
+		im->brushColorMap[i] = index;
+	}
+}
+	
+void gdImageSetTile(gdImagePtr im, gdImagePtr tile)
+{
+	int i;
+	im->tile = tile;
+	for (i=0; (i < gdImageColorsTotal(tile)); i++) {
+		int index;
+		index = gdImageColorExact(im, 
+			gdImageRed(tile, i),
+			gdImageGreen(tile, i),
+			gdImageBlue(tile, i));
+		if (index == (-1)) {
+			index = gdImageColorAllocate(im,
+				gdImageRed(tile, i),
+				gdImageGreen(tile, i),
+				gdImageBlue(tile, i));
+			if (index == (-1)) {
+				index = gdImageColorClosest(im,
+					gdImageRed(tile, i),
+					gdImageGreen(tile, i),
+					gdImageBlue(tile, i));
+			}
+		}
+		im->tileColorMap[i] = index;
+	}
+}
+
+void gdImageInterlace(gdImagePtr im, int interlaceArg)
+{
+	im->interlace = interlaceArg;
+}
+
diff --git a/src/gxhpng.c b/src/gxhpng.c
new file mode 100644
index 0000000..ce6909b
--- /dev/null
+++ b/src/gxhpng.c
@@ -0,0 +1,437 @@
+/* 
+ * include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+/* Rasterize current metafile buffer via gd library.  Loosly based
+   on the gxpng utility:
+
+   gxpng Copyright 1999 Matthias Muennich 
+
+   Has been modified to behave more like the X interface, so the
+   output image will look more like the screen image (B. Doty)
+
+   Modified for GD version 2 (B. Doty, 11/06) */
+
+#include "gd.h"
+
+gaint gxhpng (char *, gaint, gaint, gaint, gaint, char *, char *, gaint) ;
+void gxgdpoly (gaint, gaint, gaint);
+void gaprnt (gaint, char *);
+
+/* default size of the graph */
+
+#define SX 800
+#define SY 600
+
+static char pout[256];   /* Build error msgs here */
+static gdImagePtr im;
+static gdPoint xxyy[256];
+
+/* rgb values for 16 defined colors */
+/* these exactly match what's in gxX.c so that the graphical display 
+   and the printim output look the same */
+static gaint 
+ rr[16]={0,255,250,  0, 30,  0,240,230,240,160,160,  0,230,  0,130,170},
+ gg[16]={0,255, 60,220, 60,200,  0,220,130,  0,230,160,175,210,  0,170},
+ bb[16]={0,255, 60,  0,255,200,130, 50, 40,200, 50,255, 45,140,220,170};
+
+gaint gxhpng (char *fnout, gaint xin, gaint yin, gaint bwin, gaint gifflg, 
+	    char *bgImage, char *fgImage, gaint tcolor) {
+FILE *ofile, *bgfile, *fgfile;
+gdPoint *xybuf=NULL;
+gdImagePtr imfg, imbg=0;
+float xlo,xhi,ylo,yhi;
+gaint xpos,ypos,xs,ys,xrs,yrs;
+gaint cmd,i,len,cnt,flag,ii,siz,xp,yp,xp2,yp2,thck,backbw;
+gaint ccol,fflag,xyc=0,red,grn,blu,xcur,ycur,xsav,ysav,retcod;
+gaint cdef[256],cnum[256],rc[256],gc[256],bc[256]; 
+gaint xycnt=0,xyflag,gdthck;
+short *poi,*pend;
+
+  im = NULL;
+
+  if (bwin<-900) backbw = gxdbkq();
+  else backbw = bwin;
+
+  for (i=0; i<=255; i++) {
+    cdef[i]=0;
+    rc[i] = 125; gc[i] = 125; bc[i] = 125;  /* initialize colors */
+  }
+  for (i=0; i<16; i++) { 
+    rc[i] = rr[i]; gc[i] = gg[i]; bc[i] = bb[i];
+  }
+
+  /*  Set up pointers into current meta buffer list */
+
+  if (dbmode && pntf==0) {
+    lens2[pnt2-1] = hpnt-hbuff;
+    cnt = pnt2; flag = 1;
+  } else {
+    lens[pnt-1] = hpnt-hbuff;
+    cnt = pnt; flag = 0;
+  }
+
+  /*  Allocate the gd image and set up the scaling for it */
+
+  if (xin<0 || yin<0) {  
+    /* user has not specified image size */
+    if (xrsize > yrsize) {
+      xs = SX; 
+      ys = (gaint)((yrsize/xrsize)*SX);
+    }
+    else {
+      xs = (gaint)((xrsize/yrsize)*SX); 
+      ys = SX;
+    }
+  } 
+  else {
+    xs = xin; 
+    ys = yin;
+  }
+  xrs = (gaint)(xrsize*1000.0+0.5);
+  yrs = (gaint)(yrsize*1000.0+0.5);
+
+  /* handle background PNG picture */
+  if (*bgImage) {
+    /* Make sure bgImage is a .png -- otherwise return error */
+    len = 0;
+    while (*(bgImage+len)) len++;
+    len = len-4;
+    if (len>0) {
+      if (*(bgImage+len+1)!='p' || 
+	  *(bgImage+len+2)!='n' || 
+	  *(bgImage+len+3)!='g' ) {
+	if (*(bgImage+len+1)!='P' || 
+	    *(bgImage+len+2)!='N' || 
+	    *(bgImage+len+3)!='G' ) {
+	  return(5);
+	} 
+      }
+    }
+
+    if ((bgfile=fopen(bgImage,"rb"))) {
+      if ((im=gdImageCreateFromPng(bgfile)) != NULL) {
+	if (im->sx < xs || im->sy < ys) {
+	  gdImageDestroy(im);
+	  im=NULL;
+	}
+      } else {
+	fclose(bgfile);
+	return(7);
+      }
+      fclose(bgfile);
+    } else {
+      return(3);
+    }
+  }
+
+  if (!im) {
+    /* im = gdImageCreateTrueColor(xs,ys);  For anti-aliasing */
+    im = gdImageCreate(xs,ys);
+  }
+
+  /*  Set up background and foreground colors */
+  if (backbw) {
+    cnum[0] = gdImageColorAllocate(im, 255, 255, 255);
+    cnum[1] = gdImageColorAllocate(im, 0, 0, 0);
+  } else {
+    cnum[0] = gdImageColorAllocate(im, 0, 0, 0);
+    cnum[1] = gdImageColorAllocate(im, 255, 255, 255);
+  }
+  cdef[0] = 1; cdef[1] = 1;
+  ccol = 1;
+
+  /* Loop thru allocated meta buffers and handle the graphics commands found there */
+  fflag = 0;
+  xyflag = 0;
+  gdthck = 1;
+  for (ii=0; ii<cnt; ii++) {
+    if (flag) {
+      poi = bufs2[ii];
+      pend = poi + lens2[ii];
+    } else { 
+      poi = bufs[ii];
+      pend = poi + lens[ii];
+    } 
+
+    while (poi<pend) {
+      /* Get message type */
+      cmd = *poi; 
+
+      /* Handle various message types */
+      /* -9 is end of file.  Should not happen. */
+      if (cmd==-9) {
+        gaprnt(0,"Logic Error 4 in gxhpng.  Notify Developer\n");
+        return(99);
+      }
+
+      /*  -1 indicates start of file.  Should not ocurr. */
+      else if (cmd==-1) {
+        gaprnt(0,"Logic Error 8 in gxhpng.  Notify Developer\n");
+        return(99);
+      }
+
+      /* -2 indicates new frame.  Also should not ocurr */
+      else if (cmd==-2) {
+        gaprnt(0,"Logic Error 12 in gxhpng.  Notify Developer\n");
+        return(99);
+      }
+
+      /* -3 indicates new color.  One arg; color number.  */
+      /*  Allocate in gd if not done already */
+      else if (cmd==-3) {
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt=0; }
+        ccol = *(poi+1);
+        if (ccol<0) ccol=0;
+        if (cdef[ccol]==0) {
+          cnum[ccol] = gdImageColorAllocate(im, rc[ccol], gc[ccol], bc[ccol]);
+          cdef[ccol] = 1;
+        }
+        poi += 2;
+      }
+
+      /* -4 indicates new line thickness.  It has two arguments */
+      else if (cmd==-4) {
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        thck = *(poi+2);
+        gdthck = 1;
+        if (thck>5) gdthck = 2;
+        if (thck>11) gdthck = 3;
+        poi += 3;
+      }
+
+      /*  -5 defines a new color, in rgb.  It has four int args */
+      /*  If this changes the existing definition for this color, 
+          then indicate this has not yet been allocated to gd */
+      else if (cmd==-5){
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        i = *(poi+1);
+        red = *(poi+2);
+        grn = *(poi+3);
+        blu = *(poi+4);
+        if (rc[i]!=red || gc[i]!=grn || bc[i]!=blu) {
+          rc[i] = red; gc[i] = grn; bc[i] = blu;
+          cdef[i] = 0;
+        }
+        poi += 5;
+      }
+
+      /* -6 is for a filled rectangle.  It has four float args. */ 
+      else if (cmd==-6){
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        xlo = *(poi+1); ylo = *(poi+3);
+        xhi = *(poi+2); yhi = *(poi+4);
+        xp = (xlo*xs)/xrs;
+        yp = ys-(ylo*ys)/yrs;
+        xp2 = (xhi*xs)/xrs;
+        yp2 = ys-(yhi*ys)/yrs;
+        if (xp>xp2) { 
+           i = xp;
+           xp = xp2;
+           xp2 = i;
+        }
+        if (yp>yp2) { 
+           i = yp;
+           yp = yp2;
+           yp2 = i;
+        }
+        gdImageFilledRectangle(im, xp, yp, xp2, yp2, cnum[ccol]);
+        poi += 5;
+      }
+
+      /* -7 indicates the start of a polygon fill.  It has one arg. */
+      else if (cmd==-7){
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        siz = *(poi+1);
+        xybuf = (gdPoint *)malloc(sizeof(gdPoint)*(siz+1));
+        if (xybuf==NULL) {
+          gaprnt(0,"Memory allocation error: gxhpng\n");
+          return(99);
+        }
+        fflag = 1;
+        xyc = 0;
+        poi += 2;
+      }
+
+      /* -8 is to terminate polygon fill.  It has no args */
+      else if (cmd==-8) {
+        if (xybuf->x != (xybuf+xyc-1)->x ||
+            xybuf->y != (xybuf+xyc-1)->y) {
+          (xybuf+xyc)->x = xybuf->x;
+          (xybuf+xyc)->y = xybuf->y;
+          xyc++;
+        }
+        gdImageFilledPolygon(im, xybuf, xyc, cnum[ccol]); 
+        free (xybuf);
+        fflag = 0;
+        poi += 1;
+      }
+
+      /* -10 is a move to instruction.  It has two float args */ 
+      else if (cmd==-10){
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        xpos = *(poi+1); ypos = *(poi+2);
+        xsav = (xpos*xs)/xrs;
+        ysav = ys-(ypos*ys)/yrs;
+        if (fflag) {
+          (xybuf+xyc)->x = xsav;
+          (xybuf+xyc)->y = ysav;
+          xyc++;
+        } else {   
+          xxyy[0].x = xsav;
+          xxyy[0].y = ysav;
+          xycnt = 1;
+          xyflag = 0;
+        }
+        poi += 3;
+      }
+
+      /*  -11 is draw to.  It has two float args. */  
+      else if (cmd==-11){
+        xpos = *(poi+1); ypos = *(poi+2);
+        xcur = (xpos*xs)/xrs;
+        ycur = ys-(ypos*ys)/yrs;
+        if (fflag) {    /* Assume first poly point is moveto */
+          if ((xybuf+xyc-1)->x != xcur || (xybuf+xyc-1)->y != ycur) { 
+            (xybuf+xyc)->x = xcur;
+            (xybuf+xyc)->y = ycur;
+            xyc++;
+          }
+        } else {
+          xxyy[xycnt].x = xcur;
+          xxyy[xycnt].y = ycur;
+          if (xycnt<255) xycnt++;
+          else {
+            gxgdpoly(xycnt+1,cnum[ccol],gdthck);
+            xxyy[0].x = xcur;
+            xxyy[0].y = ycur;
+            xycnt = 1; 
+          }
+          xyflag = 1;
+        }
+        xsav = xcur; ysav = ycur;
+        poi += 3;
+      }
+
+      /* -12 indicates new fill pattern.  We ignore it here */
+      else if (cmd==-12) {
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        poi += 4;
+      }
+
+      /* -20 is a draw widget.  We ignore it here. */
+      else if (cmd==-20) {
+        if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+        poi += 2;
+      }
+
+      /* Any other command would be invalid */
+      else {
+        gaprnt(0,"Logic Error 20 in gxhpng.  Notify Developer\n");
+        return(99);
+      }
+    }
+  }
+  if (xyflag) { gxgdpoly(xycnt,cnum[ccol],gdthck); xyflag=0; xycnt = 0; }
+
+  /* handle foreground PNG picture */
+  if (*fgImage) {
+    /* Make sure fgImage is a .png -- otherwise return error */
+    len = 0;
+    while (*(fgImage+len)) len++;
+    len = len-4;
+    if (len>0) {
+      if (*(fgImage+len+1)!='p' || 
+	  *(fgImage+len+2)!='n' || 
+	  *(fgImage+len+3)!='g' ) {
+	if (*(fgImage+len+1)!='P' || 
+	    *(fgImage+len+2)!='N' || 
+	    *(fgImage+len+3)!='G' ) {
+	  return(6);
+	} 
+      }
+    }
+
+    if ((fgfile=fopen(fgImage,"rb"))) {
+      if ((imfg=gdImageCreateFromPng(fgfile)) !=NULL) {
+	gdImageCopy(im,imfg,0,0,0,0,imfg->sx,imfg->sy);
+      }
+      else {
+	fclose(fgfile);
+	return(8);
+      }
+    } else {
+      return(4);
+    }
+    fclose(fgfile);
+    gdImageDestroy(imfg);
+  }
+
+
+  retcod = 0;
+  /* optionally convert a color to transparent */
+  if (tcolor != -1 ) {
+    if (cdef[tcolor]){
+      gdImageColorTransparent(im,cnum[tcolor]);
+      snprintf(pout,255,"Transparent color: #%d\n",tcolor);
+      gaprnt(2,pout);
+    }
+  }
+  if (*bgImage) {
+    if ((bgfile=fopen(bgImage,"rb"))) {
+      if ((imbg=gdImageCreateFromPng(bgfile)) !=NULL) {
+	gdImageCopy(imbg,im,0,0,0,0,im->sx,im->sy);
+      }
+    }
+    fclose(bgfile);
+    gdImageDestroy(im);
+    im=imbg;
+  }
+
+  ofile = fopen(fnout, "wb");
+  if (ofile==NULL) { 
+    snprintf(pout,255,"Open error on %s\n",fnout);
+    gaprnt(0,pout);
+    retcod = 1; 
+  } else {
+    if (gifflg==1) {                    /* image output in gif format */
+      gdImageGif (im, ofile);
+    }
+    else if (gifflg==3) {     	  /* image output in jpg format */
+      gdImageJpeg(im, ofile, -1);
+    }
+    else {                       	  /* image output in png format */
+      gdImagePng(im, ofile);
+    }
+    fclose(ofile);
+  }
+
+  gdImageDestroy(im);
+  return (retcod);
+}
+
+/* Turns out that the anti-aliasing doesn't work with
+   the line thickness, in gd-v2.  Decided to not use
+   the anti-aliasing this version.  But kept the 
+   function calls here, commented out, for possible
+   future use.  */
+
+void gxgdpoly (gaint xycnt, gaint col, gaint thck) {
+  if (xycnt==2) {
+/*     gdImageSetAntiAliased(im,col); */
+     gdImageSetThickness(im,thck);
+/*     gdImageLine(im, xxyy[0].x, xxyy[0].y, xxyy[1].x, xxyy[1].y, gdAntiAliased); */
+     gdImageLine(im, xxyy[0].x, xxyy[0].y, xxyy[1].x, xxyy[1].y, col);
+  }
+  if (xycnt>2) {
+/*    gdImageSetAntiAliased(im,col); */
+    gdImageSetThickness(im,thck);
+/*    gdImageOpenPolygon(im, xxyy, xycnt, gdAntiAliased); */
+    gdImageOpenPolygon(im, xxyy, xycnt, col);
+  }
+}
+
diff --git a/src/gxmap.h b/src/gxmap.h
new file mode 100644
index 0000000..ed38db0
--- /dev/null
+++ b/src/gxmap.h
@@ -0,0 +1,11 @@
+/*  If map data sets change, these constants also change */
+
+static int hcntt[4] = {57995,13355,57661,21047};
+static int hcntg[4] = {51553,10937,44497,18415};
+static int hpos[4] = {0, 231980, 285400, 516040};
+static int mcntt[4] = {8591,2135,8553,3199};
+static int mcntg[4] = {7400,1771,6390,2767};
+static int mpos[4] = {0, 34364, 42904, 77116};
+static int lcntt[4] = {2895,872,3021,1573};
+static int lpos[4] = {0,11580,15068,27152};
+
diff --git a/src/gxmeta.c b/src/gxmeta.c
new file mode 100644
index 0000000..2bd2d4c
--- /dev/null
+++ b/src/gxmeta.c
@@ -0,0 +1,686 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Routines related to hardcopy (metafile) output. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "gatypes.h"
+#include "gx.h"
+
+static gaint bopt=BUFOPT;                   /* Buffering option   */
+static long buffsz;                         /* metafile buffer size, formerly known as HBUFSZ */
+static gaint bflag;                         /* Buffering disabled */
+static gaint hflag;                         /* File output enabled*/
+static gaint herr;                          /* Fatal error        */
+static gaint hferr;                         /* File I/O error     */
+static gaint hpflg;                         /* User printed frame */
+static short *hbuff, *hpnt, *hend;          /* Current buffer ptrs*/
+static FILE *hfile;                         /* meta file pointer  */
+static gaint hpos;                          /* Frame pos in metafi*/
+static short *bufs[250];                    /* Buffer stuff       */
+static short *bufs2[250];                   /* Enough for 50MB    */
+static gaint lens[250],lens2[250];
+static gaint pnt,pnt2,pntf;     
+static gaint dbmode;                        /* Double Buffer mode */
+static gadouble xrsize,yrsize;
+
+void xycnv (short, short, gadouble *, gadouble *);
+
+/* Specify on startup what sort of buffering we want.  
+   We can do memory buffering (the default on UNIX machines) 
+   or file buffering, done only when print is enabled */
+
+void gxhopt (gaint flag) {
+  bopt = flag;
+}
+
+/* Initialize any buffering, etc. when GrADS starts up */
+
+void gxhnew (gadouble xsiz, gadouble ysiz, gaint hbufsz) {
+  buffsz = hbufsz;
+  xrsize = xsiz;
+  yrsize = ysiz;
+  hflag = 0; 
+  herr = 0;
+  hferr = 0;
+  hpflg = 0;
+  dbmode = 0;
+  if (bopt) bflag = 1;
+  else {
+    hbuff = (short *)malloc(sizeof(short)*buffsz);
+    if (hbuff==NULL) {
+      printf ("Unable to allocate memory for metafile operations.\n");
+      herr = 1;
+      bufs[0] = NULL;
+    } else {
+      bflag = 0;
+      pnt = 1;
+      bufs[0] = hbuff;
+      hpnt = hbuff;
+      hend = hbuff+(buffsz-10L);
+    }
+  }
+  pnt2 = 0;
+}
+
+/* Enable hardcopy (metafile) output.   */
+
+gaint gxhbgn (char *fname) {
+gaint xx,rc;
+short bb[3];
+
+  if (hferr) {
+    printf ("Metafile error state is positive.\n");
+    printf ("Disable Print before attempting an Enable Print.\n");
+    return (0);
+  }
+
+  /* Open metafile if not already open.  */
+
+  if (hflag) {
+    printf ("Metafile already open\n");
+    return(0);
+  }
+
+  hfile = fopen(fname,"wb");
+  if (hfile==NULL) {
+    printf ("Error opening meta file %s \n", fname);
+    return (1);
+  }
+
+  /* Allocate the memory buffer if we are doing file buffering.  */
+
+  if (bopt) {
+    hbuff = (short *)malloc(sizeof(short)*buffsz);
+    if (hbuff==NULL) {
+      printf ("Unable to allocate memory for metafile operations.\n");
+      fclose(hfile);
+      return (1);
+    }
+    hpnt = hbuff;
+    hend = hbuff+(buffsz-10L);
+    bflag = 0;
+  }
+
+  /* Write physical page size to output metafile */
+
+  bb[0] = -1;
+  xx = (gaint)(xrsize*1000.0+0.5);
+  if (xx<0) xx=0;
+  if (xx>32760) xx=32760;
+  bb[1] = xx;
+  xx = (gaint)(yrsize*1000.0+0.5);
+  if (xx<0) xx=0;
+  if (xx>32760) xx=32760;
+  bb[2] = xx;
+  rc = gxhwri(bb, 3);
+  if (rc) return (1);
+  hpos = ftell(hfile);
+  herr = 0;
+  hpflg = 0;
+  hferr = 0;
+  hflag = 1;
+  if (bopt) {
+    printf ("File buffering enabled. ");
+    printf ("Issue CLEAR command to start buffering.\n");
+  }
+  return (0);
+}
+
+/* Metafile output, command with 0 args */
+
+void hout0 (gaint cmd) {
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus one integer argument */
+
+void hout1 (gaint cmd, gaint opt) {
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  *hpnt = opt;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus two double args */
+
+void hout2 (gaint cmd, gadouble x, gadouble y) {
+gaint xx,yy;
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  xx = (gaint)(x*1000.0+0.5);
+  if (xx<0) xx=0;
+  if (xx>32760) xx=32760;
+  *hpnt = xx;
+  hpnt++;
+  yy = (gaint)(y*1000.0+0.5);
+  if (yy<0) yy=0;
+  if (yy>32760) yy=32760;
+  *hpnt = yy;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus two integer args */
+
+void hout2i (gaint cmd, gaint i1, gaint i2) {
+
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  *hpnt = i1;
+  hpnt++;
+  *hpnt = i2;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus three integer args */
+
+void hout3i (gaint cmd, gaint i1, gaint i2, gaint i3) {
+
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  *hpnt = i1;
+  hpnt++;
+  *hpnt = i2;
+  hpnt++;
+  *hpnt = i3;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus four integer args */
+
+void hout4i (gaint cmd, gaint i1, gaint i2, gaint i3, gaint i4) {
+
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  *hpnt = i1;
+  hpnt++;
+  *hpnt = i2;
+  hpnt++;
+  *hpnt = i3;
+  hpnt++;
+  *hpnt = i4;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Metafile output, command plus four double args */
+
+void hout4 (gaint cmd, gadouble xl, gadouble xh, gadouble yl, gadouble yh) {
+gaint vv;
+  if (bflag||herr) return;
+  *hpnt = cmd;
+  hpnt++;
+  vv = (gaint)(xl*1000.0+0.5);
+  if (vv<0) vv=0;
+  if (vv>32760) vv=32760;
+  *hpnt = vv;
+  hpnt++;
+  vv = (gaint)(xh*1000.0+0.5);
+  if (vv<0) vv=0;
+  if (vv>32760) vv=32760;
+  *hpnt = vv;
+  hpnt++;
+  vv = (gaint)(yl*1000.0+0.5);
+  if (vv<0) vv=0;
+  if (vv>32760) vv=32760;
+  *hpnt = vv;
+  hpnt++;
+  vv = (gaint)(yh*1000.0+0.5);
+  if (vv<0) vv=0;
+  if (vv>32760) vv=32760;
+  *hpnt = vv;
+  hpnt++;
+  if (hpnt>hend) hfull();
+}
+
+/* Handle situation where memory buffer is full.  Either output
+   to the temporary file buffer, or disable additional input
+   into the memory buffer. */
+
+void hfull (void) {
+gaint len,rc;
+
+  if (bopt) {
+    len = hpnt - hbuff;
+    rc = gxhwri(hbuff, len);
+    if (rc) return;
+    else hpnt = hbuff;
+  } else {
+    if (dbmode && pntf==1) {
+      lens2[pnt2-1] = hpnt-hbuff;
+      if (pnt2>249) {
+        printf ("Out of buffer space\n");
+        herr=1;
+        return;
+      }
+      hbuff = (short *)malloc(sizeof(short)*buffsz);
+      if (hbuff==NULL) {
+        printf ("Memory allocation error for metafile buffers.\n");
+        herr = 1;
+      } else {
+        bufs2[pnt2] = hbuff;
+        hpnt = hbuff;
+        hend = hbuff+(buffsz-10L);
+        pnt2++;
+      } 
+    } else {
+      if (pnt>249) {
+        printf ("Out of buffer space\n");
+        herr=1;
+        return;
+      }
+      lens[pnt-1] = hpnt-hbuff;
+      hbuff = (short *)malloc(sizeof(short)*buffsz);
+      if (hbuff==NULL) {
+        printf ("Memory allocation error for metafile buffers.\n");
+        herr = 1;
+      } else {
+        bufs[pnt] = hbuff;
+        hpnt = hbuff;
+        hend = hbuff+(buffsz-10L);
+        pnt++;
+      } 
+    }
+  }
+}
+
+/* Output the current frame to the metafile.   Empty the metafile
+   buffer, and set things so that the frame will be marked on a
+   frame action.
+
+   If no metafile is open, write an EPS file by calling gxheps.
+*/
+
+void gxhprt (char *cmd) {
+gaint len,i,rc;
+
+  if (bopt && dbmode) {
+    printf ("Cannot print while in double-buffer mode ");
+    printf ("when using file buffering\n");
+    return;
+  }
+#ifndef STNDALN
+  if(!hflag) { /* No metafile open write a EPS file using gxeps */
+    gxheps(cmd);
+    return;
+  }
+#endif
+  if (herr||hferr) {
+    printf ("Error status on print metafile is positive.\n");
+    printf ("Cannot print current frame.\n");
+    return;
+  }
+  if (!hflag) {
+    printf ("Metafile not currently open\n");
+    return;
+  }
+  if (bopt) {
+    len = hpnt - hbuff;
+    rc = gxhwri(hbuff,len);
+    if (rc) return;
+    else hpnt = hbuff;
+  } else {
+    if (dbmode && pntf==0) {
+      i = 0;
+      while (i<pnt2) {
+        rc = gxhwri(bufs2[i],lens2[i]);
+        if (rc) return;
+        i++;
+      }
+    } else {
+      if (!dbmode) lens[pnt-1] = hpnt-hbuff;
+      i = 0;
+      while (i<pnt) {
+        rc = gxhwri(bufs[i],lens[i]);
+        if (rc) return;
+        i++;
+      }
+    }
+  }
+  hpflg = 1;
+  hpos = ftell(hfile);
+  return;
+}
+
+/* Write to output metafile */ 
+
+gaint gxhwri (void *buf, gaint len) {
+/* kk 020624 --- s */
+/*  if (len>0) fwrite (buf, sizeof(short), len, hfile); */
+  if (len>0) fwrite (buf, sizeof(short)*len, 1, hfile);
+/* kk 020624 --- e */
+  if (ferror(hfile)) {
+    printf ("I/O Error writing to print metafile.\n");
+    fclose(hfile);
+    hferr = 1;
+    hflag = 0;
+    hpflg = 0;
+    if (bopt) {
+      free(hbuff);
+      herr = 1;
+      bflag = 1;
+    }
+    return (1);
+  }
+  return (0);
+}
+
+/* Close the metafile output file without further output */
+
+void gxhend (void) {
+short bb[2];
+gaint rc;
+  if (hferr) {
+    printf ("Resetting print metafile error status.\n");
+    hferr = 0;
+    if (bopt) herr = 0;
+    return;
+  }
+  if (!hflag) {
+    printf ("No hardcopy metafile open\n");
+    return;
+  }
+  fseek(hfile,hpos,0L);
+  if (hpflg) {
+    bb[0] = -2;
+    bb[1] = -9;
+    rc = gxhwri(bb,2);
+  } else {
+    bb[0] = -9;
+    rc = gxhwri(bb,1);
+  }
+  if (!rc) {
+    fclose(hfile);
+    printf ("Hardcopy output file is closed \n");
+    hflag = 0;
+    if (bopt) {
+      free(hbuff);
+      bflag = 1;
+    }
+  }
+}
+
+/* User has issued a clear.  Mark an end of frame if needed in
+   the output file; free buffers if we are in memory buffering
+   mode */
+
+void gxhfrm (gaint iact) {
+short bb;
+gaint rc,i;
+
+  if (hflag) {
+    fseek(hfile,hpos,0L);
+    if (hpflg) {
+      bb = -2;
+      rc = gxhwri(&bb, 1);
+      hpflg = 0;
+      if (!rc) hpos = ftell(hfile);
+    }
+  }
+  if (iact==2 && dbmode==0) {
+    dbmode = 1;
+    if (bopt==0) {
+      hbuff = (short *)malloc(sizeof(short)*buffsz);
+      if (hbuff==NULL) {
+        printf ("Memory allocation error for metafile buffers.\n");
+        herr = 1;
+        pnt2 = 0;
+        bufs2[0] = NULL;
+      } else {
+        pnt2 = 1;
+        pntf = 1;
+        bufs2[0] = hbuff;
+      } 
+    }
+  }
+  if (iact!=2 && dbmode==1) {
+    dbmode = 0;
+    if (bopt==0) {
+      for (i=0; i<pnt2; i++) free(bufs2[i]);
+      pnt2 = 0;
+    }
+  }
+  if (bopt==0) {
+    if (dbmode) {
+      if (pntf==0) {
+        lens[pnt-1] = hpnt-hbuff;
+        for (i=1; i<pnt2; i++) free(bufs2[i]);   
+        pntf = 1;
+        pnt2 = 1;
+        hbuff = bufs2[0];
+        hpnt = hbuff;
+        hend = hbuff+(buffsz-10L);
+      } else {
+        lens2[pnt2-1] = hpnt-hbuff;
+        for (i=1; i<pnt; i++) free(bufs[i]);   
+        pntf = 0;
+        pnt = 1;
+        hbuff = bufs[0];
+        hpnt = hbuff;
+        hend = hbuff+(buffsz-10L);
+      }
+    } else {
+      for (i=1; i<pnt; i++) {
+        free(bufs[i]);
+      }
+      pnt = 1;
+      hbuff = bufs[0];
+      hpnt = hbuff;
+      hend = hbuff+(buffsz-10L);
+    }
+    if (herr && bufs[0] && !dbmode) herr = 0;
+  } else hpnt = hbuff;
+}
+
+/* Redraw based on contents of current buffers */
+
+void gxhdrw (gaint dbflg) {
+short *poi,*pend;
+gaint cmd, i, cnt, flag, ii, siz;
+gaint lcolor,fflag,xyc=0;
+gadouble xlo,xhi,ylo,yhi,xpos,ypos,*xybuf=NULL;
+
+  if (dbflg && !dbmode) {
+    printf ("Logic error 0 in Redraw.  Contact Developer.\n");
+    return;
+  }
+
+  if (dbmode && pntf==1) {
+    lens2[pnt2-1] = hpnt-hbuff;
+    cnt = pnt2; flag = 1;
+    if (dbflg) {cnt = pnt; flag = 0;}
+  } else {
+    lens[pnt-1] = hpnt-hbuff;
+    cnt = pnt; flag = 0;
+    if (dbflg) {cnt = pnt2; flag = 1;}
+  }
+
+  gxsfrm ();
+  fflag = 0;
+
+  for (ii=0; ii<cnt; ii++) {
+    if (flag) {
+      poi = bufs2[ii];
+      pend = poi + lens2[ii];
+    } else { 
+      poi = bufs[ii];
+      pend = poi + lens[ii];
+    } 
+    
+    while (poi<pend) {
+
+      /* Get message type */
+
+      cmd = *poi; 
+
+      /* Handle various message types */
+      /* -9 is end of file.  Should not happen. */
+
+      if (cmd==-9) {
+        printf ("Logic Error 4 in Redraw.  Notify Developer\n");
+        return;
+      }
+
+      /*  -1 indicates start of file.  Should not ocurr. */
+
+      else if (cmd==-1) {
+        printf ("Logic Error 8 in Redraw.  Notify Developer\n");
+        return;
+      }
+  
+      /* -2 indicates new frame.  Also should not ocurr */
+
+      else if (cmd==-2) {
+        printf ("Logic Error 12 in Redraw.  Notify Developer\n");
+        return;
+      }
+
+      /* -3 indicates new color.  One arg; color number.  */
+  
+      else if (cmd==-3) {
+        lcolor = *(poi+1);
+        gxdcol (lcolor);
+        poi += 2;
+      }
+
+      /* -4 indicates new line thickness.  It has two arguments */
+ 
+      else if (cmd==-4) {
+        i = *(poi+2);
+        gxdwid(i);
+        poi += 3;
+      }
+
+      /*  -5 defines a new color, in rgb.  It has four int args */
+
+      else if (cmd==-5){
+        gxdacl ((gaint)*(poi+1),(gaint)*(poi+2),(gaint)*(poi+3),(gaint)*(poi+4));
+        poi += 5;
+      }
+
+      /* -6 is for a filled rectangle.  It has four args. */ 
+ 
+      else if (cmd==-6){
+        xycnv (*(poi+1),*(poi+3),&xlo,&ylo);
+        xycnv (*(poi+2),*(poi+4),&xhi,&yhi);
+        gxdrec(xlo,xhi,ylo,yhi);
+        poi += 5;
+      }
+
+      /* -7 indicates the start of a polygon fill.  It has one arg. */
+
+      else if (cmd==-7){
+        siz = *(poi+1);
+        xybuf = (gadouble *)malloc(sizeof(gadouble)*siz*2);
+        if (xybuf==NULL) {
+          printf ("Memory allocation error: Redraw\n");
+          return;
+        }
+        fflag = 1;
+        xyc = 0;
+        poi += 2;
+      }
+
+      /* -8 is to terminate polygon fill.  It has no args */
+
+      else if (cmd==-8){
+        gxdfil (xybuf,xyc);
+        if (xybuf==NULL) {
+          printf ("Logic Error 16 in Redraw.  Notify Developer\n");
+          return;
+        } else free (xybuf);
+        fflag = 0;
+        poi += 1;
+      }
+
+      /* -10 is a move to instruction.  It has two double args */ 
+
+      else if (cmd==-10){
+        xycnv (*(poi+1),*(poi+2),&xpos,&ypos);
+        if (fflag) {
+          *(xybuf+xyc*2) = xpos;
+          *(xybuf+xyc*2+1) = ypos;
+          xyc++;
+        } else gxdmov(xpos,ypos);
+        poi += 3;
+      }
+
+      /*  -11 is draw to.  It has two double args. */  
+        
+      else if (cmd==-11){
+        xycnv (*(poi+1),*(poi+2),&xpos,&ypos);
+        if (fflag) {
+          xybuf[xyc*2] = xpos;
+          xybuf[xyc*2+1] = ypos;
+          xyc++;
+        } else gxddrw(xpos,ypos);
+        poi += 3;
+      }
+
+      /* -12 indicates new fill pattern.  It has three arguments. */
+ 
+      else if (cmd==-12) {
+        gxdptn ((gaint)*(poi+1),(gaint)*(poi+2),(gaint)*(poi+3));
+        poi += 4;
+      }
+
+      /* -20 is a draw widget.  We will redraw it in current state. */
+
+      else if (cmd==-20) {
+        gxdpbn ((gaint)*(poi+1),NULL,1,0,-1);
+        poi += 2;
+      }
+
+      /* Any other command would be invalid */
+
+      else {
+        printf ("Logic Error 20 in Redraw.  Notify Developer\n");
+        return;
+      }
+    }
+  }
+}
+
+void xycnv (short ix, short iy, gadouble *x, gadouble *y) {
+
+  *x = ((gadouble)ix)/1000.0;
+  *y = ((gadouble)iy)/1000.0;
+}
+
+#if GXPNG==1
+#include "gxhpng.c"
+#endif
+
+#ifndef STNDALN
+#  define GXHEPS
+#  include "gxeps.c"
+#endif
diff --git a/src/gxps.c b/src/gxps.c
new file mode 100644
index 0000000..f21e61b
--- /dev/null
+++ b/src/gxps.c
@@ -0,0 +1,635 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <math.h>
+
+
+int help=0;
+void command_line_help(void) ;
+
+char *valprs (char *, float *);
+
+char buff[132];
+int pnt;
+FILE *infile;
+FILE *outfile;
+int rotflg;
+
+void mycln (char *, int *);
+void chout (char *, int);
+void chend (void);
+int nxtcmd (char *, char *);
+void blkbck (void);
+void xycnv (short, short, float *, float *);
+void xycnva4 (short, short, float *, float *);
+
+float grey[256],red[256],green[256],blue[256];
+
+/* These values should match the RGB values in gxX.c and gxhpng.c and the documentation */
+float reds[16]   = {1.0, 0.0, 0.98, 0.00, 0.12, 0.00, 0.94, 0.90, 0.94, 0.63, 0.63, 0.00, 0.90, 0.00, 0.51, 0.67};
+float greens[16] = {1.0, 0.0, 0.24, 0.86, 0.24, 0.78, 0.00, 0.86, 0.51, 0.00, 0.90, 0.63, 0.69, 0.82, 0.00, 0.67};
+float blues[16]  = {1.0, 0.0, 0.24, 0.00, 1.00, 0.78, 0.51, 0.19, 0.16, 0.78, 0.19, 1.00, 0.18, 0.55, 0.86, 0.67};
+float greys[16]  = {1.0, 0.0, 0.16, 0.46, 0.70, 0.58, 0.10, 0.34, 0.22, 0.82, 0.40, 0.64, 0.28, 0.52, 0.76, 0.50};
+
+char *lwdesc[12] = {" 0.001 w",
+                    " 0.006 w",
+                    " 0.009 w",
+                    " 0.012 w",
+                    " 0.015 w",
+                    " 0.018 w",
+                    " 0.021 w",
+                    " 0.024 w",
+                    " 0.027 w",
+                    " 0.030 w",
+                    " 0.033 w",
+                    " 0.036 w"};
+
+static int rflag, cflag, dflag;
+static float bwide;
+
+int main (int argc, char *argv[])  {
+short opts[4];
+int cmd, i, j;
+char ch[201];
+int len, cont, iflag, oflag;
+int lcolor=0,lwide,sflag=0,fflag=0,fcnt,ccnt,filflg=0,scnt=0,a4flag,bdflag;
+float xlo,xhi,ylo,yhi,xpos,ypos,xsiz,ysiz;
+char in[256],out[256],*ifi,*ofi,ctld[2];
+
+  /* Initialize */
+
+  ctld[0] = (char)4;
+  ctld[1] = '\n';
+  for (i=0; i<=255; i++) {
+    grey[i] = -999.0;
+    red[i] = -999.0;
+    green[i] = -999.0;
+    blue[i] = -999.0;
+  }
+  for (i=0; i<16; i++) {
+    grey[i] = greys[i];
+    red[i] = reds[i];
+    green[i] = greens[i];
+    blue[i] = blues[i];
+  }
+
+  /* Parse command line arguments */
+
+  i = 1;
+  iflag = 0; oflag = 0;
+  cflag = 0; rflag = 0; dflag = 1;
+  a4flag = 0;
+  bwide = 0.5;
+  bdflag=0;
+
+  ifi = NULL; ofi = NULL;
+  while (i<argc) {
+    if (*(argv[i])=='-' && *(argv[i]+1)=='h' && *(argv[i]+2)=='e' && *(argv[i]+3)=='l' && *(argv[i]+4)=='p' ) {
+      command_line_help();
+      return(0);
+    } else if (*(argv[i])=='-') {
+      j = 1;
+      while (*(argv[i]+j)) {
+        if (*(argv[i]+j)=='i') iflag = 1;
+        else if (*(argv[i]+j)=='o') oflag = 1;
+        else if (*(argv[i]+j)=='c') cflag = 1;
+        else if (*(argv[i]+j)=='r') rflag = 1;
+        else if (*(argv[i]+j)=='a') a4flag = 1;
+        else if (*(argv[i]+j)=='d') dflag = 0;
+        else if (*(argv[i]+j)=='b') bdflag = 1;
+        else printf ("Unknown flag %c; ignored.\n",*(argv[i]+j));
+        j++;
+      }
+    } else {
+      if (iflag) {ifi = argv[i]; iflag = 0;}
+      else if (oflag) {ofi = argv[i]; oflag = 0;}
+      else if (bdflag)  {
+        if (valprs(argv[i],&bwide)==NULL) {
+          printf ("Invalid border width\n");
+          bwide = 0.5;
+        }
+      }
+      else printf ("Unknown argument: %s.  Ignored.\n",argv[i]);
+    }
+    i++;
+  }
+  if (ifi==NULL) {
+    command_line_help();
+    nxtcmd (in,"Enter input file: ");
+    ifi = in;
+  }
+  if (ofi==NULL) {
+    nxtcmd (out,"Enter output file: ");
+    ofi = out;
+  }
+
+  if (rflag) {
+    grey[0] = greys[1]; grey[1] = greys[0];
+    red[0] = reds[1]; red[1] = reds[0];
+    green[0] = greens[1]; green[1] = greens[0];
+    blue[0] = blues[1]; blue[1] = blues[0];
+  }
+
+  /* Open files */
+
+  infile = fopen(ifi,"rb");
+  if (infile == NULL) {
+    printf ("Input file does not exist: \n");
+    printf ("  %s\n",ifi);
+    return(1);
+  }
+  outfile = fopen(ofi,"wb");
+  if (outfile==NULL) {
+    printf ("Error opening output file: \n");
+    printf ("  %s\n",ofi);
+    return(1);
+  }
+
+  /* Translate the file */
+
+  pnt = 0;
+  fcnt = 0;
+
+  ccnt=0; 
+  cont = 1;
+  while (cont) {
+    fread (opts , sizeof(short), 1, infile);
+    cmd = opts[0];
+    ccnt++;
+    /* End of plotting */
+
+    if (cmd==-9) {
+      cont = 0;
+      chend();
+      if (fflag) {fwrite ("showpage\n",1,9,outfile); fcnt++;}
+      if (dflag) fwrite (ctld,1,2,outfile);
+      printf ("Number of frames = %i\n",fcnt);
+      fclose (outfile);
+    }
+
+    /* Start of plotting */
+
+    else if (cmd==-1) {
+      fread ((char *)opts, sizeof(short), 2, infile);
+      fwrite("%!\n",1,3,outfile);
+      fwrite("initgraphics 1 setlinecap 1 setlinejoin\n",1,40,outfile);
+      fwrite("72 72 scale\n",1,12,outfile);
+      fwrite("/m {moveto} def\n",1,16,outfile);
+      fwrite("/d {lineto} def\n",1,16,outfile);
+      fwrite("/c {setrgbcolor} def\n",1,21,outfile);
+      fwrite("/g {setgray} def\n",1,17,outfile);
+      fwrite("/n {newpath} def\n",1,17,outfile);
+      fwrite("/w {setlinewidth} def\n",1,22,outfile);
+      fwrite("/s {stroke} def\n",1,16,outfile);
+      fwrite("/f {fill} def\n",1,14,outfile);
+      blkbck();
+      chout(" 0 w",4);
+      xsiz = opts[0];
+      ysiz = opts[1];
+      rotflg=0;
+      if (ysiz>xsiz) rotflg=1;
+      fflag = 1;
+      sflag = 0;
+    }
+
+    /* New Page */
+
+    else if (cmd==-2) {
+      if (sflag) {chout(" s",2); sflag=0;}
+      chend();
+      fwrite ("gsave showpage\n",1,15,outfile);
+      fcnt++;
+      fflag = 0;
+    }
+
+    /* Set color */
+
+    else if (cmd==-3) {
+      if (!fflag) {
+        chout(" grestore",9);
+        blkbck();
+      }
+      if (sflag) {chout(" s",2); sflag=0;}
+      fread ((char *)opts, sizeof(short), 1, infile);
+      lcolor = opts[0];
+      if (lcolor<0) lcolor=0;
+      if (lcolor>255) lcolor=255;
+      if (cflag) {
+        if (red[lcolor]<-900.0) lcolor=15;
+        snprintf(ch,200," %.5g %.5g %.5g c",red[lcolor],green[lcolor],blue[lcolor]);
+      } else {
+        if (lcolor>0) snprintf(ch,200," %.5g g",grey[1]);
+        else snprintf(ch,200," %.5g g",grey[0]);
+      }
+      mycln(ch,&len);
+      chout(ch,len);
+      fflag = 1;
+    }
+
+    /* Set line width */
+
+    else if (cmd==-4) {
+      if (!fflag) {
+        chout(" grestore",9);
+        blkbck();
+      }
+      if (sflag) {chout(" s",2); sflag=0;}
+      fread ((char *)opts, sizeof(short), 2, infile);
+      i = opts[0];
+      if (i>12) i=12;
+      if (i<1) i=1;
+      chout(lwdesc[i-1],8);
+      lwide = i;
+      fflag = 1;
+    }
+
+    /* Define new color (mapped into grey scale via green intensity) */
+
+    else if (cmd==-5){
+      fread ((char *)opts, sizeof(short), 4, infile);
+      i = opts[0];
+      if (i>15 && i<=255) {
+        if (cflag) {
+          red[i] = ((float)opts[1])/255.0;
+          green[i] = ((float)opts[2])/255.0;
+          blue[i] = ((float)opts[3])/255.0;
+          if (red[i]<0.0) red[i]=0.0;
+          if (red[i]>1.0) red[i]=1.0;
+          if (green[i]<0.0) green[i]=0.0;
+          if (green[i]>1.0) green[i]=1.0;
+          if (blue[i]<0.0) blue[i]=0.0;
+          if (blue[i]>1.0) blue[i]=1.0;
+        } else {
+          grey[i] = ((float)(opts[2]))/255.0;
+          if (grey[i]<0.0) grey[i]=0.0;
+          if (grey[i]>1.0) grey[i]=1.0;
+          grey[i] = 1.0 - grey[i];
+        }
+      }
+    }
+
+    /* Rectangle fill */
+
+    else if (cmd==-6){
+      if (!fflag) {
+        chout(" grestore",9);
+        blkbck();
+      }
+      if (sflag) {chout(" s",2); sflag=0;}
+      fread ((char *)opts, sizeof(short), 4, infile);
+
+      if(a4flag) {
+	xycnva4 (opts[0],opts[2],&xlo,&ylo);
+	xycnva4 (opts[1],opts[3],&xhi,&yhi);
+      } else { 
+	xycnv (opts[0],opts[2],&xlo,&ylo);
+	xycnv (opts[1],opts[3],&xhi,&yhi);
+      }
+
+      if (!cflag) {
+        if (grey[lcolor]<-100.0) snprintf(ch,200," %.5g g",grey[15]);
+        else snprintf(ch,200," %.5g g",grey[lcolor]);
+        mycln(ch,&len);
+        chout(ch,len);
+      }
+      chout(" n",2);
+      snprintf(ch,200," %.5g %.5g m",xlo,ylo);
+      mycln(ch,&len);
+      chout(ch,len);
+      snprintf(ch,200," %.5g %.5g d",xhi,ylo);
+      mycln(ch,&len);
+      chout(ch,len);
+      snprintf(ch,200," %.5g %.5g d",xhi,yhi);
+      mycln(ch,&len);
+      chout(ch,len);
+      snprintf(ch,200," %.5g %.5g d",xlo,yhi);
+      mycln(ch,&len);
+      chout(ch,len);
+      snprintf(ch,200," %.5g %.5g d",xlo,ylo);
+      mycln(ch,&len);
+      chout(ch,len);
+      chout(" f",2);
+      if (!cflag) {
+        if (lcolor>0) snprintf(ch,200," %.5g g",grey[1]);
+        else snprintf(ch,200," %.5g g",grey[0]);
+        mycln(ch,&len);
+        chout(ch,len);
+      }
+      fflag = 1;
+    }
+
+    /* Start fill */
+
+    else if (cmd==-7){
+      fread ((char *)opts, sizeof(short), 1, infile);
+      if (!cflag) {
+        if (grey[lcolor]<-100.0) snprintf(ch,200," %.5g g",grey[15]);
+        else snprintf(ch,200," %.5g g",grey[lcolor]);
+        mycln(ch,&len);
+        chout(ch,len);
+      }
+      filflg = 1;
+      fflag = 1;
+    }
+
+    /* End fill */
+
+    else if (cmd==-8){
+      if (sflag) {chout(" f",2); sflag=0;}
+      if (!cflag) {
+        if (lcolor>0) snprintf(ch,200," %.5g g",grey[1]);
+        else snprintf(ch,200," %.5g g",grey[0]);
+        mycln(ch,&len);
+        chout(ch,len);
+      }
+      filflg = 0;
+      fflag = 1;
+    }
+
+    /* Move to */
+
+    else if (cmd==-10){
+      if (!fflag) {
+        chout(" grestore",9);
+        blkbck();
+      }
+      if (sflag) {chout(" s",2); sflag=0; scnt = 0;}
+      fread ((char *)opts, sizeof(short), 2, infile);
+      if(a4flag) {
+	xycnva4 (opts[0],opts[1],&xpos,&ypos);
+      } else { 
+	xycnv (opts[0],opts[1],&xpos,&ypos);
+      }
+
+      fflag = 1;
+    }
+
+    /* Draw to */
+
+    else if (cmd==-11){
+      if (!fflag) {
+        chout(" grestore",9);
+        blkbck();
+      }
+      fread (opts, sizeof(short), 2, infile);
+      if (!sflag) {
+        chout (" n",2);         
+        snprintf(ch,200," %.5g %.5g m",xpos,ypos);
+        mycln(ch,&len);
+        chout(ch,len);
+        scnt = 0;
+      }
+
+      if(a4flag) {
+	xycnva4 (opts[0],opts[1],&xpos,&ypos);
+      } else { 
+	xycnv (opts[0],opts[1],&xpos,&ypos);
+      }
+
+      if (scnt>511 && !filflg) {    /* Keep vector counts small */
+        snprintf(ch,200," %.5g %.5g d",xpos,ypos);
+        mycln(ch,&len);
+        chout(ch,len);
+        chout (" s n",4);
+        snprintf(ch,200," %.5g %.5g m",xpos,ypos);
+        mycln(ch,&len);
+        chout(ch,len);
+        scnt = 0;
+      }
+      snprintf(ch,200," %.5g %.5g d",xpos,ypos);
+      mycln(ch,&len);
+      chout(ch,len);
+      sflag = 1;
+      scnt++;
+      fflag = 1;
+    }
+    else if (cmd==-20) {       /* Draw button -- ignore */
+      fread ((char *)opts, sizeof(short), 1, infile);
+    }
+    else {
+      printf ("Invalid command found %i \n",cmd);
+      return(1);
+    }
+  }
+  return(0);
+}
+
+void blkbck () {
+  if (!rflag) return;
+  chout(" 0 0 0 c",8);
+  chout(" n 0 0 m 8.5 0 d",16);
+  chout(" 8.5 11 d",9);
+  chout(" 0 11 d",7);
+  chout(" 0 0 d f",8);
+}
+
+void mycln (char *ch, int *len) {
+int i,j,flag,cnt;
+  i = 0;
+  j = 0;
+  flag = 0;
+  cnt = 0;
+  while (ch[j]) {
+    ch[i] = ch[j];
+    if (flag) {
+      if (ch[j]<'0'||ch[j]>'9') {flag = 0; cnt=0;}
+      else cnt++;
+    }
+    if (ch[j]=='.') flag = 1;
+    if (flag&&cnt>3) j++;
+    else {i++; j++;}
+  }
+  *len = i;
+}
+
+void chout(char *ch, int len) {
+int i;
+
+  if (len+pnt>130) {
+    buff[pnt] = '\n';
+    pnt++;
+    fwrite (buff,1,pnt,outfile);
+    pnt = 0;
+  }
+  for (i=0; i<len; i++) {
+    buff[pnt] = *(ch+i);
+    pnt++;
+  }
+}
+
+void chend (void) {
+
+  buff[pnt] = '\n';
+  pnt++;
+  fwrite (buff,1,pnt,outfile);
+  pnt = 0;
+}
+
+int nxtcmd (char *cmd, char *prompt) {
+int past,cnt;
+
+  printf ("%s ",prompt);
+  past = 0;
+  cnt = 0;
+  while (1) {
+    *cmd = getchar();
+    if (*cmd == EOF) return (-1);
+    if (*cmd == '\n') {
+      *cmd = '\0';
+      return (cnt);
+    }
+    if (past || *cmd != ' ') {
+      cmd++; cnt++; past = 1;
+    }
+  }
+}
+
+void xycnv (short ix, short iy, float *x, float *y) {
+
+  if (rotflg) {
+    *x = ((float)ix)/1000.0;
+    *y = ((float)iy)/1000.0;
+  } else {
+    *x = 8.5 - ((float)iy)/1000.0;
+    *y = ((float)ix)*0.001;
+  }
+  *x = bwide + *x*((8.5-bwide*2.0)/8.5);
+  *y = bwide + *y*((11.0-bwide*2.0)/11.0);
+}
+
+/* To Mike
+     Now I finished the adjustment and test for A4 paper.
+                                              Thank you ! 
+                                    1995.10.19   H.Koide */
+
+void xycnva4 (short ix, short iy, float *x, float *y) {
+
+  if (rotflg) {
+    *x = ((float)ix)/1000.0;
+    *y = ((float)iy)/1025.6;
+  } else {
+    *x = 8.5 - ((float)iy)/1000.0;
+    *y = ((float)ix)/1025.6;
+  }
+  *x = bwide + *x*((8.5-bwide*2.0)/8.5);
+  *y = bwide + *y*((11.0-bwide*2.0)/11.0);
+}
+
+/* Parses a number in a character string.
+   This routine will detect numbers of the form:
+       nnnn
+       nnnn.fff
+       nnnn.fffExxx
+
+   Args:    ch     - pointer to the number, in character form.
+            val    - floating point value returned
+            return value  - address of 1st character past the
+                            number parsed.  NULL if no number found
+                            at pointer ch or if the number is an
+                            invalid format.
+             */
+
+char *valprs (char *ch, float *val) {
+
+int nflag,dflag,eflag,enflag,flag,cont;
+int pflag,epflag,evflag;
+float exp,dfp;
+int zip;
+
+  flag=0;
+  nflag=0;dflag=0;eflag=0;enflag=0;
+  pflag=0;epflag=0;evflag=0;
+  *val=0.0;exp=0.0;dfp=0.1;
+  zip='0';
+
+  cont=1;
+  while (cont) {
+
+    if (*ch>='0' && *ch<='9') {
+      if (!flag) flag=1;
+      if (eflag) {evflag=1; exp=(exp*10)+(*ch-zip);}
+      else if (dflag) { *val = *val+((*ch-zip)*dfp); dfp=dfp/10.0; }
+      else *val = (*val*10.0)+(*ch-zip);
+
+    } else if (*ch=='-') {
+      if (eflag&&!evflag) {
+        if (enflag) {cont=0; flag=0;}
+        enflag=1;
+      }
+      else if (!flag) {
+        if (nflag) {cont=0; flag=0;}
+        nflag=1;
+      } else cont=0;
+
+    } else if (*ch=='+') {
+      if (eflag&&!evflag) {
+        if (epflag) {cont=0; flag=0;}
+        epflag=1;
+      }
+      else if (!flag) {
+        if (pflag) {cont=0; flag=0;}
+        pflag=1;
+      } else cont=0;
+
+    } else if (*ch=='.') {
+      if (dflag||eflag) {cont=0;}
+      else dflag=1;
+
+    } else if (*ch=='e') {
+      if (eflag) {
+        cont=0;
+        if (!evflag) flag=0;
+      }
+      else if (flag) {eflag=1; dflag=0;}
+      else cont=0;
+
+    } else cont=0;
+
+    if (cont) ch++;
+  }
+
+  if (flag) {
+    if (nflag) *val = *val*(-1.0);
+    if (eflag) {
+      if (enflag) exp = exp*(-1.0);
+      *val = *val*(pow(10.0,exp));
+    }
+    return (ch);
+  } else return (NULL);
+
+}
+
+
+
+void command_line_help(void) {
+/*--- 
+  output command line options 
+---*/
+
+printf("gxps for GrADS Version " GRADS_VERSION "\n\n");
+printf("Convert GrADS meta files (from print command in grads) to postscript (level 1)\n\n");
+printf("Command line options: \n\n");
+printf("          -help   Just this help\n");
+printf("          -i      input GrADS meta file\n");
+printf("          -o      output postscript file\n");
+printf("          -c      color output (default is black and white)\n");
+printf("          -r      reverse background (typically black) default is white background\n");
+printf("          -b      border width in inches (default is 0.5)\n");
+printf("          -a      create ps suitable for A4 printers\n");
+printf("          -d      do NOT add ctrl-d to end of ps file (added for some HP printers, generally ignored)");
+printf("   Example:\n\n");
+printf("   gxps -b 0.10 -c -r -i myplot.gm -o myplot.ps\n\n");
+printf("   makes a color ps file with a black background and a border width plot of 0.10 inches\n\n");
+
+printf("\n");
+
+}
diff --git a/src/gxshad.c b/src/gxshad.c
new file mode 100644
index 0000000..b403752
--- /dev/null
+++ b/src/gxshad.c
@@ -0,0 +1,1323 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* This routine does shaded contour plots.   */
+
+#include <stdio.h>
+#include <math.h>
+#include "gatypes.h"
+#include "gx.h"
+
+void chksid(void);
+ 
+/* Common values for the shading routines.                           */
+
+#define XYBMAX 5000
+static gaint *flgh, *flgv;      /* Pointer to flags arrays                 */
+static gadouble *xystk[XYBMAX]; /* Pointers to xy stack buffers            */
+static gaint stkcnt;            /* Current number of stacked buffers       */
+static gadouble *xypnt;         /* Pointer into a stack buffer             */
+static gadouble *xybuf;         /* Pointer to xy coord buffer              */
+static gaint xycnt;             /* Current count in xy coord buffer        */
+static gaint imax, jmax;        /* grid size                               */
+static gaint imn,imx,jmn,jmx;   /* Current grid bounds                     */
+static gadouble *gr;            /* Pointer to grid                         */
+static char *gru;               /* Pointer to grid undef mask              */
+static gaint grsize;            /* Number of elements in grid              */
+static gaint color;             /* Current color to use for shading        */
+static gaint prvclr;            /* Color of one level lower                */
+static gadouble val;            /* Current shading level value             */
+static gaint bndflg;            /* Current coutour hit a boundry           */
+
+
+/* The grid r is shaded.  Size is by js.  lvs indicates the number of 
+   shaded levels.  vs contains the values bounding the shaded regions.
+   clrs contains lvs+1 colors for the shaded regions.  u is the
+   undefined grid data value.                                        */
+
+void gxshad (gadouble *r, gaint is, gaint js, gadouble *vs, gaint *clrs, gaint lvs, char *u) {
+gadouble *p1,*p2,*p3,*p4;
+gadouble x,y,rmin,rmax;
+gaint i, j, k, rc; 
+gaint *f1,*f2,*f3,*f4;
+char *p1u,*p2u,*p3u,*p4u;
+
+  /* Make some stuff global within this file     */
+  imax = is;
+  jmax = js;
+  gr = r; 
+  gru = u;
+
+  /* Initialize xy coord buffer and stack buffer setup.             */
+  stkcnt = 0;
+  for (i=0; i<XYBMAX; i++) xystk[i] = NULL;
+
+  grsize = is*js;
+  xybuf = (gadouble *)malloc(sizeof(gadouble)*grsize*2);
+  if (xybuf==NULL) {
+    printf ("Error in gxshad: Unable to allocate xy coord buffer\n");
+    return;
+  }
+  xycnt = 0;
+
+  /* Alocate flag work area.                                         */
+  flgh = (gaint *)malloc(grsize*sizeof(gaint));
+  flgv = (gaint *)malloc(grsize*sizeof(gaint));
+  if (flgh==NULL || flgv==NULL) {
+    printf ("Error in gxshad:  Unable to allocate flags buffer\n");
+    return;
+  }
+
+  /* Loop through bands of the grid.  Each band is three grid boxes
+     wide, which avoids any problems with imbedded max's within min's 
+     or with imbedded complex undefined regions.                     */
+  imn = 1;
+  imx = imax;
+  for (jmn=1; jmn<jmax; jmn+=3) {
+    jmx = jmn+3;
+    if (jmx>jmax) jmx=jmax;
+    
+    rmin = 9.99e33;
+    rmax = -9.99e33;
+    for (j=jmn; j<=jmx; j++) {
+      p1 = gr + ((j-1)*imax+imn-1);
+      p1u = gru + ((j-1)*imax+imn-1);
+      for (i=imn; i<=imx; i++) {
+        if (*p1u!=0) {
+          if (*p1>rmax) rmax = *p1;
+          if (*p1<rmin) rmin = *p1;
+        }
+        p1++; p1u++;      
+      }
+    }
+
+    /* Loop through shade levels.  */
+    prvclr = 0;
+    for (k=0; k<lvs; k++) {
+      val = vs[k];
+      color = clrs[k];
+      if (k<lvs-1 && vs[k+1]<rmin) {
+        prvclr = color;
+        continue;
+      }
+      if (val>rmax) continue;
+
+      /* Set up flags to indicate which grid boxes contain missing data values
+         and where the grid boundries are.  Flag values are:
+             0 - nothing yet
+             1 - contour has been drawn through this side
+             7 - contour drawn through missing data box side
+             8 - boundry between missing data value box and non-missing data value box
+             9 - missing data value box side                                             */
+      
+      f1 = flgh + ((jmn-1)*imax);
+      f4 = flgv + ((jmn-1)*imax);
+      for (j=jmn; j<=jmx; j++) {
+        for (i=1; i<=imax; i++) {
+         *f1 = 0; *f4 = 0;
+         f1++; f4++;
+        }
+      }
+  
+      for (j=jmn; j<jmx; j++) {
+        p1 = gr + ((j-1)*imax+imn-1);
+        p2 = p1+1;
+        p3 = p2+imax;
+        p4 = p1+imax;
+
+        p1u = gru + ((j-1)*imax+imn-1);
+        p2u = p1u+1;
+        p3u = p2u+imax;
+        p4u = p1u+imax;
+
+        f1 = flgh + ((j-1)*imax+imn-1);
+        f2 = flgv + ((j-1)*imax+imn);
+        f3 = f1 + imax;
+        f4 = f2 - 1;
+        for (i=imn; i<imx; i++) {
+          if (*p1u==0 || *p2u==0 || *p3u==0 || *p4u==0) {
+            *f1=9; *f2=9; *f3=9; *f4=9;
+          }
+          p1++; p2++; p3++; p4++; 
+          p1u++; p2u++; p3u++; p4u++; 
+          f1++; f2++; f3++; f4++;  
+        }
+      }
+
+      for (j=jmn; j<jmx; j++) {
+        p1 = gr + ((j-1)*imax+imn-1);
+        p2 = p1+1;
+        p3 = p2+imax;
+        p4 = p1+imax;
+
+        p1u = gru + ((j-1)*imax+imn-1);
+        p2u = p1u+1;
+        p3u = p2u+imax;
+        p4u = p1u+imax;
+
+        f1 = flgh + ((j-1)*imax+imn-1);
+        f2 = flgv + ((j-1)*imax+imn);
+        f3 = f1 + imax;
+        f4 = f2 - 1;
+        for (i=imn; i<imx; i++) {
+          if (*p1u!=0 && *p2u!=0 && *p3u!=0 && *p4u!=0) {
+            if (*f1==9) *f1=8;
+            if (*f2==9) *f2=8;
+            if (*f3==9) *f3=8;
+            if (*f4==9) *f4=8;
+          }
+          p1++; p2++; p3++; p4++; 
+          p1u++; p2u++; p3u++; p4u++; 
+          f1++; f2++; f3++; f4++;  
+        }
+      }
+
+      /* Loop through grid, finding starting locations for a contour 
+         line.  Once found, call gxsflw to follow the contour until 
+         it is closed.  The contour is closed by following the grid 
+         boundry (and missing-data-value boundries) if necessary.      */
+
+      for (j=jmn; j<=jmx; j++) {
+        p1 = r + ((j-1)*imax+imn-1);
+        p2 = p1+1;
+        p4 = p1+imax;
+        f1 = flgh + ((j-1)*imax+imn-1);
+        f4 = flgv + ((j-1)*imax+imn-1);
+        for (i=imn; i<=imx; i++) {
+          if (i<imx && (*f1==0 || *f1==8) &&
+              ( (*p1<=val && *p2>val) || (*p1>val && *p2<=val) ) ) {
+            if (j==jmx) rc = gxsflw(i,j-1,3);
+            else rc = gxsflw(i,j,1);
+            if (rc) goto err;
+          }
+          if (j<jmx && (*f4==0 || *f4==8) &&
+              ( (*p1<=val && *p4>val) || (*p1>val && *p4<=val) ) ) {
+            if (i==imx) rc = gxsflw(i-1,j,2);
+            else rc = gxsflw(i,j,4);
+            if (rc) goto err;
+          }
+          p1++; p2++; p4++; 
+          f1++; f4++; 
+        }
+      }
+
+
+      /* Check for any unfilled regions by looking for any unfollowed
+         boundry or missing-data-value sides that have point values
+         that are both greater than the current shade value.  This
+         indicates a possible closed region (closed by missing data
+         value boundries) that we have not yet picked up.  We will  
+         bound that region and fill it.                               */
+
+      for (j=jmn; j<=jmx; j++) {
+        p1 = r + ((j-1)*imax+imn-1);
+        p2 = p1+1;
+        p4 = p1+imax;
+        f1 = flgh + ((j-1)*imax+imn-1);
+        f4 = flgv + ((j-1)*imax+imn-1);
+        for (i=imn; i<=imx; i++) {
+          rc = 0;
+          if (i<imx) {
+            if (j==jmn && *f1==0 && *p1>val && *p2>val) rc = gxsflw(i,j,5);
+            if (j==jmx && *f1==0 && *p1>val && *p2>val) rc = gxsflw(i,j,6);
+            if (*f1==8 && *p1>val && *p2>val) rc = gxsflw(i+1,j,9);
+          }
+          if (j<jmx) {
+            if (i==imn && *f4==0 && *p1>val && *p4>val) rc = gxsflw(i,j,7);
+            if (i==imx && *f4==0 && *p1>val && *p4>val) rc = gxsflw(i,j,8);
+            if (*f4==8 && *p1>val && *p4>val) rc = gxsflw(i,j+1,10);
+          }
+          if (rc) goto err;
+          f1++; f4++; p1++; p2++; p4++;
+        }
+      }
+      prvclr = color;
+    }
+    
+    /* All closed maximas have been filled, and all closed minimas 
+       have been stacked.  Fill minimas in reverse order.           */
+
+    /* Note: to insure the various bands 'fit' together properly, 
+       the boundry points are adjusted outward slightly.  This due to
+       the Xserver not filling out to the boundry in poly fills.    */
+
+    for (i=stkcnt-1; i>=0; i--) {
+      xypnt = xystk[i];
+      xycnt = (gaint)(*xypnt);
+      color = (gaint)(*(xypnt+1));
+      xypnt+=2;
+      for (j=0; j<xycnt; j++) {
+        gxconv(*(xypnt+(j*2)),*(xypnt+(j*2+1)),&x,&y,3);
+        *(xypnt+(j*2)) = x;
+        *(xypnt+(j*2+1)) = y;
+      }
+      gxcolr (color);
+      gxfill (xypnt, xycnt);
+      free(xystk[i]);
+    }
+    stkcnt = 0;
+    xycnt = 0;
+  }
+
+  /* Free memory areas  */
+
+  free(xybuf);
+  free(flgh);
+  free(flgv);
+  return;
+
+err:
+  printf ("Error in gxshad\n");
+  for (i=0; i<stkcnt; i++) free(xystk[i]);
+  free(xybuf);
+  free(flgh);
+  free(flgv);
+  return;
+}
+ 
+gaint gxsflw (gaint i, gaint j, gaint iside) {
+ 
+/* Follow a shaded outline to the end.  Close it if necessary by 
+   following around undef areas and around the grid border.         */ 
+ 
+/* The grid box:
+
+              (f3)
+     p4      side 3     p3
+        x ------------ x
+        |              |
+ side 4 |              | side 2
+  (f4)  |              |  (f2)
+        |              |
+        x ------------ x
+      p1    side 1      p2
+             (f1)
+                                                                     */
+ 
+gaint *f1,*f2,*f3,*f4,*ff,*fu,*fd,*fl,*fr; 
+gaint cnt,rc,isave,jsave,uflag,ucflg,bflag,k; 
+gadouble *p1,*p2,*p3,*p4;
+gadouble x,y;
+ 
+  isave = i; jsave = j;
+  uflag = 0;
+  bndflg = 0;
+
+  bflag = 0;
+  if (iside==1) goto side1;              /* Jump in based on side    */
+  if (iside==2) goto side2;
+  if (iside==3) goto side3;
+  if (iside==4) goto side4;
+  bflag = 1;
+  if (iside==5) goto br;
+  if (iside==6) goto tr;
+  if (iside==7) goto lu;
+  if (iside==8) goto ru;
+  if (iside==9) goto ur;
+  if (iside==10) goto uu;
+  printf ("Logic error 40 in gxshad\n");
+  return (1);
+ 
+  /* Calculate entry point in the current grid box, then move to the
+     next grid box based on the exit side.                           */
+ 
+  side1:                                 /* Enter side 1             */
+
+    if (i<imn || i>(imx-1) || j<jmn || j>jmx) {
+      printf ("logic error 12 in gxshad\n");
+      printf ("  side1, %i %i \n",i,j);
+      return(1);
+    }
+
+    p1 = gr + (imax*(j-1)+i-1);
+    p2 = p1+1;
+    x = (gadouble)i + (val-*p1)/(*p2-*p1);  /* Calculate entry point    */
+    y = (gadouble)j;
+    rc = putxy(x,y);                     /* Put points in buffer     */
+    if (rc) return(rc);
+    f1 = flgh + (imax*(j-1)+i-1);
+    if (*f1==1 || *f1==7) goto done;     /* We may be done           */
+    if (*f1>5 && !uflag) {               /* Entered an undef box?    */
+      if (*f1==9) {
+        printf ("Logic error 4 in gxshad: %i %i\n",i,j);
+        return(1);
+      }
+      *f1 = 7;                           /* Indicate we were here    */
+      if (*p1>val) {
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uleft;                      
+      } else {
+        i++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uright;
+      }
+    }              
+    if (*f1==8) *f1 = 7;                 /* Indicate we were here    */
+    else *f1 = 1;
+    uflag = 0;
+    if (j+1>jmx) {                       /* At top boundry?          */
+      if (*p1>val) {
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto tleft;                      
+      } else {
+        i++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto tright;
+      }
+    }
+
+    /* Check for exit side.  Also check for col.                    */
+
+    p3 = p2+imax;
+    p4 = p3-1;
+    if ( (*p2<=val && *p3>val) || (*p2>val && *p3<=val) ) {
+      if ( (*p3<=val && *p4>val) || (*p3>val && *p4<=val) ) { 
+        if (!spathl(*p1, *p2, *p3, *p4)) {
+          i--;
+          goto side2;                    /* Exiting 4, go enter 2  */
+        }
+      }
+      i++;
+      goto side4;                        /* Exiting 2, go enter 4  */
+    }
+    if ( (*p3<=val && *p4>val) || (*p3>val && *p4<=val) ) {
+      j++;
+      goto side1;                        /* Exiting 3, go enter 1  */
+    }
+    if ( (*p4<=val && *p1>val) || (*p4>val && *p1<=val) ) {
+      i--;
+      goto side2;                        /* Exiting 4, go enter 2  */
+    }
+    printf ("Logic error 8 in gxshad\n");
+    return(1);
+ 
+  side2:                                 /* Enter side 2           */
+
+    if (i<(imn-1) || i>(imx-1) || j<jmn || j>(jmx-1)) {
+      printf ("logic error 12 in gxshad\n");
+      printf ("  side2, %i %i \n",i,j);
+      return(1);
+    }
+
+    p2 = gr + (imax*(j-1)+i);
+    p3 = p2+imax;
+    x = (gadouble)(i+1);
+    y = (gadouble)j + (val-*p2)/(*p3-*p2);  /* Calculate entry point    */
+    rc = putxy(x,y);                     /* Put points in buffer     */
+    if (rc) return(rc);
+    f2 = flgv + (imax*(j-1)+i);
+    if (*f2==1 || *f2==7) goto done;     /* We may be done           */
+    if (*f2>5 && !uflag) {               /* Entered an undef box?    */
+      if (*f2==9) {
+        printf ("Logic error 4 in gxshad: %i %i\n",i,j);
+        printf ("Side 2, entered %i \n",iside);
+        return(1);
+      }
+      *f2 = 7;                           /* Indicate we were here    */
+      if (*p2>val) {
+        i++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto udown;                      
+      } else {
+        i++; j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uup;
+      }
+    }
+    if (*f2==8) *f2 = 7;                 /* Indicate we were here    */
+    else *f2 = 1;
+    uflag = 0;
+    if (i<imn) {                         /* At left boundry?         */
+      if (*p2>val) {
+        i++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto ldown;                      
+      } else {
+        i++; j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto lup;
+      }
+    }
+
+    /* Check for exit side.  Also check for col.                    */
+
+    p1 = p2-1;
+    p4 = p3-1;
+    if ( (*p3<=val && *p4>val) || (*p3>val && *p4<=val) ) {
+      if ( (*p4<=val && *p1>val) || (*p4>val && *p1<=val) ) { 
+        if (spathl(*p1, *p2, *p3, *p4)) {
+          j--;
+          goto side3;                    /* Exiting 1, go enter 3  */
+        }
+      }
+      j++;
+      goto side1;                        /* Exiting 3, go enter 1  */
+    }
+    if ( (*p4<=val && *p1>val) || (*p4>val && *p1<=val) ) {
+      i--;
+      goto side2;                        /* Exiting 4, go enter 2  */
+    }
+    if ( (*p1<=val && *p2>val) || (*p1>val && *p2<=val) ) {
+      j--;
+      goto side3;                        /* Exiting 1, go enter 3  */
+    }
+    printf ("Logic error 8 in gxshad\n");
+    return(1);
+ 
+  side3:                                 /* Enter side 3             */
+
+    if (i<imn || i>(imx-1) || j<(jmn-1) || j>(jmx-1)) {
+      printf ("logic error 12 in gxshad\n");
+      printf ("  side3, %i %i \n",i,j);
+      return(1);
+    }
+
+    p3 = gr + (imax*(j)+i);
+    p4 = p3-1;
+    x = (gadouble)i + (val-*p4)/(*p3-*p4);  /* Calculate entry point    */
+    y = (gadouble)(j+1);
+    rc = putxy(x,y);                     /* Put points in buffer     */
+    if (rc) return(rc);
+    f3 = flgh + (imax*(j)+i-1);
+    if (*f3==1 || *f3==7) goto done;     /* We may be done           */
+    if (*f3>5 && !uflag) {               /* Entered an undef box?    */
+      if (*f3==9) {
+        printf ("Logic error 4 in gxshad: %i %i\n",i,j);
+        printf ("Side 3, entered %i \n",iside);
+        return(1);
+      }
+      *f3 = 7;                           /* Indicate we were here    */
+      if (*p3>val) {
+        i++; j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uright;                     
+      } else {
+        j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uleft;
+      }
+    }
+    if (*f3==8) *f3 = 7;                 /* Indicate we were here    */
+    else *f3 = 1;
+    uflag = 0;
+    if (j<jmn) {                         /* At bottom boundry?       */
+      if (*p3>val) {
+        i++; j++; 
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto bright;                     
+      } else {
+        j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto bleft; 
+      }
+    }
+
+    /* Check for exit side.  Also check for col.                    */
+
+    p1 = p4-imax;
+    p2 = p1+1;
+    if ( (*p1<=val && *p4>val) || (*p1>val && *p4<=val) ) {
+      if ( (*p1<=val && *p2>val) || (*p1>val && *p2<=val) ) { 
+        if (!spathl(*p1, *p2, *p3, *p4)) {
+          i++;
+          goto side4;                    /* Exiting 2, go enter 4  */
+        }
+      }
+      i--;
+      goto side2;                        /* Exiting 4, go enter 2  */
+    }
+    if ( (*p1<=val && *p2>val) || (*p1>val && *p2<=val) ) {
+      j--;
+      goto side3;                        /* Exiting 1, go enter 3  */
+    }
+    if ( (*p2<=val && *p3>val) || (*p2>val && *p3<=val) ) {
+      i++;
+      goto side4;                        /* Exiting 2, go enter 4  */
+    }
+    printf ("Logic error 8 in gxshad\n");
+    return(1);
+ 
+  side4:                                 /* Enter side 4           */
+
+    if (i<1 || i>imax || j<1 || j>(jmax-1)) {
+      printf ("logic error 12 in gxshad\n");
+      printf ("  side4, %i %i \n",i,j);
+      printf (" imax, jmax = %i %i \n",imax,jmax);
+      return(1);
+    }
+
+    p1 = gr + (imax*(j-1)+i-1);
+    p4 = p1+imax;
+    x = (gadouble)i;
+    y = (gadouble)j + (val-*p1)/(*p4-*p1);  /* Calculate entry point    */
+    rc = putxy(x,y);                     /* Put points in buffer     */
+    if (rc) return(rc);
+    f4 = flgv + ((j-1)*imax+i-1);
+    if (*f4==1 || *f4==7) goto done;     /* We may be done           */
+    if (*f4>5 && !uflag) {               /* Entered an undef box?    */
+      if (*f4==9) {
+        printf ("Logic error 4 in gxshad: %i %i\n",i,j);
+        printf ("Side 4, entered %i \n",iside);
+        return(1);
+      }
+      *f4 = 7;                           /* Indicate we were here    */
+      if (*p1>val) {
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto udown;                      
+      } else {
+        j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto uup;
+      }
+    }
+    if (*f4==8) *f4 = 7;                 /* Indicate we were here    */
+    else *f4 = 1;
+    uflag = 0;
+    if (i+1>imx) {                       /* At right boundry?        */
+      if (*p1>val) {
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto rdown;                      
+      } else {
+        j++;
+        rc = putxy((gadouble)i,(gadouble)j);
+        if (rc) return(rc);
+        goto rup;
+      }
+    }
+
+    /* Check for exit side.  Also check for col.                    */
+
+    p2 = p1+1;
+    p3 = p4+1;
+    if ( (*p1<=val && *p2>val) || (*p1>val && *p2<=val) ) {
+      if ( (*p2<=val && *p3>val) || (*p2>val && *p3<=val) ) { 
+        if (spathl(*p1, *p2, *p3, *p4)) {
+          j++;
+          goto side1;                    /* Exiting 3, go enter 1  */
+        }
+      }
+      j--;
+      goto side3;                        /* Exiting 1, go enter 3  */
+    }
+    if ( (*p2<=val && *p3>val) || (*p2>val && *p3<=val) ) {
+      i++;
+      goto side4;                        /* Exiting 2, go enter 4  */
+    }
+    if ( (*p3<=val && *p4>val) || (*p3>val && *p4<=val) ) {
+      j++;
+      goto side1;                        /* Exiting 3, go enter 1  */
+    }
+    printf ("Logic error 8 in gxshad\n");
+    return(1);
+
+  /* At an undefined boundry and last moved towards the left.  */
+
+  uleft:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (j<(jmn+1)||j>jmx-1) {
+      printf ("Logic error 16 in gxshad\n");
+      return (1);
+    }
+    fu = flgv + ((j-1)*imax+i-1);
+    fd = fu-imax;
+    if (i==imn) {
+      if ((*fu>5 && *fd>5) || (*fu<5 && *fd<5)) {
+        printf ("Logic error 20 in gxshad\n");
+        return (1);
+      }
+      if (*fu>5) goto ldown;
+      else goto lup;
+    }
+    ff = flgh + ((j-1)*imax+i-2);
+    cnt=0;
+    if (*ff==7 || *ff==8) cnt++;
+    if (*fu==7 || *fu==8) cnt++;
+    if (*fd==7 || *fd==8) cnt++;
+    if (cnt==2 || cnt==0) {
+      printf ("Logic error 24 in gxshad\n");
+      return (1);
+    }
+    ucflg = 0;
+    if (cnt==3) ucflg = undcol(i,j);
+    if (ucflg==9) return(1);
+    if (!ucflg && (*ff==7 || *ff==8)) {
+      i--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (*fu>5) {
+          j--;
+          goto side3;
+        } else goto side1;
+      }
+      *ff = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uleft;
+    }
+    if (ucflg!=2 && (*fd==7 || *fd==8)) {
+      j--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fu==9) {
+          goto side4;
+        } else {
+          i--;
+          goto side2;
+        }
+      }
+      *fd = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto udown;
+    }
+    if (ucflg!=1 && (*fu==7 || *fu==8)) {
+      j++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fd==9) {
+          j--;
+          goto side4;
+        } else {
+          i--; j--; 
+          goto side2;
+        }
+      }
+      *fu = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uup;
+    }
+    printf ("Logic error 28 in gxshad\n");
+    return(1);
+     
+  /* At an undefined boundry and last moved towards the right. */
+
+  uright:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  ur:
+
+    bndflg = 1;
+    if (j<(jmn+1)||j>jmx-1) {
+      printf ("Logic error 16 in gxshad\n");
+      return (1);
+    }
+    fu = flgv + ((j-1)*imax+i-1);
+    fd = fu-imax;
+    if (i==imx) {
+      if ((*fu>5 && *fd>5) || (*fu<5 && *fd<5)) {
+        printf ("Logic error 20 in gxshad\n");
+        return (1);
+      }
+      if (*fu>5) goto rdown;
+      else goto rup;
+    }
+    ff = flgh + ((j-1)*imax+i-1);
+    cnt=0;
+    if (*ff==7 || *ff==8) cnt++;
+    if (*fd==7 || *fd==8) cnt++;
+    if (*fu==7 || *fu==8) cnt++;
+    if (cnt==2 || cnt==0) {
+      printf ("Logic error 24 in gxshad\n");
+      return (1);
+    }
+    ucflg = 0;
+    if (cnt==3) ucflg = undcol(i,j);
+    if (ucflg==9) return(1);
+    if (!ucflg && (*ff==7 || *ff==8)) {
+      i++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        i--;
+        if (*fu>5) {
+          j--;
+          goto side3;
+        } else goto side1;
+      }
+      *ff = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uright;
+    }
+    if (ucflg!=1 && (*fd==7 || *fd==8)) {
+      j--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1; 
+        if (ucflg || *fu==9) {
+          i--;
+          goto side2;
+        } else {
+          goto side4;
+        }
+      }
+      *fd = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto udown;
+    }
+    if (ucflg!=2 && (*fu==7 || *fu==8)) {
+      j++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fd==9) {
+          i--; j--;
+          goto side2;
+        } else {
+          j--; 
+          goto side4;
+        }
+      }
+      *fu = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uup;
+    }
+    printf ("Logic error 28 in gxshad\n");
+    return(1);
+     
+  /* At an undefined boundry and last moved towards the top.   */
+
+  uup:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  uu:
+
+    bndflg = 1;
+    if (i<(imn+1)||i>imx-1) {
+      printf ("Logic error 16 in gxshad\n");
+      return (1);
+    }
+    fr = flgh + ((j-1)*imax+i-1);
+    fl = fr-1;
+    if (j==jmx) {
+      if ((*fr>5 && *fl>5) || (*fr<5 && *fl<5)) {
+        printf ("Logic error 20 in gxshad\n");
+        return (1);
+      }
+      if (*fr>5) goto tleft;
+      else goto tright;
+    }
+    ff = flgv + ((j-1)*imax+i-1);
+    cnt=0;
+    if (*ff==7 || *ff==8) cnt++;
+    if (*fr==7 || *fr==8) cnt++;
+    if (*fl==7 || *fl==8) cnt++;
+    if (cnt==2 || cnt==0) {
+      printf ("Logic error 24 in gxshad\n");
+      return (1);
+    }
+    ucflg = 0;
+    if (cnt==3) ucflg = undcol(i,j);
+    if (ucflg==9) return(1);
+    if (!ucflg && (*ff==7 || *ff==8)) {
+      j++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        j--;
+        uflag = 1;
+        if (*fr>5) {
+          i--;
+          goto side2;
+        }
+        else goto side4;
+      }
+      *ff = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uup;   
+    }
+    if (ucflg!=2 && (*fr==7 || *fr==8)) {
+      i++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fl==9) {
+          i--; j--;
+          goto side3;
+        } else {
+          i--;
+          goto side1;
+        }
+      }
+      *fr = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uright;
+    }
+    if (ucflg!=1 && (*fl==7 || *fl==8)) {
+      i--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fr==9) {
+          j--;
+          goto side3;
+        } else {
+          goto side1;
+        }
+      }
+      *fl = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uleft;
+    }
+    printf ("Logic error 28 in gxshad\n");
+    return(1);
+     
+  /* At an undefined boundry and last moved towards the bottom.  */
+
+  udown:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (i<(imn+1)||i>imx-1) {
+      printf ("Logic error 16 in gxshad\n");
+      return (1);
+    }
+    fr = flgh + ((j-1)*imax+i-1);
+    fl = fr-1;
+    if (j==jmn) {
+      if ((*fr>5 && *fl>5) || (*fr<5 && *fl<5)) {
+        printf ("Logic error 20 in gxshad\n");
+        return (1);
+      }
+      if (*fr>5) goto bleft;
+      else goto bright;
+    }
+    ff = flgv + ((j-2)*imax+i-1);
+    cnt=0;
+    if (*ff==7 || *ff==8) cnt++;
+    if (*fr==7 || *fr==8) cnt++;
+    if (*fl==7 || *fl==8) cnt++;
+    if (cnt==2 || cnt==0) {
+      printf ("Logic error 24 in gxshad\n");
+      return (1);
+    }
+    ucflg = 0;
+    if (cnt==3) ucflg = undcol(i,j);
+    if (ucflg==9) return(1);
+    if (!ucflg && (*ff==7 || *ff==8)) {
+      j--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (*fr>5) {
+          i--;
+          goto side2;
+        }
+        else goto side4;
+      }
+      *ff = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto udown;   
+    }
+    if (ucflg!=1 && (*fr==7 || *fr==8)) {
+      i++;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fl==9) {
+          i--;
+          goto side1;
+        } else {
+          i--; j--;
+          goto side3;
+        }
+      }
+      *fr = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uright;
+    }
+    if (ucflg!=2 && (*fl==7 || *fl==8)) {
+      i--;
+      p1 = gr + ((j-1)*imax+i-1);
+      if (*p1<=val) {
+        uflag = 1;
+        if (ucflg || *fr==9) {
+          goto side1;
+        } else {
+          j--;
+          goto side3;
+        }
+      }
+      *fl = 7;
+      rc = putxy((gadouble)i,(gadouble)j);
+      if (rc) return(rc);
+      goto uleft;
+    }
+    printf ("Logic error 28 in gxshad\n");
+    return(1);
+
+  /* Follow grid boundry until we hit a missing data area, or until
+     we hit the restart of the contour line.                         */
+
+  tright:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  tr:
+
+    bndflg = 1; 
+    if (i==imx) goto rdown;
+    ff = flgh + ((j-1)*imax+i-1);
+    if (*ff>5) goto udown;
+    i++;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      j--; i--;
+      goto side3;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto tright;
+
+  tleft:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (i==imn) goto ldown;
+    ff = flgh + ((j-1)*imax+i-2);
+    if (*ff>5) goto udown;
+    i--;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      j--;
+      goto side3;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto tleft; 
+
+  bright:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  br:
+
+    bndflg = 1;
+    if (i==imx) goto rup;
+    ff = flgh + ((j-1)*imax+i-1);
+    if (*ff>5) goto uup;
+    i++;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      i--;
+      goto side1;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto bright;
+
+  bleft:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (i==imn) goto lup;
+    ff = flgh + ((j-1)*imax+i-2);
+    if (*ff>5) goto uup;
+    i--;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      goto side1;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto bleft; 
+     
+  rup:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  ru:
+
+    bndflg = 1;
+    if (j==jmx) goto tleft;
+    ff = flgv + ((j-1)*imax+i-1);
+    if (*ff>5) goto uleft;
+    j++;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      j--; i--;
+      goto side2;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto rup;   
+     
+  rdown:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (j==jmn) goto bleft;
+    ff = flgv + ((j-2)*imax+i-1);
+    if (*ff>5) goto uleft;
+    j--;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      i--;
+      goto side2;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto rdown; 
+     
+  lup:
+
+    if (bflag && i==isave && j==jsave) goto done;
+
+  lu:
+
+    bndflg = 1;
+    if (j==jmx) goto tright;
+    ff = flgv + ((j-1)*imax+i-1);
+    if (*ff>5) goto uright;
+    j++;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      j--; 
+      goto side4;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto lup;   
+     
+  ldown:
+
+    bndflg = 1;
+    if (bflag && i==isave && j==jsave) goto done;
+    if (j==jmn) goto bright;
+    ff = flgv + ((j-2)*imax+i-1);
+    if (*ff>5) goto uright;
+    j--;
+    p1 = gr + ((j-1)*imax+i-1);
+    if (*p1<=val) {
+      goto side4;
+    }
+    *ff = 1;
+    rc = putxy((gadouble)i,(gadouble)j);
+    if (rc) return(rc);
+    goto ldown; 
+     
+  done:
+
+  shdcmp();
+  if (xycnt<4) goto cont;
+  if (shdmax()) {
+    for (k=0; k<xycnt; k++) {
+      gxconv(*(xybuf+(k*2)),*(xybuf+(k*2+1)),&x,&y,3);
+      *(xybuf+(k*2)) = x;
+      *(xybuf+(k*2+1)) = y;
+    }
+    gxcolr (color);
+    gxfill (xybuf, xycnt);
+  } else {
+    xystk[stkcnt] = (gadouble *)malloc(sizeof(gadouble)*(xycnt+1)*2);
+    if (xystk[stkcnt]==NULL) {
+      printf ("Memory allocation error in gxshad: stack buffer\n");
+      return (1);
+    }
+    xypnt = xystk[stkcnt];
+    *xypnt = (gadouble)(xycnt)+0.1;
+    *(xypnt+1) = (gadouble)(prvclr)+0.1;
+    xypnt+=2;
+    for (k=0; k<xycnt; k++) {
+      *(xypnt+(k*2)) = *(xybuf+(k*2));
+      *(xypnt+(k*2+1)) = *(xybuf+(k*2+1));
+    }
+    stkcnt++;
+    if (stkcnt>=XYBMAX) {
+      printf ("Buffer stack limit exceeded in gxshad\n");
+      return(1);
+    }
+  }
+
+cont:
+  xycnt = 0;
+  return (0);
+
+}
+ 
+/* Calculate shortest combined path length through a col point.
+   Return true if shortest path is side 1/2,3/4, else false.         */
+ 
+gaint spathl (gadouble p1, gadouble p2, gadouble p3, gadouble p4) {
+gadouble v1,v2,v3,v4,d1,d2;
+ 
+  v1 = (val-p1)/(p2-p1);
+  v2 = (val-p2)/(p3-p2);
+  v3 = (val-p4)/(p3-p4);
+  v4 = (val-p1)/(p4-p1);
+  d1 = hypot(1.0-v1, v2) + hypot(1.0-v4, v3);
+  d2 = hypot(v1, v4) + hypot(1.0-v2, 1.0-v3);
+  if (d2<d1) return (0);
+  return (1);
+}
+
+/* Determine characteristics of an undefined path col */
+
+gaint undcol (gaint i, gaint j) {
+gadouble *p1, *p2, *p3, *p4;
+char *p1u, *p2u, *p3u, *p4u;
+
+  if (i<2 || i>imax-1 || j<2 || j>jmax-1) {
+    printf ("Logic error 32 in gxshad\n");
+    return (9);
+  }
+  p1 = gr + ((j-2)*imax+i-2);
+  p2 = p1 + 2;
+  p3 = p2 + imax*2;
+  p4 = p3 - 2;
+
+  p1u = gru + ((j-2)*imax+i-2);
+  p2u = p1u + 2;
+  p3u = p2u + imax*2;
+  p4u = p3u - 2;
+
+
+  if (*p1u==0 && *p3u==0 && *p2u!=0 && *p4u!=0) return(1);
+  if (*p1u!=0 && *p3u!=0 && *p2u==0 && *p4u==0) return(2);
+  printf ("Logic error 36 in gxshad\n");
+  return (9);
+}
+
+
+gaint putxy (gadouble x, gadouble y) {
+
+  if (xycnt>=grsize) return(1);
+  *(xybuf+(xycnt*2)) = x;
+  *(xybuf+(xycnt*2+1)) = y;
+  xycnt++;
+  return(0);
+}
+
+/* Remove duplicate consecutive points from the closed contour   */
+
+void shdcmp (void) {
+gaint i,j;
+
+  i=0;
+  for (j=1; j<xycnt; j++) {
+    if ( *(xybuf+(i*2)) != *(xybuf+(j*2)) || 
+         *(xybuf+(i*2+1)) != *(xybuf+(j*2+1)) ) {
+      i++;
+      if (i!=j) {
+        *(xybuf+(i*2)) = *(xybuf+(j*2)); 
+        *(xybuf+(i*2+1)) = *(xybuf+(j*2+1));
+      }
+    }
+  }
+  xycnt = i+1;
+}
+      
+/* Determine if the current closed contour (contained in xybuf) 
+   is a max or a min.                                            */
+
+gaint shdmax(void) {
+gadouble x, y, xsave, ysave=0.0, *p1;
+gaint i,j;
+
+  /* If we hit some boundry during our travels, then this one has
+     to be a max (since we are doing strips 3 grid boxes wide, and
+     this makes it impossible to have a "floating" undef region)  */
+
+  if (bndflg) return(1);
+
+  /* Find the minimum x value in the contour line.  Check the   
+     right hand point to see if this is a max or a min.          */
+
+  xsave = 9.9e33;
+  for (i=0; i<xycnt; i++) {
+    x = *(xybuf+(i*2));
+    y = *(xybuf+(i*2+1));
+    if ( y == floor(y) && x < xsave) {
+      xsave = x;
+      ysave = y;
+    }
+  }
+  i = (gaint)xsave;
+  j = (gaint)ysave;
+  p1 = gr + ((j-1)*imax+i);
+  if (*p1 > val) return (1);
+  return (0);
+}
+
+void chksid (void) {
+gaint *f1,*f4;
+gaint i,j;
+gadouble x,y;
+    f1 = flgh;
+    f4 = flgv;
+    for (j=1; j<=jmax; j++) {
+      for (i=1; i<=imax; i++) {
+        if (i<imax) {              
+          if (*f1==1) gxcolr(1);
+          else if (*f1==7) gxcolr(3);
+          else if (*f1==8) gxcolr(8);
+          else if (*f1==9) gxcolr(4);
+          else if (*f1==0) gxcolr(15);
+          else gxcolr(2);
+          gxconv((gadouble)i,(gadouble)j,&x,&y,3);
+          gxplot(x,y,3);
+          gxconv((gadouble)(i+1),(gadouble)j,&x,&y,3);
+          gxplot(x,y,2);
+        }
+        if (j<jmax) {
+          if (*f4==1) gxcolr(1);
+          else if (*f4==7) gxcolr(3);
+          else if (*f4==8) gxcolr(8);
+          else if (*f4==9) gxcolr(4);
+          else if (*f4==0) gxcolr(15);
+          else gxcolr(2);
+          gxconv((gadouble)i,(gadouble)j,&x,&y,3);
+          gxplot(x,y,3);
+          gxconv((gadouble)i,(gadouble)(j+1),&x,&y,3);
+          gxplot(x,y,2);
+        }
+        f1++; f4++;
+      }
+    }
+    gxfrme (0);
+}
diff --git a/src/gxshad2.c b/src/gxshad2.c
new file mode 100644
index 0000000..3518121
--- /dev/null
+++ b/src/gxshad2.c
@@ -0,0 +1,1709 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty  2010,2011 */
+
+/* Version 2 of the shaded contouring routine.  The original grads implementation
+   of shaded contouring used a technique involving overlaying the polygons.
+   That did not allow for desirable applications such as transparency
+   or pattern fill.  That version also failed to maintain the "right hand rule"
+   needed for shapefile support (ie, the polygon is filled to the right-hand-side
+   of the path).  The new version, with an entry point of gxshad2, has these 
+   desirable features.
+
+   This source file actually contains two implementations of filled contouring.
+   The entry point gxshad2b generates the filled contour plot by filling a large
+   number of small polygons grid box by grid box.  The code for this is left here
+   since it may have future uses (such as for complex map projections).  It is also
+   the version of shaded contouring that is the least complex -- and thus is the 
+   version most likely to be correct.  So when in doubt -- set gxout shade2b.  */
+
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "gatypes.h"
+#include "gx.h"
+
+#if USESHP==1
+#include "shapefil.h"
+/* Structure that contains dBase field metadata */
+struct dbfld {
+  struct dbfld *next;           /* Address of next data base field */
+  DBFFieldType type;            /* string, integer, double, or logical */
+  char name[12];                /* library interface limits length to 11 charaters */
+  gaint len;                    /* for type string: width of string
+				   for type int and double: total number of digits */
+  gaint prec; 			/* for type double: used with len for format string %len.prec */
+  gaint index;                  /* index value (for identifying this field in a list of fields) */
+  gaint flag;                   /* 0==static fiels (same for all shapes), 1==dynamic (varies w/ shape) */
+  void *value;                  /* field value */
+};
+/* some function declarations */
+gaint s2shpwrt (SHPHandle, DBFHandle, struct dbfld *);
+char *intprs (char *, gaint *);
+char *getdbl (char *, gadouble *);
+#endif
+void *galloc(size_t, char *);
+void gree ();
+
+/* Variables shared between the different routines in this source file */
+
+/* Following variables for gxshad2b  */
+
+static gaint np;
+static gadouble xp[50],yp[50];
+static gaint tp[50],sp[50];
+static gaint typ1, typ2, typ3;
+static gaint numpoly, polyside;
+
+static gadouble xpo[50],ypo[50];
+static gaint npo;
+
+/* Following variables used for gxshad2  */
+
+static char *pflg,*s1flg,*s2flg,*s3flg,*s4flg;
+static char *uu;
+static gaint isize,jsize,pnum,gindex;
+static gadouble *rr,alev,blev;
+
+static gadouble *xxyy;   /* Holds one polygon */
+static gaint xynum;
+
+struct s2pbuf {
+  struct s2pbuf *fpbuf;          /* Forward pointer */
+  gaint len;                     /* Number of polygon points */
+  gaint color,index;             /* Output options for this polygon */
+  gadouble *xy;                  /* Line points, x,y number len */
+  gadouble clev1,clev2;          /* Fill range values */
+};
+
+static struct s2pbuf *s2pbufanch;  /* Anchor for polygon buffer */ 
+static struct s2pbuf *s2pbuflast;  /* Last buffer in link list  */ 
+static gaint nodraw=0;             /* If 1, polygons are not drawn */
+static gaint bufopt=0;             /* Buffer or not, default is not */
+              /* If buffering is enabled, someone needs to call s2frepbuf from somewhere */
+static gaint bufcnt;               /* Number of polys buff'd */
+static char pout[512];             /* Build strings for KML here */
+
+/* Debug variable, used by both */
+
+static int bug;
+
+
+/* The grid r is shaded.  Size is by js.  lvs indicates the number of 
+   shaded levels.  vs contains the values bounding the shaded regions.
+   clrs contains lvs+1 colors for the shaded regions.  u is the
+   undefined grid data value.
+
+   This version creates large and possibly complex polygons.  See gxshad2b for
+   the version that creats small polygons for each grid box.  gxshad2b is slower, 
+   but is less likely to have bugs, and the small polygons may be advantageous
+   for certain map projections.                                        */
+
+void gxshad2 (gadouble *r, gaint is, gaint js, gadouble *vs, gadouble rmax, gaint *clrs, gaint lvs, char *u) {
+gadouble clev1,clev2;
+gaint k;
+
+  bug=0;
+  if (bug) printf ("in gxshad2\n");
+
+  rr = r; isize=is; jsize=js; uu=u;
+/*   bufopt = 0; */
+
+  pflg  = (char *)galloc(sizeof(char)*is*js,"s2pflg");
+  s1flg = (char *)galloc(sizeof(char)*is*js,"s2s1flg");
+  s2flg = (char *)galloc(sizeof(char)*is*js,"s2s2flg");
+  s3flg = (char *)galloc(sizeof(char)*is*js,"s2s3flg");
+  s4flg = (char *)galloc(sizeof(char)*is*js,"s2s4flg");
+
+  if (pflg == NULL || s1flg==NULL || s2flg==NULL || s3flg==NULL || s4flg==NULL ) {
+    printf ("Memory allocation error in gxshad2. \n");
+    printf ("--Unable to allocate memory for work areas.\n");
+    if (pflg)  gree (pflg,"s1");
+    if (s1flg) gree (s1flg,"s2");
+    if (s2flg) gree (s2flg,"s3");
+    if (s3flg) gree (s3flg,"s4");
+    if (s4flg) gree (s4flg,"s5");
+    return;
+  }
+  k = is; 
+  if (js>is) k = js;
+  k = k*5;
+  xxyy = (gadouble *)(galloc(sizeof(gadouble)*k*2,"s2xxyy"));
+  if (xxyy==NULL) {
+    printf ("Memory allocation error in gxshad2. \n");
+    printf ("--Unable to allocate memory for polygon buffer.\n");
+    return;
+  }
+  xynum = k;
+
+  /* Loop through the shade levels and set the color.  Skip the level
+     if the color is less than zero.  */
+
+  for (k=0; k<lvs; k++) {
+    if (*(clrs+k) < 0) continue;
+    gindex = k;
+    clev1 = *(vs+k);
+    if (k<lvs-1) clev2 = *(vs+k+1);
+    else {
+      clev2 = rmax + fabs(*(vs+k)-*(vs+k-1));
+    }
+    gxcolr(*(clrs+k));
+    blev = clev1; alev = clev2;
+    if (bug) printf ("clevs %g %g\n",clev1,clev2);
+    s2flags (r, u, is, js, clev1, clev2);
+    s2poly (r, is, js, clev1, clev2); 
+    if (bug) s2debug(); 
+  }
+
+  gree(pflg,"s6");
+  gree(s1flg,"s7"); gree(s2flg,"s8"); gree(s3flg,"s9"); gree(s4flg,"s10");
+  gree(xxyy,"s11");
+
+  if (bug && bufopt) printf ("----> bufcnt = %i \n",bufcnt);
+
+}
+/* The grid r is shaded.  Size is by js.  lvs indicates the number of 
+   shaded levels.  vs contains the values bounding the shaded regions.
+   clrs contains lvs+1 colors for the shaded regions.  u is the
+   undefined grid data value.                                        */
+
+void gxshad2b (gadouble *r, gaint is, gaint js, gadouble *vs, gadouble rmax, gaint *clrs, gaint lvs, char *u) {
+gadouble v1,v2,v3,v4,clev1,clev2;
+gaint i,k,ig,jg,ijg;
+
+  bug=0;
+
+  /* Loop through the shade levels and set the color.  Skip the level
+     if the color is less than zero.  */
+
+  for (k=0; k<lvs; k++) {
+    if (*(clrs+k) < 0) continue;
+    clev1 = *(vs+k);
+    if (k<lvs-1) clev2 = *(vs+k+1);
+    else {
+      clev2 = rmax + fabs(*(vs+k)-*(vs+k-1));
+    }
+    gxcolr(*(clrs+k));
+
+    /*  Loop through all the grid boxes.  Skip box if any missing values */ 
+
+    for (jg=0; jg<js-1; jg++) {
+      for (ig=0; ig<is-1; ig++) {
+        ijg = jg*is+ig;
+        if ( *(u+ijg)==0 || *(u+ijg+1)==0 ||
+             *(u+ijg+is)==0 || *(u+ijg+is+1)==0)  continue; 
+        v1 = *(r+ijg);
+        v2 = *(r+ijg+1);
+        v4 = *(r+ijg+is);
+        v3 = *(r+ijg+is+1);
+        if (bug) printf ("%g %g %g %g\n",v1,v2,v3,v4);
+
+        /* Find all the intersect points for this box, and if it
+           is a col, determine the nature of the col and the 
+           number of polygons to be output */
+     
+        s2box(v1,v2,v3,v4,clev1,clev2);
+
+        /* Join the intersect points into polygons.  This is simple
+           if it is just one polygon.  Otherwise a determination must
+           be made how to draw the two polygons. */
+
+        if (np>1) {
+          npo = 0;
+          for (i=0; i<np; i++) {     /* Put points into grid coords */
+            xp[i] = xp[i]+(float)(ig+1);
+            yp[i] = yp[i]+(float)(jg+1);
+          }
+          if (numpoly==1) {          /* Only one polygon.  Easy.  */
+            for (i=0; i<np; i++) {
+              xpo[npo] = xp[i];
+              ypo[npo] = yp[i];
+              npo++;
+            }
+            s2outpoly();
+          }  
+          if (numpoly==2) {         /* Two polygons */
+            if (polyside==1) {      /* Poly1: sides 1 and 2.  */
+              for (i=0; i<np; i++) {
+                if (sp[i]==1 || sp[i]==2) {
+                  xpo[npo] = xp[i];
+                  ypo[npo] = yp[i];
+                  npo++;
+                }
+              }
+              s2outpoly();
+              for (i=0; i<np; i++) {
+                if (sp[i]==3 || sp[i]==4) {
+                  xpo[npo] = xp[i];
+                  ypo[npo] = yp[i];
+                  npo++;
+                }
+              }
+              s2outpoly();
+            } else {
+              for (i=0; i<np; i++) {   /* Poly1:  sides 2 and 3 */
+                if (sp[i]==2 || sp[i]==3) {
+                  xpo[npo] = xp[i];
+                  ypo[npo] = yp[i];
+                  npo++;
+                }
+              }
+              s2outpoly();
+              for (i=0; i<np; i++) {
+                if (sp[i]==1 || sp[i]==4) {
+                  xpo[npo] = xp[i];
+                  ypo[npo] = yp[i];
+                  npo++;
+                }
+              }
+              s2outpoly();
+            }
+          }       
+        }
+      }
+    }
+  }
+  return;
+}
+
+/* Output a single polygon. Remove duplicate points. */
+
+void s2outpoly(void) {
+gadouble xy[50],*pxy;
+gaint i,j;
+
+  if (bug) printf ("  xxx> %i\n",npo);
+  if (npo<3) {   /* At least 3 points needed */
+    npo = 0;
+    return;
+  }
+  j = 0;
+  for (i=1; i<npo; i++) {     /* Remove dups */
+    if (fabs(xpo[i]-xpo[j]) > 1e-5 || fabs(ypo[i]-ypo[j]) > 1e-5) {
+      if (i!=j+1) {
+        xpo[j+1] = xpo[i];
+        ypo[j+1] = ypo[i];
+      }
+      j++;
+    }
+  }
+  j++;
+  if (j<3) {
+    npo = 0;
+    return;
+  }
+  npo = j;
+
+  pxy = xy;
+  for (i=0; i<npo; i++) {     /* Scale from grid to xy */
+    gxconv (xpo[i],ypo[i],pxy,pxy+1,3);
+    if (bug) printf ("    %g %g %g %g\n",xpo[i],ypo[i],*pxy,*(pxy+1));
+    pxy = pxy + 2;
+  }
+  *pxy = xy[0];
+  *(pxy+1) = xy[1];
+  npo++;
+  if (!nodraw) {
+    gxfill(xy,npo);    /* Output polygon */
+  }
+  npo = 0;
+}
+
+/* Pre-determine flags for the entire grid
+            s2       
+         v2 --- v3
+          |     |  s3
+      s1  |     |
+         v1 --- v4
+       p1    s4
+
+*/
+
+/* flag values:  1 -- c1 intersects, v1<v2 (or v2<v3, v4<v3, v1<v4)
+                 2 -- c1 intersects, v1>v2
+                 3 -- c2 intersects, v1<v2
+                 4 -- c2 intersects, v1>v2
+                 5 -- both intersect, v1<v2
+                 6 -- both intersect, v1>v2
+               +10 -- boundary with an intersect (ie, the polygon edge
+                         is from an intersect point to a corner)
+               =10 -- boundary, no intersect (ie, the polygon
+                         edge is along the entire box side, corner to corner)
+         
+       note: a boundary can be along the outside edge, along the edge of missing 
+       data, and along artificial internal boundaries introduced to 
+       insure polygon closure or to avoid col problems.  */
+
+void s2flags (gadouble *r, char *u, gaint is, gaint js, gadouble c1, gadouble c2) {
+gaint ig,jg,ijg,flag,jj;
+gadouble v1,v2,v3,v4;
+
+  for (jg=0; jg<js; jg++) {
+    ijg=jg*is;
+    for (ig=0; ig<is; ig++) {
+      *(pflg+ijg) = 0;
+      if ( *(u+ijg)) {
+        if (*(r+ijg)>c1 && *(r+ijg)<=c2) *(pflg+ijg) = 1;   /* pflg true if within shade range */
+      }
+      ijg++;
+    }
+  }
+  for (jg=0; jg<js-1; jg++) {
+    ijg=jg*is;
+    for (ig=0; ig<is-1; ig++) {
+
+      *(s1flg+ijg) = 0;
+      *(s2flg+ijg) = 0;
+      *(s3flg+ijg) = 0;
+      *(s4flg+ijg) = 0;
+
+      if ( *(u+ijg)==0 || *(u+ijg+1)==0 || *(u+ijg+is)==0 || *(u+ijg+is+1)==0) {
+        ijg++;
+        continue; 
+      }
+      v1 = *(r+ijg);
+      v2 = *(r+ijg+is);
+      v3 = *(r+ijg+is+1);
+      v4 = *(r+ijg+1);
+
+      /* side1 */
+      if ( v1<=c1 && v2>c1 ) *(s1flg+ijg) = 1;
+      if ( v1>c1 && v2<=c1 ) *(s1flg+ijg) = 2;
+      if ( v1<=c2 && v2>c2 ) {
+         if (*(s1flg+ijg)) *(s1flg+ijg) = 5; else *(s1flg+ijg)=3;
+      }
+      if ( v1>c2 && v2<=c2 ) { 
+        if (*(s1flg+ijg)) *(s1flg+ijg) = 6; else *(s1flg+ijg)=4;
+      }
+
+      /* side2 */
+      if ( v2<=c1 && v3>c1 ) *(s2flg+ijg) = 1;
+      if ( v2>c1 && v3<=c1 ) *(s2flg+ijg) = 2;
+      if ( v2<=c2 && v3>c2 ) {
+         if (*(s2flg+ijg)) *(s2flg+ijg) = 5; else *(s2flg+ijg)=3;
+      }
+      if ( v2>c2 && v3<=c2 ) { 
+        if (*(s2flg+ijg)) *(s2flg+ijg) = 6; else *(s2flg+ijg)=4;
+      }
+
+      /* side3 */
+      if ( v3<=c1 && v4>c1 ) *(s3flg+ijg) = 2;
+      if ( v3>c1 && v4<=c1 ) *(s3flg+ijg) = 1;
+      if ( v3<=c2 && v4>c2 ) {
+         if (*(s3flg+ijg)) *(s3flg+ijg) = 6; else *(s3flg+ijg)=4;
+      }
+      if ( v3>c2 && v4<=c2 ) { 
+        if (*(s3flg+ijg)) *(s3flg+ijg) = 5; else *(s3flg+ijg)=3;
+      }
+
+      /* side4 */
+      if ( v4<=c1 && v1>c1 ) *(s4flg+ijg) = 2;
+      if ( v4>c1 && v1<=c1 ) *(s4flg+ijg) = 1;
+      if ( v4<=c2 && v1>c2 ) {
+         if (*(s4flg+ijg)) *(s4flg+ijg) = 6; else *(s4flg+ijg)=4;
+      }
+      if ( v4>c2 && v1<=c2 ) { 
+        if (*(s4flg+ijg)) *(s4flg+ijg) = 5; else *(s4flg+ijg)=3;
+      }
+
+      /* set side flag to 10 if side is completely in the range and  
+         the side is a boundary  */
+
+      if ( *(pflg+ijg) && *(pflg+ijg+is) ) { 
+        if (ig==0) *(s1flg+ijg) = 10;
+        else if (*(u+ijg-1)==0 || *(u+ijg+is-1)==0) *(s1flg+ijg) = 10;
+      }
+      if ( *(pflg+ijg+is) && *(pflg+ijg+is+1) ) { 
+        if (jg==js-2) *(s2flg+ijg) = 10;
+        else if (*(u+ijg+is*2)==0 || *(u+ijg+is*2+1)==0) *(s2flg+ijg) = 10;
+      }
+      if ( *(pflg+ijg+is+1) && *(pflg+ijg+1) ) { 
+        if (ig==is-2) *(s3flg+ijg) = 10;
+        else if (*(u+ijg+2)==0 || *(u+ijg+is+2)==0) *(s3flg+ijg) = 10;
+      }
+      if ( *(pflg+ijg+1) && *(pflg+ijg) ) {
+        if (jg==0) *(s4flg+ijg) = 10;
+        else if (*(u+ijg-is)==0 || *(u+ijg+1-is)==0) *(s4flg+ijg) = 10;
+      }
+
+      ijg++;
+    }
+  }
+
+  /* If a side flag indicates an intersect (value of 1 to 6), but the 
+     side flag "next" to it does not, then the intersect is also a 
+     boundary.  Indicate this with a +10.  */
+
+  for (jg=0; jg<js-1; jg++) { 
+    ijg=jg*is;      
+    for (ig=0; ig<is-1; ig++) {
+      if ( *(s1flg+ijg)>0 && *(s1flg+ijg)<7 ) { 
+        if (ig==0) *(s1flg+ijg) += 10;
+        else if (*(s3flg+ijg-1)==0) *(s1flg+ijg) += 10;
+      }
+      if ( *(s2flg+ijg)>0 && *(s2flg+ijg)<7 ) { 
+        if (jg==js-2) *(s2flg+ijg) += 10;
+        else if (*(s4flg+ijg+is)==0) *(s2flg+ijg) += 10;
+      }
+      if ( *(s3flg+ijg)>0 && *(s3flg+ijg)<7 ) { 
+        if (ig==is-2) *(s3flg+ijg) += 10;
+        else if (*(s1flg+ijg+1)==0) *(s3flg+ijg) += 10;
+      }
+      if ( *(s4flg+ijg)>0 && *(s4flg+ijg)<7 ) { 
+        if (jg==0) *(s4flg+ijg) += 10;
+        else if (*(s2flg+ijg-is)==0) *(s4flg+ijg) += 10;
+      }
+      ijg++;
+    }
+  }
+
+  /* Determine some needed internal boundaries.  Set flag to +10 for these.
+     Be careful not to change existing boundary values. */
+
+  for (jg=0; jg<js-1; jg++) { 
+    flag = 0;
+    ijg=jg*is+1;      
+    for (ig=1; ig<is-1; ig++) {
+      if ( ! *(pflg+ijg) && *(s1flg+ijg)>0 && *(s1flg+ijg)<7 ) {
+        if ( *(s4flg+ijg-1)>0 && *(s4flg+ijg-1)<7 ) flag = 1;
+        if ( flag && *(s4flg+ijg)>0 && *(s4flg+ijg)<7 ) {
+          jj = jg; 
+          while (jj<js-1) {
+            if (*(u+(jj+1)*is+ig)==0) break;
+            *(s1flg+jj*is+ig) += 10;
+            *(s3flg+jj*is+ig-1) += 10; 
+            jj++;
+            if (! *(pflg+jj*is+ig) ) break;
+            if (*(s1flg+jj*is+ig)>9) break;
+            if (*(s3flg+jj*is+ig-1)>9) break; 
+          }
+          flag = 0;
+        }
+      } else flag=0;
+      ijg++;
+    }
+  }
+
+  /* Handle any holes resulting from missing data */
+
+  for (jg=1; jg<js-1; jg++) { 
+    ijg=jg*is+1;      
+    for (ig=1; ig<is-1; ig++) {
+      if ( ( *(pflg+ijg) && *(s4flg+ijg-1)>9 && *(s4flg+ijg)<10
+                       && *(s3flg+ijg-1)<10 && *(s1flg+ijg)<10 ) || 
+           ( ! *(pflg+ijg) && *(s4flg+ijg-1)>9 && *(s4flg+ijg)<10
+                       && *(s1flg+ijg)<10 && *(s1flg+ijg)>0) ) {
+        jj = jg; 
+        while (jj<js-1) {
+          if (*(u+(jj+1)*is+ig)==0) break;
+          *(s1flg+jj*is+ig) += 10;
+          *(s3flg+jj*is+ig-1) += 10; 
+          jj++;
+          if (! *(pflg+jj*is+ig) ) break;
+          if (*(s1flg+jj*is+ig)>9) break;
+          if (*(s3flg+jj*is+ig-1)>9) break; 
+        }
+      }
+      ijg++;
+    }
+  }
+
+  /* Above logic may put a flag in a box with an undefined corner.
+     Remove any such flags */
+
+  for (jg=0; jg<js-1; jg++) {
+    ijg=jg*is;
+    for (ig=0; ig<is-1; ig++) {
+      if ( *(u+ijg)==0 || *(u+ijg+1)==0 || *(u+ijg+is)==0 || *(u+ijg+is+1)==0) {
+        *(s1flg+ijg) = 0; *(s2flg+ijg) = 0; 
+        *(s3flg+ijg) = 0; *(s4flg+ijg) = 0; 
+      }
+      ijg++;
+    }
+  }
+}
+
+/* Use the flags to create closed polygons of the shaded area */
+
+void s2poly (gadouble *r, gaint is, gaint js, gadouble c1, gadouble c2) {
+gaint ig,jg,ijg,rc;
+
+  /* Loop thru grid boxes to find unused polygon edges.  */
+
+  for (jg=0; jg<js-1; jg++) {
+    ijg=jg*is;
+    for (ig=0; ig<is-1; ig++) {
+      rc = 0;
+      if (*(s1flg+ijg)) rc=s2follow(r,is,js,c1,c2,1,ig,jg);
+      if (*(s2flg+ijg)) rc=s2follow(r,is,js,c1,c2,2,ig,jg);
+      if (*(s3flg+ijg)) rc=s2follow(r,is,js,c1,c2,3,ig,jg);
+      if (*(s4flg+ijg)) rc=s2follow(r,is,js,c1,c2,4,ig,jg);
+      if (rc) return;
+      ijg++;
+    }
+  }
+}
+gaint s2follow (gadouble *r, gaint is, gaint js, gadouble c1, gadouble c2, gaint side,
+             gaint ig, gaint jg) {
+gadouble p1,p2,p3,p4;
+gaint ii,jj,ij,fl,sflg,n,k,rc;
+gaint f1,f2,f3,f4;
+
+  pnum = 0;
+
+  /* save starting point */
+
+  ii = ig;
+  jj = jg;
+  sflg = 0;
+
+  /* Follow the polygon edge that begins with the indicated box and side.  
+     Keep the interior to the right hand side.  
+     It seems natural here to go to the next intersection point by 
+       using goto's.  A rare case where goto's make sense.
+     The labels with "side" are of the form sidexyz, where x is the side number, 
+       y is either i for intersect or b for boundary, and z is 1 if we are intersecting
+       with c1 or 2 for a c2 intersect.  
+     The labels with "corner" indicate we are following a boundary and are 
+       going along sides of boxes from corner to corner.                   
+     Yes, there are 20 cases in all.
+     Cols are handled as individual grid boxes, due to their complexity. */
+
+    
+  ij = jj*is+ii;
+
+  if (side==1) {  
+    fl = *(s1flg+ij);
+    if (bug) printf ("entering side 1 %i %i %i\n",ii,jj,fl);
+    if (fl==5 || fl==6) goto skip; 
+    if (fl==1) {  ii--; ig--; side=3; goto side3i1; }
+    if (fl==2 || fl==12 || fl==16) goto side1i1;
+    if (fl==11 || fl==15) goto side1b1;
+    if (fl==3 || fl==13) goto side1i2;
+    if (fl==4) { ii--; jg--; side=3; goto side3i2; }
+    if (fl==14) goto side1b2;
+    if (fl==10) goto corner2;
+  }
+  if (side==2) {
+    fl = *(s2flg+ij);
+    if (bug) printf ("entering side 2 %i %i %i\n",ii,jj,fl);
+    if (fl==5 || fl==6) goto skip; 
+    if (fl==1) {  jj++; jg++; side=4; goto side4i1; }
+    if (fl==2 || fl==12 || fl==16) goto side2i1;
+    if (fl==11 || fl==15) goto side2b1;
+    if (fl==3 || fl==13) goto side2i2;
+    if (fl==4) { jj++; jg++; side=4; goto side4i2; }
+    if (fl==14) goto side2b2;
+    if (fl==10) goto corner3;
+  }
+  if (side==3) {
+    fl = *(s3flg+ij);
+    if (bug) printf ("entering side 3 %i %i %i\n",ii,jj,fl);
+    if (fl==5 || fl==6) goto skip;
+    if (fl==2) {  ii++; ig++; side=1; goto side1i1; }
+    if (fl==1 || fl==11 || fl==15) goto side3i1;
+    if (fl==12 || fl==16) goto side3b1;
+    if (fl==4 || fl==14) goto side3i2;
+    if (fl==3) { ii++; ig++; side=1; goto side1i2; }
+    if (fl==13) goto side3b2;
+    if (fl==10) goto corner4;
+  }
+  if (side==4) {
+    fl = *(s4flg+ij);
+    if (bug) printf ("entering side 4 %i %i %i\n",ii,jj,fl);
+    if (fl==5 || fl==6) goto skip;
+    if (fl==2) {  jj--; jg--; side=2; goto side2i1; }
+    if (fl==1 || fl==11 || fl==15) goto side4i1;
+    if (fl==12 || fl==16) goto side4b1;
+    if (fl==4 || fl==14) goto side4i2;
+    if (fl==3) { jj--; jg--; side=2; goto side2i2; }
+    if (fl==13) goto side4b2;
+    if (fl==10) goto corner1;
+  }
+
+  /* we should not get here */
+
+  goto err4;
+
+side1i1:    /* Enter on side 1; c1 intersect */
+  if (bug) printf ("side1 c1 %i %i %i %i\n",ii,jj,ig,jg);
+  ij = jj*is+ii;
+  p1 = *(rr+ij); p2 = *(rr+ij+isize);
+  s2ppnt( (gadouble)(ii+1), (gadouble)(jj+1) + (c1-p1)/(p2-p1) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f1<10 && f1 != *(s3flg+ij-1)) goto cerr;
+  if (sflg) {
+    if (f1==2) { *(s1flg+ij) = 0; *(s3flg+ij-1) = 0; } 
+    else if (f1==12 || f1==14) *(s1flg+ij) = 0; 
+    else if (f1==6) { *(s1flg+ij) = 4; *(s3flg+ij-1) = 4; } 
+    else if (f1==16) *(s1flg+ij) = 14; 
+    if (ii==ig && jj==jg && side==1) goto done;
+  }
+  sflg = 1;
+  if ( (f4==2 || f4==6 || f4==12 || f4==16) &&
+       (f2==1 || f2==5 || f2==11 || f2==15) )  {   /* col */
+    if (s2col(c1,ii,jj)) {
+      if (f2==1 || f2==5) {jj++; goto side4i1; } 
+      else goto side2b1;  
+    } else {
+      if (f4==2 || f4==6) {jj--; goto side2i1; } 
+      else goto side4b1;  
+    }
+  }
+  if (f4==2 || f4==6) {jj--; goto side2i1; } 
+  if (f3==2 || f3==6) {ii++; goto side1i1; } 
+  if (f2==1 || f2==5) {jj++; goto side4i1; } 
+  if (f4==12 || f4==16) goto side4b1;  
+  if (f3==12 || f3==16) goto side3b1;  
+  if (f2==11 || f2==15) goto side2b1;  
+  goto err1;
+  
+side2i1:   /* Enter on side 2; c1 intersect */ 
+  if (bug) printf ("side2 c1 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p2 = *(rr+ij+isize); p3 = *(rr+ij+isize+1);
+  s2ppnt( (gadouble)(ii+1) + (c1-p2)/(p3-p2) , (gadouble)(jj+2) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f2<10 && f2 != *(s4flg+ij+is)) goto cerr;
+  if (sflg) {
+    if (f2==2) { *(s2flg+ij) = 0; *(s4flg+ij+is) = 0; } 
+    else if (f2==12 || f2==14) *(s2flg+ij) = 0; 
+    else if (f2==6) { *(s2flg+ij) = 4; *(s4flg+ij+is) = 4; } 
+    else if (f2==16) *(s2flg+ij) = 14; 
+    if (ii==ig && jj==jg && side==2) goto done;
+  }
+  sflg = 1;
+  if ( (f1==1 || f1==5 || f1==11 || f1==15) &&
+       (f3==2 || f3==6 || f3==12 || f3==16) )  {   /* col */
+    if (s2col(c1,ii,jj)) {
+      if (f1==1 || f1==5) {ii--; goto side3i1; } 
+      else goto side1b1;  
+    } else {
+      if (f3==2 || f3==6) {ii++; goto side1i1; } 
+      else goto side3b1;  
+    }
+  }
+  if (f1==1 || f1==5) {ii--; goto side3i1; } 
+  if (f4==2 || f4==6) {jj--; goto side2i1; } 
+  if (f3==2 || f3==6) {ii++; goto side1i1; } 
+  if (f1==11 || f1==15) goto side1b1;  
+  if (f4==12 || f4==16) goto side4b1;  
+  if (f3==12 || f3==16) goto side3b1;  
+  goto err1;
+
+side3i1:   /* Enter on side 3; c1 intersect */ 
+  if (bug) printf ("side3 c1 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p3 = *(rr+ij+isize+1); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+2), (gadouble)(jj+1) + (c1-p4)/(p3-p4) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f3<10 && f3 != *(s1flg+ij+1)) goto cerr;
+  if (sflg) {
+    if (f3==1) { *(s3flg+ij) = 0; *(s1flg+ij+1) = 0; } 
+    else if (f3==11 || f3==13) *(s3flg+ij) = 0; 
+    else if (f3==5) { *(s3flg+ij) = 3; *(s1flg+ij+1) = 3; } 
+    else if (f3==15) *(s3flg+ij) = 13; 
+    if (ii==ig && jj==jg && side==3) goto done;
+  }
+  sflg = 1;
+  if ( (f2==1 || f2==5 || f2==11 || f2==15) &&
+       (f4==2 || f4==6 || f4==12 || f4==16) )  {   /* col */
+    if (s2col(c1,ii,jj)) {
+      if (f4==2 || f4==6) {jj--; goto side2i1; } 
+      else goto side4b1;  
+    } else {
+      if (f2==1 || f2==5) {jj++; goto side4i1; } 
+      else goto side2b1;  
+    }
+  }
+  if (f2==1 || f2==5) {jj++; goto side4i1; } 
+  if (f1==1 || f1==5) {ii--; goto side3i1; } 
+  if (f4==2 || f4==6) {jj--; goto side2i1; } 
+  if (f2==11 || f2==15) goto side2b1;  
+  if (f1==11 || f1==15) goto side1b1;  
+  if (f4==12 || f4==16) goto side4b1;  
+  goto err1;
+
+side4i1:   /* Enter on side 4; c1 intersect */ 
+  if (bug) printf ("side4 c1 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p1 = *(rr+ij); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+1) + (c1-p1)/(p4-p1) , (gadouble)(jj+1) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f4<10 && f4 != *(s2flg+ij-is)) goto cerr;
+  if (sflg) {
+    if (f4==1) { *(s4flg+ij) = 0; *(s2flg+ij-is) = 0; } 
+    else if (f4==11 || f4==13) *(s4flg+ij) = 0; 
+    else if (f4==5) { *(s4flg+ij) = 3; *(s2flg+ij-is) = 3; } 
+    else if (f4==15) *(s4flg+ij) = 13; 
+    if (ii==ig && jj==jg && side==4) goto done;
+  }
+  sflg = 1;
+  if ( (f3==2 || f3==6 || f3==12 || f3==16) &&
+       (f1==1 || f1==5 || f1==11 || f1==15) )  {   /* col */
+    if (s2col(c1,ii,jj)) {
+      if (f3==2 || f3==6) {ii++; goto side1i1; } 
+      else goto side3b1;  
+    } else {
+      if (f1==1 || f1==5) {ii--; goto side3i1; } 
+      else goto side1b1;  
+    }
+  }
+  if (f3==2 || f3==6) {ii++; goto side1i1; } 
+  if (f2==1 || f2==5) {jj++; goto side4i1; } 
+  if (f1==1 || f1==5) {ii--; goto side3i1; } 
+  if (f3==12 || f3==16) goto side3b1;  
+  if (f2==11 || f2==15) goto side2b1;  
+  if (f1==11 || f1==15) goto side1b1;  
+  goto err1;
+
+side1i2:   /* Enter on side 1; c2 intersect */
+  if (bug) printf ("side1 c2 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p1 = *(rr+ij); p2 = *(rr+ij+isize);
+  s2ppnt( (gadouble)(ii+1), (gadouble)(jj+1) + (c2-p1)/(p2-p1) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f1<10 && f1 != *(s3flg+ij-1)) goto cerr;
+  if (sflg) {
+    if (f1==3) { *(s1flg+ij) = 0; *(s3flg+ij-1) = 0; } 
+    else if (f1==13 || f1==11) *(s1flg+ij) = 0; 
+    else if (f1==5) { *(s1flg+ij) = 1; *(s3flg+ij-1) = 1; } 
+    else if (f1==15) *(s1flg+ij) = 11; 
+    if (ii==ig && jj==jg && side==1) goto done;
+  }
+  sflg = 1;
+  if ( (f4==3 || f4==5 || f4==13 || f4==15) &&
+       (f2==4 || f2==6 || f2==14 || f2==16) )  {   /* col */
+    if (s2col(c2,ii,jj)) {
+      if (f2==4 || f2==6) {jj++; goto side4i2; } 
+      else goto side2b2;  
+    } else {
+      if (f4==3 || f4==5) {jj--; goto side2i2; } 
+      else goto side4b2;  
+    }
+  }
+  if (f4==3 || f4==5) {jj--; goto side2i2; } 
+  if (f3==3 || f3==5) {ii++; goto side1i2; } 
+  if (f2==4 || f2==6) {jj++; goto side4i2; } 
+  if (f4==13 || f4==15) goto side4b2;  
+  if (f3==13 || f3==15) goto side3b2;  
+  if (f2==14 || f2==16) goto side2b2;  
+  goto err2;
+
+side2i2:   /* Enter on side 2; c2 intersect */
+  if (bug) printf ("side2 c2 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p2 = *(rr+ij+isize); p3 = *(rr+ij+isize+1);
+  s2ppnt( (gadouble)(ii+1) + (c2-p2)/(p3-p2) , (gadouble)(jj+2) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f2<10 && f2 != *(s4flg+ij+is)) goto cerr;
+  if (sflg) {
+    if (f2==3) { *(s2flg+ij) = 0; *(s4flg+ij+is) = 0; } 
+    else if (f2==13 || f2==11) *(s2flg+ij) = 0; 
+    else if (f2==5) { *(s2flg+ij) = 1; *(s4flg+ij+is) = 1; } 
+    else if (f2==15) *(s2flg+ij) = 11; 
+    if (ii==ig && jj==jg && side==2) goto done;
+  }
+  sflg = 1;
+  if ( (f1==4 || f1==6 || f1==14 || f1==16) &&
+       (f3==3 || f3==5 || f3==13 || f3==15) )  {   /* col */
+    if (s2col(c2,ii,jj)) {
+      if (f1==4 || f1==6) {ii--; goto side3i2; } 
+      else goto side1b2;  
+    } else {
+      if (f3==3 || f3==5) {ii++; goto side1i2; } 
+      else goto side3b2;  
+    }
+  }
+  if (f1==4 || f1==6) {ii--; goto side3i2; } 
+  if (f4==3 || f4==5) {jj--; goto side2i2; } 
+  if (f3==3 || f3==5) {ii++; goto side1i2; } 
+  if (f1==14 || f1==16) goto side1b2;  
+  if (f4==13 || f4==15) goto side4b2;  
+  if (f3==13 || f3==15) goto side3b2;  
+  goto err2;
+
+side3i2:   /* Enter on side 3; c2 intersect */
+  if (bug) printf ("side3 c2 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p3 = *(rr+ij+isize+1); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+2), (gadouble)(jj+1) + (c2-p4)/(p3-p4) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f3<10 && f3 != *(s1flg+ij+1)) goto cerr;
+  if (sflg) {
+    if (f3==4) { *(s3flg+ij) = 0; *(s1flg+ij+1) = 0; } 
+    else if (f3==14 || f3==12) *(s3flg+ij) = 0; 
+    else if (f3==6) { *(s3flg+ij) = 2; *(s1flg+ij+1) = 2; } 
+    else if (f3==16) *(s3flg+ij) = 12; 
+    if (ii==ig && jj==jg && side==3) goto done;
+  }
+  sflg = 1;
+  if ( (f2==4 || f2==6 || f2==14 || f2==16) &&
+       (f4==3 || f4==5 || f4==13 || f4==15) )  {   /* col */
+    if (s2col(c2,ii,jj)) {
+      if (f4==3 || f4==5) {jj--; goto side2i2; } 
+      else goto side4b2;  
+    } else {
+      if (f2==4 || f2==6) {jj++; goto side4i2; } 
+      else goto side2b2;  
+    }
+  }
+  if (f2==4 || f2==6) {jj++; goto side4i2; } 
+  if (f1==4 || f1==6) {ii--; goto side3i2; } 
+  if (f4==3 || f4==5) {jj--; goto side2i2; } 
+  if (f2==14 || f2==16) goto side2b2;  
+  if (f1==14 || f1==16) goto side1b2;  
+  if (f4==13 || f4==15) goto side4b2;  
+  goto err2;
+
+side4i2:   /* Enter on side 4; c2 intersect */
+  if (bug) printf ("side4 c2 %i %i\n",ii,jj);
+  ij = jj*is+ii;
+  p1 = *(rr+ij); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+1) + (c2-p1)/(p4-p1) , (gadouble)(jj+1) );
+  f1 = *(s1flg+ij); f2 = *(s2flg+ij); f3 = *(s3flg+ij); f4 = *(s4flg+ij); 
+  if (f4<10 && f4 != *(s2flg+ij-is)) goto cerr;
+  if (sflg) {
+    if (f4==4) { *(s4flg+ij) = 0; *(s2flg+ij-is) = 0; } 
+    else if (f4==14 || f4==12) *(s4flg+ij) = 0; 
+    else if (f4==6) { *(s4flg+ij) = 2; *(s2flg+ij-is) = 2; } 
+    else if (f4==16) *(s4flg+ij) = 12; 
+    if (ii==ig && jj==jg && side==4) goto done;
+  }
+  sflg = 1;
+  if ( (f3==3 || f3==5 || f3==13 || f3==15) &&
+       (f1==4 || f1==6 || f1==14 || f1==16) )  {   /* col */
+    if (s2col(c2,ii,jj)) {
+      if (f3==3 || f3==5) {ii++; goto side1i2; } 
+      else goto side3b2;  
+    } else {
+      if (f1==4 || f1==6) {ii--; goto side3i2; } 
+      else goto side1b2;  
+    }
+  }
+  if (f3==3 || f3==5) {ii++; goto side1i2; } 
+  if (f2==4 || f2==6) {jj++; goto side4i2; } 
+  if (f1==4 || f1==6) {ii--; goto side3i2; } 
+  if (f3==13 || f3==15) goto side3b2;  
+  if (f2==14 || f2==16) goto side2b2;  
+  if (f1==14 || f1==16) goto side1b2;  
+  goto err2;
+
+side1b1:   /* Hit boundary on side1; c1 intersect  */
+  if (bug) printf ("side1 b c1 %i %i\n",ii,jj);
+  p1 = *(rr+ij); p2 = *(rr+ij+isize);
+  s2ppnt( (gadouble)(ii+1), (gadouble)(jj+1) + (c1-p1)/(p2-p1) );
+  if (sflg && ii==ig && jj==jg && side==1) {
+    *(s1flg+ij) = 0;
+    goto done;
+  }
+  if (*(s1flg+ij)==15) { *(s1flg+ij)=11; goto side1i2; }
+  goto corner2;
+
+side2b1:   /* Hit boundary on side2; c1 intersect  */
+  if (bug) printf ("side2 b c1 %i %i\n",ii,jj);
+  p2 = *(rr+ij+isize); p3 = *(rr+ij+isize+1);
+  s2ppnt( (gadouble)(ii+1) + (c1-p2)/(p3-p2) , (gadouble)(jj+2) );
+  if (sflg && ii==ig && jj==jg && side==2) {
+    *(s2flg+ij) = 0;
+    goto done;
+  }
+  if (*(s2flg+ij)==15) { *(s2flg+ij)=11; goto side2i2; }
+  goto corner3;
+
+side3b1:   /* Hit boundary on side3; c1 intersect  */
+  if (bug) printf ("side3 b c1 %i %i\n",ii,jj);
+  p3 = *(rr+ij+isize+1); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+2), (gadouble)(jj+1) + (c1-p4)/(p3-p4) );
+  if (sflg && ii==ig && jj==jg && side==3) {
+    *(s3flg+ij) = 0;
+    goto done;
+  }
+  if (*(s3flg+ij)==16) { *(s3flg+ij)=12; goto side3i2; }
+  goto corner4;
+
+side4b1:   /* Hit boundary on side4; c1 intersect  */
+  if (bug) printf ("side4 b c1 %i %i\n",ii,jj);
+  p1 = *(rr+ij); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+1) + (c1-p1)/(p4-p1) , (gadouble)(jj+1) );
+  if (sflg && ii==ig && jj==jg && side==4) {
+    *(s4flg+ij) = 0;
+    goto done;
+  }
+  if (*(s4flg+ij)==16) { *(s4flg+ij)=12; goto side4i2; }
+  goto corner1;
+
+side1b2:   /* Hit boundary on side1; c2 intersect  */
+  if (bug) printf ("side1 b c2 %i %i\n",ii,jj);
+  p1 = *(rr+ij); p2 = *(rr+ij+isize);
+  s2ppnt( (gadouble)(ii+1), (gadouble)(jj+1) + (c2-p1)/(p2-p1) );
+  p1 = *(rr+ij); p2 = *(rr+ij+isize);
+  s2ppnt( (gadouble)(ii+1), (gadouble)(jj+1) + (c2-p1)/(p2-p1) );
+  if (sflg && ii==ig && jj==jg && side==1) {
+    *(s1flg+ij) = 0;
+    goto done;
+  }
+  if (*(s1flg+ij)==16) { *(s1flg+ij)=14; goto side1i1; }
+  goto corner2;
+
+side2b2:   /* Hit boundary on side2; c2 intersect  */
+  if (bug) printf ("side2 b c2 %i %i\n",ii,jj);
+  p2 = *(rr+ij+isize); p3 = *(rr+ij+isize+1);
+  s2ppnt( (gadouble)(ii+1) + (c2-p2)/(p3-p2) , (gadouble)(jj+2) );
+  if (sflg && ii==ig && jj==jg && side==2) {
+    *(s2flg+ij) = 0;
+    goto done;
+  }
+  if (*(s2flg+ij)==16) { *(s2flg+ij)=14; goto side2i1; }
+  goto corner3;
+
+side3b2:   /* Hit boundary on side3; c2 intersect  */
+  if (bug) printf ("side3 b c2 %i %i\n",ii,jj);
+  p3 = *(rr+ij+isize+1); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+2), (gadouble)(jj+1) + (c2-p4)/(p3-p4) );
+  if (sflg && ii==ig && jj==jg && side==3) {
+    *(s3flg+ij) = 0;
+    goto done;
+  }
+  if (*(s3flg+ij)==15) { *(s3flg+ij)=13; goto side3i1; }
+  goto corner4;
+
+side4b2:   /* Hit boundary on side4; c2 intersect  */
+  if (bug) printf ("side4 b c2 %i %i\n",ii,jj);
+  p1 = *(rr+ij); p4 = *(rr+ij+1);
+  s2ppnt( (gadouble)(ii+1) + (c2-p1)/(p4-p1) , (gadouble)(jj+1) );
+  if (sflg && ii==ig && jj==jg && side==4) {
+    *(s4flg+ij) = 0;
+    goto done;
+  }
+  if (*(s4flg+ij)==15) { *(s4flg+ij)=13; goto side4i1; }
+  goto corner1;
+
+corner1:  /* Arriving at corner 1 from the right */
+  if (bug) printf ("corner 1 %i %i\n",ii,jj);
+  s2ppnt((gadouble)(ii+1), (gadouble)(jj+1));
+  ij = jj*is+ii;
+  if (sflg) {
+    *(s4flg+ij) = 0;
+    if (ii==ig && jj==jg && side==4) goto done;
+  }
+  sflg = 1;
+  if (*(s1flg+ij)==10) goto corner2;
+  if (*(s1flg+ij)==12) goto side1i1;
+  if (*(s1flg+ij)==13) goto side1i2;
+  ii--;
+  if (*(s4flg+ij-1)==10) goto corner1;
+  if (*(s4flg+ij-1)==11) goto side4i1;
+  if (*(s4flg+ij-1)==14) goto side4i2;
+  jj--;
+  ij = jj*is+ii;
+  if (*(s3flg+ij)==10) goto corner4;
+  if (*(s3flg+ij)==11) goto side3i1;
+  if (*(s3flg+ij)==14) goto side3i2;
+  ii++; jj++; 
+  printf ("err 3 corner 1 %i %i\n",ii,jj);
+  goto err3;
+
+corner2:  /* Arriving at corner 2 from below */
+  if (bug) printf ("corner 2 %i %i\n",ii,jj);
+  s2ppnt((gadouble)(ii+1), (gadouble)(jj+2));
+  ij = jj*is+ii;
+  if (sflg) { 
+    *(s1flg+ij) = 0;
+    if (ii==ig && jj==jg && side==1) goto done;
+  }
+  sflg = 1;
+  if (*(s2flg+ij)==10) goto corner3;
+  if (*(s2flg+ij)==12) goto side2i1;
+  if (*(s2flg+ij)==13) goto side2i2;
+  jj++;
+  ij = jj*is+ii;
+  if (*(s1flg+ij)==10) goto corner2;
+  if (*(s1flg+ij)==12) goto side1i1;
+  if (*(s1flg+ij)==13) goto side1i2;
+  ii--;
+  if (*(s4flg+ij-1)==10) goto corner1;
+  if (*(s4flg+ij-1)==11) goto side4i1;
+  if (*(s4flg+ij-1)==14) goto side4i2;
+  ii++; jj--; 
+  printf ("err 3 corner 2 %i %i\n",ii,jj);
+  goto err3;
+
+corner3:  /* Arriving at corner 3 from the left */
+  if (bug) printf ("corner 3 %i %i\n",ii,jj);
+  s2ppnt((gadouble)(ii+2), (gadouble)(jj+2));
+  ij = jj*is+ii;
+  if (sflg) {
+    *(s2flg+ij) = 0;
+    if (ii==ig && jj==jg && side==2) goto done;
+  }
+  sflg = 1;
+  if (*(s3flg+ij)==10) goto corner4;
+  if (*(s3flg+ij)==11) goto side3i1;
+  if (*(s3flg+ij)==14) goto side3i2;
+  ii++;
+  if (*(s2flg+ij+1)==10) goto corner3;
+  if (*(s2flg+ij+1)==12) goto side2i1;
+  if (*(s2flg+ij+1)==13) goto side2i2;
+  jj++;
+  ij = jj*is+ii;
+  if (*(s1flg+ij)==10) goto corner2;
+  if (*(s1flg+ij)==12) goto side1i1;
+  if (*(s1flg+ij)==13) goto side1i2;
+  ii--; jj--; 
+  printf ("err 3 corner 3 %i %i\n",ii,jj);
+  goto err3;
+
+corner4:  /* Arriving at corner 4 from above */
+  if (bug) printf ("corner 4 %i %i\n",ii,jj);
+  s2ppnt((gadouble)(ii+2), (gadouble)(jj+1));
+  ij = jj*is+ii;
+  if (sflg) {
+    *(s3flg+ij) = 0;
+    if (ii==ig && jj==jg && side==3) goto done;
+  }
+  sflg = 1;
+  if (*(s4flg+ij)==10) goto corner1;
+  if (*(s4flg+ij)==11) goto side4i1;
+  if (*(s4flg+ij)==14) goto side4i2;
+  jj--;
+  ij = jj*is+ii;
+  if (*(s3flg+ij)==10) goto corner4;
+  if (*(s3flg+ij)==11) goto side3i1;
+  if (*(s3flg+ij)==14) goto side3i2;
+  ii++;
+  if (*(s2flg+ij+1)==10) goto corner3;
+  if (*(s2flg+ij+1)==12) goto side2i1;
+  if (*(s2flg+ij+1)==13) goto side2i2;
+  ii--; jj++; 
+  printf ("err 3 corner 4 %i %i\n",ii,jj);
+  goto err3;
+  goto err3;
+  
+done:
+  if (bug) printf ("done\n");
+
+  if (xynum<0) return(1);
+
+  xxyy[pnum*2] = xxyy[0];  /* Insure polygon closure */
+  xxyy[pnum*2+1] = xxyy[1]; 
+  pnum++;
+  k = 0;
+  for (n=1; n<pnum; n++) {     /* Remove adjacent dups */
+    if (fabs(xxyy[n*2]-xxyy[k*2]) > 1e-5 || fabs(xxyy[n*2+1]-xxyy[k*2+1]) > 1e-5) {
+      if (n!=k+1) {
+        xxyy[(k+1)*2] = xxyy[n*2];
+        xxyy[(k+1)*2+1] = xxyy[n*2+1];
+      }
+      k++;
+    }
+  }
+  k++;
+  if (bug) printf ("pnum %i %i\n",pnum,k);
+  if (k<3) return(0);
+
+  if (!nodraw) {
+    gxfill(xxyy,k);
+  }
+
+  if (bufopt) {
+    rc = s2bufpoly(k);
+    if (rc) {
+      s2frepbuf();
+      printf ("Memory error in shade2: Unable to allocate Polygon Buffer\n");
+      bufopt = 0;
+    }
+  }
+
+  if (bug) {
+    n = gxqclr();
+    gxcolr(0);
+    gxplot(xxyy[0],xxyy[1],3);
+    for (ii=1; ii<k; ii++) {
+      gxplot(xxyy[ii*2],xxyy[ii*2+1],2);
+    }
+    gxcolr(n);
+  }
+  return(0);
+
+skip:
+  return(0);
+
+err1:
+  printf("Logic Error 1 in gxshad2 s2follow\n");
+  return(1);
+err2:
+  printf("Logic Error 2 in gxshad2 s2follow\n");
+  return(1);
+err3:
+  printf("Logic Error 3 in gxshad2 s2follow\n");
+  return(1);
+err4:
+  printf("Logic Error 4 in gxshad2 s2follow\n");
+  return(1);
+cerr:
+  printf("Logic Error 5 in gxshad2 s2follow\n");
+  return(1);
+
+}
+
+
+/* Determine the intersect points in a single grid box for the polygons
+   that are in this grid box for the requested shading range.  The intersect
+   points are provided in the range of 0 to 1.  Check for a col, and if there
+   is a col, determine if there should be one polygon or two, and if two, 
+   determine what sides each polygon intersects.  
+
+       v4 --- v3
+        |     |
+        |     |
+       v1 --- v2
+
+   c1: lower contour level
+   c2: upper contour level
+
+   No undefs in this box.  Check before calling.
+*/
+
+void s2box (gadouble v1, gadouble v2, gadouble v3, gadouble v4, gadouble c1, gadouble c2) {
+gaint fl1a,fl1b,fl2a,fl2b,fl3a,fl3b,fl4a,fl4b,col1,col2; 
+gaint path1, path2;
+
+   numpoly = 0;
+
+   np = 0;
+   typ1 = 0; typ2 = 0; typ3 = 0;
+
+   fl1a = 0; fl1b = 0; fl2a = 0; fl2b = 0;
+   fl3a = 0; fl3b = 0; fl4a = 0; fl4b = 0;
+
+   /* Determine if a contour intersects a side. 
+      flag a = c1 intersects.  flab b = c2 intersects. */
+
+   if ( (v1<=c1 && v2>c1) || (v1>c1 && v2<=c1) ) fl1a = 1;
+   if ( (v1<=c2 && v2>c2) || (v1>c2 && v2<=c2) ) fl1b = 1;
+
+   if ( (v2<=c1 && v3>c1) || (v2>c1 && v3<=c1) ) fl2a = 1;
+   if ( (v2<=c2 && v3>c2) || (v2>c2 && v3<=c2) ) fl2b = 1;
+
+   if ( (v3<=c1 && v4>c1) || (v3>c1 && v4<=c1) ) fl3a = 1;
+   if ( (v3<=c2 && v4>c2) || (v3>c2 && v4<=c2) ) fl3b = 1;
+
+   if ( (v4<=c1 && v1>c1) || (v4>c1 && v1<=c1) ) fl4a = 1;
+   if ( (v4<=c2 && v1>c2) || (v4>c2 && v1<=c2) ) fl4b = 1;
+
+   /* Travel around the box and find all the intersect points within
+      our contour range */
+
+   if (v1>c1 && v1<=c2) s2pdrop(0.0,0.0,1,1);
+   if (fl1a && fl1b) {  /* insure points are in order */
+     if (v2>=v1) { 
+       s2pdrop((c1-v1)/(v2-v1),0.0,2,1);
+       s2pdrop((c2-v1)/(v2-v1),0.0,3,1);
+     } else {
+       s2pdrop((c2-v1)/(v2-v1),0.0,3,1);
+       s2pdrop((c1-v1)/(v2-v1),0.0,2,1);
+     }
+   }
+   else if (fl1a) s2pdrop((c1-v1)/(v2-v1),0.0,2,1);
+   else if (fl1b) s2pdrop((c2-v1)/(v2-v1),0.0,3,1);
+
+   if (v2>c1 && v2<=c2) s2pdrop(1.0,0.0,1,2);
+   if (fl2a && fl2b) {
+     if (v3>=v2) {
+       s2pdrop(1.0,(c1-v2)/(v3-v2),2,2);
+       s2pdrop(1.0,(c2-v2)/(v3-v2),3,2);
+     } else {
+       s2pdrop(1.0,(c2-v2)/(v3-v2),3,2);
+       s2pdrop(1.0,(c1-v2)/(v3-v2),2,2);
+     }
+   }
+   else if (fl2a) s2pdrop(1.0,(c1-v2)/(v3-v2),2,2);
+   else if (fl2b) s2pdrop(1.0,(c2-v2)/(v3-v2),3,2);
+
+   if (v3>c1 && v3<=c2) s2pdrop(1.0,1.0,1,3);
+   if (fl3a && fl3b) {
+     if (v4>=v3) {
+       s2pdrop((c1-v4)/(v3-v4),1.0,2,3);
+       s2pdrop((c2-v4)/(v3-v4),1.0,3,3);
+     } else {
+       s2pdrop((c2-v4)/(v3-v4),1.0,3,3);
+       s2pdrop((c1-v4)/(v3-v4),1.0,2,3);
+     }
+   }
+   else if (fl3a) s2pdrop((c1-v4)/(v3-v4),1.0,2,3);
+   else if (fl3b) s2pdrop((c2-v4)/(v3-v4),1.0,3,3);
+
+   if (v4>c1 && v4<=c2) s2pdrop(0.0,1.0,1,4);
+   if (fl4a && fl4b) {
+     if (v1>=v4) {
+       s2pdrop(0.0,(c1-v1)/(v4-v1),2,4);
+       s2pdrop(0.0,(c2-v1)/(v4-v1),3,4);
+     } else {
+       s2pdrop(0.0,(c2-v1)/(v4-v1),3,4);
+       s2pdrop(0.0,(c1-v1)/(v4-v1),2,4);
+     }
+   }
+   else if (fl4a) s2pdrop(0.0,(c1-v1)/(v4-v1),2,4);
+   else if (fl4b) s2pdrop(0.0,(c2-v1)/(v4-v1),3,4);
+  
+   if (np==0) return;  /* If no intersects, just return */
+
+   numpoly = 1;
+   polyside = 1;
+
+   /* Check for col  */
+
+   col1 = 0; col2 = 0;
+   if (fl1a && fl2a && fl3a && fl4a) col1 = 1;
+   if (fl1b && fl2b && fl3b && fl4b) col2 = 1;
+   
+   if (col1 && col2) {  /* both levels are cols */
+     path1 = s2pathln(c1,v1,v2,v3,v4);
+     path2 = s2pathln(c2,v1,v2,v3,v4);
+     if (path1==path2) {
+       numpoly = 2;
+       if (path1==0) polyside = 2;
+     }
+   }
+   else if (col1) {  /* only lower level is a col */
+     path1 = s2pathln(c1,v1,v2,v3,v4);
+     if (path1==1) {
+       if (v1<=c1) {
+         numpoly = 2;
+       }
+     } else {
+       if (v2<=c1) {
+         numpoly = 2;
+         polyside = 2;
+       }
+     }
+   }
+   else if (col2) {  /* only upper level is a col */
+     path2 = s2pathln(c2,v1,v2,v3,v4);
+     if (path2==1) {
+       if (v1>c2) {
+         numpoly = 2;
+       }
+     } else {
+       if (v2>c2) {
+          numpoly = 2;
+          polyside = 2;
+       }
+     }
+   }
+
+}
+
+void s2ppnt(gadouble x, gadouble y) {
+gadouble xx,yy,*xynew;
+gaint i;
+
+  if (xynum<0) return;
+
+  /* Increase polygon buffer size if necessary */
+
+  if (pnum>xynum-3) {
+    xynum = xynum*2;
+    if (bug) printf ("Poly buff memory for %i points\n",xynum);
+    xynew = (gadouble *)(galloc(sizeof(gadouble)*xynum*2,"s2xynew"));
+    if (xynew==NULL) {
+      printf ("Memory allocation error in gxshad2. \n");
+      printf ("--Unable to allocate memory for polygon buffer.\n");
+      gree (xxyy,"s12");
+      xynum = -999;
+      return;
+    }
+    for (i=0; i<pnum*2; i++) *(xynew+i) = *(xxyy+i);
+    gree (xxyy,"s13");
+    xxyy = xynew;
+  }
+
+  gxconv (x,y,&xx,&yy,3);
+  *(xxyy+pnum*2) = xx;
+  *(xxyy+pnum*2+1) = yy;
+    
+  pnum++;
+}
+
+/* Add an intersect point to the array of points. Also add a corner point
+   if it is inside the range of clevs.  Keep track of what type of point it
+   it is: an intersect with the lower clev, upper clev, or a corner point */
+
+void s2pdrop(gadouble x, gadouble y, gaint type, gaint side) {
+  if (type==1) typ1++;
+  if (type==2) typ2++;
+  if (type==3) typ3++;
+  xp[np] = x; yp[np] = y; 
+  tp[np] = type; sp[np] = side;
+  np++;
+}
+
+/* Interface to s2pathln -- the convenction for ordering of the points in a
+   box is not the same between gxcntr and gxshad2  */
+
+gaint s2col (gadouble vv, gaint ii, gaint jj) {
+gadouble p1,p2,p3,p4;
+gaint ij,rc;
+
+  ij = jj*isize + ii;
+  p1 = *(rr+ij);
+  p2 = *(rr+ij+1);
+  p3 = *(rr+ij+isize+1);
+  p4 = *(rr+ij+isize);
+
+  rc = s2pathln (vv,p1,p2,p3,p4);
+
+  return (rc);
+}
+  
+/* Calculate shortest combined path length through a col point.
+   Return true if shortest path is side 1/2,3/4, else false.  */
+
+/*  THIS IS THE SAME AS IN GXCNTR, except the contour level is 
+     passed as an arg. THIS NEEDS TO BE THE SAME AS THE VERSION IN GXCNTR
+     SO THE SHADE BOUNDARIES ALIGN WITH LINE CONTOURS. */
+
+gaint s2pathln (gadouble vv, gadouble p1, gadouble p2, gadouble p3, gadouble p4) {
+float v1,v2,v3,v4,d1,d2;
+
+  v1 = (vv-p1)/(p2-p1);
+  v2 = (vv-p2)/(p3-p2);
+  v3 = (vv-p4)/(p3-p4);
+  v4 = (vv-p1)/(p4-p1);
+  d1 = hypot(1.0-v1, v2) + hypot(1.0-v4, v3);
+  d2 = hypot(v1, v4) + hypot(1.0-v2, 1.0-v3);
+  if (d2<d1) return (0);
+  return (1);
+} 
+
+/* for debugging... plot flags */
+
+void s2debug () {
+gaint ig,jg,offset,mk=0;
+gadouble sz,xxx,yyy;
+
+  sz = 0.03;
+  gxclip (0.0,11.0,0.0,8.5);
+  for (jg=0; jg<jsize-1; jg++) {
+    for (ig=0; ig<isize-1; ig++) {
+      offset=jg*isize+ig;
+
+      if (*(pflg+offset)) gxcolr(1); else gxcolr(2);
+      gxconv ((gadouble)ig+1.0,(gadouble)jg+1.0,&xxx,&yyy,3);
+      gxmark (3,xxx,yyy,sz);
+      if (*(s1flg+offset)) {
+        gxcolr(3);
+ /*       if (*(s1flg+offset)>7) gxcolr(12);
+          if (*(s1flg+offset)>10 && *(s1flg+offset)<20) gxcolr(6); */
+        if (*(s1flg+offset)>9) gxcolr(6);
+        if (*(s1flg+offset)==88) {gxcolr(6); mk = 1; sz = 0.06;}
+        gxconv ((gadouble)ig+1.1,(gadouble)jg+1.5,&xxx,&yyy,3);
+        gxmark (mk,xxx,yyy,sz);
+      }
+      if (*(s2flg+offset)) {
+        gxcolr(3);
+          /* if (*(s2flg+offset)>7) gxcolr(12);
+          if (*(s2flg+offset)>10 && *(s2flg+offset)<20) gxcolr(6); */
+        if (*(s2flg+offset)>9) gxcolr(6);
+        gxconv ((gadouble)ig+1.5,(gadouble)jg+1.9,&xxx,&yyy,3);
+        gxmark (3,xxx,yyy,sz);
+      }
+      if (*(s3flg+offset)) {
+        gxcolr(3);
+          /* if (*(s3flg+offset)>7) gxcolr(12);
+          if (*(s3flg+offset)>90) gxcolr(7);
+          if (*(s3flg+offset)>10 && *(s3flg+offset)<20) gxcolr(6); */
+        if (*(s3flg+offset)>9) gxcolr(6);
+        gxconv ((gadouble)ig+1.9,(gadouble)jg+1.5,&xxx,&yyy,3);
+        gxmark (3,xxx,yyy,sz);
+      }
+      if (*(s4flg+offset)) {
+        gxcolr(3);
+          /* if (*(s4flg+offset)>7) gxcolr(12);
+          if (*(s4flg+offset)>90) gxcolr(7);
+          if (*(s4flg+offset)>10 && *(s4flg+offset)<20) gxcolr(6); */
+        if (*(s4flg+offset)>9) gxcolr(6);
+        gxconv ((gadouble)ig+1.5,(gadouble)jg+1.1,&xxx,&yyy,3);
+        gxmark (3,xxx,yyy,sz);
+      }
+    }
+  }
+}
+
+/* When polygon buffering is requested, put the current polygon into 
+   the s2pbuf chain */
+
+gaint s2bufpoly (gaint pcnt) {
+struct s2pbuf *ppbuf;
+gaint sz,i;
+
+  sz = sizeof(struct s2pbuf);
+  ppbuf = (struct s2pbuf *) galloc(sz,"s2ppbuf"); 
+  if (ppbuf==NULL) return (1);
+  if (s2pbufanch==NULL) {
+    s2pbufanch = ppbuf;
+    bufcnt = 0;
+  } else s2pbuflast->fpbuf = ppbuf;
+  s2pbuflast = ppbuf;
+  ppbuf->fpbuf = NULL;
+
+  /* Allocate space for the poly points */
+
+  ppbuf->len = pcnt; 
+  sz = sizeof(gadouble)*pcnt*2;
+  ppbuf->xy = (gadouble *) galloc(sz,"s2bufxy");
+  if (ppbuf->xy==NULL) return(1);
+
+  /* Copy the poly points and info */
+
+  for (i=0;i<pcnt*2;i++) *(ppbuf->xy+i) = *(xxyy+i); 
+
+  ppbuf->color = gxqclr();
+  ppbuf->index = gindex;
+  ppbuf->clev1 = blev;
+  ppbuf->clev2 = alev;
+
+  bufcnt++;
+  return(0);
+}
+
+/* Free the polygon buffer */
+
+void s2frepbuf () {
+struct s2pbuf *ppbuf,*p2;
+
+ ppbuf = s2pbufanch;
+ while (ppbuf) {
+   p2 = ppbuf->fpbuf;
+   if (ppbuf->xy) gree (ppbuf->xy,"s14");
+   gree (ppbuf,"s15");
+   ppbuf = p2;
+ }
+ s2pbufanch = NULL;
+ s2pbuflast = NULL;
+}
+
+/* Turn buffering on/off */
+
+void s2setbuf(gaint flg) {
+  bufopt = flg; 
+}
+
+/* Turn drawing of polygons on/off. If 1, polygons are not drawn */
+
+void s2setdraw(gaint flg) {
+  nodraw = flg; 
+}
+
+
+/* When gxout shape is in use, this routine is called 
+   to dump all the polygon vertices to the shapefile.
+   For each polygon in the buffer: 
+     - get the vertex x/y coordinates 
+     - convert them to lon/lat 
+     - write out the vertices ('measured' value for each polygon is color #)
+     - write out the attributes (clev1 and clev2 are the dynamic values) 
+   The polygon buffer is released in gagx, inside the gashpwrt() routine. 
+
+   Returns -1 on error, otherwise returns number of shapes written to file.
+*/
+#if USESHP==1
+gaint s2shpwrt (SHPHandle sfid, DBFHandle dbfid, struct dbfld *dbanch) {
+gaint i,rc,ival;
+struct dbfld *fld;
+struct s2pbuf *pbuf=NULL;
+gaint shpid,*pstart=NULL,nParts,nFields;
+SHPObject *shp;
+gadouble x,y,*lons=NULL,*lats=NULL,*vals=NULL,lon,lat,val,dval;
+ 
+ nParts = 1;
+ nFields = 1;
+ pstart = (gaint*)galloc(nParts*sizeof(gaint),"pstart");
+ *pstart = 0;
+ shpid=0;
+ 
+ pbuf = s2pbufanch;
+ if (pbuf==NULL) {
+   printf("Error in s2shpwrt: polygon buffer is empty\n");
+   rc = -1; 
+   goto cleanup;
+ }
+ while (pbuf) { 
+   if (pbuf->xy) {
+     /* allocate memory for lons and lats of the vertices in polygon */
+     if ((lons = (gadouble*)galloc (pbuf->len*sizeof(gadouble),"shplons"))==NULL) {
+       printf("Error in s2shpwrt: unable to allocate memory for lon array\n");
+       rc = -1;
+       goto cleanup;
+     }
+     if ((lats = (gadouble*)galloc (pbuf->len*sizeof(gadouble),"shplats"))==NULL) {
+       printf("Error in s2shpwrt: unable to allocate memory for lat array\n");
+       rc = -1;
+       goto cleanup;
+     }
+     if ((vals = (gadouble*)galloc (pbuf->len*sizeof(gadouble),"shpvals"))==NULL) {
+       printf("Error in s2shpwrt: unable to allocate memory for val array\n");
+       rc = -1;
+       goto cleanup;
+     }
+     /* get x,y values and convert them to lon,lat */
+     for (i=0; i<pbuf->len; i++) {
+       x = *(pbuf->xy+(2*i)); 
+       y = *(pbuf->xy+(2*i+1)); 
+       gxxy2w (x,y,&lon,&lat);
+       *(lons+i) = lon;
+       *(lats+i) = lat;
+       *(vals+i) = (gadouble)pbuf->index;  /* the index number is used as the polygon's measure value */
+     }
+     /* create the shape, write it out, then release it */
+     shp = SHPCreateObject (SHPT_POLYGONM,shpid,nParts,pstart,NULL,pbuf->len,lons,lats,NULL,vals);
+     i = SHPWriteObject(sfid,-1,shp);
+     SHPDestroyObject(shp);
+     if (i!=shpid) {
+       printf("Error in s2shpwrt: SHPWriteObject returned %d, shpid=%d\n",i,shpid);
+       rc = -1;
+       goto cleanup;
+     }
+     gree(lons,"c10"); lons=NULL;
+     gree(lats,"c11"); lats=NULL;
+     gree(vals,"c12"); vals=NULL;
+     /* write out the attribute fields for this shape */
+     fld = dbanch;           /* point to the first one */
+     while (fld != NULL) {
+       if (fld->flag==0) {   /* static fields */
+	 if (fld->type==FTString) {
+	   DBFWriteStringAttribute (dbfid,shpid,fld->index,(const char *)fld->value);
+	 } else if (fld->type==FTInteger) {
+	   intprs(fld->value,&ival);
+	   DBFWriteIntegerAttribute (dbfid,shpid,fld->index,ival);
+	 } else if (fld->type==FTDouble) {
+	   getdbl(fld->value,&dval);
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,dval);
+	 }
+       }
+       else {                /* dynamic fields */
+	 if (strcmp(fld->name,"INDEX")==0) {
+	   val = pbuf->index;
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+	 }
+	 else if (strcmp(fld->name,"MIN_VALUE")==0) {
+	   val = pbuf->clev1;
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+	 }
+	 else if (strcmp(fld->name,"MAX_VALUE")==0) {
+	   val = pbuf->clev2;
+	   DBFWriteDoubleAttribute (dbfid,shpid,fld->index,val);
+	 }
+
+       }
+       fld = fld->next;      /* advance to next field */
+     }
+     shpid++;
+   }
+   pbuf = pbuf->fpbuf;
+ }
+ /* if no errors, return the number of polygons written to the file */
+ rc = shpid;
+ 
+ cleanup:
+ if (lons) gree (lons,"c7");
+ if (lats) gree (lats,"c8");
+ if (vals) gree (vals,"c8");
+ if (pstart) gree (pstart,"c9");
+
+ return (rc);
+}
+#endif
+
+/* Routine to write out polygon vertices to a KML file. 
+   For each polygon in the buffer: 
+     get the vertex x/y coordinates, 
+     convert them to lon/lat, 
+     write out the coordinates to the kmlfile,
+     release storage and return. 
+   Returns -1 on error, otherwise the number of polygons written. 
+*/
+gaint s2polyvert (FILE *kmlfp)  {
+struct s2pbuf *pbuf=NULL;
+gadouble lon,lat,x,y;  
+gaint i,j,c,err;
+
+ err=0;
+ c=0;
+ pbuf = s2pbufanch;
+ if (pbuf==NULL) {
+   printf("Error in s2polyvert: polygon buffer is empty\n");
+   err = 1; 
+   goto cleanup;
+ }
+ while (pbuf) { 
+   if (pbuf->xy) {
+     /* write out headers for each polygon */
+     snprintf(pout,511,"    <Placemark>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=1; goto cleanup;}
+     snprintf(pout,511,"      <styleUrl>#%d</styleUrl>\n",pbuf->color);
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=2; goto cleanup;}
+     snprintf(pout,511,"      <name>%g to %g</name>\n",pbuf->clev1,pbuf->clev2);
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=3; goto cleanup;}
+     snprintf(pout,511,"      <Polygon>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=4; goto cleanup;}
+     snprintf(pout,511,"        <altitudeMode>clampToGround</altitudeMode>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=5; goto cleanup;}
+     snprintf(pout,511,"        <tessellate>1</tessellate>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=6; goto cleanup;}
+     snprintf(pout,511,"        <outerBoundaryIs>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=7; goto cleanup;}
+     snprintf(pout,511,"          <LinearRing>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=8; goto cleanup;}
+     snprintf(pout,511,"            <coordinates>\n              ");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=9; goto cleanup;}
+     /* get x,y values and convert them to lon,lat */
+     j=1;
+     for (i=0; i<pbuf->len; i++) {
+       x = *(pbuf->xy+(2*i)); 
+       y = *(pbuf->xy+(2*i+1)); 
+       gxxy2w (x,y,&lon,&lat);
+       if (lat>90)  lat = 90;
+       if (lat<-90) lat = -90;
+
+       snprintf(pout,511,"%g,%g,0 ",lon,lat); 
+       if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=10; goto cleanup;}
+       if (j==6 || i==(pbuf->len-1)) { 
+	 if (j==6) snprintf(pout,511,"\n              "); 
+	 else snprintf(pout,511,"\n"); 
+	 if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=11; goto cleanup;}
+	 j=0;
+       }
+       j++;
+     }
+
+     /* write out footers for each polygon */
+     snprintf(pout,511,"            </coordinates>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=12; goto cleanup;}
+     snprintf(pout,511,"          </LinearRing>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=13; goto cleanup;}
+     snprintf(pout,511,"        </outerBoundaryIs>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=14; goto cleanup;}
+     snprintf(pout,511,"      </Polygon>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=15; goto cleanup;}
+     snprintf(pout,511,"    </Placemark>\n");
+     if ((fwrite(pout,sizeof(char),strlen(pout),kmlfp))!=strlen(pout)) {err=16; goto cleanup;}
+     c++;
+   }
+   pbuf = pbuf->fpbuf;
+ }
+ cleanup:
+ if (err) return (-1);
+ else return (c);
+}
diff --git a/src/gxstrm.c b/src/gxstrm.c
new file mode 100644
index 0000000..900ffa0
--- /dev/null
+++ b/src/gxstrm.c
@@ -0,0 +1,336 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <math.h>
+#include "gatypes.h"
+#include "gx.h"
+
+void gxstrm (gadouble *u, gadouble *v, gadouble *c, gaint is, gaint js,
+   char *umask, char *vmask, char *cmask, gaint flag, gadouble *shdlvs,
+   gaint *shdcls, gaint shdcnt, gaint den, gadouble strmarrd, gadouble strmarrsz,
+   gaint strmarrt) {
+gadouble x,y,xx,yy;
+gadouble *up, *vp, *cp, cv1,cv2,cv;
+gadouble uv1,uv2,uv,vv1,vv2,vv,auv,avv,xsav,ysav,xold=0.0,yold=0.0;
+gadouble fact,rscl,xxsv,yysv,xstrt,ystrt;
+gadouble xx1,yy1,xx2,yy2,adj,dacum,tacum;
+gaint i,ii,jj,ii1,ij1,i2,j2,ipt,acnt,icol,scol,dis;
+gaint *it,siz,iacc,iisav,iscl,imn,imx,jmn,jmx,iz,jz,iss,jss,bflg;
+char *upmask,*vpmask,*cpmask;
+
+  scol = -9;
+  icol = 1;
+
+  /* Figure out the interval for the flag grid */
+
+  i = is;
+  if (js>i) i = js;
+  iscl = 200/i;
+  iscl = iscl + den - 5;
+  if (iscl<1) iscl=1;
+  if (iscl>10) iscl=10;
+  ii = 1;
+  if (den<0) {           /* Support very high resolution grids */
+    ii = -1 * (den-1);
+    if (ii>10) ii = 10;
+    if ((is<200 || js<100) && ii>2) ii=2;    /* Limit downscaling to only high res */
+    if ((is<500 || js<250) && ii>5) ii=5;
+    if ((is<1000 || js<500) && ii>10) ii=10;
+    if ((is<1500 || js<750) && ii>15) ii=15;
+    if (ii>20) ii=20;
+  }
+  rscl = (gadouble)iscl/(gadouble)ii;
+  fact = 0.5/rscl;
+  /* if (fact<0.3) fact = 0.3; */
+
+  /* Allocate memory for the flag grid */
+
+  iss = is*iscl/ii; jss = js*iscl/ii;
+  siz = iss*jss;
+  it = (gaint *)malloc(sizeof(gaint) * siz);
+  if (it==NULL) {
+    printf ("Cannot allocate memory for streamline function\n");
+    return;
+  }
+  for (i=0; i<siz; i++) *(it+i) = 0;
+
+  /* Loop through flag grid to look for start of streamlines.  
+     To start requires no streams drawn within surrounding 
+     flag boxes.  */
+
+  i2 = 0;
+  j2 = 0;
+  for (i=0; i<siz; i++) {
+    dis = 2;
+    if (den<5) dis = 3;
+    if (den>5) dis = 1;
+    if (den<0) dis = 1;
+    if (den<-5) dis = 2;
+    imn = i2-dis; imx = i2+dis+1; 
+    jmn = j2-dis; jmx = j2+dis+1;
+    if (imn<0) imn = 0;
+    if (imx>iss) imx = iss;
+    if (jmn<0) jmn = 0;
+    if (jmx>jss) jmx = jss;
+    iacc = 0;
+    for (jz=jmn; jz<jmx; jz++) {
+      ipt = jz*iss+imn;
+      for (iz=imn; iz<imx; iz++) {
+        iacc = iacc + *(it+ipt);
+        ipt++;
+      }
+    }
+    if (iacc==0){
+      x = ((gadouble)i2)/rscl;
+      y = ((gadouble)j2)/rscl;
+      xsav = x;
+      ysav = y;
+      xstrt = x; ystrt = y;
+      gxconv (x+1.0,y+1.0,&xx,&yy,3);
+      gxplot (xx,yy,3);
+      xxsv = xx; yysv = yy;
+      iisav = -999;
+      iacc = 0;
+      acnt = 0;
+      dacum = 0.0;
+      tacum = 0.0;
+      bflg = 0;
+      while (x>=0.0 && x<(gadouble)(is-1) && y>=0.0 && y<(gadouble)(js-1)) {
+        ii = (gaint)x;
+        jj = (gaint)y;
+        xx = x - (gadouble)ii;
+        yy = y - (gadouble)jj;
+        up = u + jj*is+ii; upmask = umask + jj*is+ii;  
+        vp = v + jj*is+ii; vpmask = vmask + jj*is+ii; 
+        if (*upmask==0 || 
+	    *(upmask+1)==0 ||
+            *(upmask+is)==0 || 
+	    *(upmask+is+1)==0) break;
+        if (*vpmask==0 || 
+	    *(vpmask+1)==0 ||
+            *(vpmask+is)==0 || 
+	    *(vpmask+is+1)==0) break;
+        if (flag) {
+          cp = c + jj*is+ii; cpmask = cmask + jj*is+ii;
+          if (*cpmask==0 || 
+	      *(cpmask+1)==0 ||
+              *(cpmask+is)==0 || 
+	      *(cpmask+is+1)==0) icol = 15;
+          else {
+            cv1 = *cp + (*(cp+1)-*cp)*xx;
+            cv2 = *(cp+is) + (*(cp+is+1)-*(cp+is))*xx;
+            cv = cv1 + (cv2-cv1)*yy;
+            icol = gxshdc(shdlvs,shdcls,shdcnt,cv);
+          }
+          if (icol!=scol && icol>-1) gxcolr(icol);
+          scol = icol;
+        }
+        uv1 = *up + (*(up+1)-*up)*xx;
+        uv2 = *(up+is) + (*(up+is+1)-*(up+is))*xx;
+        uv = uv1 + (uv2-uv1)*yy;
+        vv1 = *vp + (*(vp+1)-*vp)*xx;
+        vv2 = *(vp+is) + (*(vp+is+1)-*(vp+is))*xx;
+        vv = vv1 + (vv2-vv1)*yy;
+        auv = fabs(uv); avv=fabs(vv);
+        if (auv<0.1 && avv<0.1) break;
+        if (auv>avv) {
+          vv = vv*fact/auv;
+          uv = uv*fact/auv;
+        } else {
+          uv = uv*fact/avv;
+          vv = vv*fact/avv;
+        }
+        gxconv (x+1.0,y+1.0,&xx,&yy,3);     /* account for localized grid distortions */
+        gxconv (x+1.1,y+1.0,&xx1,&yy1,3);
+        gxconv (x+1.0,y+1.1,&xx2,&yy2,3);
+        adj = hypot(xx-xx1,yy-yy1)/hypot(xx-xx2,yy-yy2);
+        if (adj>1.0) uv=uv/adj;
+        else vv = vv*adj;
+        if (fabs(uv)<1e-6 && fabs(vv)<1e-6) break;
+        x = x + uv;
+        y = y + vv;
+        ii1 = (gaint)(x*rscl);
+        ij1 = (gaint)(y*rscl);
+        ii1 = ij1*iss + ii1;
+        if (ii1<0 || ii1>=siz) break;
+        if (*(it+ii1)==1) break;
+        if (ii1!=iisav && iisav>-1) *(it+iisav) = 1;
+        if (ii1==iisav) iacc++;
+        else {iacc = 0; tacum = 0; }
+        if (iacc>10 && tacum<0.1) break;
+        if (iacc>100) break;
+        iisav = ii1;
+        gxconv (x+1.0,y+1.0,&xx,&yy,3);
+        if (icol>-1) {
+          if (bflg) {gxplot(xold,yold,3); bflg=0;}
+          gxplot (xx,yy,2);
+        } else bflg = 1;
+        dacum += hypot(xx-xold,yy-yold);
+        tacum += hypot(xx-xold,yy-yold);
+        acnt++;
+        if (dacum>strmarrd) {
+          if (icol>-1) strmar (xxsv,yysv,xx,yy,strmarrsz,strmarrt);
+          acnt = 0; dacum = 0.0;
+        }
+        xold = xx;
+        yold = yy;
+        xxsv = xx; yysv = yy;
+      }
+      bflg = 0;
+      x = xsav; y = ysav;
+      gxconv (x+1.0,y+1.0,&xx,&yy,3);
+      gxplot (xx,yy,3);
+      xxsv = xx;
+      yysv = yy;
+      iisav = -999;
+      iacc = 0;
+      acnt = 19;
+      dacum = 0.0;
+      tacum = 0.0;
+      while (x>=0.0 && x<(gadouble)(is-1) && y>=0.0 && y<(gadouble)(js-1)) {
+        ii = (gaint)x;
+        jj = (gaint)y;
+        xx = x - (gadouble)ii;
+        yy = y - (gadouble)jj;
+        up = u + jj*is+ii; upmask = umask + jj*is+ii;  
+        vp = v + jj*is+ii; vpmask = vmask + jj*is+ii; 
+        if (*upmask==0 || 
+	    *(upmask+1)==0 ||
+            *(upmask+is)==0 || 
+	    *(upmask+is+1)==0) break;
+        if (*vpmask==0 || 
+	    *(vpmask+1)==0 ||
+            *(vpmask+is)==0 || 
+	    *(vpmask+is+1)==0) break;
+        if (flag) {
+          cp = c + jj*is+ii; cpmask = cmask + jj*is+ii; 
+          if (*cpmask==0 || 
+	      *(cpmask+1)==0 ||
+              *(cpmask+is)==0 || 
+	      *(cpmask+is+1)==0) icol = 15;
+          else {
+            cv1 = *cp + (*(cp+1)-*cp)*xx;
+            cv2 = *(cp+is) + (*(cp+is+1)-*(cp+is))*xx;
+            cv = cv1 + (cv2-cv1)*yy;
+            icol = gxshdc(shdlvs,shdcls,shdcnt,cv);
+          }
+          if (icol!=scol && icol>-1) gxcolr(icol);
+          scol = icol;
+        }
+        uv1 = *up + (*(up+1)-*up)*xx;
+        uv2 = *(up+is) + (*(up+is+1)-*(up+is))*xx;
+        uv = uv1 + (uv2-uv1)*yy;
+        vv1 = *vp + (*(vp+1)-*vp)*xx;
+        vv2 = *(vp+is) + (*(vp+is+1)-*(vp+is))*xx;
+        vv = vv1 + (vv2-vv1)*yy;
+        auv = fabs(uv); avv=fabs(vv);
+        if (auv<0.1 && avv<0.1) break;
+        if (auv>avv) {
+          vv = vv*fact/auv;
+          uv = uv*fact/auv;
+        } else {
+          uv = uv*fact/avv;
+          vv = vv*fact/avv;
+        }
+        gxconv (x+1.0,y+1.0,&xx,&yy,3);     /* account for localized grid distortions */
+        gxconv (x+1.1,y+1.0,&xx1,&yy1,3);
+        gxconv (x+1.0,y+1.1,&xx2,&yy2,3);
+        adj = hypot(xx-xx1,yy-yy1)/hypot(xx-xx2,yy-yy2);
+        if (adj>1.0) uv=uv/adj;
+        else vv = vv*adj;
+        if (fabs(uv)<1e-6 && fabs(vv)<1e-6) break;
+        x = x - uv;
+        y = y - vv;
+        ii1 = (gaint)(x*rscl);
+        ij1 = (gaint)(y*rscl);
+        ii1 = ij1*iss + ii1;
+        if (ii1<0 || ii1>=siz) break;
+        if (*(it+ii1)==1) break;
+        if (ii1!=iisav && iisav>-1) *(it+iisav) = 1;
+        if (ii1==iisav) iacc++;
+        else iacc = 0;
+        if (iacc>10 && tacum<0.1) break;
+        if (iacc>100) break;
+        iisav = ii1;
+        gxconv (x+1.0,y+1.0,&xx,&yy,3);
+        if (icol>-1) {
+          if (bflg) {gxplot(xold,yold,3); bflg=0;}
+          gxplot (xx,yy,2);
+        } else bflg = 1;
+        dacum += hypot(xx-xold,yy-yold);
+        tacum += hypot(xx-xold,yy-yold);
+        xold = xx;
+        yold = yy;
+        acnt++;
+        if (dacum>strmarrd) {
+          if (icol>-1) strmar(xx,yy,xxsv,yysv,strmarrsz,strmarrt);
+          acnt = 0; dacum=0.0;
+        }
+        xxsv = xx; yysv = yy;
+      }
+      ii1 = (gaint)(xstrt*rscl);
+      ij1 = (gaint)(ystrt*rscl);
+      ii1 = ij1*iss + ii1;
+      if (ii1>=0 || ii1<siz) *(it+ii1) = 1;
+    }
+    i2++;
+    if (i2==iss) { i2 = 0; j2++; }
+  }
+  free (it);
+}
+
+static gadouble a150 = 150.0*M_PI/180;
+
+void strmar (gadouble xx1, gadouble yy1, gadouble xx2, gadouble yy2, gadouble sz, gaint type) {
+gadouble dir,xy[8];
+
+  if (sz<0.0001) return;
+  dir = atan2(yy2-yy1,xx2-xx1);
+  xy[0] = xx2; xy[1] = yy2;
+  xy[2] = xx2+sz*cos(dir+a150); xy[3] = yy2+sz*sin(dir+a150);
+  xy[4] = xx2+sz*cos(dir-a150); xy[5] = yy2+sz*sin(dir-a150);
+  xy[6] = xx2; xy[7] = yy2;
+  if (type==1) {
+    gxplot (xx2,yy2,3);
+    gxplot (xy[2],xy[3],2);
+    gxplot (xx2,yy2,3);
+    gxplot (xy[4],xy[5],2);
+    gxplot (xx2,yy2,3);
+  }
+  if (type==2) {
+    gxfill(xy,4);
+  }
+}
+
+/* Given a shade value, return the relevent color */
+
+gaint gxshdc (gadouble *shdlvs, gaint *shdcls, gaint shdcnt, gadouble val) {
+gaint i;
+
+  if (shdcnt==0) return(1);
+  if (shdcnt==1) return(shdcls[0]);
+  if (val<shdlvs[1]) return(shdcls[0]);
+  for (i=1; i<shdcnt-1; i++) {
+    if (val>=shdlvs[i] && val<shdlvs[i+1])
+                 return(shdcls[i]); 
+  }
+  return(shdcls[shdcnt-1]);
+}
diff --git a/src/gxsubs.c b/src/gxsubs.c
new file mode 100644
index 0000000..af7e842
--- /dev/null
+++ b/src/gxsubs.c
@@ -0,0 +1,1090 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+/*  Low level graphics interface, providing scaling, line styles,
+    clipping, character drawing, metafile output, etc.         */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "gatypes.h"
+#include "gx.h"
+
+void *galloc(size_t,char *);
+void gree();
+
+/* The following variables are local to this file, and are used by
+   all the routines in the file.    */
+
+static char *datad = "/usr/local/lib/grads";
+static gadouble xsize, ysize;                /* Virtual size       */
+static gadouble rxsize, rysize;              /* Real size          */
+static gaint lwflg;                          /* Reduce lw due vpage*/
+static gadouble clminx,clmaxx,clminy,clmaxy; /* Clipping region    */
+static gaint cflag;                          /* Clipping flag      */
+static gaint mflag;                          /* mask flag          */
+static gadouble dash[8];                     /* Linestyle pattern  */
+static gaint dnum,lstyle;                    /* Current linestyle  */
+static gaint color;                          /* Current color      */
+static gaint lwide;                          /* Current linewidth  */
+static gadouble oldx,oldy;                   /* Previous position  */
+static gaint bufmod;                         /* Buffering mode     */
+static gadouble xsave,ysave,alen,slen;       /* Linestyle constants*/
+static gaint jpen,dpnt;
+static gaint bcol;                           /* Background color   */
+static gaint intflg;                         /* Batch flag         */
+static gaint reds[256],grns[256],blus[256];  /* Save defined color info */
+static void (*fconv) (gadouble, gadouble, gadouble *, gadouble *);
+                                             /* fconv points to proj rnt  */
+static void (*gconv) (gadouble, gadouble, gadouble *, gadouble *);
+                                             /* gconv points to grid rnt  */
+static void (*bconv) (gadouble, gadouble, gadouble *, gadouble *);
+                                             /* gconv points to grid rnt  */
+static char *mask;                           /* pointer to mask array */
+static gaint maskflg;                        /* mask flag; -999 no mask yet,
+                                                0 no mask used, 1 mask values set, -888 error  */
+static gaint masksize;                       /* Size of mask array */
+static gaint maskx;                          /* Size of a row in the array */
+
+/* For STNDALN, routines included are gxgnam and gxgsym */
+#ifndef STNDALN
+
+/* Initialize graphics output  */
+/* batch flag = 1, batch mode only (no graphics output) */
+
+void gxstrt (gadouble xmx, gadouble ymx, gaint batch, gaint hbufsz) {
+  gaint ii;
+
+  printf ("GX Package Initialization: Size = %g %g \n",xmx,ymx);
+  if (batch) printf ("Running in Batch mode\n");
+  intflg = !batch;
+  if (intflg) {
+    gxdbgn (xmx, ymx);
+    gxdcol (1);                             /* Initial device color    */
+    gxdwid (1);                             /* Initial line width      */
+  } else {
+    gxdbat ();
+  }
+  rxsize = xmx;  rysize = ymx;
+  clminx=0; clmaxx=xmx;                     /* Set clipping area       */
+  clminy=0; clmaxy=ymx;
+  xsave=0.0; ysave=0.0; lstyle=0; lwide = 1;
+  oldx=0.0; oldy=0.0;
+  fconv=NULL;                               /* No projection set up    */
+  gconv=NULL;                               /* No grid scaling set up  */
+  bconv=NULL;                               /* No back transform       */
+  gxscal (0.0,xmx,0.0,ymx,0.0,xmx,0.0,ymx); /* Linear scaling=inches*/
+  gxvpag (xmx,ymx,0.0,xmx,0.0,ymx);         /* Virtual page scaling */
+  gxchii();                                 /* Init character plotting */
+  bufmod=0;
+  bcol = 0;                                 /* Background is black     */
+  for (ii=0; ii<=255; ii++) reds[ii]=-999;
+  gxhnew(rxsize,rysize,hbufsz);             /* Init hardcopy buffering */
+  color = 1;
+  mask = NULL; maskflg = -999;              /* Don't allocate mask until first use */
+}
+
+/* Terminate graphics output */
+
+void gxend (void){                     /* Return screen to normal */
+  gxhend();
+  if (mask) free(mask);
+  if (intflg) gxdend();
+  printf ("GX package terminated \n");
+}
+
+/* Frame action.  Values for action are:
+      0 -- new frame (clear display), wait before clearing.
+      1 -- new frame, no wait.
+      2 -- New frame in double buffer mode.  If not supported
+           has same result as action=1.  Usage involves multiple
+           calls with action=2 to obtain an animation effect.  
+      7 -- new frame, but just clear graphics.  Do not clear  
+           event queue; redraw buttons. 
+      8 -- clear only the event queue.
+      9 -- clear only the X request buffer */
+
+void gxfrme (gaint action) {
+gaint scol,i;
+
+  if (action>7) { 
+    if (intflg) gxdfrm(action);
+    return;
+  }
+  gxmaskclear();
+  if (intflg) {
+    if (action==0) getchar();              /* Wait if requested    */
+    if (action!=2&&bufmod) {
+      gxdsgl ();
+      bufmod=0;
+    }
+    if (action==2&&(!bufmod)) {
+      gxddbl ();
+      bufmod=1;
+    }
+    if (bufmod) gxdswp ();
+    gxdfrm (action);
+  }
+
+  gxhfrm (action);                         /* Reset meta buffer */
+
+  for (i=16; i<=255; i++) {
+    if (reds[i]>-1) hout4i(-5,i,reds[i],grns[i],blus[i]);
+  }
+  if (bcol>0) {
+    scol = color;
+    gxcolr(bcol);
+    color = scol;
+    gxrecf (0.0, rxsize, 0.0, rysize);
+    if (intflg) gxdfrm (9);
+  }
+
+}
+
+/* Perform new frame stuff for redraw.  This primarily involves
+   the background color. */
+
+void gxsfrm (void) {
+  if (bcol>0) {
+    gxdcol(bcol);
+    gxdrec (0.0, rxsize, 0.0, rysize);
+    gxdcol(color);
+  }
+}
+
+/* Set color.  Colors are: 0 - black;  1 - white
+                           2 - red;    3 - green;    4 - blue
+                           5 - cyan;   6 - magenta   7 - yellow
+                           8 - orange; 9 - purple;  10 - lt. green
+                          11 - m.blue 12 - d.yellow 13 - aqua
+			  14 - d.purple 15  - gray
+   Other colors may be available but are defined by the device
+   driver.   */
+
+void gxcolr (gaint clr){                 /* Set color     */
+  if (clr<0) clr=0;
+  if (clr>255) clr=255; 
+  hout1(-3,clr);
+  if (intflg) gxdcol (clr);
+  color = clr;
+}
+
+/* Set and query background color */
+
+void gxbckg (gaint col) {
+  bcol = col;
+}
+
+gaint gxqbck (void) {
+  return(bcol);
+}
+
+gaint gxacol (gaint clr, gaint red, gaint green, gaint blue ) {
+gaint rtn;
+  rtn=1;
+  hout4i(-5,clr,red,green,blue);
+  if (intflg) rtn = gxdacl (clr, red, green, blue);
+  if (clr>15 && clr<=255) {
+    reds[clr] = red;
+    grns[clr] = green;
+    blus[clr] = blue;
+  }
+  return rtn;
+}
+
+
+/* Set line weight */
+
+void gxwide (gaint wid){                 /* Set width     */
+gaint hwid;
+  hwid = wid;
+  if (lwflg) hwid = (wid+1)/2;
+  hout2i(-4,hwid,wid);
+  if (intflg) gxdwid (wid);
+  lwide = wid;
+}
+
+
+/* Move to x, y with 'clipping'.  Clipping is implmented
+   corsely, where any move or draw point that is outside the
+   clip region is not plotted.                          */
+
+void gxmove (gadouble x, gadouble y) {        /* Move to x,y   */
+  mflag = 0;
+  oldx = x;
+  oldy = y;
+  if ( x<clminx || x>clmaxx || y<clminy || y>clmaxy ) {
+    cflag=1;
+    return;
+  }
+  cflag=0;
+  gxvcon(x,y,&x,&y);
+  hout2(-10,x,y);
+  if (intflg) gxdmov (x,y);
+}
+
+/* Draw to x, y with clipping */
+
+void gxdraw (gadouble x, gadouble y){        /* Draw to x,y   */
+gadouble xnew,ynew;
+gaint pos=0;
+  if ( x<clminx || x>clmaxx || y<clminy || y>clmaxy ) {
+    if (!cflag) {
+      bdterp (oldx,oldy,x,y,&xnew,&ynew);
+      gxvcon(xnew,ynew,&xnew,&ynew);
+      hout2(-11,xnew,ynew);
+      if (intflg) gxddrw (xnew,ynew);
+      cflag=1;
+    }
+    oldx = x; oldy = y;
+    return;
+  }
+  if (cflag) {
+    bdterp (oldx,oldy,x,y,&xnew,&ynew);
+    cflag=0;
+    gxvcon(xnew,ynew,&xnew,&ynew);
+    hout2(-10,xnew,ynew);
+    if (intflg) gxdmov (xnew,ynew);
+  }
+  oldx = x; oldy = y;
+  gxvcon(x,y,&x,&y);
+  if (maskflg>0) pos = ((gaint)(y*100.0))*maskx + (gaint)(x*100.0);
+  if (maskflg>0 && pos>0 && pos<masksize && *(mask+pos)=='1') {
+    hout2(-10,x,y);
+    if (intflg) gxdmov (x,y);
+    mflag = 1;
+    return;
+  }
+  if (mflag) {
+    hout2(-10,x,y);
+    if (intflg) gxdmov (x,y);
+    mflag = 0;
+    return;
+  }
+  hout2(-11,x,y);
+  if (intflg) gxddrw (x, y);
+}
+
+/* Draw lines in small segments, sometimes needed when masking is in use 
+   (eg, grid lines)  */
+
+void gxsdrw (gadouble x, gadouble y){ 
+gadouble xdif,ydif,xx,yy,slope,incr;
+gaint xnum,ynum,i;
+
+  if (maskflg > 0) {
+    ydif = fabs(oldy-y);
+    xdif = fabs(oldx-x);
+    if (ydif<0.03 && xdif<0.03) gxdraw(x,y);
+    else {
+      if (xdif>ydif) {
+        incr = 0.03;
+        if (ydif/xdif<0.3) incr = 0.02;
+        xnum = (gaint)(xdif/incr);
+        slope = (y-oldy)/(x-oldx);
+        xx = oldx; yy = oldy;
+        if (x < oldx) incr = -1.0 * incr;
+        for (i=0; i<xnum; i++) {
+          xx = xx + incr;
+          yy = yy + incr*slope;
+          gxdraw(xx,yy);
+        }
+        gxdraw(x,y);
+      } else {
+        incr = 0.03;
+        if (xdif/ydif<0.3) incr = 0.02;
+        ynum = (gaint)(ydif/incr);
+        slope = (x-oldx)/(y-oldy);
+        xx = oldx; yy = oldy;
+        if (y < oldy) incr = -1.0 * incr;
+        for (i=0; i<ynum; i++) {
+          xx = xx + incr*slope;
+          yy = yy + incr;
+          gxdraw(xx,yy);
+        }
+        gxdraw(x,y);
+      }
+    } 
+  } else {
+    gxdraw (x,y);
+  }
+}
+
+/* Set software linestyle */
+
+void gxstyl (gaint style) {              /* Set line style  */
+  if (style==-9) style=1;
+  lstyle=style;
+  if (style==2) {
+    dnum=1;
+    dash[0]=0.25;
+    dash[1]=0.1;  }
+  else if (style==3) {
+    dnum=1;
+    dash[0]=0.03;
+    dash[1]=0.03;   }
+  else if (style==4) {
+    dnum=3;
+    dash[0]=0.25;
+    dash[1]=0.1;
+    dash[2]=0.1;
+    dash[3]=0.1;   }
+  else if (style==5) {
+    dnum=1;
+    dash[0]=0.01;
+    dash[1]=0.08;  }
+  else if (style==6) {
+    dnum=3;
+    dash[0]=0.15;
+    dash[1]=0.08;
+    dash[2]=0.01; ;
+    dash[3]=0.08;   }
+  else if (style==7) {
+    dnum=5;
+    dash[0]=0.15;
+    dash[1]=0.08;
+    dash[2]=0.01;
+    dash[3]=0.08;
+    dash[4]=0.01;
+    dash[5]=0.08;  }
+  else lstyle=0;
+  slen=dash[0]; jpen=2; dpnt=0;
+}
+
+/* Move and draw with linestyles and clipping */
+
+void gxplot (gadouble x, gadouble y, gaint ipen ) {    /* Move or draw  */
+gadouble x1,y1;
+
+  if (lstyle<2) {
+     if (ipen==2) gxdraw (x,y);
+     else gxmove (x,y);
+     xsave=x; ysave=y;
+     return;
+  }
+  if (ipen==3) {
+    slen=dash[0];
+    dpnt=0;
+    jpen=2;
+    xsave=x;
+    ysave=y;
+    gxmove (x,y);
+    return;
+  }
+  alen=hypot ((x-xsave),(y-ysave));
+  if (alen<0.001) return;
+  while (alen>slen) {
+    x1=xsave+(x-xsave)*(slen/alen);
+    y1=ysave+(y-ysave)*(slen/alen);
+    if (jpen==2) gxdraw (x1,y1);
+            else gxmove (x1,y1);
+    dpnt+=1;
+    if (dpnt>dnum) dpnt=0;
+    slen=slen+dash[dpnt];
+    jpen+=1;
+    if (jpen>3) jpen=2;
+  }
+  slen=slen-alen;
+  xsave=x;
+  ysave=y;
+  if (jpen==2) gxdraw (x,y);
+          else gxmove (x,y);
+  if (slen<0.001) {
+    dpnt+=1;
+    if (dpnt>dnum) dpnt=0;
+    slen=dash[dpnt];
+    jpen+=1;
+    if (jpen>3) jpen=2;
+  }
+}
+
+/* Specify software clip region.  */
+
+void gxclip (gadouble xmin, gadouble xmax, gadouble ymin, gadouble ymax) {
+  clminx = xmin;
+  clmaxx = xmax;
+  clminy = ymin;
+  clmaxy = ymax;
+  if (clminx<0.0) clminx = 0.0;
+  if (clmaxx>xsize) clmaxx = xsize;
+  if (clminy<0.0) clminy = 0.0;
+  if (clmaxy>ysize) clmaxy = ysize;
+}
+
+/* Constants for linear scaling */
+
+static gadouble xm,xb,ym,yb;
+
+/* Specify low level linear scaling (scaling level 1) */
+
+void gxscal (gadouble xmin, gadouble xmax, gadouble ymin, gadouble ymax,
+             gadouble smin, gadouble smax, gadouble tmin, gadouble tmax){
+  xm=(xmax-xmin)/(smax-smin);
+  xb=xmin-(xm*smin);
+  ym=(ymax-ymin)/(tmax-tmin);
+  yb=ymin-(ym*tmin);
+}
+
+/* Constants for virtual page scaling */
+
+static gadouble vxm,vxb,vym,vyb;
+
+/* Specify virtual page scaling */
+
+void gxvpag (gadouble xmax, gadouble ymax,
+             gadouble smin, gadouble smax, gadouble tmin, gadouble tmax){
+gadouble xmin, ymin;
+  xmin = 0.0;
+  ymin = 0.0;
+  xsize = xmax;
+  ysize = ymax;
+  if (smin<0.0) smin=0.0;
+  if (smax>rxsize) smax = rxsize;
+  if (tmin<0.0) tmin=0.0;
+  if (tmax>rysize) tmax = rysize;
+  clminx = 0.0;
+  clmaxx = xmax;
+  clminy = 0.0;
+  clmaxy = ymax;
+  if ((smax-smin)/rxsize < 0.6 || (tmax-tmin)/rysize < 0.6) lwflg = 1;
+  else lwflg = 0;
+  vxm=(smax-smin)/(xmax-xmin);
+  vxb=smin-(vxm*xmin);
+  vym=(tmax-tmin)/(ymax-ymin);
+  vyb=tmin-(vym*ymin);
+}
+
+/* Do virtual page scaling conversion */
+
+void gxvcon (gadouble s, gadouble t, gadouble *x, gadouble *y) {
+  *x = s*vxm+vxb;
+  *y = t*vym+vyb;
+}
+ 
+void gxppvp (gadouble x, gadouble y, gadouble *s, gadouble *t) {
+  *s = (x-vxb)/vxm;
+  *t = (y-vyb)/vym;
+}
+
+
+/* Specify projection-level scaling, typically used for map
+   projections.  The address of the routine to perform the scaling
+   is provided.  This is scaling level 2, and is the level that
+   mapping is done. */
+
+void gxproj ( void (*fproj) (gadouble s, gadouble t, gadouble *x, gadouble *y)){
+
+  fconv=fproj;
+}
+
+/* Specify grid level scaling, typically used to convert a grid
+   to lat-lon values that can be input to the projection or linear
+   level scaling.  The address of a routine is provided to perform
+   the possibly non-linear scaling.  This is scaling level 3, and
+   is the level that contouring is done.  */
+
+void gxgrid ( void (*fproj) (gadouble s, gadouble t, gadouble *x, gadouble *y)){
+
+  gconv=fproj;
+}
+
+/* Convert coordinates at a particular level to level 0 coordinates
+   (hardware coords, 'inches').  The level of the input coordinates
+   is provided.  User projection and grid scaling routines are called
+   as needed.  */
+
+void gxconv (gadouble s, gadouble t, gadouble *x, gadouble *y, gaint level) { 
+
+  if (level>2 && gconv!=NULL) (*gconv)(s,t,&s,&t);
+  if (level>1 && fconv!=0) (*fconv)(s,t,&s,&t);
+  if (level>0) {
+    s=s*xm+xb;
+    t=t*ym+yb;
+  }
+  *x=s;
+  *y=t;
+}
+
+/* Convert from level 0 coordinates (inches) to level 2 world
+   coordinates.  The back transform is done via conversion
+   linearly from level 0 to level 1, then calling the back
+   transform map routine, if available, to do level 1 to level
+   2 transform.  */
+
+void gxxy2w (gadouble x, gadouble y, gadouble *s, gadouble *t) { 
+
+  /* Do level 0 to level 1 */
+  if (xm==0.0 || ym==0.0) {
+    *s = -999.9;
+    *t = -999.9;
+    return;
+  }
+  *s = (x-xb)/xm;
+  *t = (y-yb)/ym;
+
+  /* Do level 1 to level 2 */
+  if (bconv!=NULL) (*bconv)(*s,*t,s,t);
+}
+
+/* Allow caller to specify a routine to do the back transform from
+   level 1 to level 2 coordinates. */
+void gxback ( void (*fproj) (gadouble s, gadouble t, gadouble *x, gadouble *y)){
+
+  bconv=fproj;
+}
+
+
+/* Convert from grid coordinates to map coordinates (level 3 to level 2) */
+void gxgrmp (gadouble s, gadouble t, gadouble *x, gadouble *y) {
+
+  if (gconv!=NULL) (*gconv)(s,t,&s,&t);
+  *x = s;
+  *y = t;
+}
+
+/* Convert an array of higher level coordinates to level 0 coordinates.
+   The conversion is done 'in place' and the input coordinates are
+   lost.  This routine performs the same function as coord except is
+   somewhat more efficient for many coordinate transforms.         */
+
+void gxcord (gadouble *coords, gaint num, gaint level) {
+gaint i;
+gadouble *xy;
+
+  if (level>2 && gconv!=NULL) {
+    xy=coords;
+    for (i=0; i<num; i++) {
+      (*gconv) (*xy,*(xy+1),xy,xy+1);
+      xy+=2;
+    }
+  }
+
+  if (level>1 && fconv!=NULL) {
+    xy=coords;
+    for (i=0; i<num; i++) {
+      (*fconv) (*xy,*(xy+1),xy,xy+1);
+      xy+=2;
+    }
+  }
+
+  if (level>0) {
+    xy=coords;
+    for (i=0; i<num; i++) {
+      *xy = *xy*xm+xb;
+      xy++;
+      *xy = *xy*ym+yb;
+      xy++;
+    }
+  }
+}
+
+/* Delete level 3 or level 2 and level 3 scaling.  
+   Level 1 scaling cannot be deleted.  */
+
+void gxrset (gaint level) {
+
+  if (level > 2) gconv=NULL;
+  if (level > 1) { fconv=NULL; bconv=NULL; }
+}
+
+/* Plot a color filled rectangle.  */
+
+void gxrecf (gadouble xlo, gadouble xhi, gadouble ylo, gadouble yhi) {
+gadouble x;
+
+  if (xlo>xhi) {
+    x = xlo;
+    xlo = xhi;
+    xhi = x;
+  }
+  if (ylo>yhi) {
+    x = ylo;
+    ylo = yhi;
+    yhi = x;
+  }
+  if (xhi<=clminx || xlo>=clmaxx || yhi<=clminy || ylo>=clmaxy) return;
+  if (xlo<clminx) xlo = clminx;
+  if (xhi>clmaxx) xhi = clmaxx;
+  if (ylo<clminy) ylo = clminy;
+  if (yhi>clmaxy) yhi = clmaxy;
+  gxvcon (xlo,ylo,&xlo,&ylo);
+  gxvcon (xhi,yhi,&xhi,&yhi);
+  hout4(-6,xlo,xhi,ylo,yhi);
+  if (intflg) gxdrec (xlo, xhi, ylo, yhi);
+}
+
+/* Define fill pattern for rectangles and polygons. */
+
+void gxptrn (gaint typ, gaint den, gaint ang) {
+  hout3i(-12,typ,den,ang);
+  if (intflg) gxdptn (typ, den, ang);
+}
+
+/* query line width */
+
+gaint gxqwid (void) {
+  return (lwide);
+}
+
+/* query color */
+
+gaint gxqclr (void) {
+  return (color);
+}
+
+/* query non-default color rgb values*/
+
+void gxqrgb (gaint clr, gaint *r, gaint *g, gaint *b) {
+  if (clr>15 && clr<=255) {
+    *r = reds[clr];
+    *g = grns[clr];
+    *b = blus[clr];
+  } 
+  return;
+}
+
+/* query style */
+
+gaint gxqstl (void) {
+  return (lstyle);
+}
+
+/* Draw markers 1-5. */
+
+void gxmark (gaint mtype, gadouble x, gadouble y, gadouble siz ) {
+gadouble xy[80],siz2;
+gaint i,ii,cnt;
+
+  siz2 = siz/2.0;
+  if (mtype==1) {                      /* cross hair */
+    gxmove (x,y-siz2);
+    gxdraw (x,y+siz2);
+    gxmove (x-siz2,y);
+    gxdraw (x+siz2,y);
+    return;
+  }
+  if (mtype==2 || mtype==3 || mtype==10 || mtype==11) { /* circles */
+    if (siz<0.1) ii = 30;
+    else if (siz<0.3) ii = 15;
+    else ii = 10;
+    if (mtype>3) ii = 15;
+    cnt = 0;
+    for (i=60; i<415; i+=ii) {
+      xy[cnt*2]   = x + siz2*cos((gadouble)(i)*pi/180.0);
+      xy[cnt*2+1] = y + siz2*sin((gadouble)(i)*pi/180.0);
+      cnt++;
+    }
+    xy[cnt*2]   = xy[0];
+    xy[cnt*2+1] = xy[1];
+    cnt++;
+    if (mtype==2) {                  /* Open circle */
+      gxmove(xy[0],xy[1]);
+      for (i=1; i<cnt; i++) gxdraw (xy[i*2],xy[i*2+1]);
+    } else if (mtype==3) {           /* Filled circle */
+      gxfill (xy,cnt);
+    } else if (mtype==10) {          /* Scattered fill */
+      gxmove(xy[6],xy[7]);
+      for (i=4; i<14; i++) gxdraw (xy[i*2],xy[i*2+1]);
+      gxmove(xy[30],xy[31]);
+      for (i=16; i<25; i++) gxdraw (xy[i*2],xy[i*2+1]);
+      gxdraw (xy[0],xy[1]);
+      for (i=8; i<14; i++) xy[i] = xy[i+18];
+      xy[14] = xy[2]; xy[15] = xy[3];
+      gxfill (xy+2,7);
+    } else if (mtype==11) {          /* Broken fill */
+      xy[0]  = x + siz2*cos(68.0*pi/180.0);
+      xy[1]  = y + siz2*sin(68.0*pi/180.0);
+      xy[8]  = x + siz2*cos(112.0*pi/180.0);
+      xy[9]  = y + siz2*sin(112.0*pi/180.0);
+      xy[24] = x + siz2*cos(248.0*pi/180.0);
+      xy[25] = y + siz2*sin(248.0*pi/180.0);
+      xy[32] = x + siz2*cos(292.0*pi/180.0);
+      xy[33] = y + siz2*sin(292.0*pi/180.0);
+      gxmove(xy[0],xy[1]);
+      for (i=1; i<5; i++) gxdraw (xy[i*2],xy[i*2+1]);
+      gxmove(xy[24],xy[25]);
+      for (i=13; i<17; i++) gxdraw (xy[i*2],xy[i*2+1]);
+      xy[26] = xy[8]; xy[27] = xy[9];
+      gxfill (xy+8,10);
+      xy[50] = xy[0]; xy[51] = xy[1];
+      gxfill (xy+32,10);
+    }
+    return;
+  }
+  if (mtype==4 || mtype==5) {          /* Draw sqaures */
+    xy[0] = x-siz2; xy[1] = y+siz2;
+    xy[2] = x+siz2; xy[3] = y+siz2;
+    xy[4] = x+siz2; xy[5] = y-siz2;
+    xy[6] = x-siz2; xy[7] = y-siz2;
+    xy[8] = xy[0]; xy[9] = xy[1];
+    if (mtype==4) {
+      gxmove (xy[0],xy[1]);
+      for (i=1; i<5; i++) gxdraw (xy[i*2],xy[i*2+1]);
+    } else {
+      gxfill (xy,5);
+    }
+    return;
+  }
+  if (mtype==6) {                      /* ex marks the spot */
+    gxmove (x-siz2*0.71,y-siz2*0.71);
+    gxdraw (x+siz2*0.71,y+siz2*0.71);
+    gxmove (x-siz2*0.71,y+siz2*0.71);
+    gxdraw (x+siz2*0.71,y-siz2*0.71);
+    return;
+  }
+  if (mtype==7) {                      /* Open diamond */
+    gxmove (x-siz2*0.75,y);
+    gxdraw (x,y+siz2*1.1);
+    gxdraw (x+siz2*0.75,y);
+    gxdraw (x,y-siz2*1.1);
+    gxdraw (x-siz2*0.75,y);
+    return;
+  }
+  if (mtype==8 || mtype==9) {          /* Triangles */
+    xy[0] = x; xy[1] = y+siz2;
+    xy[2] = x+siz2*0.88; xy[3] = y-siz2*0.6;
+    xy[4] = x-siz2*0.88; xy[5] = y-siz2*0.6;
+    xy[6] = x; xy[7] = y+siz2;
+    if (mtype==8) {
+      gxmove (xy[0],xy[1]);
+      for (i=1; i<4; i++) gxdraw (xy[i*2],xy[i*2+1]);
+    } else {
+      gxfill (xy,4);
+    }
+    return;
+  }
+}
+
+/* Plot centered title.  Only supports angle of 0 and 90 */
+
+void gxtitl (char *chrs, gadouble x, gadouble y, gadouble height,
+             gadouble width, gadouble angle) {
+gadouble xx,yy;
+gaint len,i;
+
+  i = 0;
+  len = 0;
+  while (*(chrs+i)) {
+    if (*(chrs+i)!=' ') len=i+1;
+    i++;
+  }
+  if (len==0) return;
+
+  xx = x; yy = y;
+  if (angle > 45.0) {
+    yy = y - 0.5*width*(gadouble)len;
+  } else {
+    xx = x - 0.5*width*(gadouble)len;
+  }
+  gxchpl (chrs, len, xx, yy, height, width, angle);
+}
+
+/* Do polygon fill.  It is assumed the bulk of the work will be done
+   in hardware.  We do perform clipping at this level, and
+   actually do the work to clip at the clipping boundry.       */
+
+void gxfill (gadouble *xy, gaint num) {
+gadouble *r, *out, *buff, x, y, xybuff[40];
+gaint i,flag,onum,aflag;
+
+  if (num<3) return;
+
+  /* Do clipping.    */
+
+  aflag = 0;
+  if (num<10) buff = xybuff;
+  else {
+    buff = (gadouble *)malloc(sizeof(gadouble)*num*4);
+    if (buff==NULL) {
+      printf("Memory allocation error in gxfill.  Can't fill contour\n");
+      return;
+    }
+    aflag = 1;
+  }
+
+  r = xy;
+  out = buff;
+  onum = 0;
+  flag = 0;
+  if (*r<clminx || *r>clmaxx || *(r+1)<clminy || *(r+1)>clmaxy) flag=1;
+  for (i=0; i<num; i++) {
+    if (*r<clminx || *r>clmaxx || *(r+1)<clminy || *(r+1)>clmaxy) {
+      if (!flag) {
+        bdterp (*(r-2), *(r-1), *r, *(r+1), &x, &y);
+        *out = x;
+        *(out+1) = y;
+        onum++;
+        out+=2;
+      }
+      *out = *r;
+      *(out+1) = *(r+1);
+      if (*r<clminx) *out = clminx;
+      if (*r>clmaxx) *out = clmaxx;
+      if (*(r+1)<clminy) *(out+1) = clminy;
+      if (*(r+1)>clmaxy) *(out+1) = clmaxy;
+      onum++;
+      out+=2;
+      flag = 1;
+    } else {
+      if (flag) {
+        bdterp (*(r-2), *(r-1), *r, *(r+1), &x, &y);
+        *out = x;
+        *(out+1) = y;
+        onum++;
+        out+=2;
+      }
+      *out = *r;
+      *(out+1) = *(r+1);
+      onum++;
+      out+=2;
+      flag = 0;
+    }
+    r+=2;
+  }
+
+  r = buff;
+  for (i=0; i<onum; i++) {
+    gxvcon (*r,*(r+1),r,r+1);
+    r+=2;
+  }
+
+  /* Output to meta buffer if requested.   */
+
+  hout1(-7,onum);
+  r = buff;
+  hout2(-10,*r,*(r+1));
+  r+=2;
+  for (i=1; i<onum; i++) {
+    hout2(-11,*r,*(r+1));
+    r+=2;
+  }
+  hout0(-8);
+
+  /* Output to hardware */
+
+  if (intflg) gxdfil (buff, onum);
+  if (aflag) free(buff);
+}
+
+/* Perform edge interpolation for clipping  */
+
+void bdterp (gadouble x1, gadouble y1, gadouble x2, gadouble y2,
+             gadouble *x, gadouble *y) {
+
+  if (x1<clminx || x2<clminx || x1>clmaxx || x2>clmaxx) {
+    *x = clminx;
+    if (x1>clmaxx || x2>clmaxx) *x = clmaxx;
+    *y = y1 - ((y1-y2)*(x1-*x)/(x1-x2));
+    if (*y<clminy || *y>clmaxy) goto sideh;
+    return;
+  }
+
+  sideh:
+
+  if (y1<clminy || y2<clminy || y1>clmaxy || y2>clmaxy) {
+    *y = clminy;
+    if (y1>clmaxy || y2>clmaxy) *y = clmaxy;
+    *x = x1 - ((x1-x2)*(y1-*y)/(y1-y2));
+    return;
+  }
+}
+
+void gxbutn (gaint bnum, struct gbtn *pbn) {
+  hout1(-20,bnum);
+  gxdpbn(bnum, pbn, 0, 0, -1);
+}
+
+/* Set mask for a rectangular area */
+
+void gxmaskrec (gadouble xlo, gadouble xhi, gadouble ylo, gadouble yhi) {
+gaint siz,i,j,pos,ilo,ihi,jlo,jhi,jj;
+
+  if (maskflg == -888) return;
+
+  if (mask==NULL) {                     /* If not allocated yet, now's the time */
+    siz = (gaint)(rxsize*rysize*10000.0); 
+    mask = (char *)malloc(siz);
+    if (mask==NULL) {
+      printf ("Error allocating mask array memory\n");
+      printf ("Execution continues with no mask\n");
+      maskflg = -888;
+      return;
+    }
+    masksize = siz;
+    maskx = (gaint)(rxsize*100.0);
+    gxmaskclear();
+  } 
+  maskflg = 1;
+  
+  /* do clipping for the mask */
+  if (xlo<clminx && xhi<clminx) return;
+  if (xlo>clmaxx && xhi>clmaxx) return;
+  if (ylo<clminy && yhi<clminy) return;
+  if (ylo>clmaxy && yhi>clmaxy) return;
+
+  if (xlo<clminx) xlo=clminx;
+  if (xhi>clmaxx) xhi=clmaxx;
+  if (ylo<clminy) ylo=clminy;
+  if (yhi>clmaxy) yhi=clmaxy;
+
+  /* convert to virtual page coordinates */
+  gxvcon(xlo,ylo,&xlo,&ylo);
+  gxvcon(xhi,yhi,&xhi,&yhi);
+  
+  ilo = (gaint)(xlo*100.0);
+  ihi = (gaint)(xhi*100.0);
+  jlo = (gaint)(ylo*100.0);
+  jhi = (gaint)(yhi*100.0);
+  if (ilo<0) ilo = 0;
+  if (ihi<0) ihi = 0;
+  if (ilo>=maskx) ilo = maskx-1;
+  if (ihi>=maskx) ihi = maskx-1;
+  for (j=jlo; j<=jhi; j++) {
+    jj = j*maskx;
+    for (i=ilo; i<=ihi; i++) {
+      pos = jj+i;
+      if (pos>=0 && pos<masksize) *(mask+pos) = '1';
+    }
+  }
+}
+
+/* Given a rectangular area, check to see if it overlaps with any existing
+   mask.  This is used to avoid overlaying contour labels. */
+
+int gxmaskrq (gadouble xlo, gadouble xhi, gadouble ylo, gadouble yhi) {
+gaint i,j,ilo,ihi,jlo,jhi,jj,pos;
+
+  if (maskflg == -888) return(0);
+  if (mask==NULL) return (0);
+  if (maskflg==0) return (0);
+
+  /* If query region is partially or completely outside of clip area, indicate an overlap */
+
+  if (xlo<clminx || xhi>clmaxx || ylo<clminy || yhi>clmaxy) return(1);
+
+  /* convert to virtual page coordinates */
+  gxvcon(xlo,ylo,&xlo,&ylo);
+  gxvcon(xhi,yhi,&xhi,&yhi);
+  
+  ilo = (gaint)(xlo*100.0);
+  ihi = (gaint)(xhi*100.0);
+  jlo = (gaint)(ylo*100.0);
+  jhi = (gaint)(yhi*100.0);
+  if (ilo<0) ilo = 0;
+  if (ihi<0) ihi = 0;
+  if (ilo>maskx) ilo = maskx;
+  if (ihi>maskx) ihi = maskx;
+  for (j=jlo; j<=jhi; j++) {
+    jj = j*maskx;
+    for (i=ilo; i<=ihi; i++) {
+      pos = jj+i;
+      if (pos>=0 && pos<masksize) {
+        if (*(mask+pos) == '1') return(1);
+      }
+    }
+  }
+  return (0);
+}
+
+/* Set mask to unset state */
+
+void gxmaskclear(void) {
+gaint i;   
+  if (maskflg > 0)  {
+    for (i=0; i<masksize; i++) *(mask+i) = '0';
+    maskflg = 0;
+  }
+}
+
+#endif  /* matches #ifndef STNDALN */
+
+
+/* Query env symbol */
+
+char *gxgsym(char *ch) {
+  return (getenv(ch));
+}
+
+/* Construct full file path name from env symbol or default */
+
+char *gxgnam(char *ch) {
+char *fname, *ddir;
+gaint len,i,j;
+size_t sz;
+
+  /* calc partial length of output string */
+  len = 0;
+  i = 0;
+  while (*(ch+i)) { i++; len++;}
+
+  /* Query the env symbol */
+  ddir = gxgsym("GADDIR");
+
+  /* calc the total length of the output string */
+  if (ddir==NULL) {
+    i = 0;
+    while (*(datad+i)) { i++; len++;}
+  } else {
+    i = 0;
+    while (*(ddir+i)) { i++; len++;}
+  }
+
+  /* Allocate memory for the output */
+  sz = len+15;
+  fname = (char *)galloc(sz,"fname");
+  if (fname==NULL) {
+    printf ("Memory allocation error in data set open\n");
+    return (NULL);
+  }
+
+  /* fill in the directory depending on the value of the env var */
+  if (ddir==NULL) {
+    i = 0;
+    while (*(datad+i)) {
+      *(fname+i) = *(datad+i);
+      i++;
+    }
+  } else if (*ddir=='.') {
+    i = 0;
+  } else {
+    i = 0;
+    while (*(ddir+i)) {
+      *(fname+i) = *(ddir+i);
+      i++;
+    }
+  }
+
+  /* Insure a slash between dir name and file name */
+  if (i!=0 && *(fname+i-1)!='/') {
+    *(fname+i) = '/';
+    i++;
+  }
+
+  /* fill in the file name */
+  j = 0;
+  while (*(ch+j)) {
+    *(fname+i) = *(ch+j);
+    i++; j++;
+  }
+  *(fname+i) = '\0';
+
+  return (fname);
+}
+
diff --git a/src/gxtran.c b/src/gxtran.c
new file mode 100644
index 0000000..c642d88
--- /dev/null
+++ b/src/gxtran.c
@@ -0,0 +1,312 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Note that a GrADS metafile is composed of messages, which themselves
+   are composed of from one to five short integers.  In each case, 
+   the first integer contains the message type, which also indicates
+   how many arguments (and what type of arguments) follow.  Note that
+   if the argument is in plot units, it needs to be divided by 1000
+   to get floating point units.  */
+
+#include <stdio.h>
+#include <math.h>
+#include "grads.h"
+#include "gx.h"
+
+struct gamfcmn mfcmn;
+
+int help=0;
+void command_line_help(void) ;
+
+char buff[132];
+int pnt;
+FILE *infile;
+
+int nxtcmd (char *, char *);
+void xyccc (short, short, float *, float *);
+int fflag;
+
+/*mf 980115 -- 
+  increase buffer from 1000 to 10000 - this is dynamically allocated in gxmeta
+  gxtran was seg faulting for plots with BIG polygon files
+mf*/
+
+double xybuf[10000];
+
+int main (int argc, char *argv[])  {
+
+short opts[4];
+int cmd,i,j,iflag,rflag,aflag,gflag,wflag,rc;
+int cont,xyc,lcolor,fflag,fcnt;
+float xlo,xhi,ylo,yhi,xpos,ypos,xsiz,ysiz;
+char in[100],*ifi;
+
+
+  /* Parse command line arguments */
+
+  i = 1;
+  iflag = 0; rflag = 0; aflag = 0; gflag = 0; wflag = 0; xyc = 0;
+  ifi = NULL;
+  while (i<argc) {
+    if (*(argv[i])=='-' && *(argv[i]+1)=='h' && *(argv[i]+2)=='e' && *(argv[i]+3)=='l' && *(argv[i]+4)=='p' ) {
+      command_line_help();
+      return(0);
+    } else if (*(argv[i])=='-') {
+      j = 1;
+      while (*(argv[i]+j)) {
+        if (*(argv[i]+j)=='i') iflag = 1;
+        else if (*(argv[i]+j)=='i') iflag = 1;
+        else if (*(argv[i]+j)=='r') rflag = 1;
+        else if (*(argv[i]+j)=='a') aflag = 1;
+        else if (*(argv[i]+j)=='g') gflag = 1;
+        else printf ("Unknown flag %c; ignored.\n",*(argv[i]+j));
+        j++;
+      }
+    } else {
+      if (iflag) {ifi = argv[i]; iflag = 0;}
+      else if (gflag) { gxdgeo(argv[i]); wflag = 1; gflag = 0; }
+      else printf ("Unknown argument: %s.  Ignored.\n",argv[i]);
+    }
+    i++;
+  }
+
+  if (ifi==NULL) {
+    command_line_help();
+    nxtcmd (in,"Enter input file: ");
+    ifi = in;
+  }
+
+  infile = fopen(ifi,"rb");
+  if (infile == NULL) {
+    printf ("Cannot open input file: %s\n",ifi);
+    return 1;
+  }
+
+  pnt = 0;
+  fcnt = 0;
+  fflag = 0;
+
+  cont = 1;
+  while (cont) {
+    
+    /* Read the 1st integer, which is the message type */
+
+    rc = fread (opts , sizeof(short), 1, infile);
+    if (rc != 1) {
+      printf ("Error on fread of message type\n");
+      return 1;
+    }
+    cmd = opts[0];
+
+    /* -9 indicates end of file.  Terminate graphics output.
+       It is followed by 0 arguments */
+
+    if (cmd==-9) {
+      cont = 0;
+      if (aflag) gxfrme(0);
+      gxend();
+    }
+
+    /*  -1 indicates start of file.  It is followed by two arguments,
+        which are the X and Y size of the virtual device in plotter
+        units */ 
+
+    else if (cmd==-1) {
+      fread ((char *)opts, sizeof(short), 2, infile);
+      xyccc (opts[0],opts[1],&xsiz,&ysiz);
+      gxstrt (xsiz,ysiz,0,1000000);  /* default buffer size */
+      if (rflag) gxdbck(1);          
+      if (wflag) gxfrme(1);
+      else gxfrme(0);
+      if (aflag) gxfrme(2);
+    }
+  
+    /* -2 indicates new frame.  It has no arguments */
+
+    else if (cmd==-2) {
+      gxfrme(9);
+      if (aflag) gxfrme(2);
+      else gxfrme(0);
+    }
+
+    /* -3 indicates new color.  It has one argument, a color number.
+       Colors 0 to 15 are predefined; colors 16 through 99 are 
+       allowed to be user defined (colors 100 through 255 are 
+       reserved for image use, a feature under development). */
+  
+    else if (cmd==-3) {
+      fread ((char *)opts, sizeof(short), 1, infile);
+      lcolor = opts[0];
+      gxcolr(lcolor);
+    }
+
+    /*  -4 indicates new line thickness.  It has one argument, 
+        where 1 indicates the thinnest line, 10 indicates a fairly
+        thick line.  Postscript Line thicknesses (used by gxps):
+  
+                    " 0.001 w",
+                    " 0.006 w",
+                    " 0.009 w",
+                    " 0.012 w",
+                    " 0.015 w",
+                    " 0.018 w",
+                    " 0.021 w",
+                    " 0.024 w",
+                    " 0.027 w",
+                    " 0.030 w",
+                    " 0.033 w",
+                    " 0.036 w"    
+
+         Line weights greater than 12 are just set to 0.036.  */
+ 
+    else if (cmd==-4) {
+      fread ((char *)opts, sizeof(short), 2, infile);
+      i = opts[0];
+      gxwide(i);
+    }
+
+    /*  -5 defines a new color, in rgb.  it is followed by  four
+        args:  color number (16 to 99), then red, green, blue, 
+        each ranging from 0 to 255 */
+
+    else if (cmd==-5){
+      fread ((char *)opts, sizeof(short), 4, infile);
+      i = opts[0];
+      gxacol (i,opts[1],opts[2],opts[3]);
+    }
+
+    /*  -6 is for a filled rectangle.  It is followed by four args, 
+        each a plotting coordinate (divide by 1000 to get floating
+        point arg).  The coords are:  xlo, xhi, ylo, yhi */
+ 
+    else if (cmd==-6){
+      fread ((char *)opts, sizeof(short), 4, infile);
+      xyccc (opts[0],opts[2],&xlo,&ylo);
+      xyccc (opts[1],opts[3],&xhi,&yhi);
+      gxrecf(xlo,xhi,ylo,yhi);
+    }
+
+    /* -7 indicates the start of a polygon fill.  It is followed
+       by the polygon outline, provided as move and draw instructions,
+       which are followed by the -8 command.  This command has
+       one arg, the length. */
+
+    else if (cmd==-7){
+      fread ((char *)opts, sizeof(short), 1, infile);
+      fflag = 1;
+      xyc = 0;
+    }
+
+    /*  -8 is to terminate polygon fill.  It has no args */
+
+    else if (cmd==-8){
+      gxfill (xybuf,xyc);
+      fflag = 0;
+    }
+
+    /* -10 is a move to instruction.  It is followed by two args, 
+       the X and Y position to move to, in plotting units.  If this
+       is between a -7 and a -8 command, then it is part of the 
+       polygon outline to be filled */
+
+    else if (cmd==-10){
+      fread ((char *)opts, sizeof(short), 2, infile);
+      xyccc (opts[0],opts[1],&xpos,&ypos);
+      if (fflag) {
+        xybuf[xyc*2] = xpos;
+        xybuf[xyc*2+1] = ypos;
+        xyc++;
+      } else gxplot(xpos,ypos,3);
+    }
+
+    /*  -11 is draw to.  It is followed by two instructions.  
+        If between a -7 and -8 instruction, it is part of a polygon
+        to be filled. */ 
+        
+    else if (cmd==-11){
+      fread ((char *)opts, sizeof(short), 2, infile);
+      xyccc (opts[0],opts[1],&xpos,&ypos);
+      if (fflag) {
+        xybuf[xyc*2] = xpos;
+        xybuf[xyc*2+1] = ypos;
+        xyc++;
+      } else {
+	gxplot(xpos,ypos,2);
+      }
+    }
+
+    else if (cmd==-20) {       /* Draw button -- ignore */
+      fread ((char *)opts, sizeof(short), 1, infile);
+    }
+
+    /* Any other command would be invalid */
+
+    else {
+      printf ("Invalid command found %i \n",cmd);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int nxtcmd (char *cmd, char *prompt) {
+int past,cnt;
+
+  printf ("%s ",prompt);
+  past = 0;
+  cnt = 0;
+  while (1) {
+    *cmd = getchar();
+    if (*cmd == EOF) return (-1);
+    if (*cmd == '\n') {
+      *cmd = '\0';
+      return (cnt);
+    }
+    if (past || *cmd != ' ') {
+      cmd++; cnt++; past = 1;
+    }
+  }
+}
+
+void xyccc (short ix, short iy, float *x, float *y) {
+
+  *x = ((float)ix)/1000.0;
+  *y = ((float)iy)/1000.0;
+}
+
+
+void command_line_help(void) {
+/*--- 
+  output command line options 
+---*/
+
+printf("gxtran for GrADS Version " GRADS_VERSION "\n\n");
+printf("Display a GrADS meta file (from the \"print\" command in grads)\n\n");
+printf("Command line options: \n\n");
+printf("          -help   Just this help\n");
+printf("          -i      input GrADS meta file\n");
+printf("          -o      output postscript file\n");
+printf("          -r      reverse background (typically black) default is white background\n");
+printf("          -g LLLLxHHHH+(-)XXXX+(-)YYYY  set size of graphics window (like X windows)\n");
+printf("                LLLL -- length of box in pixels (x side)\n");
+printf("                HHHH -- height of box in pixels (y side)\n");
+printf("       + or -   XXXX -- starting pixel point in x (0,0 is upper lefthand corner)\n");
+printf("       + or -   YYYY -- starting pixel point in y\n");
+printf("          -a      \"animate\" by displaying all images as fast as possible\n");
+printf("   Example:\n\n");
+printf("   gxtran -r -i myplot.gm\n\n");
+printf("   displays the plot(s) in the GrADS meta file mplot.gm \n\n");
+
+}
+
+void gaprnt (int i, char *ch) {
+  printf ("%s",ch);
+}
diff --git a/src/gxwmap.c b/src/gxwmap.c
new file mode 100644
index 0000000..39927c2
--- /dev/null
+++ b/src/gxwmap.c
@@ -0,0 +1,1309 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* Authored by B. Doty */
+
+/* Add caching of the map file if less than CACHEMAX in length.  10/2011 B. Doty */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+#include "gatypes.h"
+#include "gx.h"
+/* #include "gxmap.h" */
+
+int gagby (char *, int, int);
+void gree();
+void *galloc(size_t,char *);
+
+static gaint imap;
+static gadouble lomin, lomax, lamin, lamax;
+static gadouble lonref;    /* Reference longitude for adjustment */
+static gaint adjtyp = 0;  /* Direction adjustment class */
+
+/* Caching stuff */
+
+#define CACHEMAX 2000000
+
+gaint gxwopen (char *, char *);
+gaint gxwread (char *, gaint);
+gaint gxwseek (gaint);
+void gxwclose (gaint);
+
+struct mapcache {
+  struct mapcache *forw;   /* Chain pointer */
+  gaint size;           /* size of the file cached here */
+  char *name;           /* file name cached here */
+  char *data;           /* contents of the file cached here */
+};
+static struct mapcache *manchor=NULL;  /* link list anchor */
+static struct mapcache *cmc;   /* pointer to currently "open" cached file*/ 
+static gaint mcpos;     /* current position in cached file */
+static gaint mclen;     /* length of the data in current cache */
+static FILE *mfile;     /* for file i/o instead of caching */
+static gaint cflag;     /* indicate if i/o from cache or file */
+
+void gxrsmapt (void) {
+  adjtyp = 0;
+}
+
+void gxdmap (struct mapopt *mopt) {
+gadouble lon[255],lat[255],xx,yy,lnmin,lnmax,ltmin,ltmax,lnfact;
+gaint num,i,ipen,rc,type,ilon,ilat,rnum,flag,st1,st2,spos;
+gafloat sln1,sln2,slt1,slt2;
+gafloat lnsav,ltsav,lndif,ltdif,lntmp,lttmp,llinc,llsum,lldist;
+char *fname;
+char hdr[3],rec[1530];
+
+  llinc = hypot(mopt->lnmax-mopt->lnmin,mopt->ltmax-mopt->ltmin);
+  llinc = llinc/200;
+  if (llinc<0.0001) llinc=0.0001;
+
+  /* Open the map data set */
+
+  if (*(mopt->mpdset)=='/' || *(mopt->mpdset)=='\\') {
+    imap = gxwopen(mopt->mpdset,"rb");
+    if (imap==0) {
+      printf ("Open Error on Map Data Set: %s\n",mopt->mpdset);
+      return;
+    }
+  } else {
+    fname = gxgnam(mopt->mpdset);
+    imap = gxwopen(fname,"rb");
+    if (imap==0) {
+      imap = gxwopen(mopt->mpdset,"rb");
+      if (imap==0) {
+        printf ("Open Error on Map Data Set: %s\n",fname);
+        gree(fname,"f297");
+        return;
+      }
+    }
+    gree(fname,"f298");
+  }
+
+  /* Read and process each record */
+
+  rnum = 0;
+  while (1) {
+    if (cflag) rc = gxwread(hdr,3);
+    else  rc = fread(hdr,1,3,mfile);
+    if (rc!=3) break;
+    rnum++;
+    i = gagby (hdr,0,1);
+    if (i<1 || i>3) {
+      printf ("Map file format error: Invalid rec type %i rec num %i\n",i,rnum);
+      return;
+    }
+    if (i==2) {
+      st1 = gagby(hdr,1,1);
+      st2 = gagby(hdr,2,1);
+      if (cflag) gxwread(rec,16);
+      else fread(rec,1,16,mfile);
+      spos = gagby(rec,0,4);
+      ilon = gagby(rec,4,3);
+      sln1 = ((float)ilon)/1e4;
+      ilon = gagby(rec,7,3);
+      sln2 = ((float)ilon)/1e4;
+      ilat = gagby(rec,10,3);
+      slt1 = ((float)ilat)/1e4 - 90.0;
+      ilat = gagby(rec,13,3);
+      slt2 = ((float)ilat)/1e4 - 90.0;
+      flag = 0;
+      for (i=0; i<256; i++) {
+        if (*(mopt->mcol+i)!=-9 && i>=st1 && i<=st2) flag = 1;
+      }
+      if (flag==0) {
+        if (spos==0) {
+          if (cflag) gxwclose(imap);
+          else fclose(mfile);
+          return;
+        }
+        if (cflag) gxwseek(spos);
+        else fseek(mfile,spos,0);
+        continue;
+      }
+      flag = 0;
+      if (sln1>360.0) flag = 1;
+      else {
+        if (slt2 <= mopt->ltmin || slt1 >= mopt->ltmax) flag = 0;
+        else {
+          lnfact = 0.0;
+          while (sln2+lnfact > mopt->lnmin) lnfact -= 360.0;
+          lnfact += 360.0;
+          if (sln1+lnfact >= mopt->lnmax) flag = 0;
+          else flag = 1;
+        }
+      }
+      if (flag==0) {
+        if (spos==0) {
+          if (cflag) gxwclose(imap);
+          else fclose(mfile);
+          return;
+        }
+        if (cflag) gxwseek(spos);
+        else fseek(mfile,spos,0);
+      }
+      continue;
+    }
+    type = gagby(hdr,1,1);
+    num = gagby(hdr,2,1);
+
+    /* Read the next record; convert the data points;
+       and get the lat/lon bounds for this line segment */
+
+    if (cflag) gxwread(rec,num*6);
+    else fread(rec,1,num*6,mfile);
+    if (*(mopt->mcol+type) == -9) continue;
+    if (*(mopt->mcol+type) == -1) {
+      gxcolr(mopt->dcol);
+      gxstyl(mopt->dstl);
+      gxwide(mopt->dthk);
+    } else {
+      gxcolr(*(mopt->mcol+type));
+      gxstyl(*(mopt->mstl+type));
+      gxwide(*(mopt->mthk+type));
+    }
+    lnmin = 9999.9; lnmax = -9999.9; ltmin = 9999.9; ltmax = -9999.9;
+    for (i=0; i<num; i++) {
+      ilon = gagby(rec,i*6,3);
+      ilat = gagby(rec,i*6+3,3);
+      lat[i] = ((float)ilat)/1e4 - 90.0;
+      lon[i] = ((float)ilon)/1e4;
+      if (lat[i]<ltmin) ltmin=lat[i]; if (lat[i]>ltmax) ltmax=lat[i];
+      if (lon[i]<lnmin) lnmin=lon[i]; if (lon[i]>lnmax) lnmax=lon[i];
+    }
+
+    /* Plot this line segment if it falls within the
+       appropriate lat/lon bounds */
+
+    if (ltmax < mopt->ltmin) continue;
+    if (ltmin > mopt->ltmax) continue;
+
+    lnfact = 0.0;
+    while (lnmax+lnfact > mopt->lnmin) lnfact -= 360.0;
+    lnfact += 360.0;
+
+    while (lnmin+lnfact < mopt->lnmax) {
+      if (lnmax+lnfact < mopt->lnmin) {
+        lnfact += 360.0;
+        continue;
+      }
+
+      /* Split long lines into shorter segments and limit
+         drawing at lat-lon bounds */
+
+      ipen = 3;
+      lnsav = lon[0]; ltsav = lat[0];
+      for (i=1; i<num; i++) {
+        lndif = fabs(lon[i] - lon[i-1]);
+        ltdif = fabs(lat[i] - lat[i-1]);
+        if (lndif>ltdif) lldist = lndif;
+        else lldist = ltdif;
+        llsum = llinc;
+        lntmp = lnsav; lttmp = ltsav;
+        while (llsum<lldist+llinc) {
+          if (llsum>=lldist-llinc/4.0) {
+            lntmp = lon[i]; lttmp = lat[i];
+            llsum += llinc;   /* Insure loop dropout */
+          } else {
+            if (lndif>ltdif) {
+              if (lon[i-1]<lon[i]) {
+                lntmp += llinc;
+                lttmp += llinc * (lat[i]-lat[i-1])/(lon[i]-lon[i-1]);
+              } else {
+                lntmp -= llinc;
+                lttmp -= llinc * (lat[i]-lat[i-1])/(lon[i]-lon[i-1]);
+              }
+            } else {
+              if (lat[i-1]<lat[i]) {
+                lttmp += llinc;
+                lntmp += llinc * (lon[i]-lon[i-1])/(lat[i]-lat[i-1]);
+              } else {
+                lttmp -= llinc;
+                lntmp -= llinc * (lon[i]-lon[i-1])/(lat[i]-lat[i-1]);
+              }
+            }
+          }
+          if (lntmp+lnfact<mopt->lnmin ||
+              lntmp+lnfact>mopt->lnmax ||
+              lttmp<mopt->ltmin || lttmp>mopt->ltmax) {
+            if (ipen==2) {
+              gxconv (lntmp+lnfact,lttmp,&xx,&yy,2);
+              gxplot (xx,yy,ipen);
+            }
+            ipen = 3;
+          } else {
+            if (ipen==3) {
+              gxconv (lnsav+lnfact,ltsav,&xx,&yy,2);
+              gxplot (xx,yy,ipen);
+            }
+            ipen = 2;
+            gxconv (lntmp+lnfact,lttmp,&xx,&yy,2);
+            gxplot (xx,yy,ipen);
+          }
+          lnsav = lntmp; ltsav = lttmp;
+          llsum += llinc;
+        }
+      }
+      lnfact += 360.0;
+    }
+  }
+  if (cflag) gxwclose (imap);
+  else fclose (mfile);
+}
+
+/* Routine to set up scaling for lat-lon projection.  The aspect
+   ratio is *not* maintained.                                   */
+
+int gxscld (struct mapprj *mpj, int xflip, int yflip) {
+float x1,x2,y1,y2;
+
+  if (mpj->lnmn>=mpj->lnmx) return(1);
+  if (mpj->ltmn>=mpj->ltmx) return(1);
+  if (mpj->xmn>=mpj->xmx) return(1);
+  if (mpj->ymn>=mpj->ymx) return(1);
+  mpj->axmn = mpj->xmn;
+  mpj->axmx = mpj->xmx;
+  mpj->aymn = mpj->ymn;
+  mpj->aymx = mpj->ymx;
+  x1 = mpj->lnmn; x2 = mpj->lnmx; y1 = mpj->ltmn; y2 = mpj->ltmx;
+  if (xflip) { x1 = mpj->lnmx; x2 = mpj->lnmn; }
+  if (yflip) { y1 = mpj->ltmx; y2 = mpj->ltmn; }
+  gxscal (mpj->axmn, mpj->axmx, mpj->aymn, mpj->aymx, x1, x2, y1, y2);
+  gxproj (NULL);
+  adjtyp = 0;
+  return (0);
+}
+
+/* Routine to set up scaling for lat-lon projection.  Aspect
+   ratio of the projection is maintained as a constant, and it
+   fills the plotting area as much as possible.                 */
+
+int gxltln (struct mapprj *mpj) {
+float lndif,ltdif,aspect,aspect2,xdif,xlo,xhi,ydif,ylo,yhi;
+
+  if (mpj->lnmn>=mpj->lnmx) return(1);
+  if (mpj->ltmn>=mpj->ltmx) return(1);
+  if (mpj->xmn>=mpj->xmx) return(1);
+  if (mpj->ymn>=mpj->ymx) return(1);
+
+  lndif = mpj->lnmx - mpj->lnmn;
+  ltdif = mpj->ltmx - mpj->ltmn;
+  aspect = 1.2*ltdif/lndif;
+  aspect2 = (mpj->ymx - mpj->ymn) / (mpj->xmx - mpj->xmn);
+  if (aspect > aspect2) {
+    xdif = (mpj->xmx - mpj->xmn) * aspect2/aspect;
+    xlo = ((mpj->xmx - mpj->xmn)/2.0)-(xdif*0.5);
+    xhi = ((mpj->xmx - mpj->xmn)/2.0)+(xdif*0.5);
+    mpj->axmx = mpj->xmn + xhi;
+    mpj->axmn = mpj->xmn + xlo;
+    mpj->aymn = mpj->ymn;
+    mpj->aymx = mpj->ymx;
+  } else {
+    ydif = (mpj->ymx - mpj->ymn) * aspect/aspect2;
+    ylo = ((mpj->ymx - mpj->ymn)/2.0)-(ydif*0.5);
+    yhi = ((mpj->ymx - mpj->ymn)/2.0)+(ydif*0.5);
+    mpj->aymx = mpj->ymn + yhi;
+    mpj->aymn = mpj->ymn + ylo;
+    mpj->axmn = mpj->xmn;
+    mpj->axmx = mpj->xmx;
+  }
+
+  gxscal (mpj->axmn, mpj->axmx, mpj->aymn, mpj->aymx,
+          mpj->lnmn, mpj->lnmx, mpj->ltmn, mpj->ltmx);
+  gxproj (NULL);
+  adjtyp = 0;
+  return (0);
+}
+
+/* Routine for north polar stereographic.  Projection scaling
+   is set along with level 1 linear scaling.   The only difficult
+   aspect to this is to set the level 1 linear scaling such that
+   the proper aspect ratio is maintained.   */
+
+static float londif;
+
+int gxnste (struct mapprj *mpj) {
+gadouble x1,x2,y1,y2,dum,lonave;
+gadouble w1,xave,yave;
+gadouble lonmn, lonmx, latmn, latmx, xmin, xmax, ymin, ymax;
+
+  lonmn = mpj->lnmn; lonmx = mpj->lnmx;
+  latmn = mpj->ltmn; latmx = mpj->ltmx;
+  xmin = mpj->xmn; xmax = mpj->xmx;
+  ymin = mpj->ymn; ymax = mpj->ymx;
+
+  if ((lonmx-lonmn) > 360.0) {
+    return (1);
+  }
+  if (lonmn<-360.0 || lonmx>360.0) {
+    return (1);
+  }
+  if (latmn<-80.0 || latmx>90.0) {
+    return (1);
+  }
+  if (latmn>=latmx||lonmn>=lonmx||xmin>=xmax||ymin>=ymax) {
+    return(1);
+  }
+
+  lonave = (lonmx+lonmn)/2.0;            /* Longitude adjustment to put */
+  londif = -90.0 - lonave;               /*  central meridian at bottom.*/
+  lonref = lonave;
+
+  /* Plotting limits depend on how much of the hemisphere we are
+     actually plotting.  */
+
+  if ( (lonmx-lonmn) < 180.0 ) {
+
+     gxnpst ( lonmn, latmn, &x1, &dum );         /* Left side coord  */
+     gxnpst ( lonmx, latmn, &x2, &dum );         /* Right side coord */
+     gxnpst ( lonmn, latmx, &dum, &y2 );         /* Top coord        */
+     gxnpst ( lonave, latmn, &dum, &y1 );        /* Bottom coord     */
+
+  } else {
+
+     gxnpst ( lonave-90.0, latmn, &x1, &dum );   /* Left side coord  */
+     gxnpst ( lonave+90.0, latmn, &x2, &dum );   /* Right side coord */
+     gxnpst ( lonmn, latmn, &dum, &y2 );         /* Top coord        */
+     gxnpst ( lonave, latmn, &dum, &y1 );        /* Bottom coord     */
+
+  }
+
+  /* Set up linear level scaling while maintaining aspect ratio.   */
+
+  if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) ) {
+    w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+    xave = (xmax+xmin)/2.0;
+    gxscal ( xave-w1, xave+w1, ymin, ymax, x1, x2, y1, y2 );
+    mpj->axmn = xave-w1;  mpj->axmx = xave+w1;
+    mpj->aymn = ymin;  mpj->aymx = ymax;
+  } else {
+    w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+    yave = (ymax+ymin)/2.0;
+    gxscal ( xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+    mpj->axmn = xmin;  mpj->axmx = xmax;
+    mpj->aymn = yave-w1;  mpj->aymx = yave+w1;
+  }
+
+  gxproj (gxnpst);
+  gxback (gxnrev);
+  adjtyp = 1;
+  return (0);
+
+}
+
+void gxnpst (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y) {
+gadouble radius,theta;
+
+  radius = tan (0.785315-(0.00872572*rlat));
+  theta = (rlon+londif)*0.0174514;
+  *x = radius * cos(theta);
+  *y = radius * sin(theta);
+}
+
+/* Routine for back transform for npst */
+
+void gxnrev (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+gadouble rad,alpha;
+
+  rad = hypot(x,y);
+  alpha = 180.0*atan(rad)/pi;
+  *rlat = 90.0 - 2.0*alpha;
+
+  if (x==0.0 && y==0.0) *rlon = 0.0;
+  else {
+    *rlon = (180.0*atan2(y,x)/pi)-londif;
+    while (*rlon < lonref-180.0) *rlon += 360.0;
+    while (*rlon > lonref+180.0) *rlon -= 360.0;
+  }
+}
+
+/* Routine for south polar stereographic.  Projection scaling
+   is set along with level 1 linear scaling.   The only difficult
+   aspect to this is to set the level 1 linear scaling such that
+   the proper aspect ratio is maintained.   */
+
+int gxsste (struct mapprj *mpj) {
+gadouble x1,x2,y1,y2,dum,lonave;
+gadouble w1,xave,yave;
+gadouble lonmn, lonmx, latmn, latmx, xmin, xmax, ymin, ymax;
+
+  lonmn = mpj->lnmn; lonmx = mpj->lnmx;
+  latmn = mpj->ltmn; latmx = mpj->ltmx;
+  xmin = mpj->xmn; xmax = mpj->xmx;
+  ymin = mpj->ymn; ymax = mpj->ymx;
+
+  if ((lonmx-lonmn) > 360.0) {
+    return (1);
+  }
+  if (lonmn<-360.0 || lonmx>360.0) {
+    return (1);
+  }
+  if (latmn<-90.0 || latmx>80.0) {
+    return (1);
+  }
+  if (latmn>=latmx||lonmn>=lonmx||xmin>=xmax||ymin>=ymax) {
+    return(1);
+  }
+
+  lonave = (lonmx+lonmn)/2.0;            /* Longitude adjustment to put */
+  londif = -90.0 - lonave;               /*  central meridian at bottom.*/
+  lonref = lonave;
+
+  /* Plotting limits depend on how much of the hemisphere we are
+     actually plotting.  */
+
+  if ( (lonmx-lonmn) < 180.0 ) {
+
+     gxspst ( lonmn, latmx, &x1, &dum );         /* Left side coord  */
+     gxspst ( lonmx, latmx, &x2, &dum );         /* Right side coord */
+     gxspst ( lonmn, latmn, &dum, &y1 );         /* Top coord        */
+     gxspst ( lonave, latmx, &dum, &y2 );        /* Bottom coord     */
+
+  } else {
+
+     gxspst ( lonave-90.0, latmx, &x1, &dum );   /* Left side coord  */
+     gxspst ( lonave+90.0, latmx, &x2, &dum );   /* Right side coord */
+     gxspst ( lonmn, latmx, &dum, &y1 );         /* Top coord        */
+     gxspst ( lonave, latmx, &dum, &y2 );        /* Bottom coord     */
+
+  }
+
+  /* Set up linear level scaling while maintaining aspect ratio.   */
+
+  if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) ) {
+    w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+    xave = (xmax+xmin)/2.0;
+    gxscal ( xave-w1, xave+w1, ymin, ymax, x1, x2, y1, y2 );
+    mpj->axmn = xave-w1;  mpj->axmx = xave+w1;
+    mpj->aymn = ymin;  mpj->aymx = ymax;
+  } else {
+    w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+    yave = (ymax+ymin)/2.0;
+    gxscal ( xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+    mpj->axmn = xmin;  mpj->axmx = xmax;
+    mpj->aymn = yave-w1;  mpj->aymx = yave+w1;
+  }
+  gxproj (gxspst);
+  gxback (gxsrev);
+  adjtyp = 2;
+  return (0);
+
+}
+
+void gxspst (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y) {
+gadouble radius,theta;
+
+  radius = tan(0.785315+(0.00872572*rlat));
+  theta = (rlon+londif)*(-0.0174514);
+  *x = radius * cos(theta);
+  *y = radius * sin(theta);
+}
+
+/* Routine for back transform for spst */
+
+void gxsrev (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+gadouble rad,alpha;
+
+  rad = hypot(x,y);
+  alpha = 180.0*atan(rad)/pi;
+  *rlat = 2.0*alpha - 90.0;
+
+  if (x==0.0 && y==0.0) *rlon = 0.0;
+  else {
+    *rlon = (-180.0*atan2(y,x)/pi)-londif;
+    while (*rlon < lonref-180.0) *rlon += 360.0;
+    while (*rlon > lonref+180.0) *rlon -= 360.0;
+  }
+}
+
+/* Return adjustment angle (in radians) to apply to a wind direction
+   to correct for current map projection and position. */
+
+gadouble gxaarw (gadouble lon, gadouble lat) {
+gadouble xx1,yy1,xx2,yy2,dir;
+
+  if (adjtyp==0) return(0.0);
+  if (adjtyp==1) {
+    lon = (lon - lonref)*pi/180.0;
+    return (lon);
+  }
+  if (adjtyp==2) {
+    lon = (lonref - lon)*pi/180.0;
+    return (lon);
+  }
+
+  /* For type 3 map projections that lack back transforms, estimate the north
+     direction using finite difference. */
+
+  if (adjtyp==3) {
+    if (lat>89.9) {     /* back difference if near np */
+      gxconv (lon,lat-0.05,&xx1,&yy1,2);
+      gxconv (lon,lat,&xx2,&yy2,2);
+    } else if (lat<-89.9) {  /* forward difference if near sp */
+      gxconv (lon,lat,&xx1,&yy1,2);
+      gxconv (lon,lat+0.05,&xx2,&yy2,2);
+    } else {                 /* otherwise centered diff */
+      gxconv (lon,lat-0.03,&xx1,&yy1,2);
+      gxconv (lon,lat+0.03,&xx2,&yy2,2);
+    }
+    dir = atan2(xx1-xx2,yy2-yy1);
+    return (dir);
+  }
+
+  /* type 4 map projections do not have lat/lon lines that cross at 
+     right angles (non-conformal).  This is too hard to deal with.  */
+
+  return (-999.9);
+}
+
+/*  Set up Robinson Projection */
+
+static gadouble fudge;
+
+int gxrobi (struct mapprj *mpj) {
+gadouble lonmn, lonmx, latmn, latmx, xmin, xmax, ymin, ymax;
+gadouble x1,x2,y1,y2,xd,yd,xave,yave,w1;
+
+  lonmn = mpj->lnmn; lonmx = mpj->lnmx;
+  latmn = mpj->ltmn; latmx = mpj->ltmx;
+  xmin = mpj->xmn; xmax = mpj->xmx;
+  ymin = mpj->ymn; ymax = mpj->ymx;
+
+  /* Check for errors */
+
+  fudge = 0.0;
+  if (lonmn<-180.0 || lonmx>180.0 || latmn<-90.0 || latmx>90.0) {
+    if (dequal(lonmn,0.0,1e-7) || dequal(lonmx,360.0,1e-7)) return (1); 
+    else fudge = 180.0;
+  }
+  if (latmn>=latmx||lonmn>=lonmx||xmin>=xmax||ymin>=ymax) {
+    return(1);
+  }
+
+  /* Get bounds of the map in linear units */
+
+  gxrobp ( lonmn, latmn, &x1, &y1);           /* Lower Left       */
+  gxrobp ( lonmn, latmx, &xd, &y2);           /* Upper Left       */
+  if (xd<x1) x1 = xd;
+  if (latmn<0.0 && latmx>0.0) {
+    gxrobp (lonmn, 0.0, &xd, &yd);            /* Left Middle      */
+    if (xd<x1) x1 = xd;
+  }
+  gxrobp ( lonmx, latmn, &x2, &y1);           /* Lower Right      */
+  gxrobp ( lonmx, latmx, &xd, &y2);           /* Upper Right      */
+  if (xd>x2) x2 = xd;
+  if (latmn<0.0 && latmx>0.0) {
+    gxrobp (lonmx, 0.0, &xd, &yd);            /* Right Middle     */
+    if (xd>x2) x2 = xd;
+  }
+
+  /* Set up linear level scaling while maintaining aspect ratio.   */
+
+  if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) ) {
+    w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+    xave = (xmax+xmin)/2.0;
+    gxscal ( xave-w1, xave+w1, ymin, ymax, x1, x2, y1, y2 );
+    mpj->axmn = xave-w1;  mpj->axmx = xave+w1;
+    mpj->aymn = ymin;  mpj->aymx = ymax;
+  } else {
+    w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+    yave = (ymax+ymin)/2.0;
+    gxscal ( xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+    mpj->axmn = xmin;  mpj->axmx = xmax;
+    mpj->aymn = yave-w1;  mpj->aymx = yave+w1;
+  }
+
+  gxproj (gxrobp);
+  gxback (gxrobb);
+  adjtyp = 4;
+  return (0);
+}
+
+/* Transform routine for Robinson Projection */
+
+gadouble rob1[37] = {-1.349,-1.317,-1.267,-1.206,-1.138,-1.066,-0.991,
+    -0.913,-0.833,-0.752,-0.669,-0.586,-0.502,-0.418,-0.334,-0.251,
+    -0.167,-0.084,0.000,0.084,0.167,0.251,0.334,0.418,0.502,0.586,
+    0.669,0.752,0.833,0.913,0.991,1.066,1.138,1.206,1.267,1.317,1.349};
+gadouble rob2[37] = {1.399,1.504,1.633,1.769,1.889,1.997,2.099,
+    2.195,2.281,2.356,2.422,2.478,2.532,2.557,2.582,2.602,2.616,
+    2.625,2.628,2.625,2.616,2.602,2.582,2.557,2.532,2.478,2.422,
+    2.356,2.281,2.195,2.099,1.997,1.889,1.769,1.633,1.504,1.399};
+
+void gxrobp (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y) {
+int i;
+  rlat = (rlat+90.0)/5.0;
+  i = (int)rlat;
+  rlat = rlat - (gadouble)i;
+  if (i<0) {
+    *y = -1.349;
+    *x = 1.399*(rlon-fudge)/180.0;
+    return;
+  }
+  if (i>=36) {
+    *y = 1.349;
+    *x = 1.399*(rlon-fudge)/180.0;
+    return;
+  }
+  *y = rob1[i] + rlat*(rob1[i+1]-rob1[i]);
+  *x = rob2[i] + rlat*(rob2[i+1]-rob2[i]);
+  *x = *x * (rlon-fudge)/180.0;
+  return;
+}
+
+/* Back Transform for Robinson Projection */
+
+void gxrobb (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+  *rlon = -999.9;
+  *rlat = -999.9;
+}
+/*------------------------------------------------------------------
+     DKRZ appends: Mollweide Projection
+     10.08.95   Karin Meier (karin.meier at dkrz.de)
+  ------------------------------------------------------------------*/
+
+int gxmoll (struct mapprj *mpj) {
+    gadouble lonmn, lonmx, latmn, latmx, xmin, xmax, ymin, ymax;
+    gadouble x1,x2,y1,y2,xd,yd,xave,yave,w1;
+
+	lonmn  = mpj->lnmn; lonmx = mpj->lnmx;
+	latmn  = mpj->ltmn; latmx = mpj->ltmx;
+	xmin   = mpj->xmn;  xmax  = mpj->xmx;
+	ymin   = mpj->ymn;  ymax  = mpj->ymx;
+	lomin  = lonmn;     lomax = lonmx;
+	lamin  = latmn;     lamax = latmx;
+
+/* Check for errors */
+
+  	if (latmn<-90.0 || latmx>90.0) {
+    	  return (1);
+  	}
+  	if (latmn>=latmx||lonmn>=lonmx||xmin>=xmax||ymin>=ymax) {
+  	  return(1);
+  	}
+
+  /* Get bounds of the map in linear units */
+
+  	gxmollp ( lonmn, latmn, &x1, &y1);           /* Lower Left       */
+  	gxmollp ( lonmn, latmx, &xd, &y2);           /* Upper Left       */
+  	if (xd<x1) x1 = xd;
+  	if (latmn<0.0 && latmx>0.0) {
+  	  gxmollp (lonmn, 0.0, &xd, &yd);            /* Left Middle      */
+  	  if (xd<x1) x1 = xd;
+  	}
+  	gxmollp ( lonmx, latmn, &x2, &y1);           /* Lower Right      */
+  	gxmollp ( lonmx, latmx, &xd, &y2);           /* Upper Right      */
+  	if (xd>x2) x2 = xd;
+  	if (latmn<0.0 && latmx>0.0) {
+  	  gxmollp (lonmx, 0.0, &xd, &yd);            /* Right Middle     */
+  	  if (xd>x2) x2 = xd;
+  	}
+
+  /* Set up linear level scaling while maintaining aspect ratio.   */
+
+  	if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) ) {
+  	  w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+ 	  xave = (xmax+xmin)/2.0;
+  	  gxscal ( xave-w1, xave+w1, ymin, ymax, x1, x2, y1, y2 );
+  	  mpj->axmn = xave-w1;  mpj->axmx = xave+w1;
+  	  mpj->aymn = ymin;     mpj->aymx = ymax;
+  	} else {
+  	  w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+	  yave = (ymax+ymin)/2.0;
+  	  gxscal ( xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+  	  mpj->axmn = xmin;     mpj->axmx = xmax;
+  	  mpj->aymn = yave-w1;  mpj->aymx = yave+w1;
+  	}
+
+  	gxproj (gxmollp);
+  	gxback (gxmollb);
+  	adjtyp = 4;
+  	return (0);
+}
+
+void gxmollp (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y) {
+   gadouble diff, radlat, radlon;
+
+	if (lomin != -180.0) {
+	  diff = -180.0 - lomin;
+	  rlon = rlon + diff;
+	}
+	radlat = (pi*rlat)/180.0;
+	radlon = (pi*rlon)/180.0;
+
+	*x = cos(radlat);
+	*y = sin(radlat)/2.0;
+	*x = *x*rlon/180.0;
+
+  	return;
+}
+
+/* Back Transform for Mollweide Projection */
+
+void gxmollb (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+  *rlon = -999.9;
+  *rlat = -999.9;
+}
+
+/* Orthographic projection.  Requires exact setup with the lat/lon range
+   being exactly what is visible.  lat -90 to 90 and lon diff exactly 180. */
+
+/* A secret mpvals mod, where the area can be clipped by x1,y1,x2,y2 where the
+   values are in the range of -1 to 1 */
+
+int gxortg (struct mapprj *mpj) {
+    gadouble lonmn, lonmx, latmn, latmx, xmin, xmax, ymin, ymax;
+    gadouble x1,x2,y1,y2,xd,yd,xave,yave,w1;
+    gadouble xlmn, xlmx, ylmn, ylmx;
+    gaint lflg;
+
+        lflg = 0;
+	xlmn = xlmx = ylmn = ylmx = -999; 
+	lonmn  = mpj->lnmn; lonmx = mpj->lnmx;
+	latmn  = mpj->ltmn; latmx = mpj->ltmx;
+	xmin   = mpj->xmn;  xmax  = mpj->xmx;
+	ymin   = mpj->ymn;  ymax  = mpj->ymx;
+	lomin  = lonmn;     lomax = lonmx;
+	lamin  = latmn;     lamax = latmx;
+	lonref = (lonmx+lonmn)/2.0;
+        if (mpj->axmn > -999.0) {
+          xlmn = mpj->axmn; xlmx = mpj->axmx;
+          ylmn = mpj->aymn; ylmx = mpj->aymx;
+          if (xlmn >= -1.0 && xlmn <= 1.0 && xlmx >= -1.0 && xlmx <= 1.0 &&
+              ylmn >= -1.0 && ylmn <= 1.0 && ylmx >= -1.0 && ylmx <= 1.0 &&
+              ylmx > ylmn && xlmx > xlmn) lflg = 1;
+        }
+
+  /* Check boundaries */
+
+	if (latmn != -90.0 || latmx != 90.0) {
+	   printf("Map Projection Error:  Latitude must be in range -90 90\n");
+	   return (1);
+	}
+	if ((lonmx - lonmn) > 180.001 ) {   
+	   printf("Map Projection Error:  %.1f - %.1f  > 180.0\n", 
+		   lonmx, lonmn);
+	   return (1);
+	}
+	if ((lonmx - lonmn) < 179.999) {    
+	   printf("Map Projection Error:  %.1f - %.1f  < 180.0\n",
+		   lonmx, lonmn);
+	   return (1);
+	}
+  	if (latmn>=latmx||lonmn>=lonmx||xmin>=xmax||ymin>=ymax) return(1);
+
+	if (lonmn < -180.0) {
+	    mpj->lnmn = lonmn + 360.0;
+	    mpj->lnmx = lonmx + 360.0;
+	    lonmn  = mpj->lnmn; lonmx = mpj->lnmx;
+	}
+	if (lonmx > 180.0 ) {
+	    mpj->lnmn = lonmn - 360.0;
+	    mpj->lnmx = lonmx - 360.0;
+	    lonmn  = mpj->lnmn; lonmx = mpj->lnmx;
+	}
+
+  /* Get bounds of the map in linear units */
+
+	  gxortgp ( lonmn,  latmn, &x1, &y1);
+	  gxortgp ( lonmn,  latmx, &xd, &y2);
+	  if (xd<x1) x1 = xd;
+	  if (latmn<0.0 && latmx>0.0) {
+  	     gxortgp ( lonmn, 0.0, &xd, &yd);
+	     if (xd<x1)	x1 = xd;
+  	  }
+	  gxortgp ( lonmx,  latmn, &x2, &y1);
+	  gxortgp ( lonmx,  latmx, &xd, &y2);
+	  if(xd>x2) x2 = xd;
+	  if (latmn<0.0 && latmx>0.0) {
+	     gxortgp ( lonmx, 0.0, &xd, &yd);
+	     if (xd>x2) x2 = xd;
+	  }
+         
+         if (lflg) {
+           x1 = xlmn; x2 = xlmx; y1 = ylmn; y2 = ylmx;
+         }
+
+  /* Set up linear level scaling while maintaining aspect ratio.   */
+
+  	if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) ) {
+  	  w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+ 	  xave = (xmax+xmin)/2.0;
+  	  gxscal ( xave-w1, xave+w1, ymin, ymax, x1, x2, y1, y2 );
+  	  mpj->axmn = xave-w1;  mpj->axmx = xave+w1;
+  	  mpj->aymn = ymin;     mpj->aymx = ymax;
+  	} else {
+  	  w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+	  yave = (ymax+ymin)/2.0;
+  	  gxscal ( xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+  	  mpj->axmn = xmin;     mpj->axmx = xmax;
+  	  mpj->aymn = yave-w1;  mpj->aymx = yave+w1;
+  	}
+
+  	gxproj (gxortgp);
+  	gxback (gxortgb);
+  	adjtyp = 4;
+  	return (0);
+}
+
+void gxortgp (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y) {
+
+  gadouble radlat, radlon, diff;
+
+  if (lomin != -90.0) {
+    diff = -90.0 - lomin;
+    rlon = rlon + diff;
+  }
+  
+  radlat = (pi*rlat)/180.0;
+  radlon = (pi*rlon)/180.0;
+  
+  *x = cos(radlat);
+  *y = sin(radlat);
+  *x = *x * sin(radlon);
+  
+  return;
+}
+
+/* Back Transform for Orthographic Projection */
+
+void gxortgb (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+  *rlon = -999.9;
+  *rlat = -999.9;
+}
+
+/*------------------------------------------------------------------
+     DKRZ appends: Lambert conformal conic Projection
+     15.03.96                       Karin Meier (karin.meier at dkrz.de)
+  ------------------------------------------------------------------*/
+static gadouble  hemi, r;
+
+int gxlamc (struct mapprj *mpj) {
+  gadouble  lonmn, lonmx, latmn, latmx, dlat, dlon, dx, dy;
+  gadouble  xave,yave, w1, lonave, xmin, xmax, ymin, ymax, x1, x2, y1, y2, xd, yd;
+
+	lonmn  = mpj->lnmn;          lonmx = mpj->lnmx;
+	latmn  = mpj->ltmn;          latmx = mpj->ltmx;
+	xmin   = mpj->xmn;           xmax  = mpj->xmx;
+	ymin   = mpj->ymn;           ymax  = mpj->ymx;
+	lomin  = lonmn;              lomax = lonmx;
+	lamin  = latmn;              lamax = latmx;
+	lonave = (lonmx+lonmn)/2.0;
+	dlat   = lamax - lamin;	     dlon  = lomax - lomin;
+	dx     = xmax - xmin;	     dy    = ymax - ymin;
+
+  	if ((lonmn>=lonmx)||(latmn>=latmx)||(xmin>=xmax)||(ymin>=ymax)) {
+	   return(1);
+  	}
+	if (((latmn > 0.0) && (latmx < 0.0)) || ((latmn < 0.0) && (latmx >0.0))) {
+	   printf("Map Projection Error:  Latitude must be in range -90 0 or 0 90\n");
+	   return (1);
+	}
+
+/*--- set constant for northern or southern hemisphere  ---*/
+
+	if (latmn >= 0.0) {
+	    hemi = 1.0;		/** northern hemisphere **/
+	} else {
+	    hemi = -1.0;	/** southern hemisphere **/
+	}
+
+/*--- reset 90.0/-90.0 degrees to 89.99/-89.99 because of tangent  ---*/
+
+	if (latmn == -90.0) latmn = -89.99;
+	if (latmx ==  90.0) latmx =  89.99;
+
+/*--- get viewport coordinates  x1, x2, y1, y2---*/
+
+	gxlamcp (lonmn, latmn, &x1, &y1);
+	gxlamcp (lonmn, latmx, &xd, &y2);
+	if (xd<x1)  x1=xd;
+	if (y2<y1) {
+	    yd = y2;  y2 = y1;  y1 = yd;
+	}
+	if (latmn>=0.0 && latmx>0.0) {
+	    gxlamcp (lonmn,0.0,&xd,&yd);
+	    if (xd<x1) x1=xd;
+	}
+	gxlamcp (lonmx, latmn, &x2, &y1);
+	gxlamcp (lonmx, latmx, &xd, &y2);
+	if (xd>x2)  x2=xd;
+	if (y2<y1) {
+	    yd = y2;  y2 = y1;  y1 = yd;
+	}
+	if (latmn<0.0 && latmx<=0.0) {
+	    gxlamcp (lonmx,0.0,&xd,&yd);
+	    if (xd>x2) x2=xd;
+	}
+
+/*--- determining terms for scaling  ---*/
+
+	xave = (xmin+xmax)/2.0;
+	yave = (ymin+ymax)/2.0;
+
+ 	if ( ((xmax-xmin)/(ymax-ymin)) > ((x2-x1)/(y2-y1)) )
+	{
+	  if (hemi==-1.0 && 180.0<(lomax-lomin) && (lomax-lomin)<=270.0)
+		yave -= 1.5;
+	  else if (hemi==1.0 && 180.0<(lomax-lomin) && (lomax-lomin)<=270.0)
+		yave += 1.5;
+	  else if (hemi==-1.0 && 270.0<=(lomax-lomin) && (lomax-lomin)<=360.0)
+		yave -= 1.2;
+	  else if (hemi==1.0 && 270.0<=(lomax-lomin) && (lomax-lomin)<=360.0)
+		yave += 1.2;
+	  else if (hemi==-1.0 && 90.0<(lomax-lomin) && (lomax-lomin)<=180.0)
+		yave -= 0.5;
+	  else if (hemi==1.0 && 90.0<(lomax-lomin) && (lomax-lomin)<=180.0)
+		yave += 1.0;
+	  else if (hemi==-1.0 && (lomax-lomin)<=90.0)
+		yave += 0.0;
+	  else if (hemi==1.0 && (lomax-lomin)<=90.0)
+		yave += 1.0;
+
+  	 w1 = 0.5*(ymax-ymin)*(x2-x1)/(y2-y1);
+	  if (w1 < 1.0)
+		gxscal (xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+	  else if (w1 < 2.0)
+		gxscal (xave-0.5*(w1), xave+0.5*w1, yave-w1, yave+w1,
+			x1, x2, y1, y2 );
+	  else if (w1 < 3.0)
+		gxscal (xave-0.5*w1, xave+0.5*w1, yave-w1, yave+w1,
+			x1, x2, y1, y2 );
+	  else if (w1 > 3.0)
+		gxscal (xave-0.75*w1, xave+0.75*w1, yave-0.75*w1,
+			yave+0.75*w1, x1, x2, y1, y2 );
+	  else
+  	  	gxscal (xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+	}
+	else
+	{
+	  if (hemi==-1.0 && 180.0<(lomax-lomin) && (lomax-lomin)<=270.0)
+		yave -= 1.0;
+	  else if (hemi==1.0 && 180.0<(lomax-lomin) && (lomax-lomin)<=270.0)
+		yave += 1.5;
+	  else if (hemi==-1.0 && 270.0<=(lomax-lomin) && (lomax-lomin)<=360.0)
+		yave -= 1.0;
+	  else if (hemi==1.0 && 270.0<=(lomax-lomin) && (lomax-lomin)<=360.0)
+		yave += 1.0;
+	  else if (hemi==-1.0 && 90.0<(lomax-lomin) && (lomax-lomin)<=180.0)
+		yave -= 0.5;
+	  else if (hemi==1.0 && 90.0<(lomax-lomin) && (lomax-lomin)<=180.0)
+		yave += 1.0;
+	  else if (hemi==-1.0 && (lomax-lomin)<=90.0)
+		yave += 0.0;
+	  else if (hemi==1.0 && (lomax-lomin)<=90.0)
+		yave += 1.0;
+
+  	  w1 = 0.5*(xmax-xmin)*(y2-y1)/(x2-x1);
+	  if (w1 < 1.0)
+		gxscal (xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+	  else if (w1 < 2.0)
+		gxscal (xmin+0.5*w1, xmax-0.5*w1, yave-1.25*w1,
+			yave+1.25*w1, x1, x2, y1, y2 );
+	  else if (w1 < 3.0)
+		gxscal (xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+	  else if (w1 > 3.0)
+		gxscal (xave-0.5*w1, xave+0.5*w1, yave-0.5*w1,
+			yave+0.5*w1, x1, x2, y1, y2 );
+	  else
+  	  	gxscal (xmin, xmax, yave-w1, yave+w1, x1, x2, y1, y2 );
+	}
+
+  	mpj->axmn = xmin;  mpj->axmx = xmax;
+  	mpj->aymn = ymin;  mpj->aymx = ymax;
+
+  	gxproj (gxlamcp);
+	gxback (gxlamcb);
+  	adjtyp = 3;
+  	return (0);
+}
+
+
+
+/*--- transform routine for lambert conformal conic projection  ---*/
+
+void gxlamcp (gadouble rlon, gadouble rlat, gadouble *x, gadouble *y)
+{
+	gadouble d2r, cone, phis, phin, clon, term1, term2;
+
+	d2r    = pi/180.0;
+
+/*--- standard latitudes:  north - phin;  south - phis  ---*/
+	phis   = lamin;
+	phin   = lamax;
+
+/*--- reset 90.0/-90.0 degrees to 89.99/-89.99 because of tangent  ---*/
+        if(phis == -90.0)  phis = -89.99;
+        if(phin ==  90.0)  phin =  89.99;
+
+/*--- calculate the constant of the cone +++ radius, x, y ---*/
+/*--- clon -  central meridian;    cone -  cone constant  ---*/
+	 clon  = floor((lomax + lomin)/2.0);
+	 term1 = tan((45.0-hemi*phis/2.0)*d2r);
+	 term2 = tan((45.0-hemi*phin/2.0)*d2r);
+
+         if(phis!=phin)
+		cone = (log10(cos(phis*d2r))-log10(cos(phin*d2r)))/
+                       (log10(term1)-log10(term2));
+	 else
+		cone = cos((90.0-hemi*phis)*d2r);
+
+	  r = pow(tan((45.0-hemi*rlat/2.0)*d2r),cone);
+	 *x =        r*sin((rlon-clon)*d2r*cone);
+	 *y =  -hemi*r*cos((rlon-clon)*d2r*cone);
+
+  	 return;
+}
+
+
+
+/*--- Back Transform for Lambert conformal Projection ---*/
+
+void gxlamcb (gadouble x, gadouble y, gadouble *rlon, gadouble *rlat) {
+  *rlon = -999.9;
+  *rlat = -999.9;
+}
+
+/* Interpolate lat/lon boundaries, and convert to xy, on 
+   behalf of 'draw mappoly' .  For most part, the same
+   code as in gxdmap  */
+
+gadouble *gxmpoly(gadouble *xy, gaint cnt, gadouble llinc, gaint *newcnt) {
+gadouble ln1, ln2, lt1, lt2, lnsav, ltsav, llsum;
+gadouble lndif, ltdif, lldist, lntmp, lttmp, xx, yy; 
+gadouble *newxy;
+gaint i,j,ip,ncnt;
+
+  /* Determine total 'path' length */
+
+  llsum = 0.0;
+  for (i=1; i<cnt; i++) {
+    ip = (i-1)*2;
+    lndif = fabs(*(xy+ip+2) - *(xy+ip));
+    ltdif = fabs(*(xy+ip+3) - *(xy+ip+1));
+    if (lndif>ltdif) lldist = lndif;
+    else lldist = ltdif;
+    llsum += lldist;
+  }
+
+  /* Estimate number of output points, and allocate storage for them. */
+  /* add one more point in case polygon doesn't close, 
+     an extra point (to close polygon) needs to be added by calling routine 
+     add one more point to include the very first point, before interpolation begins */
+
+  ncnt = cnt + llsum/llinc + 2;  
+  newxy = (gadouble *)galloc(sizeof(gadouble)*ncnt*2,"newxy");
+  if (newxy==NULL) return(NULL);  /* caller issues error */
+
+  /* Write out the very first point, before interpolation begins (this is for j=0) */
+  gxconv (*xy,*(xy+1),&xx,&yy,2);
+  *(newxy) = xx;
+  *(newxy+1) = yy;
+  /* Now interpolate each point, convert to x,y, and put in list */
+  j = 1;
+  lnsav = *xy; ltsav = *(xy+1);
+  for (i=1; i<cnt; i++) {
+    ip = (i-1)*2;
+    ln1 = *(xy+ip);   ln2 = *(xy+ip+2);
+    lt1 = *(xy+ip+1); lt2 = *(xy+ip+3);
+    lndif = fabs(ln2-ln1);
+    ltdif = fabs(lt2-lt1);
+    if (lndif>ltdif) lldist = lndif;
+    else lldist = ltdif;
+    llsum = llinc;
+    lntmp = lnsav; lttmp = ltsav;
+    while (llsum<lldist+llinc) {
+      if (llsum>=lldist-llinc/4.0) {
+        lntmp = ln2; lttmp = lt2;
+        llsum += llinc;   /* Insure loop dropout */
+      } else {
+        if (lndif>ltdif) {
+          if (ln1<ln2) {
+            lntmp += llinc;
+            lttmp += llinc * (lt2-lt1)/(ln2-ln1);
+          } else {
+            lntmp -= llinc;
+            lttmp -= llinc * (lt2-lt1)/(ln2-ln1);
+          }
+        } else {
+          if (lt1<lt2) {
+            lttmp += llinc;
+            lntmp += llinc * (ln2-ln1)/(lt2-lt1);
+          } else {
+            lttmp -= llinc;
+            lntmp -= llinc * (ln2-ln1)/(lt2-lt1);
+          }
+        }
+      }
+      gxconv (lntmp,lttmp,&xx,&yy,2);
+      *(newxy+j*2) = xx;
+      *(newxy+j*2+1) = yy;
+      j++;
+      if (j>=ncnt) {
+        printf ("Logic Error in gxmpoly\n");
+        free (newxy);
+        return (NULL);
+      }
+      lnsav = lntmp; ltsav = lttmp;
+      llsum += llinc;
+    }
+  }
+  *newcnt = j;
+  return (newxy);
+}
+
+/* If the file has not been read into cache, read it.  If the file
+   is alrady cached, set the pointer to it. */
+
+gaint gxwopen (char *name, char *opts) {
+FILE *ifile;
+struct mapcache *pmc, *tmppmc; 
+gaint i,rc,flen;
+char *ch,*cdat,*fname;
+
+  cflag = 0;  /* indicate i/o from file; change later */
+
+  /* traverse link list to find this file */
+
+  pmc = manchor; 
+  while (pmc) {
+    ch = pmc->name; 
+    i = 0;
+    while (*(ch+i)) {
+      if (*(ch+i) != *(name+i)) break;
+      i++;
+    }
+    if (*(ch+i)=='\0') { 
+      cmc = pmc; 
+      mcpos = 0;
+      mclen = cmc->size;
+      cflag = 1; 
+      return (1);
+    }
+    pmc = pmc->forw;
+  } 
+
+  /* this file is not in the cache.  try to open it.  */
+
+  ifile = fopen(name,opts);
+  if (ifile==NULL) return(0);
+
+  /* check size of file */
+
+  fseek(ifile,0L,2);
+  flen = ftell(ifile);
+  fseek(ifile,0L,0);
+
+  /* if file is too big, do regular file i/o.  set this up.  */
+
+  if (flen > CACHEMAX) {
+    mfile = ifile;  
+    return (2);
+  }
+
+  /* allocate memory for all the cache items */
+
+  cdat = (char *)malloc(flen);
+  if (cdat==NULL) {
+    mfile = ifile;  
+    return (2);
+  }
+
+  i = 0;
+  while (i<9999 && *(name+i)) i++; 
+  fname = (char *)malloc(i+2);
+  if (fname==NULL) {
+    free (cdat);
+    mfile = ifile;  
+    return (2);
+  }
+  *(fname+i) = '\0';
+  i = 0;
+  while (i<9999 && *(name+i)) {
+    *(fname+i) = *(name+i);
+    i++;
+  }
+
+  pmc = (struct mapcache *)malloc(sizeof(struct mapcache));
+  if (pmc==NULL) {
+    free (cdat);
+    free (fname);
+    mfile = ifile;  
+    return (2);
+  }
+
+  /* read in the file.  on error, fall back to file i/o. */
+
+  rc = fread(cdat,1,flen,ifile);
+  if (rc!=flen) {
+    mfile = ifile;  
+    free (cdat);
+    free (fname);
+    free (pmc);
+    return (2);
+  }
+  fclose (ifile);
+
+  /* chain it up, set it up, and return */
+
+  pmc->forw = NULL;
+  pmc->size = flen;
+  pmc->name = fname;
+  pmc->data = cdat;
+  if (manchor==NULL) {
+    manchor = pmc; 
+  } else {
+    tmppmc = manchor;
+    while (tmppmc->forw) tmppmc = tmppmc->forw;
+    tmppmc->forw = pmc;
+  }
+  mcpos = 0;   /* initial position in cache */
+  mclen = flen; 
+  cflag = 1;   /* indicate cache i/o */
+  cmc = pmc; 
+  return (1);
+} 
+
+/* pull requested length of data from cache from the current cache location.
+   update the cache location.  Return the length of the data -- this can be
+   less than the requested length if the end of buffer is hit.  */
+
+gaint gxwread (char *rec, gaint len) {
+gaint i;
+char *cdat;
+
+  cdat = cmc->data;
+  i = 0;
+  while (i<len && mcpos<mclen) {
+    *(rec+i) = *(cdat+mcpos);
+    i++;  mcpos++;
+  }
+  return (i);
+}
+
+gaint gxwseek (gaint pos) {
+  mcpos = pos;
+}
+
+void gxwclose (gaint flag) {
+  cflag = 0;
+  mcpos = 0;
+  mclen = 0;
+}
diff --git a/src/mtables.c b/src/mtables.c
new file mode 100644
index 0000000..5b43b00
--- /dev/null
+++ b/src/mtables.c
@@ -0,0 +1,734 @@
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define costScale 1024
+int cost[] = {
+  1024,
+  1023,
+  1023,
+  1022,
+  1021,
+  1020,
+  1018,
+  1016,
+  1014,
+  1011,
+  1008,
+  1005,
+  1001,
+  997,
+  993,
+  989,
+  984,
+  979,
+  973,
+  968,
+  962,
+  955,
+  949,
+  942,
+  935,
+  928,
+  920,
+  912,
+  904,
+  895,
+  886,
+  877,
+  868,
+  858,
+  848,
+  838,
+  828,
+  817,
+  806,
+  795,
+  784,
+  772,
+  760,
+  748,
+  736,
+  724,
+  711,
+  698,
+  685,
+  671,
+  658,
+  644,
+  630,
+  616,
+  601,
+  587,
+  572,
+  557,
+  542,
+  527,
+  512,
+  496,
+  480,
+  464,
+  448,
+  432,
+  416,
+  400,
+  383,
+  366,
+  350,
+  333,
+  316,
+  299,
+  282,
+  265,
+  247,
+  230,
+  212,
+  195,
+  177,
+  160,
+  142,
+  124,
+  107,
+  89,
+  71,
+  53,
+  35,
+  17,
+  0,
+  -17,
+  -35,
+  -53,
+  -71,
+  -89,
+  -107,
+  -124,
+  -142,
+  -160,
+  -177,
+  -195,
+  -212,
+  -230,
+  -247,
+  -265,
+  -282,
+  -299,
+  -316,
+  -333,
+  -350,
+  -366,
+  -383,
+  -400,
+  -416,
+  -432,
+  -448,
+  -464,
+  -480,
+  -496,
+  -512,
+  -527,
+  -542,
+  -557,
+  -572,
+  -587,
+  -601,
+  -616,
+  -630,
+  -644,
+  -658,
+  -671,
+  -685,
+  -698,
+  -711,
+  -724,
+  -736,
+  -748,
+  -760,
+  -772,
+  -784,
+  -795,
+  -806,
+  -817,
+  -828,
+  -838,
+  -848,
+  -858,
+  -868,
+  -877,
+  -886,
+  -895,
+  -904,
+  -912,
+  -920,
+  -928,
+  -935,
+  -942,
+  -949,
+  -955,
+  -962,
+  -968,
+  -973,
+  -979,
+  -984,
+  -989,
+  -993,
+  -997,
+  -1001,
+  -1005,
+  -1008,
+  -1011,
+  -1014,
+  -1016,
+  -1018,
+  -1020,
+  -1021,
+  -1022,
+  -1023,
+  -1023,
+  -1024,
+  -1023,
+  -1023,
+  -1022,
+  -1021,
+  -1020,
+  -1018,
+  -1016,
+  -1014,
+  -1011,
+  -1008,
+  -1005,
+  -1001,
+  -997,
+  -993,
+  -989,
+  -984,
+  -979,
+  -973,
+  -968,
+  -962,
+  -955,
+  -949,
+  -942,
+  -935,
+  -928,
+  -920,
+  -912,
+  -904,
+  -895,
+  -886,
+  -877,
+  -868,
+  -858,
+  -848,
+  -838,
+  -828,
+  -817,
+  -806,
+  -795,
+  -784,
+  -772,
+  -760,
+  -748,
+  -736,
+  -724,
+  -711,
+  -698,
+  -685,
+  -671,
+  -658,
+  -644,
+  -630,
+  -616,
+  -601,
+  -587,
+  -572,
+  -557,
+  -542,
+  -527,
+  -512,
+  -496,
+  -480,
+  -464,
+  -448,
+  -432,
+  -416,
+  -400,
+  -383,
+  -366,
+  -350,
+  -333,
+  -316,
+  -299,
+  -282,
+  -265,
+  -247,
+  -230,
+  -212,
+  -195,
+  -177,
+  -160,
+  -142,
+  -124,
+  -107,
+  -89,
+  -71,
+  -53,
+  -35,
+  -17,
+  0,
+  17,
+  35,
+  53,
+  71,
+  89,
+  107,
+  124,
+  142,
+  160,
+  177,
+  195,
+  212,
+  230,
+  247,
+  265,
+  282,
+  299,
+  316,
+  333,
+  350,
+  366,
+  383,
+  400,
+  416,
+  432,
+  448,
+  464,
+  480,
+  496,
+  512,
+  527,
+  542,
+  557,
+  572,
+  587,
+  601,
+  616,
+  630,
+  644,
+  658,
+  671,
+  685,
+  698,
+  711,
+  724,
+  736,
+  748,
+  760,
+  772,
+  784,
+  795,
+  806,
+  817,
+  828,
+  838,
+  848,
+  858,
+  868,
+  877,
+  886,
+  895,
+  904,
+  912,
+  920,
+  928,
+  935,
+  942,
+  949,
+  955,
+  962,
+  968,
+  973,
+  979,
+  984,
+  989,
+  993,
+  997,
+  1001,
+  1005,
+  1008,
+  1011,
+  1014,
+  1016,
+  1018,
+  1020,
+  1021,
+  1022,
+  1023,
+  1023
+};
+#define sintScale 1024
+int sint[] = {
+  0,
+  17,
+  35,
+  53,
+  71,
+  89,
+  107,
+  124,
+  142,
+  160,
+  177,
+  195,
+  212,
+  230,
+  247,
+  265,
+  282,
+  299,
+  316,
+  333,
+  350,
+  366,
+  383,
+  400,
+  416,
+  432,
+  448,
+  464,
+  480,
+  496,
+  512,
+  527,
+  542,
+  557,
+  572,
+  587,
+  601,
+  616,
+  630,
+  644,
+  658,
+  671,
+  685,
+  698,
+  711,
+  724,
+  736,
+  748,
+  760,
+  772,
+  784,
+  795,
+  806,
+  817,
+  828,
+  838,
+  848,
+  858,
+  868,
+  877,
+  886,
+  895,
+  904,
+  912,
+  920,
+  928,
+  935,
+  942,
+  949,
+  955,
+  962,
+  968,
+  973,
+  979,
+  984,
+  989,
+  993,
+  997,
+  1001,
+  1005,
+  1008,
+  1011,
+  1014,
+  1016,
+  1018,
+  1020,
+  1021,
+  1022,
+  1023,
+  1023,
+  1024,
+  1023,
+  1023,
+  1022,
+  1021,
+  1020,
+  1018,
+  1016,
+  1014,
+  1011,
+  1008,
+  1005,
+  1001,
+  997,
+  993,
+  989,
+  984,
+  979,
+  973,
+  968,
+  962,
+  955,
+  949,
+  942,
+  935,
+  928,
+  920,
+  912,
+  904,
+  895,
+  886,
+  877,
+  868,
+  858,
+  848,
+  838,
+  828,
+  817,
+  806,
+  795,
+  784,
+  772,
+  760,
+  748,
+  736,
+  724,
+  711,
+  698,
+  685,
+  671,
+  658,
+  644,
+  630,
+  616,
+  601,
+  587,
+  572,
+  557,
+  542,
+  527,
+  512,
+  496,
+  480,
+  464,
+  448,
+  432,
+  416,
+  400,
+  383,
+  366,
+  350,
+  333,
+  316,
+  299,
+  282,
+  265,
+  247,
+  230,
+  212,
+  195,
+  177,
+  160,
+  142,
+  124,
+  107,
+  89,
+  71,
+  53,
+  35,
+  17,
+  0,
+  -17,
+  -35,
+  -53,
+  -71,
+  -89,
+  -107,
+  -124,
+  -142,
+  -160,
+  -177,
+  -195,
+  -212,
+  -230,
+  -247,
+  -265,
+  -282,
+  -299,
+  -316,
+  -333,
+  -350,
+  -366,
+  -383,
+  -400,
+  -416,
+  -432,
+  -448,
+  -464,
+  -480,
+  -496,
+  -512,
+  -527,
+  -542,
+  -557,
+  -572,
+  -587,
+  -601,
+  -616,
+  -630,
+  -644,
+  -658,
+  -671,
+  -685,
+  -698,
+  -711,
+  -724,
+  -736,
+  -748,
+  -760,
+  -772,
+  -784,
+  -795,
+  -806,
+  -817,
+  -828,
+  -838,
+  -848,
+  -858,
+  -868,
+  -877,
+  -886,
+  -895,
+  -904,
+  -912,
+  -920,
+  -928,
+  -935,
+  -942,
+  -949,
+  -955,
+  -962,
+  -968,
+  -973,
+  -979,
+  -984,
+  -989,
+  -993,
+  -997,
+  -1001,
+  -1005,
+  -1008,
+  -1011,
+  -1014,
+  -1016,
+  -1018,
+  -1020,
+  -1021,
+  -1022,
+  -1023,
+  -1023,
+  -1024,
+  -1023,
+  -1023,
+  -1022,
+  -1021,
+  -1020,
+  -1018,
+  -1016,
+  -1014,
+  -1011,
+  -1008,
+  -1005,
+  -1001,
+  -997,
+  -993,
+  -989,
+  -984,
+  -979,
+  -973,
+  -968,
+  -962,
+  -955,
+  -949,
+  -942,
+  -935,
+  -928,
+  -920,
+  -912,
+  -904,
+  -895,
+  -886,
+  -877,
+  -868,
+  -858,
+  -848,
+  -838,
+  -828,
+  -817,
+  -806,
+  -795,
+  -784,
+  -772,
+  -760,
+  -748,
+  -736,
+  -724,
+  -711,
+  -698,
+  -685,
+  -671,
+  -658,
+  -644,
+  -630,
+  -616,
+  -601,
+  -587,
+  -572,
+  -557,
+  -542,
+  -527,
+  -512,
+  -496,
+  -480,
+  -464,
+  -448,
+  -432,
+  -416,
+  -400,
+  -383,
+  -366,
+  -350,
+  -333,
+  -316,
+  -299,
+  -282,
+  -265,
+  -247,
+  -230,
+  -212,
+  -195,
+  -177,
+  -160,
+  -142,
+  -124,
+  -107,
+  -89,
+  -71,
+  -53,
+  -35,
+  -17
+};
diff --git a/src/stnmap.c b/src/stnmap.c
new file mode 100644
index 0000000..46c68d9
--- /dev/null
+++ b/src/stnmap.c
@@ -0,0 +1,451 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/* This program creates a station map file given the name of a control
+   file for a station data set.  It reads the control file, then
+   using information from the control file, it reads the data file,
+   then creates the map file (using the name specified in the control
+   file).  */
+
+/* 
+ * Include ./configure's header file
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+/* If autoconfed, only include malloc.h when it's presen */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#else /* undef HAVE_CONFIG_H */
+
+#include <malloc.h>
+
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "grads.h"
+#include "gx.h"
+
+gaint help=0;
+void command_line_help(void) ;
+
+gaint skstn (void);
+gaint rdstn (char *, gaint);
+
+FILE *dfile=NULL,*mfile;
+struct gafile *pfi;
+char *ifi,*fn=NULL,*ch=NULL;
+off_t fpos;
+
+gaint main (gaint argc, char *argv[])  {
+  struct gavar *pvar;
+  struct rpthdr hdr;
+  struct dt dtim, dtimi;
+  char rec[256],cname[256],stid[10];
+  off_t pos;
+  gaint i,j,scnt,lcnt,rc,mxtim,mxcnt,mxsiz,cnt,siz,mpsiz;
+  gaint rdw,rtot,verb,iarg,flg,quiet;
+  gaint sizhdr,idum;
+  gaint *map;
+  gaint diag=0;
+  gaint vermap=2;          /* default version */ 
+  gaint noread=0;
+  gaint flag;
+  gaint maxlevels=250;
+  gaint maxlevelsflag=0;
+  gaint offset;
+
+/* Look at command line args */
+  ifi = NULL;
+  verb = 0;
+  quiet = 0;
+
+  if (argc>1) {
+    iarg = 1;
+    while (iarg<argc) {
+      flg = 1;
+      ch = argv[iarg];
+      if (*(ch)=='-' && *(ch+1)=='h' && *(ch+2)=='e' && *(ch+3)=='l' && *(ch+4)=='p' ) {
+	command_line_help();
+	return(0);
+      } else if (*ch=='-' && *(ch+1)=='i') {
+	iarg++;
+	if (iarg<argc) {
+	  ifi = argv[iarg];
+	  flg = 0;
+	} else iarg--;		/* Let error message pop */
+      }
+      else if (*ch=='-' && *(ch+1)=='v') {
+	verb = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='q') {
+	quiet = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='0') {
+        noread = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='M') {
+	maxlevelsflag=1;
+        ch+=2;
+        i = 0;
+        while(*(ch+i) && i<20) {
+          if (*(ch+i)<'0' || *(ch+i)>'9') i = 999;
+          i++;
+        }
+        if (i<20) {
+          sscanf(ch,"%i",&maxlevels);
+          flg = 0;
+        }
+	if(i == 0) goto err1;
+	if(maxlevels < 10 || maxlevels > 10000) goto err1a;
+      }
+      else if (*ch=='-' && *(ch+1)=='0') {
+        noread = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='0') {
+        noread = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='1') {
+        vermap = 1;
+	flg = 0;
+      }
+      else if (*ch=='-' && *(ch+1)=='2') {
+        vermap = 2;
+	flg = 0;
+      }
+      if (flg) {
+	printf ("Invalid command line argument: %s  Ignored.\n",argv[iarg]);
+      }
+      iarg++;
+    }
+  }
+
+  if(!noread && maxlevelsflag) goto err1;
+ 
+  if (ifi==NULL) {
+    command_line_help();
+    nxtcmd (rec,"Enter stn ctl filename: ");
+    getwrd (cname,rec,255);
+    ifi = cname;
+  }
+
+  /* Scan descriptor file */
+  pfi = getpfi();
+  if (pfi==NULL) {
+    printf ("Memory allocation error \n");
+    return (1);
+  }
+  rc = gaddes (ifi, pfi, 0);
+  if (rc) {
+    printf ("File name is:  %s\n",ifi);
+    return(1);
+  }
+
+/* Check that descriptor file is for station data, and that
+   the variables are in the correct order (surface before levels) */
+  if (pfi->type!=2) {
+    printf ("Descriptor file is not for station data\n");
+    return (1);
+  }
+  pvar = pfi->pvar1;
+  lcnt=0; scnt=0;
+  for (i=0; i<pfi->vnum; i++) {
+    if (pvar->levels==0) {
+      if (lcnt>0) {
+	printf ("Variable records not properly ordered\n");
+	printf ("   Surface variables must appear first\n");
+	return(1);
+      }
+      scnt++;
+    } else {
+      lcnt++;
+    }
+    pvar++;
+  }
+  if (pfi->mnam==NULL) {
+    printf ("Station map file name not in descriptor file\n");
+    return (1);
+  }
+
+/* We are ready to start reading the binary station data file.
+   We read for the specified number of times, and build our
+   table of time starting points in the file. */
+  if(! quiet) {
+    printf ("  Name of binary data set: %s\n",pfi->name);
+    printf ("  Number of times in the data set: %i\n",pfi->dnum[3]);
+    printf ("  Number of surface variables: %i\n",scnt);
+    printf ("  Number of level dependent variables: %i\n\n",lcnt);
+    printf ("Starting scan of station data binary file.\n");
+  }
+  sizhdr = sizeof(struct rpthdr);
+  mpsiz = pfi->dnum[3]*2 + 2;
+  map = (gaint *)malloc(sizeof(gaint)*mpsiz);
+  if (map==NULL) {
+    printf ("  Error allocating memory.  \n");
+    printf ("  Probable cause: Invalid TDEF record\n");
+    return(1);
+  }
+  mxtim = 0;
+  mxcnt = -1;
+  mxsiz = 0;
+  i = 0;
+  if (!pfi->tmplat) {
+    dfile = fopen(pfi->name,"rb");
+    if (dfile==NULL) {
+      printf ("Error opening station data binary file\n");
+      printf (" File name is: %s\n",pfi->name);
+      return (1);
+    }
+    fpos = 0;
+    if (verb || ( !quiet ) ) printf ("Binary data file open: %s\n",pfi->name);
+  }
+  while (i<pfi->dnum[3]) {
+    if (verb || ( !quiet ) ) printf ("\nProcessing time step %i\n",i+1);
+    if (pfi->tmplat) {
+      gr2t(pfi->grvals[3],(gadouble)(i+1),&dtim);
+      gr2t(pfi->grvals[3],1.0,&dtimi);
+      ch = gafndt(pfi->name,&dtim, &dtimi,pfi->abvals[3],pfi->pchsub1,pfi->ens1,i+1,1,&flag);
+      if (ch==NULL) {
+	printf ("Memory allocation error\n");
+	return (1);
+      }
+      if (i==0 || strcmp(ch,fn)!=0) {     
+	/* we need to open a new file */
+	if (i>0) {
+	  /* close the current file */
+	  if (fn != NULL) free(fn);
+	  if (dfile != NULL) { fclose(dfile); dfile = NULL; }
+	}
+	fn = ch;
+	dfile = fopen(fn,"rb");
+	if (dfile==NULL) {
+	  printf ("  Error opening binary data file %s\n",fn);
+	}
+	else {
+	  if (verb || (!quiet)) printf ("  Binary data file open: %s\n",fn);
+	}
+	fpos = 0;
+      } 
+      else free(ch);
+    }
+    cnt = 0;
+    pos = fpos;
+    if(noread == 0) {
+      while (1) {
+	if (dfile==NULL) break;
+	if (!pfi->seqflg) {
+	  rc = skstn();
+	  if (rc) return (rc);
+	} else {
+	  rc = rdstn ((char *)(&rdw), 4);
+	  if (rc) return (rc);
+	  if (pfi->bswap) gabswp((gafloat *)(&rdw),1);
+	}
+	siz = sizhdr;
+	rc = rdstn ((char *)(&hdr),siz);
+
+	if (rc) return (rc);
+	if (pfi->bswap) gahswp(&hdr);
+      
+	if (hdr.flag<0 || hdr.flag>1 || hdr.nlev<0 || hdr.nlev>10000 ||
+	    hdr.t < -2.0 || hdr.t>2.0 ) {
+	  printf ("  Invalid station hdr found in station binary file\n");
+	  printf ("  Possible causes:  Invalid level count in hdr\n");
+	  printf ("                    Descriptor file mismatch\n");
+	  printf ("                    File not station data\n");
+	  printf ("                    Invalid relative time\n");
+	  if (pfi->seqflg) printf ("                    Invalid sequential format\n");
+	  printf ("    levs = %i  flag = %i  time = %g \n", hdr.nlev,hdr.flag,hdr.t);
+	  if (pfi->tmplat) printf("  File name = %s\n",fn);
+	  return(1);
+	}
+	if (hdr.flag) {
+	  siz = scnt + (hdr.nlev-1)*(lcnt+1);
+	} else {
+	  siz = hdr.nlev*(lcnt+1);
+	}
+	if (siz>mxsiz) mxsiz=siz;
+	siz = sizeof(gafloat)*siz + sizeof(struct rpthdr);
+	if (hdr.nlev==0) {
+	  siz = sizhdr;
+	}
+	if (verb) {
+	  for (j=0; j<8; j++) stid[j] = hdr.id[j];
+	  stid[8] = '\0';
+	  printf ("  ID,LON,LAT,T,NLEV,FLAG: ");
+	  printf ("%s %8.3f %7.3f %g %i %i  ",stid,hdr.lon,hdr.lat,hdr.t,hdr.nlev,hdr.flag);
+	  printf ("SIZE = %i\n",siz);
+	}
+	if (pfi->seqflg) {
+	  if (diag) printf ("   Seq Rec Lens: %i",rdw);
+	  rtot = rdw;
+	  while (rtot<=siz) {
+	    fpos = fpos + rdw + 8;
+	    rc = skstn();
+	    if (rc) return (rc);
+	    if (rtot==siz) break;
+	    rc = rdstn ((char *)(&rdw), 4);
+	    if (rc) return (rc);
+	    if (pfi->bswap) gabswp((gafloat *)(&rdw),1);
+	    if (diag) printf (" %i",rdw);
+	    rtot += rdw;
+	  }
+	  if (diag) printf ("\n");
+	  if (rtot>siz) {
+	    printf ("Sequential Read Error: ");
+	    printf ("Record size greater than one station report: %d :: %d\n",rtot,siz);
+	    return (1);
+	  }  
+	} else {
+	  fpos += siz;
+	}
+	if (hdr.nlev==0) break;
+	cnt++;
+      }
+    }
+    *(map+i+2) = pos;
+    *(map+pfi->dnum[3]+i+2) = cnt;
+    if(! quiet) printf ("     Time = %i has stn count = %i \n",i+1,cnt);
+    if (cnt>mxcnt) { mxcnt = cnt; mxtim = i+1; }
+    i++;
+  }
+  *(map) = pfi->dnum[3];
+  if(noread)  mxsiz=maxlevels ;
+  *(map+1) = mxsiz;
+  if(! quiet) {
+    printf ("  Max reports per time:  %i reports at t = %i\n",mxcnt,mxtim);
+    printf ("  Max data elements in largest report: %i\n",mxsiz);
+  }
+  mfile = fopen (pfi->mnam, "wb");
+  if (mfile==NULL) {
+    printf ("  Could not open output map data set: %s \n",pfi->mnam);
+    return(1);
+  }
+  if( vermap == 1) {
+    fwrite (map,sizeof(gaint),mpsiz,mfile);
+  } 
+  else if (vermap == 2) {
+    strncpy(rec,"GrADS_stnmapV002",16);
+    fwrite(rec,1,16,mfile);
+    for(i=0;i<mpsiz;i++) {
+      idum=*(map+i);
+      offset=i*4;
+      if(idum < 0) {
+	idum=-idum;
+	gapby(idum,(unsigned char*)map,offset,4);
+	gapbb(1,(unsigned char*)map,offset*8,1);
+      } else {
+	gapby(idum,(unsigned char*)map,offset,4);
+      }
+    }
+    fwrite (map,4,mpsiz,mfile);
+  }
+
+  if(! quiet) {
+    printf ("\nVersion %1d Station map file created: %s\n\n",vermap,pfi->mnam);
+    if(vermap == 2) {
+      printf("stnmap: WARNING!!  This stnmap file can only be accessed by GrADS Version " GRADS_VERSION "\n");
+      printf("stnmap: WARNING!!  However, GrADS Version " GRADS_VERSION " can read both versions\n\n");
+      printf("stnmap: COMMENT  -- use the -1 command line option to create a map for older GrADS versions\n");
+    }
+    if(verb) {
+      printf("\nstnmap: COMMENT  -- use the -q command line option to disable the station header listing\n");
+    }
+
+  }
+
+  return(0);
+
+
+ err1:
+  gaprnt (0,"-------------------------------------------------------------------\n\n");
+  gaprnt (0,"-M option Error:  maxlevels for -0 option not set or -0 not set\n\n");
+  gaprnt (0,"-------------------------------------------------------------------\n\n");
+  command_line_help();
+  return(1);
+
+ err1a:
+  gaprnt (0,"-------------------------------------------------------------------\n\n");
+  gaprnt (0,"-M option Error:  maxlevels is < 10 or > 10000 ; not a good idea for -0\n\n");
+  gaprnt (0,"-------------------------------------------------------------------\n\n");
+  command_line_help();
+  return(1);
+
+}
+
+
+gaint skstn (void) {
+gaint rc;
+  rc = fseeko(dfile, fpos, 0);
+  if (rc!=0) {
+    printf ("  Low Level I/O Error:  Seek error on data file \n");
+    printf ("  Error occurred when seeking to byte %lld \n",fpos);
+    printf ("  Possible cause:  Fewer times than expected\n");
+    if (pfi->seqflg) printf ("  Possible cause:  Invalid sequential format\n");
+    if (pfi->tmplat) printf("  File name = %s\n",fn);
+    return(1);
+  }
+  return (0);
+}
+
+gaint rdstn (char *rec, gaint siz) {
+gaint rc;
+  rc = fread (rec, 1, siz, dfile);
+  if (rc<siz) {
+    printf ("  Low Level I/O Error:  Read error on data file \n");
+    printf ("  Error reading %i bytes at location %lld \n", siz, fpos);
+    printf ("  Possible cause: Premature EOF\n");
+    if (pfi->seqflg) printf ("  Possible cause: Invalid sequential data\n");
+    if (pfi->tmplat) printf("  File name = %s\n",fn);
+    return(1);
+  }
+  return (0);
+}
+
+void gaprnt (gaint i, char *ch) {
+  printf ("%s",ch);
+}
+
+
+void command_line_help(void) {
+
+printf("stnmap for GrADS Version " GRADS_VERSION "\n\n");
+printf("Create the \"map\" file for using station data in grads\n\n");
+printf("Command line options: \n\n");
+printf("          -help   Just this help\n");
+printf("          -i      the data descriptor file (.ctl) to map\n");
+printf("          -v      turn ON verbose listing\n");
+printf("          -q      very quiet mode\n");
+printf("          -0      DO NOT READ - used for templating and no variation in variables\n");
+printf("          -MLLLL  for -0 set max number of levels LLLL (e.g., -M1000 for 1000 levels)\n");
+printf("          -1      create a machine specific version 1 map \n");
+printf("          -2      create a machine-INDEPENDENT version 2 map (the default for " GRADS_VERSION " and above\n\n");
+printf("   Example:\n\n");
+printf("   stnmap -i station_data.ctl\n");
+printf("   stnmap -0 -M100 -i station_data.ctl ;  do not read the data \n\n");
+
+}
+
+/* Query env symbol */
+
+char *gxgsym(char *ch) {
+  return (getenv(ch));
+}
+void set_nc_cache(size_t arg) {
+  return;
+}
+gadouble qcachesf(void) {
+  return(1.0);
+}
diff --git a/src/wgrib.c b/src/wgrib.c
new file mode 100644
index 0000000..59e5dbd
--- /dev/null
+++ b/src/wgrib.c
@@ -0,0 +1,13389 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <math.h>
+#include <float.h>
+/* 
+ * version 1.2.1 of grib headers  w. ebisuzaki 
+ *         1.2.2 added access to spectral reference value l. kornblueh
+ */
+
+#ifndef INT2
+#define INT2(a,b)   ((1-(int) ((unsigned) (a & 0x80) >> 6)) * (int) (((a & 0x7f) << 8) + b))
+#endif
+
+#define BDS_LEN(bds)		(ec_large_grib ? len_ec_bds : ((int) ((bds[0]<<16)+(bds[1]<<8)+bds[2])) )
+
+#define BDS_Flag(bds)		(bds[3])
+
+#define BDS_Grid(bds)		((bds[3] & 128) == 0)
+#define BDS_Harmonic(bds)	(bds[3] & 128)
+
+#define BDS_Packing(bds)	((bds[3] & 64) != 0)
+#define BDS_SimplePacking(bds)	((bds[3] & 64) == 0)
+#define BDS_ComplexPacking(bds)	((bds[3] & 64) != 0)
+
+#define BDS_OriginalType(bds)	((bds[3] & 32) != 0)
+#define BDS_OriginalFloat(bds)	((bds[3] & 32) == 0)
+#define BDS_OriginalInt(bds)	((bds[3] & 32) != 0)
+
+#define BDS_MoreFlags(bds)      ((bds[3] & 16) != 0)
+#define BDS_UnusedBits(bds)	((int) (bds[3] & 15))
+
+#define BDS_BinScale(bds)	INT2(bds[4],bds[5])
+
+#define BDS_RefValue(bds)	(ibm2flt(bds+6))
+#define BDS_NumBits(bds)	((int) bds[10])
+
+#define BDS_Harmonic_RefValue(bds) (ibm2flt(bds+11))
+
+#define BDS_DataStart(bds)      ((int) (11 + BDS_MoreFlags(bds)*3))
+
+/* breaks if BDS_NumBits(bds) == 0 */
+/*
+#define BDS_NValues(bds)        (((BDS_LEN(bds) - BDS_DataStart(bds))*8 - \
+				BDS_UnusedBits(bds)) / BDS_NumBits(bds))
+*/
+/*
+#define BDS_NValues(bds)        ((BDS_NumBits(bds) == 0) ? 0 : \
+				(((BDS_LEN(bds) - BDS_DataStart(bds))*8 - \
+				BDS_UnusedBits(bds)) / BDS_NumBits(bds)))
+*/
+
+#define BDS_P1(bds)		(bds[16] * 256 + bds[17])
+#define BDS_P2(bds)		(bds[18] * 256 + bds[19])
+
+/* undefined value -- if bitmap */
+#define UNDEFINED		9.999e20
+
+/* version 1.2 of grib headers  w. ebisuzaki */
+
+#define BMS_LEN(bms)		((bms) == NULL ? 0 : (bms[0]<<16)+(bms[1]<<8)+bms[2])
+#define BMS_UnusedBits(bms)	((bms) == NULL ? 0 : bms[3])
+#define BMS_StdMap(bms)		((bms) == NULL ? 0 : ((bms[4]<<8) + bms[5]))
+#define BMS_bitmap(bms)		((bms) == NULL ? NULL : (bms)+6)
+#define BMS_nxny(bms)		((((bms) == NULL) || BMS_StdMap(bms)) \
+	? 0 : (BMS_LEN(bms)*8 - 48 - BMS_UnusedBits(bms)))
+/* cnames_file.c */
+
+/* search order for parameter names
+ *
+ * #define P_TABLE_FIRST
+ * look at external parameter table first
+ *
+ * otherwise use builtin NCEP-2 or ECMWF-160 first
+ */
+/* #define P_TABLE_FIRST */
+
+/* search order for external parameter table
+ * 1) environment variable GRIBTAB
+ * 2) environment variable gribtab
+ * 3) the file 'gribtab' in current directory
+ */
+
+
+/* cnames.c */
+/* then default values */
+char *k5toa(unsigned char *pds);
+char *k5_comments(unsigned char *pds);
+int setup_user_table(int center, int subcenter, int ptable);
+
+
+struct ParmTable {
+	/* char *name, *comment; */
+	char *name, *comment;
+};
+/* version 1.4.5 of grib headers  w. ebisuzaki */
+/* this version is incomplete */
+/* 5/00 - dx/dy or di/dj controlled by bit 1 of resolution byte */
+/* 8/00 - dx/dy or di/dj for polar and lambert not controlled by res. byte */
+/* Added headers for the triangular grid of the gme model of DWD
+         Helmut P. Frank, 13.09.2001 */
+/* Clean up of triangular grid properties access and added spectral information
+         Luis Kornblueh, 27.03.2002 */
+/* 8/08 - dx/dy (polar,lambert) controlled by bit 1 of resolution byte */
+/* 5/11 Paul Schou: fixed GDS_Lambert_LonSP(gds) */
+/* 6/11 Jeffery S. Smith Albers equal area projection */
+
+#ifndef INT3
+#define INT3(a,b,c) ((1-(int) ((unsigned) (a & 0x80) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
+#endif
+#ifndef INT2
+#define INT2(a,b)   ((1-(int) ((unsigned) (a & 0x80) >> 6)) * (int) (((a & 127) << 8) + b))
+#endif
+
+#ifndef UINT4
+#define UINT4(a,b,c,d) ((int) ((a << 24) + (b << 16) + (c << 8) + (d)))
+#endif
+
+#ifndef UINT3
+#define UINT3(a,b,c) ((int) ((a << 16) + (b << 8) + (c)))
+#endif
+
+#ifndef UINT2
+#define UINT2(a,b) ((int) ((a << 8) + (b)))
+#endif
+
+
+#define GDS_Len1(gds)		(gds[0])
+#define GDS_Len2(gds)		(gds[1])
+#define GDS_Len3(gds)		(gds[2])
+#define GDS_LEN(gds)		((int) ((gds[0]<<16)+(gds[1]<<8)+gds[2]))
+
+#define GDS_NV(gds)		(gds[3])
+#define GDS_DataType(gds)	(gds[5])
+
+#define GDS_LatLon(gds)		(gds[5] == 0)
+#define GDS_Mercator(gds)	(gds[5] == 1)
+#define GDS_Gnomonic(gds)	(gds[5] == 2)
+#define GDS_Lambert(gds)	(gds[5] == 3)
+#define GDS_Gaussian(gds)	(gds[5] == 4)
+#define GDS_Polar(gds)		(gds[5] == 5)
+#define GDS_Albers(gds)		(gds[5] == 8)
+#define GDS_RotLL(gds)		(gds[5] == 10)
+#define GDS_Harmonic(gds)	(gds[5] == 50)
+#define GDS_Triangular(gds)	(gds[5] == 192)
+#define GDS_ssEgrid(gds)	(gds[5] == 201)	/* semi-staggered E grid */
+#define GDS_fEgrid(gds)		(gds[5] == 202) /* filled E grid */
+#define GDS_ss2dEgrid(gds)	(gds[5] == 203) /* semi-staggered E grid 2 d*/
+#define GDS_ss2dBgrid(gds)      (gds[5] == 205) /* semi-staggered B grid 2 d*/
+
+#define GDS_has_dy(mode)	((mode) & 128)
+#define GDS_LatLon_nx(gds)	((int) ((gds[6] << 8) + gds[7]))
+#define GDS_LatLon_ny(gds)	((int) ((gds[8] << 8) + gds[9]))
+#define GDS_LatLon_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_LatLon_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_LatLon_mode(gds)	(gds[16])
+#define GDS_LatLon_La2(gds)	INT3(gds[17],gds[18],gds[19])
+#define GDS_LatLon_Lo2(gds)	INT3(gds[20],gds[21],gds[22])
+
+#define GDS_LatLon_dx(gds)      (gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_LatLon_dy(gds)      (gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_Gaussian_nlat(gds)  ((gds[25]<<8)+gds[26])
+
+#define GDS_LatLon_scan(gds)	(gds[27])
+
+#define GDS_Polar_nx(gds)	(gds[16] & 128 ? ((gds[6] << 8) + gds[7]) : 0)
+#define GDS_Polar_ny(gds)	(gds[16] & 128 ? ((gds[8] << 8) + gds[9]) : 0)
+#define GDS_Polar_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_Polar_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_Polar_mode(gds)	(gds[16])
+#define GDS_Polar_Lov(gds)	INT3(gds[17],gds[18],gds[19])
+#define GDS_Polar_scan(gds)	(gds[27])
+#define GDS_Polar_Dx(gds)	INT3(gds[20], gds[21], gds[22])
+#define GDS_Polar_Dy(gds)	INT3(gds[23], gds[24], gds[25])
+#define GDS_Polar_pole(gds)	((gds[26] & 128) == 128)
+
+#define GDS_Lambert_nx(gds)	((gds[6] << 8) + gds[7])
+#define GDS_Lambert_ny(gds)	((gds[8] << 8) + gds[9])
+#define GDS_Lambert_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_Lambert_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_Lambert_mode(gds)	(gds[16])
+#define GDS_Lambert_Lov(gds)	INT3(gds[17],gds[18],gds[19])
+#define GDS_Lambert_dx(gds)	INT3(gds[20],gds[21],gds[22])
+#define GDS_Lambert_dy(gds)	INT3(gds[23],gds[24],gds[25])
+#define GDS_Lambert_NP(gds)	((gds[26] & 128) == 0)
+#define GDS_Lambert_scan(gds)   (gds[27])
+#define GDS_Lambert_Latin1(gds)	INT3(gds[28],gds[29],gds[30])
+#define GDS_Lambert_Latin2(gds)	INT3(gds[31],gds[32],gds[33])
+#define GDS_Lambert_LatSP(gds)	INT3(gds[34],gds[35],gds[36])
+
+/* bug found by Paul Schou 5/3/2011
+   #define GDS_Lambert_LonSP(gds)	INT3(gds[37],gds[37],gds[37])
+*/
+#define GDS_Lambert_LonSP(gds)	INT3(gds[37],gds[38],gds[39])
+
+#define GDS_ssEgrid_n(gds)	UINT2(gds[6],gds[7])
+#define GDS_ssEgrid_n_dum(gds)  UINT2(gds[8],gds[9])
+#define GDS_ssEgrid_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_ssEgrid_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_ssEgrid_mode(gds)	(gds[16])
+#define GDS_ssEgrid_La2(gds)	UINT3(gds[17],gds[18],gds[19])
+#define GDS_ssEgrid_Lo2(gds)	UINT3(gds[20],gds[21],gds[22])
+#define GDS_ssEgrid_di(gds)	(gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_ssEgrid_dj(gds)	(gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_ssEgrid_scan(gds)	(gds[27])
+
+#define GDS_fEgrid_n(gds)	UINT2(gds[6],gds[7])
+#define GDS_fEgrid_n_dum(gds)   UINT2(gds[8],gds[9])
+#define GDS_fEgrid_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_fEgrid_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_fEgrid_mode(gds)	(gds[16])
+#define GDS_fEgrid_La2(gds)	UINT3(gds[17],gds[18],gds[19])
+#define GDS_fEgrid_Lo2(gds)	UINT3(gds[20],gds[21],gds[22])
+#define GDS_fEgrid_di(gds)	(gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_fEgrid_dj(gds)	(gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_fEgrid_scan(gds)	(gds[27])
+
+#define GDS_ss2dEgrid_nx(gds)     UINT2(gds[6],gds[7])
+#define GDS_ss2dEgrid_ny(gds)     UINT2(gds[8],gds[9])
+#define GDS_ss2dEgrid_La1(gds)    INT3(gds[10],gds[11],gds[12])
+#define GDS_ss2dEgrid_Lo1(gds)    INT3(gds[13],gds[14],gds[15])
+#define GDS_ss2dEgrid_mode(gds)   (gds[16])
+#define GDS_ss2dEgrid_La2(gds)    INT3(gds[17],gds[18],gds[19])
+#define GDS_ss2dEgrid_Lo2(gds)    INT3(gds[20],gds[21],gds[22])
+#define GDS_ss2dEgrid_di(gds)     (gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_ss2dEgrid_dj(gds)     (gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_ss2dEgrid_scan(gds)   (gds[27])
+
+#define GDS_ss2dBgrid_nx(gds)     UINT2(gds[6],gds[7])
+#define GDS_ss2dBgrid_ny(gds)     UINT2(gds[8],gds[9])
+#define GDS_ss2dBgrid_La1(gds)    INT3(gds[10],gds[11],gds[12])
+#define GDS_ss2dBgrid_Lo1(gds)    INT3(gds[13],gds[14],gds[15])
+#define GDS_ss2dBgrid_mode(gds)   (gds[16])
+#define GDS_ss2dBgrid_La2(gds)    INT3(gds[17],gds[18],gds[19])
+#define GDS_ss2dBgrid_Lo2(gds)    INT3(gds[20],gds[21],gds[22])
+#define GDS_ss2dBgrid_di(gds)     (gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_ss2dBgrid_dj(gds)     (gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_ss2dBgrid_scan(gds)   (gds[27]) 
+
+
+#define GDS_Merc_nx(gds)	UINT2(gds[6],gds[7])
+#define GDS_Merc_ny(gds)	UINT2(gds[8],gds[9])
+#define GDS_Merc_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_Merc_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_Merc_mode(gds)	(gds[16])
+#define GDS_Merc_La2(gds)	INT3(gds[17],gds[18],gds[19])
+#define GDS_Merc_Lo2(gds)	INT3(gds[20],gds[21],gds[22])
+#define GDS_Merc_Latin(gds)	INT3(gds[23],gds[24],gds[25])
+#define GDS_Merc_scan(gds)	(gds[27])
+#define GDS_Merc_dx(gds)        (gds[16] & 128 ? INT3(gds[28],gds[29],gds[30]) : 0)
+#define GDS_Merc_dy(gds)        (gds[16] & 128 ? INT3(gds[31],gds[32],gds[33]) : 0)
+
+/* rotated Lat-lon grid */
+
+#define GDS_RotLL_nx(gds)	UINT2(gds[6],gds[7])
+#define GDS_RotLL_ny(gds)	UINT2(gds[8],gds[9])
+#define GDS_RotLL_La1(gds)	INT3(gds[10],gds[11],gds[12])
+#define GDS_RotLL_Lo1(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_RotLL_mode(gds)	(gds[16])
+#define GDS_RotLL_La2(gds)	INT3(gds[17],gds[18],gds[19])
+#define GDS_RotLL_Lo2(gds)	INT3(gds[20],gds[21],gds[22])
+#define GDS_RotLL_dx(gds)       (gds[16] & 128 ? INT2(gds[23],gds[24]) : 0)
+#define GDS_RotLL_dy(gds)       (gds[16] & 128 ? INT2(gds[25],gds[26]) : 0)
+#define GDS_RotLL_scan(gds)	(gds[27])
+#define GDS_RotLL_LaSP(gds)	INT3(gds[32],gds[33],gds[34])
+#define GDS_RotLL_LoSP(gds)	INT3(gds[35],gds[36],gds[37])
+#define GDS_RotLL_RotAng(gds)	ibm2flt(&(gds[38]))
+
+/* Triangular grid of DWD */
+#define GDS_Triangular_ni2(gds)	INT2(gds[6],gds[7])
+#define GDS_Triangular_ni3(gds)	INT2(gds[8],gds[9])
+#define GDS_Triangular_ni(gds)	INT3(gds[13],gds[14],gds[15])
+#define GDS_Triangular_nd(gds)  INT3(gds[10],gds[11],gds[12])
+
+/* Harmonics data */
+#define GDS_Harmonic_nj(gds)     ((int) ((gds[6] << 8) + gds[7])) 
+#define GDS_Harmonic_nk(gds)     ((int) ((gds[8] << 8) + gds[9])) 
+#define GDS_Harmonic_nm(gds)     ((int) ((gds[10] << 8) + gds[11])) 
+#define GDS_Harmonic_type(gds)   (gds[12])
+#define GDS_Harmonic_mode(gds)   (gds[13])
+
+/* index of NV and PV */
+#define GDS_PV(gds)		((gds[3] == 0) ? -1 : (int) gds[4] - 1)
+#define GDS_PL(gds)		((gds[4] == 255) ? -1 : (int) gds[3] * 4 + (int) gds[4] - 1)
+
+enum Def_NCEP_Table {rean, opn, rean_nowarn, opn_nowarn};
+
+unsigned char *seek_grib(FILE *file, unsigned long *pos, long *len_grib, 
+        unsigned char *buffer, unsigned int buf_len);
+
+int read_grib(FILE *file, long pos, long len_grib, unsigned char *buffer);
+
+long echack(FILE *file, long pos, long len_grib);
+
+double ibm2flt(unsigned char *ibm);
+ 
+void BDS_unpack(float *flt, unsigned char *bds, unsigned char *bitmap,
+        int n_bits, int n, double ref, double scale);
+
+int BDS_NValues(unsigned char *bds);
+
+double int_power(double x, int y);
+
+int flt2ieee(float x, unsigned char *ieee);
+
+int wrtieee(float *array, int n, int header, FILE *output);
+int wrtieee_header(unsigned int n, FILE *output);
+
+void levels(int, int, int, int verbose);
+ 
+void PDStimes(int time_range, int p1, int p2, int time_unit);
+
+int missing_points(unsigned char *bitmap, int n);
+
+void EC_ext(unsigned char *pds, char *prefix, char *suffix, int verbose);
+
+int GDS_grid(unsigned char *gds, unsigned char *bds, int *nx, int *ny, 
+             long int *nxny);
+
+void GDS_prt_thin_lon(unsigned char *gds);
+
+void GDS_winds(unsigned char *gds, int verbose);
+
+int PDS_date(unsigned char *pds, int option, int verf_time);
+
+int add_time(int *year, int *month, int *day, int *hour, int dtime, int unit);
+
+int verf_time(unsigned char *pds, int *year, int *month, int *day, int *hour);
+
+void print_pds(unsigned char *pds, int print_PDS, int print_PDS10, int verbose);
+void print_gds(unsigned char *gds, int print_GDS, int print_GDS10, int verbose);
+
+void ensemble(unsigned char *pds, int mode);
+/* version 3.4 of grib headers  w. ebisuzaki */
+/* this version is incomplete */
+/* add center DWD    Helmut P. Frank */
+/* 10/02 add center CPTEC */
+/* 29/04/2005 add center CHM   Luiz Claudio M. Fonseca*/
+/* 11/2008 add center LAMI   Davide Sacchetti */
+
+#ifndef INT2
+#define INT2(a,b)   ((1-(int) ((unsigned) (a & 0x80) >> 6)) * (int) (((a & 0x7f) << 8) + b))
+#endif
+#ifndef UINT4
+#define UINT4(a,b,c,d) ((int) ((a << 24) + (b << 16) + (c << 8) + (d)))
+#endif
+#ifndef UINT2
+#define UINT2(a,b) ((int) ((a << 8) + (b)))
+#endif
+#define __LEN24(pds)    ((pds) == NULL ? 0 : (int) ((pds[0]<<16)+(pds[1]<<8)+pds[2]))
+
+#define PDS_Len1(pds)		(pds[0])
+#define PDS_Len2(pds)		(pds[1])
+#define PDS_Len3(pds)		(pds[2])
+#define PDS_LEN(pds)		((int) ((pds[0]<<16)+(pds[1]<<8)+pds[2]))
+#define PDS_Vsn(pds)		(pds[3])
+#define PDS_Center(pds)		(pds[4])
+#define PDS_Model(pds)		(pds[5])
+#define PDS_Grid(pds)		(pds[6])
+#define PDS_HAS_GDS(pds)	((pds[7] & 128) != 0)
+#define PDS_HAS_BMS(pds)	((pds[7] & 64) != 0)
+#define PDS_PARAM(pds)		(pds[8])
+#define PDS_L_TYPE(pds)		(pds[9])
+#define PDS_LEVEL1(pds)		(pds[10])
+#define PDS_LEVEL2(pds)		(pds[11])
+
+#define PDS_KPDS5(pds)		(pds[8])
+#define PDS_KPDS6(pds)		(pds[9])
+#define PDS_KPDS7(pds)		((int) ((pds[10]<<8) + pds[11]))
+
+/* this requires a 32-bit default integer machine */
+#define PDS_Field(pds)		((pds[8]<<24)+(pds[9]<<16)+(pds[10]<<8)+pds[11])
+
+#define PDS_Year(pds)		(pds[12])
+#define PDS_Month(pds)		(pds[13])
+#define PDS_Day(pds)		(pds[14])
+#define PDS_Hour(pds)		(pds[15])
+#define PDS_Minute(pds)		(pds[16])
+#define PDS_ForecastTimeUnit(pds)	(pds[17])
+#define PDS_P1(pds)		(pds[18])
+#define PDS_P2(pds)		(pds[19])
+#define PDS_TimeRange(pds)	(pds[20])
+#define PDS_NumAve(pds)		((int) ((pds[21]<<8)+pds[22]))
+#define PDS_NumMissing(pds)	(pds[23])
+#define PDS_Century(pds)	(pds[24])
+#define PDS_Subcenter(pds)	(pds[25])
+#define PDS_DecimalScale(pds)	INT2(pds[26],pds[27])
+/* old #define PDS_Year4(pds)   (pds[12] + 100*(pds[24] - (pds[12] != 0))) */
+#define PDS_Year4(pds)          (pds[12] + 100*(pds[24] - 1))
+
+/* various centers */
+#define NMC			7
+#define ECMWF			98
+#define DWD			78
+#define CMC			54
+#define CPTEC			46
+#define CHM			146
+#define LAMI			200
+
+/* ECMWF Extensions */
+
+#define PDS_EcLocalId(pds)	(PDS_LEN(pds) >= 41 ? (pds[40]) : 0)
+#define PDS_EcClass(pds)	(PDS_LEN(pds) >= 42 ? (pds[41]) : 0)
+#define PDS_EcType(pds)		(PDS_LEN(pds) >= 43 ? (pds[42]) : 0)
+#define PDS_EcStream(pds)	(PDS_LEN(pds) >= 45 ? (INT2(pds[43], pds[44])) : 0)
+
+#define PDS_EcENS(pds)		(PDS_LEN(pds) >= 52 && pds[40] == 1 && \
+				pds[43] * 256 + pds[44] == 1035 && pds[50] != 0)
+#define PDS_EcFcstNo(pds)	(pds[49])
+#define PDS_EcNoFcst(pds)	(pds[50])
+
+#define PDS_Ec16Version(pds)	(pds + 45)
+#define PDS_Ec16Number(pds)	(PDS_EcLocalId(pds) == 16 ? UINT2(pds[49],pds[50]) : 0)
+#define PDS_Ec16SysNum(pds)	(PDS_EcLocalId(pds) == 16 ? UINT2(pds[51],pds[52]) : 0)
+#define PDS_Ec16MethodNum(pds)	(PDS_EcLocalId(pds) == 16 ? UINT2(pds[53],pds[54]) : 0)
+#define PDS_Ec16VerfMon(pds)	(PDS_EcLocalId(pds) == 16 ? UINT4(pds[55],pds[56],pds[57],pds[58]) : 0)
+#define PDS_Ec16AvePeriod(pds)	(PDS_EcLocalId(pds) == 16 ? pds[59] : 0)
+#define PDS_Ec16FcstMon(pds)	(PDS_EcLocalId(pds) == 16 ? UINT2(pds[60],pds[61]) : 0)
+
+/* NCEP Extensions */
+
+#define PDS_NcepENS(pds)	(PDS_LEN(pds) >= 44 && pds[25] == 2 && pds[40] == 1)
+#define PDS_NcepFcstType(pds)	(pds[41])
+#define PDS_NcepFcstNo(pds)	(pds[42])
+#define PDS_NcepFcstProd(pds)	(pds[43])
+
+/* time units */
+
+#define MINUTE  0
+#define HOUR    1
+#define DAY     2
+#define MONTH   3
+#define YEAR    4
+#define DECADE  5
+#define NORMAL  6
+#define CENTURY 7
+#define HOURS3  10
+#define HOURS6  11
+#define HOURS12  12
+#define MINUTES15 13
+#define MINUTES30 14
+#define SECOND  254
+
+
+
+#define VERSION "v1.8.1.2a (6-11) Wesley Ebisuzaki\n\t\tDWD-tables 2,201-205 (11-28-2005) Helmut P. Frank\n\t\tspectral: Luis Kornblueh (MPI)"
+
+#define CHECK_GRIB
+/* #define DEBUG */
+
+/*
+ * wgrib.c is placed into the public domain.  While you could
+ * legally do anything you want with the code, telling the world
+ * that you wrote it would be uncool.  Selling it would be really
+ * uncool.  The code was originally written for NMC/NCAR Reanalysis 
+ * and handles most GRIB files except for the ECMWF spectral files.
+ * (ECMWF's spectral->grid code are copyrighted and in FORTRAN.)
+ * The code, as usual, is not waranteed to be fit for any purpose 
+ * what so ever.  However, wgrib is operational NCEP code, so it
+ * better work for our files.
+ */
+
+/*
+ * wgrib.c extract/inventory grib records
+ *
+ *                              Wesley Ebisuzaki
+ *
+ * See Changes for update information
+ *
+ */
+
+/*
+ * MSEEK = I/O buffer size for seek_grib
+ */
+
+#define MSEEK 1024
+#define BUFF_ALLOC0	40000
+
+
+#ifndef min
+#define min(a,b)  ((a) < (b) ? (a) : (b))
+#define max(a,b)  ((a) < (b) ? (b) : (a))
+#endif
+
+#ifndef DEF_T62_NCEP_TABLE
+#define DEF_T62_NCEP_TABLE	rean
+#endif
+enum Def_NCEP_Table def_ncep_table = DEF_T62_NCEP_TABLE;
+int minute = 0;
+int ncep_ens = 0;
+int cmc_eq_ncep = 0;
+extern int ec_large_grib, len_ec_bds;
+
+int main(int argc, char **argv) {
+
+    unsigned char *buffer;
+    float *array;
+    double temp, rmin, rmax;
+    int i, nx, ny, file_arg;
+    long int len_grib, nxny, buffer_size, n_dump, count = 1;
+    long unsigned pos = 0;
+    unsigned char *msg, *pds, *gds, *bms, *bds, *pointer;
+    FILE *input, *dump_file = NULL;
+    char line[2000];
+    enum {BINARY, TEXT, IEEE, GRIB, NONE} output_type = NONE;
+    enum {DUMP_ALL, DUMP_RECORD, DUMP_POSITION, DUMP_LIST, INVENTORY} 
+	mode = INVENTORY;
+    enum {none, dwd, simple} header = simple;
+
+    long int dump = -1;
+    int verbose = 0, append = 0, v_time = 0, year_4 = 0, output_PDS_GDS = 0;
+    int print_GDS = 0, print_GDS10 = 0, print_PDS = 0, print_PDS10 = 0;
+    char *dump_file_name = "dump", open_parm[3];
+    int return_code = 0;
+
+    if (argc == 1) {
+	fprintf(stderr, "\nPortable Grib decoder for %s etc.\n",
+	    (def_ncep_table == opn_nowarn || def_ncep_table == opn) ?
+	    "NCEP Operations" : "NCEP/NCAR Reanalysis");
+	fprintf(stderr, "   it slices, dices    %s\n", VERSION);
+	fprintf(stderr, "   usage: %s [grib file] [options]\n\n", argv[0]);
+
+	fprintf(stderr, "Inventory/diagnostic-output selections\n");
+	fprintf(stderr, "   -s/-v                   short/verbose inventory\n");
+	fprintf(stderr, "   -V                      diagnostic output (not inventory)\n");
+	fprintf(stderr, "   (none)                  regular inventory\n");
+
+	fprintf(stderr, " Options\n");
+	fprintf(stderr, "   -PDS/-PDS10             print PDS in hex/decimal\n");
+	fprintf(stderr, "   -GDS/-GDS10             print GDS in hex/decimal\n");
+	fprintf(stderr, "   -verf                   print forecast verification time\n");
+	fprintf(stderr, "   -ncep_opn/-ncep_rean    default T62 NCEP grib table\n");
+	fprintf(stderr, "   -4yr                    print year using 4 digits\n");
+	fprintf(stderr, "   -min                    print minutes\n");
+	fprintf(stderr, "   -ncep_ens               ensemble info encoded in ncep format\n");
+
+	fprintf(stderr, "Decoding GRIB selection\n");
+	fprintf(stderr, "   -d [record number|all]  decode record number\n");
+	fprintf(stderr, "   -p [byte position]      decode record at byte position\n");
+	fprintf(stderr, "   -i                      decode controlled by stdin (inventory list)\n");
+	fprintf(stderr, "   (none)                  no decoding\n");
+
+	fprintf(stderr, " Options\n");
+	fprintf(stderr, "   -text/-ieee/-grib/-bin  convert to text/ieee/grib/bin (default)\n");
+	fprintf(stderr, "   -nh/-h                  output will have no headers/headers (default)\n");
+	fprintf(stderr, "   -dwdgrib                output dwd headers, grib (do not append)\n");
+	fprintf(stderr, "   -H                      output will include PDS and GDS (-bin/-ieee only)\n");
+	fprintf(stderr, "   -append                 append to output file\n");
+	fprintf(stderr, "   -o [file]               output file name, 'dump' is default\n");
+	fprintf(stderr, " Misc\n");
+	fprintf(stderr, "   -cmc [file]             use NCEP tables for CMC (dangerous)\n");
+	exit(8);
+    }
+    file_arg = 0;
+    for (i = 1; i < argc; i++) {
+	if (strcmp(argv[i],"-PDS") == 0) {
+	    print_PDS = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-PDS10") == 0) {
+	    print_PDS10 = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-GDS") == 0) {
+	    print_GDS = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-GDS10") == 0) {
+	    print_GDS10 = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-v") == 0) {
+	    verbose = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-V") == 0) {
+	    verbose = 2;
+	    continue;
+	}
+	if (strcmp(argv[i],"-s") == 0) {
+	    verbose = -1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-text") == 0) {
+	    output_type = TEXT;
+	    continue;
+	}
+	if (strcmp(argv[i],"-bin") == 0) {
+	    output_type = BINARY;
+	    continue;
+	}
+	if (strcmp(argv[i],"-ieee") == 0) {
+	    output_type = IEEE;
+	    continue;
+	}
+	if (strcmp(argv[i],"-grib") == 0) {
+	    output_type = GRIB;
+	    continue;
+	}
+	if (strcmp(argv[i],"-nh") == 0) {
+	    header = none;
+	    continue;
+	}
+	if (strcmp(argv[i],"-h") == 0) {
+	    header = simple;
+	    continue;
+	}
+	if (strcmp(argv[i],"-dwdgrib") == 0) {
+	    header = dwd;
+	    output_type = GRIB;
+	    continue;
+	}
+	if (strcmp(argv[i],"-append") == 0) {
+	    append = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-verf") == 0) {
+	    v_time = 1;
+	    continue;
+        }
+	if (strcmp(argv[i],"-cmc") == 0) {
+	    cmc_eq_ncep = 1;
+	    continue;
+        }
+	if (strcmp(argv[i],"-d") == 0) {
+	    if (strcmp(argv[i+1],"all") == 0) {
+	        mode = DUMP_ALL;
+	    }
+	    else {
+	        dump = atol(argv[i+1]);
+	        mode = DUMP_RECORD;
+	    }
+	    i++;
+	    if (output_type == NONE) output_type = BINARY;
+	    continue;
+	}
+	if (strcmp(argv[i],"-p") == 0) {
+	    pos = atol(argv[i+1]);
+	    i++;
+	    dump = 1;
+	    if (output_type == NONE) output_type = BINARY;
+	    mode = DUMP_POSITION;
+	    continue;
+	}
+	if (strcmp(argv[i],"-i") == 0) {
+	    if (output_type == NONE) output_type = BINARY;
+	    mode = DUMP_LIST;
+	    continue;
+	}
+	if (strcmp(argv[i],"-H") == 0) {
+	    output_PDS_GDS = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-NH") == 0) {
+	    output_PDS_GDS = 0;
+	    continue;
+	}
+	if (strcmp(argv[i],"-4yr") == 0) {
+	    year_4 = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-ncep_opn") == 0) {
+	    def_ncep_table = opn_nowarn;
+	    continue;
+	}
+	if (strcmp(argv[i],"-ncep_rean") == 0) {
+	    def_ncep_table = rean_nowarn;
+	    continue;
+	}
+	if (strcmp(argv[i],"-o") == 0) {
+	    dump_file_name = argv[i+1];
+	    i++;
+	    continue;
+	}
+	if (strcmp(argv[i],"--v") == 0) {
+	    printf("wgrib: %s\n", VERSION);
+	    exit(0);
+	}
+	if (strcmp(argv[i],"-min") == 0) {
+	    minute = 1;
+	    continue;
+	}
+	if (strcmp(argv[i],"-ncep_ens") == 0) {
+	    ncep_ens = 1;
+	    continue;
+	}
+	if (file_arg == 0) {
+	    file_arg = i;
+	}
+	else {
+	    fprintf(stderr,"argument: %s ????\n", argv[i]);
+	}
+    }
+    if (file_arg == 0) {
+	fprintf(stderr,"no GRIB file to process\n");
+	exit(8);
+    }
+    if ((input = fopen(argv[file_arg],"rb")) == NULL) {
+        fprintf(stderr,"could not open file: %s\n", argv[file_arg]);
+        exit(7);
+    }
+
+    if ((buffer = (unsigned char *) malloc(BUFF_ALLOC0)) == NULL) {
+	fprintf(stderr,"not enough memory\n");
+    }
+    buffer_size = BUFF_ALLOC0;
+
+    /* open output file */
+    if (mode != INVENTORY) {
+	open_parm[0] = append ? 'a' : 'w'; open_parm[1] = 'b'; open_parm[2] = '\0';
+	if (output_type == TEXT) open_parm[1] = '\0';
+
+	if ((dump_file = fopen(dump_file_name,open_parm)) == NULL) {
+	    fprintf(stderr,"could not open dump file\n");
+	    exit(8);
+        }
+	if (header == dwd && output_type == GRIB) wrtieee_header(0, dump_file);
+    }
+
+    /* skip dump - 1 records */
+    for (i = 1; i < dump; i++) {
+	msg = seek_grib(input, &pos, &len_grib, buffer, MSEEK);
+	if (msg == NULL) {
+	    fprintf(stderr, "ran out of data or bad file\n");
+	    exit(8);
+	}
+	pos += len_grib;
+    }
+    if (dump > 0) count += dump - 1;
+    n_dump = 0;
+
+    for (;;) {
+	if (n_dump == 1 && (mode == DUMP_RECORD || mode == DUMP_POSITION)) break;
+	if (mode == DUMP_LIST) {
+	    if (fgets(line,sizeof(line), stdin) == NULL) break;
+            line[sizeof(line) - 1] = 0;
+            if (sscanf(line,"%ld:%lu:", &count, &pos) != 2) {
+		fprintf(stderr,"bad input from stdin\n");
+                fprintf(stderr,"   %s\n", line);
+	        exit(8);
+	    }
+	}
+
+	msg = seek_grib(input, &pos, &len_grib, buffer, MSEEK);
+	if (msg == NULL) {
+	    if (mode == INVENTORY || mode == DUMP_ALL) break;
+	    fprintf(stderr,"missing GRIB record(s)\n");
+	    exit(8);
+	}
+
+        /* read all whole grib record */
+        if (len_grib + msg - buffer > buffer_size) {
+            buffer_size = len_grib + msg - buffer + 1000;
+            buffer = (unsigned char *) realloc((void *) buffer, buffer_size);
+            if (buffer == NULL) {
+                fprintf(stderr,"ran out of memory\n");
+                exit(8);
+            }
+        }
+        if (read_grib(input, pos, len_grib, buffer) == 0) {
+                fprintf(stderr,"error, could not read to end of record %ld\n",count);
+                exit(8);
+	}
+
+	/* parse grib message */
+
+	msg = buffer;
+        pds = (msg + 8);
+        pointer = pds + PDS_LEN(pds);
+#ifdef DEBUG
+	printf("LEN_GRIB= 0x%x\n", len_grib);
+	printf("PDS_LEN= 0x%x: at 0x%x\n", PDS_LEN(pds),pds-msg);
+#endif
+        if (PDS_HAS_GDS(pds)) {
+            gds = pointer;
+            pointer += GDS_LEN(gds);
+#ifdef DEBUG
+	    printf("GDS_LEN= 0x%x: at 0x%x\n", GDS_LEN(gds), gds-msg);
+#endif
+        }
+        else {
+            gds = NULL;
+        }
+#ifdef DEBUG
+        printf("Has BMS=%d\n", PDS_HAS_BMS(pds));
+#endif
+        if (PDS_HAS_BMS(pds)) {
+            bms = pointer;
+            pointer += BMS_LEN(bms);
+#ifdef DEBUG
+	    printf("BMS_LEN= 0x%x: at 0x%x\n", BMS_LEN(bms),bms-msg);
+#endif
+        }
+        else {
+            bms = NULL;
+        }
+
+        bds = pointer;
+        pointer += BDS_LEN(bds);
+
+
+#ifdef DEBUG
+	printf("BDS_LEN= 0x%x\n", BDS_LEN(bds));
+	printf("END_LEN= 0x%x: at 0x%x\n", 4,pointer-msg);
+#endif
+	if (pointer-msg+4 != len_grib) {
+	    fprintf(stderr,"Len of grib message is inconsistent.\n");
+	}
+
+        /* end section - "7777" in ascii */
+        if (pointer[0] != 0x37 || pointer[1] != 0x37 ||
+            pointer[2] != 0x37 || pointer[3] != 0x37) {
+            fprintf(stderr,"\n\n    missing end section\n");
+            fprintf(stderr, "%2x %2x %2x %2x\n", pointer[0], pointer[1], 
+		pointer[2], pointer[3]);
+#ifdef DEBUG
+	    printf("ignoring missing end section\n");
+#else
+	    exit(8);
+#endif
+        }
+
+	/* figure out size of array */
+	if (gds != NULL) {
+	    GDS_grid(gds, bds, &nx, &ny, &nxny);
+	}
+	else if (bms != NULL) {
+	    nxny = nx = BMS_nxny(bms);
+	    ny = 1;
+	}
+	else {
+	    if (BDS_NumBits(bds) == 0) {
+                nxny = nx = 1;
+                fprintf(stderr,"Missing GDS, constant record .. cannot "
+                    "determine number of data points\n");
+	    }
+	    else {
+	        nxny = nx = BDS_NValues(bds);
+	    }
+	    ny = 1;
+	}
+#ifdef CHECK_GRIB
+	if (gds && ! GDS_Harmonic(gds)) {
+	/* this grib check only works for simple packing */
+	/* turn off if harmonic */
+	    if (BDS_NumBits(bds) != 0) {
+	        i = BDS_NValues(bds);
+	        if (bms != NULL) {
+	            i += missing_points(BMS_bitmap(bms),nxny);
+	        }
+	        if (i != nxny) {
+	            fprintf(stderr,"grib header at record %ld: two values of nxny %ld %d\n",
+			count,nxny,i);
+		    fprintf(stderr,"   LEN %d DataStart %d UnusedBits %d #Bits %d nxny %ld\n",
+			BDS_LEN(bds), BDS_DataStart(bds),BDS_UnusedBits(bds),
+			BDS_NumBits(bds), nxny);
+		    return_code = 15;
+		    nxny = nx = i;
+		    ny = 1;
+	        }
+	    }
+ 
+        }
+#endif
+ 
+        if (verbose <= 0) {
+	    printf("%ld:%lu:d=", count, pos);
+	    PDS_date(pds,year_4,v_time);
+	    printf(":%s:", k5toa(pds));
+
+            if (verbose == 0) printf("kpds5=%d:kpds6=%d:kpds7=%d:TR=%d:P1=%d:P2=%d:TimeU=%d:",
+	        PDS_PARAM(pds),PDS_KPDS6(pds),PDS_KPDS7(pds),
+	        PDS_TimeRange(pds),PDS_P1(pds),PDS_P2(pds),
+                PDS_ForecastTimeUnit(pds));
+	    levels(PDS_KPDS6(pds), PDS_KPDS7(pds),PDS_Center(pds),verbose); printf(":");
+	    PDStimes(PDS_TimeRange(pds),PDS_P1(pds),PDS_P2(pds),
+                PDS_ForecastTimeUnit(pds));
+	    if (PDS_Center(pds) == ECMWF) EC_ext(pds,"",":",verbose);
+	    ensemble(pds, verbose);
+	    printf("NAve=%d",PDS_NumAve(pds));
+	    if (print_PDS || print_PDS10) print_pds(pds, print_PDS, print_PDS10, verbose);
+	    if (gds && (print_GDS || print_GDS10)) print_gds(gds, print_GDS, print_GDS10, verbose);
+            printf("\n");
+       }
+       else if (verbose == 1) {
+	    printf("%ld:%lu:D=", count, pos);
+            PDS_date(pds, 1, v_time);
+	    printf(":%s:", k5toa(pds));
+	    levels(PDS_KPDS6(pds), PDS_KPDS7(pds), PDS_Center(pds),verbose); printf(":");
+            printf("kpds=%d,%d,%d:",
+	        PDS_PARAM(pds),PDS_KPDS6(pds),PDS_KPDS7(pds));
+	    PDStimes(PDS_TimeRange(pds),PDS_P1(pds),PDS_P2(pds),
+                PDS_ForecastTimeUnit(pds));
+	    if (PDS_Center(pds) == ECMWF) EC_ext(pds,"",":",verbose);
+	    ensemble(pds, verbose);
+	    GDS_winds(gds, verbose);
+            printf("\"%s", k5_comments(pds));
+	    if (print_PDS || print_PDS10) print_pds(pds, print_PDS, print_PDS10, verbose);
+	    if (gds && (print_GDS || print_GDS10)) print_gds(gds, print_GDS, print_GDS10, verbose);
+            printf("\n");
+	}
+        else if (verbose == 2) {
+	    printf("rec %ld:%lu:date ", count, pos);
+	    PDS_date(pds, 1, v_time);
+	    printf(" %s kpds5=%d kpds6=%d kpds7=%d levels=(%d,%d) grid=%d ", 
+	        k5toa(pds), PDS_PARAM(pds), PDS_KPDS6(pds), PDS_KPDS7(pds), 
+                PDS_LEVEL1(pds), PDS_LEVEL2(pds), PDS_Grid(pds));
+	        levels(PDS_KPDS6(pds),PDS_KPDS7(pds),PDS_Center(pds),verbose);
+
+	    printf(" ");
+	    if (PDS_Center(pds) == ECMWF) EC_ext(pds,""," ",verbose);
+	    ensemble(pds, verbose);
+	    PDStimes(PDS_TimeRange(pds),PDS_P1(pds),PDS_P2(pds),
+                 PDS_ForecastTimeUnit(pds));
+	    if (bms != NULL) 
+		printf(" bitmap: %d undef", missing_points(BMS_bitmap(bms),nxny));
+            printf("\n  %s=%s\n", k5toa(pds), k5_comments(pds));
+	
+            printf("  timerange %d P1 %d P2 %d TimeU %d  nx %d ny %d GDS grid %d "
+		"num_in_ave %d missing %d\n", 
+	        PDS_TimeRange(pds),PDS_P1(pds),PDS_P2(pds), 
+                PDS_ForecastTimeUnit(pds), nx, ny, 
+                gds == NULL ? -1 : GDS_DataType(gds), 
+                PDS_NumAve(pds), PDS_NumMissing(pds));
+
+	    printf("  center %d subcenter %d process %d Table %d", 
+		PDS_Center(pds),PDS_Subcenter(pds),PDS_Model(pds),
+                PDS_Vsn(pds));
+	    GDS_winds(gds, verbose);
+	    printf("\n");
+
+	    if (gds && GDS_LatLon(gds) && nx != -1) 
+		printf("  latlon: lat  %f to %f by %f  nxny %ld\n"
+                       "          long %f to %f by %f, (%d x %d) scan %d "
+                       "mode %d bdsgrid %d\n",
+		  0.001*GDS_LatLon_La1(gds), 0.001*GDS_LatLon_La2(gds),
+		  0.001*GDS_LatLon_dy(gds), nxny, 0.001*GDS_LatLon_Lo1(gds),
+		  0.001*GDS_LatLon_Lo2(gds), 0.001*GDS_LatLon_dx(gds),
+	    	  nx, ny, GDS_LatLon_scan(gds), GDS_LatLon_mode(gds),
+		  BDS_Grid(bds));
+	    else if (gds && GDS_LatLon(gds) && nx == -1) {
+		printf("  thinned latlon: lat  %f to %f by %f  nxny %ld\n"
+                       "          long %f to %f, %ld grid pts   (%d x %d) scan %d"
+			" mode %d bdsgrid %d\n",
+		  0.001*GDS_LatLon_La1(gds), 0.001*GDS_LatLon_La2(gds),
+		  0.001*GDS_LatLon_dy(gds), nxny, 0.001*GDS_LatLon_Lo1(gds),
+		  0.001*GDS_LatLon_Lo2(gds),
+	    	  nxny, nx, ny, GDS_LatLon_scan(gds), GDS_LatLon_mode(gds),
+		  BDS_Grid(bds));
+		  GDS_prt_thin_lon(gds);
+	    }
+	    else if (gds && GDS_Gaussian(gds) && nx != -1)
+		printf("  gaussian: lat  %f to %f\n"
+                       "            long %f to %f by %f, (%d x %d) scan %d"
+			" mode %d bdsgrid %d\n",
+		  0.001*GDS_LatLon_La1(gds), 0.001*GDS_LatLon_La2(gds),
+		  0.001*GDS_LatLon_Lo1(gds), 0.001*GDS_LatLon_Lo2(gds), 
+		  0.001*GDS_LatLon_dx(gds),
+	    	  nx, ny, GDS_LatLon_scan(gds), GDS_LatLon_mode(gds),
+		  BDS_Grid(bds));
+	    else if (gds && GDS_Gaussian(gds) && nx == -1) {
+		printf("  thinned gaussian: lat  %f to %f\n"
+                       "          long %f to %f, %ld grid pts   (%d x %d) scan %d"
+			" mode %d bdsgrid %d\n",
+		  0.001*GDS_LatLon_La1(gds), 0.001*GDS_LatLon_La2(gds),
+		  0.001*GDS_LatLon_Lo1(gds), 0.001*GDS_LatLon_Lo2(gds),
+	    	  nxny, nx, ny, GDS_LatLon_scan(gds), GDS_LatLon_mode(gds),
+		  BDS_Grid(bds));
+		  GDS_prt_thin_lon(gds);
+	    }
+	    else if (gds && GDS_Polar(gds))
+		printf("  polar stereo: Lat1 %f Long1 %f Orient %f\n"
+			"     %s pole (%d x %d) Dx %d Dy %d scan %d mode %d\n",
+		    0.001*GDS_Polar_La1(gds),0.001*GDS_Polar_Lo1(gds),
+		    0.001*GDS_Polar_Lov(gds),
+		    GDS_Polar_pole(gds) == 0 ? "north" : "south", nx,ny,
+		    GDS_Polar_Dx(gds),GDS_Polar_Dy(gds),
+		    GDS_Polar_scan(gds), GDS_Polar_mode(gds));
+	    else if (gds && GDS_Lambert(gds))
+		printf("  Lambert Conf: Lat1 %f Lon1 %f Lov %f\n"
+                       "      Latin1 %f Latin2 %f LatSP %f LonSP %f\n"
+                       "      %s (%d x %d) Dx %f Dy %f scan %d mode %d\n",
+                     0.001*GDS_Lambert_La1(gds),0.001*GDS_Lambert_Lo1(gds),
+                     0.001*GDS_Lambert_Lov(gds),
+                     0.001*GDS_Lambert_Latin1(gds), 0.001*GDS_Lambert_Latin2(gds),
+                     0.001*GDS_Lambert_LatSP(gds), 0.001*GDS_Lambert_LonSP(gds),
+                      GDS_Lambert_NP(gds) ? "North Pole": "South Pole",
+                     GDS_Lambert_nx(gds), GDS_Lambert_ny(gds),
+                     0.001*GDS_Lambert_dx(gds), 0.001*GDS_Lambert_dy(gds),
+                     GDS_Lambert_scan(gds), GDS_Lambert_mode(gds));
+	    else if (gds && GDS_Albers(gds))
+		/* Albers equal area has same parameters as Lambert conformal */
+		printf("  Albers Equal-Area: Lat1 %f Lon1 %f Lov %f\n"
+                       "      Latin1 %f Latin2 %f LatSP %f LonSP %f\n"
+                       "      %s (%d x %d) Dx %f Dy %f scan %d mode %d\n",
+                     0.001*GDS_Lambert_La1(gds),0.001*GDS_Lambert_Lo1(gds),
+                     0.001*GDS_Lambert_Lov(gds),
+                     0.001*GDS_Lambert_Latin1(gds), 0.001*GDS_Lambert_Latin2(gds),
+                     0.001*GDS_Lambert_LatSP(gds), 0.001*GDS_Lambert_LonSP(gds),
+                      GDS_Lambert_NP(gds) ? "North Pole": "South Pole",
+                     GDS_Lambert_nx(gds), GDS_Lambert_ny(gds),
+                     0.001*GDS_Lambert_dx(gds), 0.001*GDS_Lambert_dy(gds),
+                     GDS_Lambert_scan(gds), GDS_Lambert_mode(gds));
+	    else if (gds && GDS_Mercator(gds))
+		printf("  Mercator: lat  %f to %f by %f km  nxny %ld\n"
+                       "          long %f to %f by %f km, (%d x %d) scan %d"
+			" mode %d Latin %f bdsgrid %d\n",
+		  0.001*GDS_Merc_La1(gds), 0.001*GDS_Merc_La2(gds),
+		  0.001*GDS_Merc_dy(gds), nxny, 0.001*GDS_Merc_Lo1(gds),
+		  0.001*GDS_Merc_Lo2(gds), 0.001*GDS_Merc_dx(gds),
+	    	  nx, ny, GDS_Merc_scan(gds), GDS_Merc_mode(gds), 
+		  0.001*GDS_Merc_Latin(gds), BDS_Grid(bds));
+	    else if (gds && GDS_ssEgrid(gds))
+		printf("  Semi-staggered Arakawa E-Grid: lat0 %f lon0 %f nxny %d\n"
+                       "    dLat %f dLon %f (%d x %d) scan %d mode %d\n",
+		  0.001*GDS_ssEgrid_La1(gds), 0.001*GDS_ssEgrid_Lo1(gds), 
+                  GDS_ssEgrid_n(gds)*GDS_ssEgrid_n_dum(gds), 
+                  0.001*GDS_ssEgrid_dj(gds), 0.001*GDS_ssEgrid_di(gds), 
+                  GDS_ssEgrid_Lo2(gds), GDS_ssEgrid_La2(gds),
+                  GDS_ssEgrid_scan(gds), GDS_ssEgrid_mode(gds));
+            else if (gds && GDS_ss2dEgrid(gds))
+                printf("  Semi-staggered Arakawa E-Grid (2D): lat0 %f lon0 %f nxny %d\n"
+                       "    dLat %f dLon %f (tlm0d %f tph0d %f) scan %d mode %d\n",
+                   0.001*GDS_ss2dEgrid_La1(gds), 0.001*GDS_ss2dEgrid_Lo1(gds),
+                   GDS_ss2dEgrid_nx(gds)*GDS_ss2dEgrid_ny(gds),
+                   0.001*GDS_ss2dEgrid_dj(gds), 0.001*GDS_ss2dEgrid_di(gds),
+                   0.001*GDS_ss2dEgrid_Lo2(gds), 0.001*GDS_ss2dEgrid_La2(gds),
+                   GDS_ss2dEgrid_scan(gds), GDS_ss2dEgrid_mode(gds));
+            else if (gds && GDS_ss2dBgrid(gds))
+                printf("  Semi-staggered Arakawa B-Grid (2D): lat0 %f lon0 %f nxny %d\n"
+                       "    dLat %f dLon %f (tlm0d %f tph0d %f) scan %d mode %d\n",
+                   0.001*GDS_ss2dBgrid_La1(gds), 0.001*GDS_ss2dBgrid_Lo1(gds),
+                   GDS_ss2dBgrid_nx(gds)*GDS_ss2dBgrid_ny(gds),
+                   0.001*GDS_ss2dBgrid_dj(gds), 0.001*GDS_ss2dBgrid_di(gds),
+                   0.001*GDS_ss2dBgrid_Lo2(gds), 0.001*GDS_ss2dBgrid_La2(gds),
+                   GDS_ss2dBgrid_scan(gds), GDS_ss2dBgrid_mode(gds)); 
+	    else if (gds && GDS_fEgrid(gds)) 
+		printf("  filled Arakawa E-Grid: lat0 %f lon0 %f nxny %d\n"
+                       "    dLat %f dLon %f (%d x %d) scan %d mode %d\n",
+		  0.001*GDS_fEgrid_La1(gds), 0.001*GDS_fEgrid_Lo1(gds), 
+                  GDS_fEgrid_n(gds)*GDS_fEgrid_n_dum(gds), 
+                  0.001*GDS_fEgrid_dj(gds), 0.001*GDS_fEgrid_di(gds), 
+                  GDS_fEgrid_Lo2(gds), GDS_fEgrid_La2(gds),
+                  GDS_fEgrid_scan(gds), GDS_fEgrid_mode(gds));
+	    else if (gds && GDS_RotLL(gds))
+		printf("  rotated LatLon grid  lat %f to %f  lon %f to %f\n"
+		       "    nxny %ld  (%d x %d)  dx %d dy %d  scan %d  mode %d\n"
+		       "    transform: south pole lat %f lon %f  rot angle %f\n", 
+		   0.001*GDS_RotLL_La1(gds), 0.001*GDS_RotLL_La2(gds), 
+		   0.001*GDS_RotLL_Lo1(gds), 0.001*GDS_RotLL_Lo2(gds),
+		   nxny, GDS_RotLL_nx(gds), GDS_RotLL_ny(gds),
+		   GDS_RotLL_dx(gds), GDS_RotLL_dy(gds),
+		   GDS_RotLL_scan(gds), GDS_RotLL_mode(gds),
+		   0.001*GDS_RotLL_LaSP(gds), 0.001*GDS_RotLL_LoSP(gds),
+		   GDS_RotLL_RotAng(gds) );
+	    else if (gds && GDS_Gnomonic(gds))
+		printf("  Gnomonic grid\n");
+	    else if (gds && GDS_Harmonic(gds))
+		printf("  Harmonic (spectral):  pentagonal spectral truncation: nj %d nk %d nm %d\n",
+		       GDS_Harmonic_nj(gds), GDS_Harmonic_nk(gds),
+		       GDS_Harmonic_nm(gds));
+		if (gds && GDS_Harmonic_type(gds) == 1)
+		  printf("  Associated Legendre polynomials\n");
+            else if (gds && GDS_Triangular(gds))
+                printf("  Triangular grid:  nd %d ni %d (= 2^%d x 3^%d)\n",
+		    GDS_Triangular_nd(gds), GDS_Triangular_ni(gds), 
+                    GDS_Triangular_ni2(gds), GDS_Triangular_ni3(gds) );
+	    if (print_PDS || print_PDS10) 
+                print_pds(pds, print_PDS, print_PDS10, verbose);
+	    if (gds && (print_GDS || print_GDS10)) 
+                 print_gds(gds, print_GDS, print_GDS10, verbose);
+	}
+
+	if (mode != INVENTORY && output_type == GRIB) {
+	        if (header == dwd) wrtieee_header((int) len_grib, dump_file);
+	        fwrite((void *) msg, sizeof(char), len_grib, dump_file);
+	        if (header == dwd) wrtieee_header((int) len_grib, dump_file);
+	    n_dump++;
+	}
+
+	if ((mode != INVENTORY && output_type != GRIB) || verbose > 1) {
+	    /* decode numeric data */
+ 
+            if ((array = (float *) malloc(sizeof(float) * nxny)) == NULL) {
+                fprintf(stderr,"memory problems\n");
+                exit(8);
+            }
+
+	    temp = int_power(10.0, - PDS_DecimalScale(pds));
+
+ 	    BDS_unpack(array, bds, BMS_bitmap(bms), BDS_NumBits(bds), nxny,
+			   temp*BDS_RefValue(bds),temp*int_power(2.0, BDS_BinScale(bds)));
+
+	    if (verbose > 1) {
+		rmin = FLT_MAX;
+		rmax = -FLT_MAX;
+	        for (i = 0; i < nxny; i++) {
+		    if (fabs(array[i]-UNDEFINED) > 0.0001*UNDEFINED) {
+	                rmin = min(rmin,array[i]);
+	                rmax = max(rmax,array[i]);
+		    }
+	        }
+	        printf("  min/max data %g %g  num bits %d "
+			" BDS_Ref %g  DecScale %d BinScale %d\n", 
+		    rmin, rmax, BDS_NumBits(bds), BDS_RefValue(bds),
+		    PDS_DecimalScale(pds), BDS_BinScale(bds));
+	    }
+
+	    if (mode != INVENTORY && output_type != GRIB) {
+		/* dump code */
+		if (output_PDS_GDS == 1) {
+		    /* insert code here */
+	            if (output_type == BINARY || output_type == IEEE) {
+			/* write PDS */
+			i = PDS_LEN(pds) + 4;
+	                if (header == simple && output_type == BINARY) 
+				fwrite((void *) &i, sizeof(int), 1, dump_file);
+	                if (header == simple && output_type == IEEE) wrtieee_header(i, dump_file);
+	                fwrite((void *) "PDS ", 1, 4, dump_file);
+	                fwrite((void *) pds, 1, i - 4, dump_file);
+	                if (header == simple && output_type == BINARY) 
+				fwrite((void *) &i, sizeof(int), 1, dump_file);
+	                if (header == simple && output_type == IEEE) wrtieee_header(i, dump_file);
+
+			/* write GDS */
+			i = (gds) ?  GDS_LEN(gds) + 4 : 4;
+	                if (header == simple && output_type == BINARY) 
+				fwrite((void *) &i, sizeof(int), 1, dump_file);
+	                if (header == simple && output_type == IEEE) wrtieee_header(i, dump_file);
+	                fwrite((void *) "GDS ", 1, 4, dump_file);
+	                if (gds) fwrite((void *) gds, 1, i - 4, dump_file);
+	                if (header == simple && output_type == BINARY) 
+				fwrite((void *) &i, sizeof(int), 1, dump_file);
+	                if (header == simple && output_type == IEEE) wrtieee_header(i, dump_file);
+		    }
+		} 
+
+	        if (output_type == BINARY) {
+	            i = nxny * sizeof(float);
+	            if (header == simple) fwrite((void *) &i, sizeof(int), 1, dump_file);
+	            fwrite((void *) array, sizeof(float), nxny, dump_file);
+	            if (header == simple) fwrite((void *) &i, sizeof(int), 1, dump_file);
+	        }
+		else if (output_type == IEEE) {
+		    wrtieee(array, nxny, header, dump_file);
+		}
+	        else if (output_type == TEXT) {
+	            /* number of points in grid */
+	            if (header == simple) {
+		        if (nx <= 0 || ny <= 0 || nxny != nx*ny) {
+                            fprintf(dump_file, "%ld %d\n", nxny, 1);
+			}
+			else {
+			    fprintf(dump_file, "%d %d\n", nx, ny);
+			}
+		    }
+	            for (i = 0; i < nxny; i++) {
+		        fprintf(dump_file,"%g\n", array[i]);
+		    }
+	        }
+	        n_dump++;
+	    }
+	    free(array);
+	    if (verbose > 0) printf("\n");
+	}
+	    
+        pos += len_grib;
+        count++;
+    }
+
+    if (mode != INVENTORY) {
+	if (header == dwd && output_type == GRIB) wrtieee_header(0, dump_file);
+	if (ferror(dump_file)) {
+		fprintf(stderr,"error writing %s\n",dump_file_name);
+		exit(8);
+	}
+    }
+    fclose(input);
+    return (return_code);
+}
+
+void print_pds(unsigned char *pds, int print_PDS, int print_PDS10, int verbose) {
+    int i, j;
+
+    j = PDS_LEN(pds);
+    if (verbose < 2) {
+        if (print_PDS && verbose < 2) {
+            printf(":PDS=");
+            for (i = 0; i < j; i++) {
+                printf("%2.2x", (int) pds[i]);
+            }
+        }
+        if (print_PDS10 && verbose < 2) {
+            printf(":PDS10=");
+            for (i = 0; i < j; i++) {
+                printf(" %d", (int) pds[i]);
+            }
+        }
+    }
+    else {
+        if (print_PDS) {
+            printf("  PDS(1..%d)=",j);
+            for (i = 0; i < j; i++) {
+                if (i % 20 == 0) printf("\n    %4d:",i+1);
+                printf(" %3.2x", (int) pds[i]);
+            }
+            printf("\n");
+        }
+        if (print_PDS10) {
+            printf("  PDS10(1..%d)=",j);
+            for (i = 0; i < j; i++) {
+                if (i % 20 == 0) printf("\n    %4d:",i+1);
+                printf(" %3d", (int) pds[i]);
+            }
+            printf("\n");
+        }
+    }
+}
+
+void print_gds(unsigned char *gds, int print_GDS, int print_GDS10, int verbose) {
+    int i, j;
+
+    j = GDS_LEN(gds);
+    if (verbose < 2) {
+        if (print_GDS && verbose < 2) {
+            printf(":GDS=");
+            for (i = 0; i < j; i++) {
+                printf("%2.2x", (int) gds[i]);
+            }
+        }
+        if (print_GDS10 && verbose < 2) {
+            printf(":GDS10=");
+            for (i = 0; i < j; i++) {
+                printf(" %d", (int) gds[i]);
+            }
+        }
+    }
+    else {
+        if (print_GDS) {
+            printf("  GDS(1..%d)=",j);
+            for (i = 0; i < j; i++) {
+                if (i % 20 == 0) printf("\n    %4d:",i+1);
+                printf(" %3.2x", (int) gds[i]);
+            }
+            printf("\n");
+        }
+        if (print_GDS10) {
+            printf("  GDS10(1..%d)=",j);
+            for (i = 0; i < j; i++) {
+                if (i % 20 == 0) printf("\n    %4d:",i+1);
+                printf(" %3d", (int) gds[i]);
+            }
+            printf("\n");
+        }
+    }
+}
+/*
+ * find next grib header
+ *
+ * file = what do you think?
+ * pos = initial position to start looking at  ( = 0 for 1st call)
+ *       returns with position of next grib header (units=bytes)
+ * len_grib = length of the grib record (bytes)
+ * buffer[buf_len] = buffer for reading/writing
+ *
+ * returns (char *) to start of GRIB header+PDS
+ *         NULL if not found
+ *
+ * adapted from SKGB (Mark Iredell)
+ *
+ * v1.1 9/94 Wesley Ebisuzaki
+ * v1.2 3/96 Wesley Ebisuzaki handles short records at end of file
+ * v1.3 8/96 Wesley Ebisuzaki increase NTRY from 3 to 100 for the folks
+ *      at Automation decided a 21 byte WMO bulletin header wasn't long 
+ *      enough and decided to go to an 8K header.  
+ * v1.4 11/10/2001 D. Haalman, looks at entire file, does not try
+ *      to read past EOF
+ *      3/8/2010 echack added by Brian Doty
+ * v1.5 5/2011 changes for ECMWF who have grib1+grib2 files, scan entire file
+ */
+
+#ifndef min
+   #define min(a,b)  ((a) < (b) ? (a) : (b))
+#endif
+
+/* #define LEN_HEADER_PDS (28+42+100) */
+#define LEN_HEADER_PDS (28+8)
+
+int ec_large_grib = 0,  len_ec_bds;
+
+unsigned char *seek_grib(FILE *file, unsigned long *pos, long *len_grib, 
+        unsigned char *buffer, unsigned int buf_len) {
+
+    int i, len;
+    long length_grib;
+    static int warn_grib2 = 0;
+    clearerr(file);
+    while ( !feof(file) ) {
+
+        if (fseek(file, *pos, SEEK_SET) == -1) break;
+	i = fread(buffer, sizeof (unsigned char), buf_len, file);     
+        if (ferror(file)) break;
+        len = i - LEN_HEADER_PDS;
+     
+        for (i = 0; i < len; i++) {
+            if (buffer[i] == 'G' && buffer[i+1] == 'R' && buffer[i+2] == 'I'
+                && buffer[i+3] == 'B') {
+		/* grib edition 1 */
+		if (buffer[i+7] == 1) {
+                    *pos = i + *pos;
+                    *len_grib = length_grib = (buffer[i+4] << 16) + (buffer[i+5] << 8) +
+                            buffer[i+6];
+
+		    /* small records don't have ECMWF hack */
+		    if ((length_grib & 0x800000) == 0) { ec_large_grib = 0; return (buffer + i); }
+
+		    /* potential for ECMWF hack */
+		    ec_large_grib = 1;
+		    *len_grib = echack(file, *pos, length_grib);
+                    return (buffer+i);
+		}
+
+		/* grib edition 2 */
+		else if (buffer[i+7] == 2) {
+		    if (warn_grib2++ == 0) fprintf(stderr,"grib2 message ignored (use wgrib2)\n");
+		}
+
+            }
+        }
+	*pos = *pos + (buf_len - LEN_HEADER_PDS);
+    }
+
+    *len_grib = 0;
+    return (unsigned char *) NULL;
+}
+
+
+/* If the encoded grib record length is long enough, we may have an encoding
+   of an even longer record length using the ecmwf hack.  To check for this
+   requires getting the length of the binary data section.  To get this requires
+   getting the lengths of the various sections before the bds.  To see if those
+   sections are there requires checking the flags in the pds.  */
+
+long echack(FILE *file, long pos, long len_grib) {
+
+    int gdsflg, bmsflg, center;
+    unsigned int pdslen, gdslen, bmslen, bdslen;
+    unsigned char buf[8];
+    long len;
+
+    len = len_grib;
+
+    /* Get pdslen */
+
+    if (fseek(file, pos+8, SEEK_SET) == -1) return 0;
+    if (fread(buf, sizeof (unsigned char), 8, file) != 8) return 0;
+    pdslen = __LEN24(buf);
+
+    center = buf[4];
+
+    /* know that NCEP and CMC do not use echack */
+    if (center == NMC || center == CMC) {
+	ec_large_grib = 0;
+        return len_grib;
+    }
+
+
+    gdsflg = buf[7] & 128;
+    bmsflg = buf[7] & 64;
+
+    gdslen=0;
+    if (gdsflg) {
+        if (fseek(file, pos+8+pdslen, SEEK_SET) == -1) return 0;
+        if (fread(buf, sizeof (unsigned char), 3, file) != 3) return 0;
+        gdslen = __LEN24(buf);
+    }
+
+    /* if there, get length of bms */
+
+    bmslen = 0;
+    if (bmsflg) {
+       if (fseek(file, pos+8+pdslen+gdslen, SEEK_SET) == -1) return 0;
+       if (fread(buf, sizeof (unsigned char), 3, file) != 3) return 0;
+       bmslen = __LEN24(buf);
+    }
+
+    /* get bds length */
+
+    if (fseek(file, pos+8+pdslen+gdslen+bmslen, SEEK_SET) == -1) return 0;
+    if (fread(buf, sizeof (unsigned char), 3, file) != 3) return 0;
+    bdslen = __LEN24(buf);
+
+    /* Now we can check if this record is hacked */
+
+    if (bdslen >= 120) {
+	/* normal record */
+	ec_large_grib = 0;
+    }
+    else {
+        /* ECMWF hack */
+        len_grib = (len & 0x7fffff) * 120 - bdslen + 4;
+        len_ec_bds = len_grib - (12 + pdslen + gdslen + bmslen);
+	ec_large_grib = 1;
+    }
+    return len_grib;
+}
+
+/* ibm2flt       wesley ebisuzaki
+ *
+ * v1.1 .. faster
+ * v1.1 .. if mant == 0 -> quick return
+ *
+ */
+
+
+double ibm2flt(unsigned char *ibm) {
+
+	int positive, power;
+	unsigned int abspower;
+	long int mant;
+	double value, exp;
+
+	mant = (ibm[1] << 16) + (ibm[2] << 8) + ibm[3];
+        if (mant == 0) return 0.0;
+
+	positive = (ibm[0] & 0x80) == 0;
+	power = (int) (ibm[0] & 0x7f) - 64;
+	abspower = power > 0 ? power : -power;
+
+
+	/* calc exp */
+	exp = 16.0;
+	value = 1.0;
+	while (abspower) {
+		if (abspower & 1) {
+			value *= exp;
+		}
+		exp = exp * exp;
+		abspower >>= 1;
+	}
+
+	if (power < 0) value = 1.0 / value;
+	value = value * mant / 16777216.0;
+	if (positive == 0) value = -value;
+	return value;
+}
+	
+/*
+ * read_grib.c
+ *
+ * reads grib message
+ *
+ * input: pos, byte position of grib message
+ *        len_grib, length of grib message
+ * output: *buffer, grib message
+ *
+ * note: call seek_grib first
+ *
+ * v1.0 9/94 Wesley Ebisuzaki
+ *
+ */
+
+int read_grib(FILE *file, long pos, long len_grib, unsigned char *buffer) {
+
+    int i;
+
+
+    if (fseek(file, pos, SEEK_SET) == -1) {
+	    return 0;
+    }
+
+    i = fread(buffer, sizeof (unsigned char), len_grib, file);
+    return (i == len_grib);
+}
+
+/*
+ * w. ebisuzaki
+ *
+ *  return x**y
+ *
+ *
+ *  input: double x
+ *	   int y
+ */
+double int_power(double x, int y) {
+
+	double value;
+
+	if (y < 0) {
+		y = -y;
+		x = 1.0 / x;
+	}
+	value = 1.0;
+
+	while (y) {
+		if (y & 1) {
+			value *= x;
+		}
+		x = x * x;
+		y >>= 1;
+	}
+	return value;
+}
+
+/* cnames.c 				Wesley Ebisuzaki
+ *
+ * returns strings with either variable name or comment field
+ * v1.4 4/98
+ * reanalysis can use process 180 and subcenter 0
+ *
+ * Add DWD tables 2, 201, 202, 203      Helmut P. Frank, DWD, FE13
+ *                                      Thu Aug 23 09:28:34 GMT 2001
+ * add DWD tables 204, 205              H. Frank, 10-19-2005
+ * LAMI => DWD				11/2008 Davide Sacchetti 
+ */
+
+
+extern const  struct ParmTable parm_table_ncep_opn[256];
+extern const  struct ParmTable parm_table_ncep_reanal[256];
+extern const  struct ParmTable parm_table_nceptab_128[256];
+extern const  struct ParmTable parm_table_nceptab_129[256];
+extern const  struct ParmTable parm_table_nceptab_130[256];
+extern const  struct ParmTable parm_table_nceptab_131[256];
+extern const  struct ParmTable parm_table_nceptab_133[256];
+extern const  struct ParmTable parm_table_nceptab_140[256];
+extern const  struct ParmTable parm_table_nceptab_141[256];
+extern const  struct ParmTable parm_table_mdl_nceptab[256];
+
+extern const  struct ParmTable parm_table_ecmwf_128[256];
+extern const  struct ParmTable parm_table_ecmwf_129[256];
+extern const  struct ParmTable parm_table_ecmwf_130[256];
+extern const  struct ParmTable parm_table_ecmwf_131[256];
+extern const  struct ParmTable parm_table_ecmwf_132[256];
+extern const  struct ParmTable parm_table_ecmwf_133[256];
+extern const  struct ParmTable parm_table_ecmwf_140[256];
+extern const  struct ParmTable parm_table_ecmwf_150[256];
+extern const  struct ParmTable parm_table_ecmwf_151[256];
+extern const  struct ParmTable parm_table_ecmwf_160[256];
+extern const  struct ParmTable parm_table_ecmwf_162[256];
+extern const  struct ParmTable parm_table_ecmwf_170[256];
+extern const  struct ParmTable parm_table_ecmwf_171[256];
+extern const  struct ParmTable parm_table_ecmwf_172[256];
+extern const  struct ParmTable parm_table_ecmwf_173[256];
+extern const  struct ParmTable parm_table_ecmwf_174[256];
+extern const  struct ParmTable parm_table_ecmwf_180[256];
+extern const  struct ParmTable parm_table_ecmwf_190[256];
+extern const  struct ParmTable parm_table_ecmwf_200[256];
+extern const  struct ParmTable parm_table_ecmwf_210[256];
+extern const  struct ParmTable parm_table_ecmwf_211[256];
+extern const  struct ParmTable parm_table_ecmwf_228[256];
+extern struct ParmTable parm_table_user[256];
+extern const  struct ParmTable parm_table_dwd_002[256];
+extern const  struct ParmTable parm_table_dwd_201[256];
+extern const  struct ParmTable parm_table_dwd_202[256];
+extern const  struct ParmTable parm_table_dwd_203[256];
+extern const  struct ParmTable parm_table_dwd_204[256];
+extern const  struct ParmTable parm_table_dwd_205[256];
+extern const  struct ParmTable parm_table_cptec_254[256];
+
+extern enum Def_NCEP_Table def_ncep_table;
+extern int cmc_eq_ncep;
+
+/*
+ * returns pointer to the parameter table
+ */
+
+
+
+static const struct ParmTable *Parm_Table(unsigned char *pds) {
+
+    int i, center, subcenter, ptable, process;
+    static int missing_count = 0, reanal_opn_count = 0;
+
+    center = PDS_Center(pds);
+    subcenter = PDS_Subcenter(pds);
+    ptable = PDS_Vsn(pds);
+
+    /* CMC (54) tables look like NCEP tables */
+    if (center == CMC && cmc_eq_ncep) center = NMC;
+
+#ifdef P_TABLE_FIRST
+    i = setup_user_table(center, subcenter, ptable);
+    if (i == 1) return &parm_table_user[0];
+#endif
+    /* figure out if NCEP opn or reanalysis */
+    if (center == NMC && ptable <= 3) {
+	if (subcenter == 1) return &parm_table_ncep_reanal[0];
+	if (subcenter == 14) return &parm_table_mdl_nceptab[0];
+        process = PDS_Model(pds);
+	if (subcenter != 0 || (process != 80 && process != 180) || 
+		(ptable != 1 && ptable != 2)) 
+            return &parm_table_ncep_opn[0];
+
+	/* at this point could be either the opn or reanalysis table */
+	if (def_ncep_table == opn_nowarn) return &parm_table_ncep_opn[0];
+	if (def_ncep_table == rean_nowarn) return &parm_table_ncep_reanal[0];
+        if (reanal_opn_count++ == 0) {
+	    fprintf(stderr, "Using NCEP %s table, see -ncep_opn, -ncep_rean options\n",
+               (def_ncep_table == opn) ?  "opn" : "reanalysis");
+	}
+        return (def_ncep_table == opn) ?  &parm_table_ncep_opn[0] 
+		: &parm_table_ncep_reanal[0];
+    }
+
+    if (center == NMC) {
+        if (ptable == 128) return &parm_table_nceptab_128[0];
+        if (ptable == 129) return &parm_table_nceptab_129[0];
+        if (ptable == 130) return &parm_table_nceptab_130[0];
+        if (ptable == 131) return &parm_table_nceptab_131[0];
+        if (ptable == 132) return &parm_table_ncep_reanal[0];
+        if (ptable == 133) return &parm_table_nceptab_133[0];
+        if (ptable == 140) return &parm_table_nceptab_140[0];
+        if (ptable == 141) return &parm_table_nceptab_141[0];
+    }
+    if (center == ECMWF) {
+        if (ptable == 128) return &parm_table_ecmwf_128[0];
+        if (ptable == 129) return &parm_table_ecmwf_129[0];
+        if (ptable == 130) return &parm_table_ecmwf_130[0];
+        if (ptable == 131) return &parm_table_ecmwf_131[0];
+        if (ptable == 132) return &parm_table_ecmwf_132[0];
+        if (ptable == 133) return &parm_table_ecmwf_133[0];
+        if (ptable == 140) return &parm_table_ecmwf_140[0];
+        if (ptable == 150) return &parm_table_ecmwf_150[0];
+        if (ptable == 151) return &parm_table_ecmwf_151[0];
+        if (ptable == 160) return &parm_table_ecmwf_160[0];
+        if (ptable == 162) return &parm_table_ecmwf_162[0];
+        if (ptable == 170) return &parm_table_ecmwf_170[0];
+        if (ptable == 171) return &parm_table_ecmwf_171[0];
+        if (ptable == 172) return &parm_table_ecmwf_172[0];
+        if (ptable == 173) return &parm_table_ecmwf_173[0];
+        if (ptable == 174) return &parm_table_ecmwf_174[0];
+        if (ptable == 180) return &parm_table_ecmwf_180[0];
+        if (ptable == 190) return &parm_table_ecmwf_190[0];
+        if (ptable == 200) return &parm_table_ecmwf_200[0];
+        if (ptable == 210) return &parm_table_ecmwf_210[0];
+        if (ptable == 211) return &parm_table_ecmwf_211[0];
+        if (ptable == 228) return &parm_table_ecmwf_228[0];
+    }
+    /* if (center == DWD || center == CHM || center == LAMI) { */
+    if (center == DWD || center == CHM) {
+        if (ptable ==   2) return &parm_table_dwd_002[0];
+        if (ptable == 201) return &parm_table_dwd_201[0];
+        if (ptable == 202) return &parm_table_dwd_202[0];
+        if (ptable == 203) return &parm_table_dwd_203[0];
+        if (ptable == 204) return &parm_table_dwd_204[0];
+        if (ptable == 205) return &parm_table_dwd_205[0];
+    }
+    if (center == CPTEC) {
+	if (ptable == 254) return &parm_table_cptec_254[0];
+    }
+
+#ifndef P_TABLE_FIRST
+    i = setup_user_table(center, subcenter, ptable);
+    if (i == 1) return &parm_table_user[0];
+#endif
+
+    if ((ptable > 3 || (PDS_PARAM(pds)) > 127) && missing_count++ == 0) {
+	fprintf(stderr,
+            "\nUndefined parameter table (center %d-%d table %d), using NCEP-opn\n",
+            center, subcenter, ptable);
+    }
+    return &parm_table_ncep_opn[0];
+}
+
+/*
+ * return name field of PDS_PARAM(pds)
+ */
+
+char *k5toa(unsigned char *pds) {
+
+    return (Parm_Table(pds) + PDS_PARAM(pds))->name;
+}
+
+/*
+ * return comment field of the PDS_PARAM(pds)
+ */
+
+char *k5_comments(unsigned char *pds) {
+
+    return (Parm_Table(pds) + PDS_PARAM(pds))->comment;
+}
+
+/* 1996				wesley ebisuzaki
+ *
+ * Unpack BDS section
+ *
+ * input: *bits, pointer to packed integer data
+ *        *bitmap, pointer to bitmap (undefined data), NULL if none
+ *        n_bits, number of bits per packed integer
+ *        n, number of data points (includes undefined data)
+ *        ref, scale: flt[] = ref + scale*packed_int
+ * output: *flt, pointer to output array
+ *        undefined values filled with UNDEFINED
+ *
+ * note: code assumes an integer > 32 bits
+ *
+ * 7/98 v1.2.1 fix bug for bitmaps and nbit >= 25 found by Larry Brasfield
+ * 2/01 v1.2.2 changed jj from long int to double
+ * 3/02 v1.2.3 added unpacking extensions for spectral data 
+ *             Luis Kornblueh, MPIfM 
+ * 7/06 v.1.2.4 fixed some bug complex packed data was not set to undefined
+ */
+
+static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+static unsigned int map_masks[8] = {128, 64, 32, 16, 8, 4, 2, 1};
+static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+
+void BDS_unpack(float *flt, unsigned char *bds, unsigned char *bitmap,
+	int n_bits, int n, double ref, double scale) {
+
+    unsigned char *bits;
+
+    int i, mask_idx, t_bits, c_bits, j_bits;
+    unsigned int j, map_mask, tbits, jmask, bbits;
+    double jj;
+
+
+    if (BDS_ComplexPacking(bds)) {
+	fprintf(stderr,"*** Cannot decode complex packed fields n=%d***\n", n);
+	exit(8);
+	for (i = 0; i < n; i++) {
+	    *flt++ = UNDEFINED;
+	}
+	return;
+    }
+
+    if (BDS_Harmonic(bds)) {
+        bits = bds + 15;
+        /* fill in global mean */
+        *flt++ = BDS_Harmonic_RefValue(bds);
+        n -= 1; 
+    }
+    else {
+        bits = bds + 11;  
+    }
+
+    tbits = bbits = 0;
+
+    /* assume integer has 32+ bits */
+    if (n_bits <= 25) {
+        jmask = (1 << n_bits) - 1;
+        t_bits = 0;
+
+        if (bitmap) {
+	    for (i = 0; i < n; i++) {
+		/* check bitmap */
+		mask_idx = i & 7;
+		if (mask_idx == 0) bbits = *bitmap++;
+	        if ((bbits & map_masks[mask_idx]) == 0) {
+		    *flt++ = UNDEFINED;
+		    continue;
+	        }
+
+	        while (t_bits < n_bits) {
+	            tbits = (tbits * 256) + *bits++;
+	            t_bits += 8;
+	        }
+	        t_bits -= n_bits;
+	        j = (tbits >> t_bits) & jmask;
+	        *flt++ = ref + scale*j;
+            }
+        }
+        else {
+	    for (i = 0; i < n; i++) {
+		if (n_bits - t_bits > 8) {
+                    tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
+		    bits += 2;
+                    t_bits += 16;
+		}
+                while (t_bits < n_bits) {
+                    tbits = (tbits * 256) + *bits++;
+                    t_bits += 8;
+                }
+                t_bits -= n_bits;
+                flt[i] = (tbits >> t_bits) & jmask;
+            }
+	    /* at least this vectorizes :) */
+	    for (i = 0; i < n; i++) {
+		flt[i] = ref + scale*flt[i];
+	    }
+        }
+    }
+    else {
+	/* older unoptimized code, not often used */
+        c_bits = 8;
+        map_mask = 128;
+        while (n-- > 0) {
+	    if (bitmap) {
+	        j = (*bitmap & map_mask);
+	        if ((map_mask >>= 1) == 0) {
+		    map_mask = 128;
+		    bitmap++;
+	        }
+	        if (j == 0) {
+		    *flt++ = UNDEFINED;
+		    continue;
+	        }
+	    }
+
+	    jj = 0.0;
+	    j_bits = n_bits;
+	    while (c_bits <= j_bits) {
+	        if (c_bits == 8) {
+		    jj = jj * 256.0  + (double) (*bits++);
+		    j_bits -= 8;
+	        }
+	        else {
+		    jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+		    bits++;
+		    j_bits -= c_bits;
+		    c_bits = 8;
+	        }
+	    }
+	    if (j_bits) {
+	        c_bits -= j_bits;
+	        jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
+	    }
+	    *flt++ = ref + scale*jj;
+        }
+    }
+    return;
+}
+
+/*
+ * convert a float to an ieee single precision number v1.1
+ * (big endian)
+ *                      Wesley Ebisuzaki
+ *
+ * bugs: doesn't handle subnormal numbers
+ * bugs: assumes length of integer >= 25 bits
+ */
+
+int flt2ieee(float x, unsigned char *ieee) {
+
+	int sign, exp;
+        unsigned int umant;
+	double mant;
+
+	if (x == 0.0) {
+		ieee[0] = ieee[1] = ieee[2] = ieee[3] = 0;
+		return 0;
+	}
+
+	/* sign bit */
+	if (x < 0.0) {
+		sign = 128;
+		x = -x;
+	}
+	else sign = 0;
+	mant = frexp((double) x, &exp);
+
+        /* 2^24 = 16777216 */
+
+	umant = mant * 16777216 + 0.5;
+	if (umant >= 16777216) {
+            umant = umant / 2;
+            exp++;
+        }
+        /* bit 24 should be a 1 .. not used in ieee format */
+
+	exp = exp - 1 + 127;
+
+	if (exp < 0) {
+		/* signed zero */
+		ieee[0] = sign;
+		ieee[1] = ieee[2] = ieee[3] = 0;
+		return 0;
+	}
+	if (exp > 255) {
+		/* signed infinity */
+		ieee[0] = sign + 127;
+		ieee[1] = 128;
+                ieee[2] = ieee[3] = 0;
+                return 0;
+	}
+	/* normal number */
+
+	ieee[0] = sign + (exp >> 1);
+
+        ieee[3] = umant & 255;
+        ieee[2] = (umant >> 8) & 255;
+        ieee[1] = ((exp & 1) << 7) + ((umant >> 16) & 127);
+	return 0;
+}
+
+
+/* wesley ebisuzaki v1.3
+ *
+ * write ieee file -- big endian format
+ *
+ * input float *array		data to be written
+ *	 int n			size of array
+ *	 int header		1 for f77 style header 0 for none
+ *				(header is 4 byte header
+ *	 FILE *output		output file
+ *
+ * v1.2 7/97 buffered, faster
+ * v1.3 2/99 fixed (typo) error in wrtieee_header found by
+ *     Bob Farquhar
+ */
+
+#define BSIZ 1024*4
+
+int wrtieee(float *array, int n, int header, FILE *output) {
+
+	unsigned long int l;
+	int i, nbuf;
+	unsigned char buff[BSIZ];
+	unsigned char h4[4];
+
+	nbuf = 0;
+	if (header) {
+		l = n * 4;
+		for (i = 0; i < 4; i++) {
+			h4[i] = l & 255;
+			l >>= 8;
+		}
+		buff[nbuf++] = h4[3];
+		buff[nbuf++] = h4[2];
+		buff[nbuf++] = h4[1];
+		buff[nbuf++] = h4[0];
+	}
+	for (i = 0; i < n; i++) {
+		if (nbuf >= BSIZ) {
+		    fwrite(buff, 1, BSIZ, output);
+		    nbuf = 0;
+		}
+		flt2ieee(array[i], buff + nbuf);
+		nbuf += 4;
+	}
+	if (header) {
+		if (nbuf == BSIZ) {
+		    fwrite(buff, 1, BSIZ, output);
+		    nbuf = 0;
+		}
+		buff[nbuf++] = h4[3];
+		buff[nbuf++] = h4[2];
+		buff[nbuf++] = h4[1];
+		buff[nbuf++] = h4[0];
+	}
+	if (nbuf) fwrite(buff, 1, nbuf, output);
+	return 0;
+}
+
+/* write a big-endian 4 byte integer .. f77 IEEE  header */
+
+int wrtieee_header(unsigned int n, FILE *output) {
+	unsigned h4[4];
+
+	h4[0] = n & 255;
+	h4[1] = (n >> 8) & 255;
+	h4[2] = (n >> 16) & 255;
+	h4[3] = (n >> 24) & 255;
+
+	putc(h4[3],output);
+	putc(h4[2],output);
+	putc(h4[1],output);
+	putc(h4[0],output);
+
+	return 0;
+}
+
+
+/* wesley ebisuzaki v1.0
+ *
+ * levels.c
+ *
+ * prints out a simple description of kpds6, kpds7
+ *    (level/layer data)
+ *  kpds6 = octet 10 of the PDS
+ *  kpds7 = octet 11 and 12 of the PDS
+ *    (kpds values are from NMC's grib routines)
+ *  center = PDS_Center(pds) .. NMC, ECMWF, etc
+ *
+ * the description of the levels is 
+ *   (1) incomplete
+ *   (2) include some NMC-only values (>= 200?)
+ *
+ * v1.1 wgrib v1.7.3.1 updated with new levels
+ * v1.2 added new level and new parameter
+ * v1.2.1 modified level 117 pv units
+ * v1.2.2 corrected level 141
+ * v1.2.3 fixed layer 206 (was 205)
+ * v1.2.4 layer 210: new wmo defn > NCEP version
+ * v1.2.5 updated table 3/2007 to on388
+ */
+
+void levels(int kpds6, int kpds7, int center, int verbose) {
+
+	int o11, o12;
+
+	/* octets 11 and 12 */
+	o11 = kpds7 / 256;
+	o12 = kpds7 % 256;
+
+
+	switch (kpds6) {
+
+	case 1: printf("sfc");
+		break;
+	case 2: printf("cld base");
+		break;
+	case 3: printf("cld top");
+		break;
+	case 4: printf("0C isotherm");
+		break;
+	case 5: printf("cond lev");
+		break;
+	case 6: printf("max wind lev");
+		break;
+	case 7: printf("tropopause");
+		break;
+	case 8: printf("nom. top");
+		break;
+	case 9: printf("sea bottom");
+		break;
+	case 200:
+	case 10: printf("atmos col");
+		break;
+
+	case 12:
+	case 212: printf("low cld bot");
+		break;
+	case 13:
+	case 213: printf("low cld top");
+		break;
+	case 14:
+	case 214: printf("low cld lay");
+		break;
+	case 20: 
+		if (verbose == 2) printf("temp=%fK", kpds7/100.0);
+		else printf("T=%fK", kpds7/100.0);
+		break;
+	case 22:
+	case 222: printf("mid cld bot");
+		break;
+	case 23:
+	case 223: printf("mid cld top");
+		break;
+	case 24:
+	case 224: printf("mid cld lay");
+		break;
+	case 32:
+	case 232: printf("high cld bot");
+		break;
+	case 33:
+	case 233: printf("high cld top");
+		break;
+	case 34:
+	case 234: printf("high cld lay");
+		break;
+
+	case 201: printf("ocean column");
+		break;
+	case 204: printf("high trop freezing lvl");
+		break;
+	case 206: printf("grid-scale cld bot");
+		break;
+	case 207: printf("grid-scale cld top");
+		break;
+	case 209: printf("bndary-layer cld bot");
+		break;
+	case 210: 
+                if (center == NMC) printf("bndary-layer cld top");
+		else printf("%.2f mb",kpds7*0.01);
+		break;
+	case 211: printf("bndary-layer cld layer");
+		break;
+	case 215: printf("cloud ceiling");
+		break;
+	case 216: printf("Cb base");
+		break;
+	case 217: printf("Cb top");
+		break;
+	case 220: printf("planetary boundary layer (from Richardson no.)");
+		break;
+	case 235: if (kpds7 % 10 == 0)
+		printf("%dC ocean isotherm level",kpds7/10);
+		else printf("%.1fC ocean isotherm level",kpds7/10.0);
+		break;
+	case 236: printf("%d-%dm ocean layer",o11*10,o12*10);
+		break;
+	case 237: printf("ocean mixed layer bot");
+		break;
+	case 238: printf("ocean isothermal layer bot");
+		break;
+	case 239: printf("sfc-26C ocean layer");
+		break;
+	case 240: printf("ocean mixed layer");
+		break;
+	case 241: printf("ordered sequence of data");
+		break;
+	case 242: printf("convect-cld bot");
+		break;
+	case 243: printf("convect-cld top");
+		break;
+	case 244: printf("convect-cld layer");
+		break;
+	case 245: printf("lowest level of wet bulb zero");
+		break;
+	case 246: printf("max e-pot-temp lvl");
+		break;
+	case 247: printf("equilibrium lvl");
+		break;
+	case 248: printf("shallow convect-cld bot");
+		break;
+	case 249: printf("shallow convect-cld top");
+		break;
+	case 251: printf("deep convect-cld bot");
+		break;
+	case 252: printf("deep convect-cld top");
+		break;
+	case 253: printf("lowest bottom level of supercooled liequid water layer");
+		break;
+	case 254: printf("highest top level of supercooled liquid water layer");
+		break;
+	case 100: printf("%d mb",kpds7);
+	 	break;
+	case 101: printf("%d-%d mb",o11*10,o12*10);
+	 	break;
+	case 102: printf("MSL");
+	 	break;
+	case 103: printf("%d m above MSL",kpds7);
+	 	break;
+	case 104: printf("%d-%d m above msl",o11*100,o12*100);
+	 	break;
+	case 105: printf("%d m above gnd",kpds7);
+	 	break;
+	case 106: printf("%d-%d m above gnd",o11*100,o12*100);
+	 	break;
+	case 107: printf("sigma=%.4f",kpds7/10000.0);
+	 	break;
+	case 108: printf("sigma %.2f-%.2f",o11/100.0,o12/100.0);
+	 	break;
+	case 109: printf("hybrid lev %d",kpds7);
+	 	break;
+	case 110: printf("hybrid %d-%d",o11,o12);
+	 	break;
+	case 111: printf("%d cm down",kpds7);
+	 	break;
+	case 112: printf("%d-%d cm down",o11,o12);
+	 	break;
+	case 113: 
+		if (verbose == 2) printf("pot-temp=%dK",kpds7);
+		else printf("%dK",kpds7);
+	 	break;
+	case 114: printf("%d-%dK",475-o11,475-o12);
+	 	break;
+	case 115: printf("%d mb above gnd",kpds7);
+	 	break;
+	case 116: printf("%d-%d mb above gnd",o11,o12);
+	 	break;
+	case 117: printf("%d pv units",INT2(o11,o12)); /* units are suspect */
+	 	break;
+	case 119: printf("%.5f (ETA level)",kpds7/10000.0);
+	 	break;
+	case 120: printf("%.2f-%.2f (ETA levels)",o11/100.0,o12/100.0);
+	 	break;
+	case 121: printf("%d-%d mb",1100-o11,1100-o12);
+	 	break;
+	case 125: printf("%d cm above gnd",kpds7);
+	 	break;
+	case 126: 
+		if (center == NMC) printf("%.2f mb",kpds7*0.01);
+	 	break;
+	case 128: printf("%.3f-%.3f (sigma)",1.1-o11/1000.0, 1.1-o12/1000.0);
+	 	break;
+	case 141: printf("%d-%d mb",o11*10,1100-o12);
+	 	break;
+	case 160: printf("%d m below sea level",kpds7);
+	 	break;
+	default:
+	 	break;
+	}
+}
+
+/*
+ * PDStimes.c   v1.2 wesley ebisuzaki
+ *
+ * prints something readable for time code in grib file
+ *
+ * not all cases decoded
+ * for NCEP/NCAR Reanalysis
+ *
+ * v1.2.1 1/99 fixed forecast time unit table
+ * v1.2.2 10/01 add time_range = 11 (at DWD)  Helmut P. Frank
+ * v1.2.3 10/05 add time units 13 = 15 min, 14 = 30 min, and
+ *              time range 13 = nudging analysis, 14 = relabeled forecast
+ *              (at DWD), Helmut P. Frank
+ */
+
+static char *units[] = {
+	"min", "hr", "d", "mon", "yr",
+	"decade", "normal", "century", "??", "??", " x3 hours", " x6 hours",
+        " x12 hours",
+        "x15 min", "x30 min", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
+        "??", " sec"}; 
+
+void PDStimes(int time_range, int p1, int p2, int time_unit) {
+
+	char *unit;
+	enum {anal, fcst, unknown} type;
+	int fcst_len = 0;
+
+	if (time_unit >= 0 && time_unit <= sizeof(units)/sizeof(char *))
+             unit = units[time_unit];
+	else unit = "";
+
+        /* change x3/x6/x12 to hours */
+
+        if (time_unit == HOURS3) {
+	    p1 *= 3; p2 *= 3;
+	    time_unit = HOUR;
+        }
+        else if (time_unit == HOURS6) {
+	    p1 *= 6; p2 *= 6;
+	    time_unit = HOUR;
+        }
+        else if (time_unit == HOURS12) {
+	    p1 *= 12; p2 *= 12;
+	    time_unit = HOUR;
+        }
+	else if (time_unit == MINUTES30) {
+	    p1 *= 30; p2 *= 30;
+	    time_unit = MINUTE;
+        }
+	else if (time_unit == MINUTES15) {
+	    p1 *= 15; p2 *= 15;
+	    time_unit = MINUTE;
+        }
+	/* turn off 5/13/2010 
+	if (time_unit == MINUTE && p1 % 60 == 0 && p2 % 60 == 0) {
+	    p1 /= 60; p2 /= 60;
+	    time_unit = HOUR;
+        }
+	*/
+
+	if (time_unit >= 0 && time_unit <= sizeof(units)/sizeof(char *))
+             unit = units[time_unit];
+	else unit = "";
+
+	/* figure out if analysis or forecast */
+	/* in GRIB, there is a difference between init and uninit analyses */
+	/* not case at NMC .. no longer run initialization */
+	/* ignore diff between init an uninit analyses */
+
+	switch (time_range) {
+
+	case 0:
+	case 1:
+	case 113:
+	case 114:
+	case 118:
+		if (p1 == 0) type = anal;
+		else {
+			type = fcst;
+			fcst_len = p1;
+		}
+		break;
+	case 10: /* way NMC uses it, should be unknown? */
+		type = fcst;
+		fcst_len = p1*256 + p2;
+		if (fcst_len == 0) type = anal;
+		break;
+
+	case 51:
+		type = unknown;
+		break;
+	case 123:
+	case 124:
+		type = anal;
+		break;
+
+	case 135:
+		type = anal;
+		break;
+
+	default: type = unknown;
+		break;
+	}
+
+	/* ----------------------------------------------- */
+
+	if (type == anal) printf("anl:");
+	else if (type == fcst) printf("%d%s fcst:",fcst_len,unit);
+
+
+	if (time_range == 123 || time_range == 124) {
+		if (p1 != 0) printf("start@%d%s:",p1,unit);
+	}
+
+
+	/* print time range */
+
+
+	switch (time_range) {
+
+	case 0:
+	case 1:
+	case 10:
+		break;
+	case 2: printf("valid %d-%d%s:",p1,p2,unit);
+		break;
+	case 3: printf("%d-%d%s ave:",p1,p2,unit);
+		break;
+	case 4: printf("%d-%d%s acc:",p1,p2,unit);
+		break;
+	case 5: printf("%d-%d%s diff:",p1,p2,unit);
+		break;
+        case 6: printf("-%d to -%d %s ave:", p1,p2,unit);
+                break;
+        case 7: printf("-%d to %d %s ave:", p1,p2,unit);
+                break;
+	case 11: if (p1 > 0) {
+		    printf("init fcst %d%s:",p1,unit);
+		}
+		else {
+	            printf("time?:");
+		}
+		break;
+	case 13: printf("nudge ana %d%s:",p1,unit);
+		break;
+	case 14: printf("rel. fcst %d%s:",p1,unit);
+		break;
+	case 51: if (p1 == 0) {
+		    /* printf("clim %d%s:",p2,unit); */
+		    printf("0-%d%s product:ave at 1yr:",p2,unit);
+		}
+		else if (p1 == 1) {
+		    /* printf("clim (diurnal) %d%s:",p2,unit); */
+		    printf("0-%d%s product:same-hour,ave at 1yr:",p2,unit);
+		}
+		else {
+		    printf("clim? p1=%d? %d%s?:",p1,p2,unit);
+		}
+		break;
+	case 113:
+	case 123:
+		printf("ave@%d%s:",p2,unit);
+		break;
+	case 114:
+	case 124:
+		printf("acc@%d%s:",p2,unit);
+		break;
+	case 115:
+		printf("ave of fcst:%d to %d%s:",p1,p2,unit);
+		break;
+	case 116:
+		printf("acc of fcst:%d to %d%s:",p1,p2,unit);
+		break;
+	case 118: 
+		printf("var@%d%s:",p2,unit);
+		break;
+	case 128:
+		printf("%d-%d%s fcst acc:ave at 24hr:", p1, p2, unit);
+		break;
+	case 129:
+		printf("%d-%d%s fcst acc:ave@%d%s:", p1, p2, unit, p2-p1,unit);
+		break;
+	case 130:
+		printf("%d-%d%s fcst ave:ave at 24hr:", p1, p2, unit);
+		break;
+	case 131:
+		printf("%d-%d%s fcst ave:ave@%d%s:", p1, p2, unit,p2-p1,unit);
+		break;
+		/* for CFS */
+	case 132:
+		printf("%d-%d%s anl:ave at 1yr:", p1, p2, unit);
+		break;
+	case 133:
+		printf("%d-%d%s fcst:ave at 1yr:", p1, p2, unit);
+		break;
+	case 134:
+		printf("%d-%d%s fcst-anl:rms at 1yr:", p1, p2, unit);
+		break;
+	case 135:
+		printf("%d-%d%s fcst-fcst_mean:rms at 1yr:", p1, p2, unit);
+		break;
+	case 136:
+		printf("%d-%d%s anl-anl_mean:rms at 1yr:", p1, p2, unit);
+		break;
+	case 137:
+		printf("%d-%d%s fcst acc:ave at 6hr:", p1, p2, unit);
+		break;
+	case 138:
+		printf("%d-%d%s fcst ave:ave at 6hr:", p1, p2, unit);
+		break;
+	case 139:
+		printf("%d-%d%s fcst acc:ave at 12hr:", p1, p2, unit);
+		break;
+	case 140:
+		printf("%d-%d%s fcst ave:ave at 12hr:", p1, p2, unit);
+		break;
+		
+	default: printf("time?:");
+	}
+}
+
+/*
+ *  number of missing data points w. ebisuzaki
+ *
+ *  v1.1: just faster my dear
+ *  v1.2: just faster my dear
+ *
+ */
+
+static int bitsum[256] = {
+    8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4, 
+    7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 
+    7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 
+    7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 
+    6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, 
+    5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 
+    5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, 
+    4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+
+
+int missing_points(unsigned char *bitmap, int n) {
+
+    int count;
+    unsigned int tmp;
+    if (bitmap == NULL) return 0;
+
+    count = 0;
+    while (n >= 8) {
+	tmp = *bitmap++;
+	n -= 8;
+        count += bitsum[tmp];
+    }
+    tmp = *bitmap | ((1 << (8 - n)) - 1);
+    count += bitsum[tmp];
+
+    return count;
+}
+
+/*
+ * parameter table for NCEP (operations)
+ * center = 7, subcenter != 2 parameter table = 1, 2, 3 etc
+ * note: see reanalysis parameter table for problems
+ * updated 3/2003
+ */
+
+const struct ParmTable parm_table_ncep_opn[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"MSLSA", "Mean sea level pressure (Std Atm) [Pa]"},
+      /* 129 */ {"MSLMA", "Mean sea level pressure (MAPS) [Pa]"},
+      /* 130 */ {"MSLET", "Mean sea level pressure (ETA model) [Pa]"},
+      /* 131 */ {"LFTX", "Surface lifted index [K]"},
+      /* 132 */ {"4LFTX", "Best (4-layer) lifted index [K]"},
+      /* 133 */ {"KX", "K index [K]"},
+      /* 134 */ {"SX", "Sweat index [K]"},
+      /* 135 */ {"MCONV", "Horizontal moisture divergence [kg/kg/s]"},
+      /* 136 */ {"VWSH", "Vertical speed shear [1/s]"},
+      /* 137 */ {"TSLSA", "3-hr pressure tendency (Std Atmos Red) [Pa/s]"},
+      /* 138 */ {"BVF2", "Brunt-Vaisala frequency^2 [1/s^2]"},
+      /* 139 */ {"PVMW", "Potential vorticity (mass-weighted) [1/s/m]"},
+      /* 140 */ {"CRAIN", "Categorical rain [yes=1;no=0]"},
+      /* 141 */ {"CFRZR", "Categorical freezing rain [yes=1;no=0]"},
+      /* 142 */ {"CICEP", "Categorical ice pellets [yes=1;no=0]"},
+      /* 143 */ {"CSNOW", "Categorical snow [yes=1;no=0]"},
+      /* 144 */ {"SOILW", "Volumetric soil moisture [fraction]"},
+      /* 145 */ {"PEVPR", "Potential evaporation rate [W/m^2]"},
+      /* 146 */ {"CWORK", "Cloud work function [J/kg]"},
+      /* 147 */ {"U-GWD", "Zonal gravity wave stress [N/m^2]"},
+      /* 148 */ {"V-GWD", "Meridional gravity wave stress [N/m^2]"},
+      /* 149 */ {"PV", "Potential vorticity [m^2/s/kg]"},
+      /* 150 */ {"COVMZ", "Covariance between u and v [m^2/s^2]"},
+      /* 151 */ {"COVTZ", "Covariance between u and T [K*m/s]"},
+      /* 152 */ {"COVTM", "Covariance between v and T [K*m/s]"},
+      /* 153 */ {"CLWMR", "Cloud water [kg/kg]"},
+      /* 154 */ {"O3MR", "Ozone mixing ratio [kg/kg]"},
+      /* 155 */ {"GFLUX", "Ground heat flux [W/m^2]"},
+      /* 156 */ {"CIN", "Convective inhibition [J/kg]"},
+      /* 157 */ {"CAPE", "Convective Avail. Pot. Energy [J/kg]"},
+      /* 158 */ {"TKE", "Turbulent kinetic energy [J/kg]"},
+      /* 159 */ {"CONDP", "Lifted parcel condensation pressure [Pa]"},
+      /* 160 */ {"CSUSF", "Clear sky upward solar flux [W/m^2]"},
+      /* 161 */ {"CSDSF", "Clear sky downward solar flux [W/m^2]"},
+      /* 162 */ {"CSULF", "Clear sky upward long wave flux [W/m^2]"},
+      /* 163 */ {"CSDLF", "Clear sky downward long wave flux [W/m^2]"},
+      /* 164 */ {"CFNSF", "Cloud forcing net solar flux [W/m^2]"},
+      /* 165 */ {"CFNLF", "Cloud forcing net long wave flux [W/m^2]"},
+      /* 166 */ {"VBDSF", "Visible beam downward solar flux [W/m^2]"},
+      /* 167 */ {"VDDSF", "Visible diffuse downward solar flux [W/m^2]"},
+      /* 168 */ {"NBDSF", "Near IR beam downward solar flux [W/m^2]"},
+      /* 169 */ {"NDDSF", "Near IR diffuse downward solar flux [W/m^2]"},
+      /* 170 */ {"RWMR", "Rain water mixing ratio [kg/kg]"},
+      /* 171 */ {"SNMR", "Snow mixing ratio [kg/kg]"},
+      /* 172 */ {"MFLX", "Momentum flux [N/m^2]"},
+      /* 173 */ {"LMH", "Mass point model surface [non-dim]"},
+      /* 174 */ {"LMV", "Velocity point model surface [non-dim]"},
+      /* 175 */ {"MLYNO", "Model layer number (from bottom up) [non-dim]"},
+      /* 176 */ {"NLAT", "Latitude (-90 to +90) [deg]"},
+      /* 177 */ {"ELON", "East longitude (0-360) [deg]"},
+      /* 178 */ {"ICMR", "Ice mixing ratio [kg/kg]"},
+      /* 179 */ {"GRMR", "Graupel mixing ratio [kg/kg]"},
+      /* 180 */ {"GUST", "Surface wind gust [m/s]"},
+      /* 181 */ {"LPSX", "x-gradient of log pressure [1/m]"},
+      /* 182 */ {"LPSY", "y-gradient of log pressure [1/m]"},
+      /* 183 */ {"HGTX", "x-gradient of height [m/m]"},
+      /* 184 */ {"HGTY", "y-gradient of height [m/m]"},
+      /* 185 */ {"TURB", "Turbulence SIGMET/AIRMET [non-dim]"},
+      /* 186 */ {"ICNG", "Icing SIGMET/AIRMET [non-dim]"},
+      /* 187 */ {"LTNG", "Lightning [non-dim]"},
+      /* 188 */ {"DRIP", "Rate of water dropping from canopy to gnd [kg/m^2]"},
+      /* 189 */ {"VPTMP", "Virtual pot. temp. [K]"},
+      /* 190 */ {"HLCY", "Storm relative helicity [m^2/s^2]"},
+      /* 191 */ {"PROB", "Prob. from ensemble [non-dim]"},
+      /* 192 */ {"PROBN", "Prob. from ensemble norm. to clim. expect. [non-dim]"},
+      /* 193 */ {"POP", "Prob. of precipitation [%]"},
+      /* 194 */ {"CPOFP", "Prob. of frozen precipitation [%]"},
+      /* 195 */ {"CPOZP", "Prob. of freezing precipitation [%]"},
+      /* 196 */ {"USTM", "u-component of storm motion [m/s]"},
+      /* 197 */ {"VSTM", "v-component of storm motion [m/s]"},
+      /* 198 */ {"NCIP", "No. concen. ice particles []"},
+      /* 199 */ {"EVBS", "Direct evaporation from bare soil [W/m^2]"},
+      /* 200 */ {"EVCW", "Canopy water evaporation [W/m^2]"},
+      /* 201 */ {"ICWAT", "Ice-free water surface [%]"},
+      /* 202 */ {"CWDI", "Convective weather detection index []"},
+      /* 203 */ {"VAFTAD", "VAFTAD?? [??]"},
+      /* 204 */ {"DSWRF", "Downward short wave flux [W/m^2]"},
+      /* 205 */ {"DLWRF", "Downward long wave flux [W/m^2]"},
+      /* 206 */ {"UVI", "Ultraviolet index [W/m^2]"},
+      /* 207 */ {"MSTAV", "Moisture availability [%]"},
+      /* 208 */ {"SFEXC", "Exchange coefficient [(kg/m^3)(m/s)]"},
+      /* 209 */ {"MIXLY", "No. of mixed layers next to surface [integer]"},
+      /* 210 */ {"TRANS", "Transpiration [W/m^2]"},
+      /* 211 */ {"USWRF", "Upward short wave flux [W/m^2]"},
+      /* 212 */ {"ULWRF", "Upward long wave flux [W/m^2]"},
+      /* 213 */ {"CDLYR", "Non-convective cloud [%]"},
+      /* 214 */ {"CPRAT", "Convective precip. rate [kg/m^2/s]"},
+      /* 215 */ {"TTDIA", "Temp. tendency by all physics [K/s]"},
+      /* 216 */ {"TTRAD", "Temp. tendency by all radiation [K/s]"},
+      /* 217 */ {"TTPHY", "Temp. tendency by non-radiation physics [K/s]"},
+      /* 218 */ {"PREIX", "Precip index (0.0-1.00) [fraction]"},
+      /* 219 */ {"TSD1D", "Std. dev. of IR T over 1x1 deg area [K]"},
+      /* 220 */ {"NLGSP", "Natural log of surface pressure [ln(kPa)]"},
+      /* 221 */ {"HPBL", "Planetary boundary layer height [m]"},
+      /* 222 */ {"5WAVH", "5-wave geopotential height [gpm]"},
+      /* 223 */ {"CNWAT", "Plant canopy surface water [kg/m^2]"},
+      /* 224 */ {"SOTYP", "Soil type (Zobler) [0..9]"},
+      /* 225 */ {"VGTYP", "Vegetation type (as in SiB) [0..13]"},
+      /* 226 */ {"BMIXL", "Blackadar's mixing length scale [m]"},
+      /* 227 */ {"AMIXL", "Asymptotic mixing length scale [m]"},
+      /* 228 */ {"PEVAP", "Pot. evaporation [kg/m^2]"},
+      /* 229 */ {"SNOHF", "Snow phase-change heat flux [W/m^2]"},
+      /* 230 */ {"5WAVA", "5-wave geopot. height anomaly [gpm]"},
+      /* 231 */ {"MFLUX", "Convective cloud mass flux [Pa/s]"},
+      /* 232 */ {"DTRF", "Downward total radiation flux [W/m^2]"},
+      /* 233 */ {"UTRF", "Upward total radiation flux [W/m^2]"},
+      /* 234 */ {"BGRUN", "Baseflow-groundwater runoff [kg/m^2]"},
+      /* 235 */ {"SSRUN", "Storm surface runoff [kg/m^2]"},
+      /* 236 */ {"SIPD", "Supercooled large droplet (SLD) icing pot. diagn. []"},
+      /* 237 */ {"O3TOT", "Total ozone [kg/m^2]"},
+      /* 238 */ {"SNOWC", "Snow cover [%]"},
+      /* 239 */ {"SNOT", "Snow temp. [K]"},
+      /* 240 */ {"COVTW", "Covariance T and w [K*m/s]"},
+      /* 241 */ {"LRGHR", "Large scale condensation heating [K/s]"},
+      /* 242 */ {"CNVHR", "Deep convective heating [K/s]"},
+      /* 243 */ {"CNVMR", "Deep convective moistening [kg/kg/s]"},
+      /* 244 */ {"SHAHR", "Shallow convective heating [K/s]"},
+      /* 245 */ {"SHAMR", "Shallow convective moistening [kg/kg/s]"},
+      /* 246 */ {"VDFHR", "Vertical diffusion heating [K/s]"},
+      /* 247 */ {"VDFUA", "Vertical diffusion zonal accel [m/s^2]"},
+      /* 248 */ {"VDFVA", "Vertical diffusion meridional accel [m/s^2]"},
+      /* 249 */ {"VDFMR", "Vertical diffusion moistening [kg/kg/s]"},
+      /* 250 */ {"SWHR", "Solar radiative heating [K/s]"},
+      /* 251 */ {"LWHR", "Longwave radiative heating [K/s]"},
+      /* 252 */ {"CD", "Drag coefficient [non-dim]"},
+      /* 253 */ {"FRICV", "Friction velocity [m/s]"},
+      /* 254 */ {"RI", "Richardson number [non-dim]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+/*
+ * parameter table for the NCEP/NCAR Reanalysis Project
+ * center = 7, subcenter = 0/2, parameter table = 1/2
+ * in a SNAFU the operational and reanalysis tables diverged
+ * and both retained the same parameter table numbers (1,2)
+ *
+ * some of the Reanalysis files have subcenter=2 while others
+ * use subcenter=0  (subcenter field is not standard (7/97))
+ *
+ * Some ways to tell Reanalysis files from OPN files
+ *  Reanalysis: always generated by process 80 - T62 28 level model
+ * Original subcenter=0 Reanalysis files had 
+ *  2.5x2.5 (144x73) lat-long grid or 192x94 Gaussian grid (PDS grid=255?)
+ */
+
+const struct ParmTable parm_table_ncep_reanal[256] = {
+   /* 0 */ {"var0", "undefined"},
+   /* 1 */ {"PRES", "Pressure [Pa]"},
+   /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+   /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+   /* 4 */ {"var4", "undefined"},
+   /* 5 */ {"var5", "undefined"},
+   /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+   /* 7 */ {"HGT", "Geopotential height [gpm]"},
+   /* 8 */ {"DIST", "Geometric height [m]"},
+   /* 9 */ {"HSTDV", "Std dev of height [m]"},
+   /* 10 */ {"HVAR", "Variance of height [m^2]"},
+   /* 11 */ {"TMP", "Temp. [K]"},
+   /* 12 */ {"VTMP", "Virtual temp. [K]"},
+   /* 13 */ {"POT", "Potential temp. [K]"},
+   /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+   /* 15 */ {"TMAX", "Max. temp. [K]"},
+   /* 16 */ {"TMIN", "Min. temp. [K]"},
+   /* 17 */ {"DPT", "Dew point temp. [K]"},
+   /* 18 */ {"DEPR", "Dew point depression [K]"},
+   /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+   /* 20 */ {"VISIB", "Visibility [m]"},
+   /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+   /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+   /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+   /* 24 */ {"var24", "undefined"},
+   /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+   /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+   /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+   /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+   /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+   /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+   /* 31 */ {"WDIR", "Wind direction [deg]"},
+   /* 32 */ {"WIND", "Wind speed [m/s]"},
+   /* 33 */ {"UGRD", "u wind [m/s]"},
+   /* 34 */ {"VGRD", "v wind [m/s]"},
+   /* 35 */ {"STRM", "Stream function [m^2/s]"},
+   /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+   /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+   /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+   /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+   /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+   /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+   /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+   /* 43 */ {"RELV", "Relative vorticity [/s]"},
+   /* 44 */ {"RELD", "Relative divergence [/s]"},
+   /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+   /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+   /* 47 */ {"DIRC", "Direction of current [deg]"},
+   /* 48 */ {"SPC", "Speed of current [m/s]"},
+   /* 49 */ {"UOGRD", "u of current [m/s]"},
+   /* 50 */ {"VOGRD", "v of current [m/s]"},
+   /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+   /* 52 */ {"RH", "Relative humidity [%]"},
+   /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+   /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+   /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+   /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+   /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+   /* 58 */ {"CICE", "Cloud Ice [kg/kg]"},
+   /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+   /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+   /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+   /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+   /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+   /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+   /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+   /* 66 */ {"SNOD", "Snow depth [m]"},
+   /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+   /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+   /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+   /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+   /* 71 */ {"TCDC", "Total cloud cover [%]"},
+   /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+   /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+   /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+   /* 75 */ {"HCDC", "High level cloud cover [%]"},
+   /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+   /* 77 */ {"var77", "undefined"},
+   /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+   /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+   /* 80 */ {"WTMP", "Water temp. [K]"},
+   /* 81 */ {"LAND", "Land-sea mask [1=land; 0=sea]"},
+   /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+   /* 83 */ {"SFCR", "Surface roughness [m]"},
+   /* 84 */ {"ALBDO", "Albedo [%]"},
+   /* 85 */ {"TSOIL", "Soil temp. [K]"},
+   /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+   /* 87 */ {"VEG", "Vegetation [%]"},
+   /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+   /* 89 */ {"DEN", "Density [kg/m^3]"},
+   /* 90 */ {"RUNOF", "Runoff [kg/m^2]"},
+   /* 91 */ {"ICEC", "Ice concentration [ice=1;no ice=0]"},
+   /* 92 */ {"ICETK", "Ice thickness [m]"},
+   /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+   /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+   /* 95 */ {"UICE", "u of ice drift [m/s]"},
+   /* 96 */ {"VICE", "v of ice drift [m/s]"},
+   /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+   /* 98 */ {"ICED", "Ice divergence [/s]"},
+   /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+   /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+   /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+   /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+   /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+   /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+   /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+   /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+   /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+   /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+   /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+   /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+   /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+   /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+   /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+   /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+   /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+   /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+   /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+   /* 118 */ {"var118", "undefined"},
+   /* 119 */ {"var119", "undefined"},
+   /* 120 */ {"var120", "undefined"},
+   /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+   /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+   /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+   /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+   /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+   /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+   /* 127 */ {"IMGD", "Image data [integer]"},
+   /* 128 */ {"MSLSA", "Mean sea level pressure (Std Atm) [Pa]"},
+   /* 129 */ {"MSLMA", "Mean sea level pressure (MAPS) [Pa]"},
+   /* 130 */ {"MSLET", "Mean sea level pressure (ETA model) [Pa]"},
+   /* 131 */ {"LFTX", "Surface lifted index [K]"},
+   /* 132 */ {"4LFTX", "Best (4-layer) lifted index [K]"},
+   /* 133 */ {"KX", "K index [K]"},
+   /* 134 */ {"SX", "Sweat index [K]"},
+   /* 135 */ {"MCONV", "Horizontal moisture divergence [kg/kg/s]"},
+   /* 136 */ {"VSSH", "Vertical speed shear [1/s]"},
+   /* 137 */ {"TSLSA", "3-hr pressure tendency [Pa/s]"},
+   /* 138 */ {"BVF2", "Brunt-Vaisala frequency^2 [1/s^2]"},
+   /* 139 */ {"PVMW", "Potential vorticity (mass-weighted) [1/s/m]"},
+   /* 140 */ {"CRAIN", "Categorical rain [yes=1;no=0]"},
+   /* 141 */ {"CFRZR", "Categorical freezing rain [yes=1;no=0]"},
+   /* 142 */ {"CICEP", "Categorical ice pellets [yes=1;no=0]"},
+   /* 143 */ {"CSNOW", "Categorical snow [yes=1;no=0]"},
+   /* 144 */ {"SOILW", "Volumetric soil moisture [fraction]"},
+   /* 145 */ {"PEVPR", "Potential evaporation rate [W/m^2]"},
+   /* 146 */ {"CWORK", "Cloud work function [J/kg]"},
+   /* 147 */ {"U-GWD", "Zonal gravity wave stress [N/m^2]"},
+   /* 148 */ {"V-GWD", "Meridional gravity wave stress [N/m^2]"},
+   /* 149 */ {"PV___", "Potential vorticity [m^2/s/kg]"},
+   /* 150 */ {"var150", "undefined"},
+   /* 151 */ {"var151", "undefined"},
+   /* 152 */ {"var152", "undefined"},
+   /* 153 */ {"MFXDV", "Moisture flux divergence [gr/gr*m/s/m]"},
+   /* 154 */ {"var154", "undefined"},
+   /* 155 */ {"GFLUX", "Ground heat flux [W/m^2]"},
+   /* 156 */ {"CIN", "Convective inhibition [J/kg]"},
+   /* 157 */ {"CAPE", "Convective Avail. Pot. Energy [J/kg]"},
+   /* 158 */ {"TKE", "Turbulent kinetic energy [J/kg]"},
+   /* 159 */ {"CONDP", "Lifted parcel condensation pressure [Pa]"},
+   /* 160 */ {"CSUSF", "Clear sky upward solar flux [W/m^2]"},
+   /* 161 */ {"CSDSF", "Clear sky downward solar flux [W/m^2]"},
+   /* 162 */ {"CSULF", "Clear sky upward long wave flux [W/m^2]"},
+   /* 163 */ {"CSDLF", "Clear sky downward long wave flux [W/m^2]"},
+   /* 164 */ {"CFNSF", "Cloud forcing net solar flux [W/m^2]"},
+   /* 165 */ {"CFNLF", "Cloud forcing net long wave flux [W/m^2]"},
+   /* 166 */ {"VBDSF", "Visible beam downward solar flux [W/m^2]"},
+   /* 167 */ {"VDDSF", "Visible diffuse downward solar flux [W/m^2]"},
+   /* 168 */ {"NBDSF", "Near IR beam downward solar flux [W/m^2]"},
+   /* 169 */ {"NDDSF", "Near IR diffuse downward solar flux [W/m^2]"},
+   /* 170 */ {"USTR", "U wind stress [N/m^2]"},
+   /* 171 */ {"VSTR", "V wind stress [N/m^2]"},
+   /* 172 */ {"MFLX", "Momentum flux [N/m^2]"},
+   /* 173 */ {"LMH", "Mass point model surface [integer]"},
+   /* 174 */ {"LMV", "Velocity point model surface [integer]"},
+   /* 175 */ {"SGLYR", "Nearby model level [integer]"},
+   /* 176 */ {"NLAT", "Latitude [deg]"},
+   /* 177 */ {"ELON", "Longitude [deg]"},
+   /* 178 */ {"UMAS", "Mass weighted u [gm/m*K*s]"},
+   /* 179 */ {"VMAS", "Mass weighted v [gm/m*K*s]"},
+   /* 180 */ {"XPRATE", "corrected precip [kg/m^2/s]"},
+   /* 181 */ {"LPSX", "x-gradient of log pressure [1/m]"},
+   /* 182 */ {"LPSY", "y-gradient of log pressure [1/m]"},
+   /* 183 */ {"HGTX", "x-gradient of height [m/m]"},
+   /* 184 */ {"HGTY", "y-gradient of height [m/m]"},
+   /* 185 */ {"STDZ", "Std dev of Geop. hgt. [m]"},
+   /* 186 */ {"STDU", "Std dev of zonal wind [m/s]"},
+   /* 187 */ {"STDV", "Std dev of meridional wind [m/s]"},
+   /* 188 */ {"STDQ", "Std dev of spec. hum. [gm/gm]"},
+   /* 189 */ {"STDT", "Std dev of temp. [K]"},
+   /* 190 */ {"CBUW", "Covar. u and omega [m/s*Pa/s]"},
+   /* 191 */ {"CBVW", "Covar. v and omega [m/s*Pa/s]"},
+   /* 192 */ {"CBUQ", "Covar. u and specific hum [m/s*gm/gm]"},
+   /* 193 */ {"CBVQ", "Covar. v and specific hum [m/s*gm/gm]"},
+   /* 194 */ {"CBTW", "Covar. T and omega [K*Pa/s]"},
+   /* 195 */ {"CBQW", "Covar. spec. hum and omega [gm/gm*Pa/s]"},
+   /* 196 */ {"CBMZW", "Covar. v and u [m^2/s^2]"},
+   /* 197 */ {"CBTZW", "Covar. u and T [K*m/s]"},
+   /* 198 */ {"CBTMW", "Covar. v and T [K*m/s]"},
+   /* 199 */ {"STDRH", "Std dev of Rel. Hum. [%]"},
+   /* 200 */ {"SDTZ", "Std dev of time tend of geop. hgt [m]"},
+   /* 201 */ {"ICWAT", "Ice-free water surface [%]"},
+   /* 202 */ {"SDTU", "Std dev of time tend of zonal wind [m/s]"},
+   /* 203 */ {"SDTV", "Std dev of time tend of merid wind [m/s]"},
+   /* 204 */ {"DSWRF", "Downward solar radiation flux [W/m^2]"},
+   /* 205 */ {"DLWRF", "Downward long wave flux [W/m^2]"},
+   /* 206 */ {"SDTQ", "Std dev of time tend of spec. hum [gm/gm]"},
+   /* 207 */ {"MSTAV", "Moisture availability [%]"},
+   /* 208 */ {"SFEXC", "Exchange coefficient [kg*m/m^3/s]"},
+   /* 209 */ {"MIXLY", "No. of mixed layers next to sfc [integer]"},
+   /* 210 */ {"SDTT", "Std dev of time tend of temp. [K]"},
+   /* 211 */ {"USWRF", "Upward solar radiation flux [W/m^2]"},
+   /* 212 */ {"ULWRF", "Upward long wave flux [W/m^2]"},
+   /* 213 */ {"CDLYR", "Non-convective cloud [%]"},
+   /* 214 */ {"CPRAT", "Convective precip. rate [kg/m^2/s]"},
+   /* 215 */ {"TTDIA", "Temp. tendency by all physics [K/s]"},
+   /* 216 */ {"TTRAD", "Temp. tendency by all radiation [K/s]"},
+   /* 217 */ {"TTPHY", "Temp. tendency by nonrad physics [K/s]"},
+   /* 218 */ {"PREIX", "Precipitation index [fraction]"},
+   /* 219 */ {"TSD1D", "Std dev of IR T over 1x1 deg area [K]"},
+   /* 220 */ {"NLSGP", "Natural log of surface pressure [ln(kPa)]"},
+   /* 221 */ {"SDTRH", "Std dev of time tend of rel hum [%]"},
+   /* 222 */ {"5WAVH", "5-wave geopotential height [gpm]"},
+   /* 223 */ {"CNWAT", "Plant canopy surface water [kg/m^2]"},
+   /* 224 */ {"PLTRS", "Max. stomato plant resistance [s/m]"},
+   /* 225 */ {"RHCLD", "RH-type cloud cover [%]"},
+   /* 226 */ {"BMIXL", "Blackadar's mixing length scale [m]"},
+   /* 227 */ {"AMIXL", "Asymptotic mixing length scale [m]"},
+   /* 228 */ {"PEVAP", "Pot. evaporation [kg/m^2]"},
+   /* 229 */ {"SNOHF", "Snow melt heat flux [W/m^2]"},
+   /* 230 */ {"SNOEV", "Snow sublimation heat flux [W/m^2]"},
+   /* 231 */ {"MFLUX", "Convective cloud mass flux [Pa/s]"},
+   /* 232 */ {"DTRF", "Downward total radiation flux [W/m^2]"},
+   /* 233 */ {"UTRF", "Upward total radiation flux [W/m^2]"},
+   /* 234 */ {"BGRUN", "Baseflow-groundwater runoff [kg/m^2]"},
+   /* 235 */ {"SSRUN", "Storm surface runoff [kg/m^2]"},
+   /* 236 */ {"var236", "undefined"},
+   /* 237 */ {"OZONE", "Total column ozone [Dobson]"},
+   /* 238 */ {"SNOWC", "Snow cover [%]"},
+   /* 239 */ {"SNOT", "Snow temp. [K]"},
+   /* 240 */ {"GLCR", "Permanent snow points [mask]"},
+   /* 241 */ {"LRGHR", "Large scale condensation heating [K/s]"},
+   /* 242 */ {"CNVHR", "Deep convective heating [K/s]"},
+   /* 243 */ {"CNVMR", "Deep convective moistening [kg/kg/s]"},
+   /* 244 */ {"SHAHR", "Shallow convective heating [K/s]"},
+   /* 245 */ {"SHAMR", "Shallow convective moistening [kg/kg/s]"},
+   /* 246 */ {"VDFHR", "Vertical diffusion heating [K/s]"},
+   /* 247 */ {"VDFUA", "Vertical diffusion zonal accel [m/s^2]"},
+   /* 248 */ {"VDFVA", "Vertical diffusion meridional accel [m/s^2]"},
+   /* 249 */ {"VDFMR", "Vertical diffusion moistening [kg/kg/s]"},
+   /* 250 */ {"SWHR", "Solar radiative heating [K/s]"},
+   /* 251 */ {"LWHR", "Longwave radiative heating [K/s]"},
+   /* 252 */ {"CD", "Drag coefficient [non-dim]"},
+   /* 253 */ {"FRICV", "Friction velocity [m/s]"},
+   /* 254 */ {"RI", "Richardson number [non-dim]"},
+   /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_131[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Mean sea level pressure (Shuell method) [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"MSLSA", "Mean sea level pressure (Std Atm) [Pa]"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"MSLET", "Mean sea level pressure (Mesinger method) [Pa]"},
+      /* 131 */ {"LFTX", "Surface lifted index [K]"},
+      /* 132 */ {"4LFTX", "Best (4-layer) lifted index [K]"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"PRESN", "Pressure (nearest grid point) [Pa]"},
+      /* 135 */ {"MCONV", "Horizontal moisture divergence [kg/kg/s]"},
+      /* 136 */ {"VWSH", "Vertical speed shear [1/s]"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"PVMW", "Potential vorticity (mass-weighted) [1/s/m]"},
+      /* 140 */ {"CRAIN", "Categorical rain [yes=1;no=0]"},
+      /* 141 */ {"CFRZR", "Categorical freezing rain [yes=1;no=0]"},
+      /* 142 */ {"CICEP", "Categorical ice pellets [yes=1;no=0]"},
+      /* 143 */ {"CSNOW", "Categorical snow [yes=1;no=0]"},
+      /* 144 */ {"SOILW", "Volumetric soil moisture (frozen + liquid) [fraction]"},
+      /* 145 */ {"PEVPR", "Potential evaporation rate [W/m^2]"},
+      /* 146 */ {"VEGT", "Vegetation canopy temperature [K]"},
+      /* 147 */ {"BARET", "Bare soil surface skin temperature [K]"},
+      /* 148 */ {"AVSFT", "Average surface skin temperature [K]"},
+      /* 149 */ {"RADT", "Effective radiative skin temperature [K]"},
+      /* 150 */ {"SSTOR", "Surface water storage [kg/m^2]"},
+      /* 151 */ {"LSOIL", "Liquid soil moisture content (non-frozen) [kg/m^2]"},
+      /* 152 */ {"EWATR", "Open water evaporation (standing water) [W/m^2]"},
+      /* 153 */ {"CLWMR", "Cloud water [kg/kg]"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"GFLUX", "Ground Heat Flux [W/m^2]"},
+      /* 156 */ {"CIN", "Convective inhibition [J/kg]"},
+      /* 157 */ {"CAPE", "Convective available potential energy [J/kg]"},
+      /* 158 */ {"TKE", "Turbulent Kinetic Energy [J/kg]"},
+      /* 159 */ {"MXSALB", "Maximum snow albedo [%]"},
+      /* 160 */ {"SOILL", "Liquid volumetric soil moisture (non-frozen) [fraction]"},
+      /* 161 */ {"ASNOW", "Frozen precipitation (e.g. snowfall) [kg/m^2]"},
+      /* 162 */ {"ARAIN", "Liquid precipitation (rainfall) [kg/m^2]"},
+      /* 163 */ {"GWREC", "Groundwater recharge [kg/m^2]"},
+      /* 164 */ {"QREC", "Flood plain recharge [kg/m^2]"},
+      /* 165 */ {"SNOWT", "Snow temperature, depth-avg [K]"},
+      /* 166 */ {"VBDSF", "Visible beam downward solar flux [W/m^2]"},
+      /* 167 */ {"VDDSF", "Visible diffuse downward solar flux [W/m^2]"},
+      /* 168 */ {"NBDSF", "Near IR beam downward solar flux [W/m^2]"},
+      /* 169 */ {"NDDSF", "Near IR diffuse downward solar flux [W/m^2]"},
+      /* 170 */ {"SNFALB", "Snow-free albedo [%]"},
+      /* 171 */ {"RLYRS", "Number of soil layers in root zone [non-dim]"},
+      /* 172 */ {"FLX", "Momentum flux N/m2 [M]"},
+      /* 173 */ {"LMH", "Mass point model surface [non-dim]"},
+      /* 174 */ {"LMV", "Velocity point model surface [non-dim]"},
+      /* 175 */ {"MLYNO", "Model layer number (from bottom up) [non-dim]"},
+      /* 176 */ {"NLAT", "Latitude (-90 to +90) [deg]"},
+      /* 177 */ {"ELON", "East longitude (0-360) [deg]"},
+      /* 178 */ {"ICMR", "Ice mixing ratio [kg/kg]"},
+      /* 179 */ {"ACOND", "Aerodynamic conductance [m/s]"},
+      /* 180 */ {"SNOAG", "Snow age [s]"},
+      /* 181 */ {"CCOND", "Canopy conductance [m/s]"},
+      /* 182 */ {"LAI", "Leaf area index (0-9) [non-dim]"},
+      /* 183 */ {"SFCRH", "Roughness length for heat [m]"},
+      /* 184 */ {"SALBD", "Snow albedo (over snow cover area only) [%]"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"NDVI", "Normalized Difference Vegetation Index []"},
+      /* 188 */ {"DRIP", "Rate of water dropping from canopy to gnd [kg/m^2]"},
+      /* 189 */ {"LANDN", "Land cover (nearest neighbor) [sea=0,land=1]"},
+      /* 190 */ {"HLCY", "Storm relative helicity [m^2/s^2]"},
+      /* 191 */ {"NLATN", "Latitude (nearest neigbhbor) (-90 to +90) [deg]"},
+      /* 192 */ {"ELONN", "East longitude (nearest neigbhbor) (0-360) [deg]"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"CPOFP", "Prob. of frozen precipitation [%]"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"USTM", "u-component of storm motion [m/s]"},
+      /* 197 */ {"VSTM", "v-component of storm motion [m/s]"},
+      /* 198 */ {"SBSNO", "Sublimation (evaporation from snow) [W/m^2]"},
+      /* 199 */ {"EVBS", "Direct evaporation from bare soil [W/m^2]"},
+      /* 200 */ {"EVCW", "Canopy water evaporation [W/m^2]"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"APCPN", "Total precipitation (nearest grid point) [kg/m^2]"},
+      /* 203 */ {"RSMIN", "Minimal stomatal resistance [s/m]"},
+      /* 204 */ {"DSWRF", "Downward shortwave radiation flux [W/m^2]"},
+      /* 205 */ {"DLWRF", "Downward longwave radiation flux [W/m^2]"},
+      /* 206 */ {"ACPCPN", "Convective precipitation (nearest grid point) [kg/m^2]"},
+      /* 207 */ {"MSTAV", "Moisture availability [%]"},
+      /* 208 */ {"SFEXC", "Exchange coefficient [(kg/m^3)(m/s)]"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"TRANS", "Transpiration [W/m^2]"},
+      /* 211 */ {"USWRF", "Upward short wave radiation flux [W/m^2]"},
+      /* 212 */ {"ULWRF", "Upward long wave radiation flux [W/m^2]"},
+      /* 213 */ {"CDLYR", "Non-convective cloud [%]"},
+      /* 214 */ {"CPRAT", "Convective precip. rate [kg/m^2/s]"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"TTRAD", "Temp. tendency by all radiation [K/s]"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"HGTN", "Geopotential Height (nearest grid point) [gpm]"},
+      /* 219 */ {"WILT", "Wilting point [fraction]"},
+      /* 220 */ {"FLDCP", "Field Capacity [fraction]"},
+      /* 221 */ {"HPBL", "Planetary boundary layer height [m]"},
+      /* 222 */ {"SLTYP", "Surface slope type [Index]"},
+      /* 223 */ {"CNWAT", "Plant canopy surface water [kg/m^2]"},
+      /* 224 */ {"SOTYP", "Soil type [Index]"},
+      /* 225 */ {"VGTYP", "Vegetation type [Index]"},
+      /* 226 */ {"BMIXL", "Blackadars mixing length scale [m]"},
+      /* 227 */ {"AMIXL", "Asymptotic mixing length scale [m]"},
+      /* 228 */ {"PEVAP", "Potential evaporation [kg/m^2]"},
+      /* 229 */ {"SNOHF", "Snow phase-change heat flux [W/m^2]"},
+      /* 230 */ {"SMREF", "Transpiration stress-onset (soil moisture) [fraction]"},
+      /* 231 */ {"SMDRY", "Direct evaporation cease (soil moisture) [fraction]"},
+      /* 232 */ {"WVINC", "water vapor added by precip assimilation [kg/m^2]"},
+      /* 233 */ {"WCINC", "water condensate added by precip assimilaition [kg/m^2]"},
+      /* 234 */ {"BGRUN", "Subsurface runoff (baseflow) [kg/m^2]"},
+      /* 235 */ {"SSRUN", "Surface runoff (non-infiltrating) [kg/m^2]"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"WVCONV", "Water vapor flux convergence (vertical int) [kg/m^2]"},
+      /* 238 */ {"SNOWC", "Snow cover [%]"},
+      /* 239 */ {"SNOT", "Snow temperature [K]"},
+      /* 240 */ {"POROS", "Soil porosity [fraction]"},
+      /* 241 */ {"WCCONV", "Water condensate flux convergence (vertical int) [kg/m^2]"},
+      /* 242 */ {"WVUFLX", "Water vapor zonal transport (vertical int)[kg/m]"},
+      /* 243 */ {"WVVFLX", "Water vapor meridional transport (vertical int) [kg/m]"},
+      /* 244 */ {"WCUFLX", "Water condensate zonal transport (vertical int) [kg/m]"},
+      /* 245 */ {"WCVFLX", "Water condensate meridional transport (vertical int) [kg/m]"},
+      /* 246 */ {"RCS", "Solar parameter in canopy conductance [fraction]"},
+      /* 247 */ {"RCT", "Temperature parameter in canopy conductance [fraction]"},
+      /* 248 */ {"RCQ", "Humidity parameter in canopy conductance [fraction]"},
+      /* 249 */ {"RCSOL", "Soil moisture parameter in canopy conductance [fraction]"},
+      /* 250 */ {"SWHR", "Solar radiative heating [K/s]"},
+      /* 251 */ {"LWHR", "Longwave radiative heating [K/s]"},
+      /* 252 */ {"CD", "Surface drag coefficient [non-dim]"},
+      /* 253 */ {"FRICV", "Surface friction velocity [m/s]"},
+      /* 254 */ {"RI", "Richardson number [non-dim]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_130[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined 143"},
+      /* 144 */ {"SOILW", "Volumetric soil moisture (frozen + liquid) [fraction]"},
+      /* 145 */ {"PEVPR", "Potential evaporation rate [W/m^2]"},
+      /* 146 */ {"VEGT", "Vegetation canopy temperature [K]"},
+      /* 147 */ {"BARET", "Bare soil surface skin temperature [K]"},
+      /* 148 */ {"AVSFT", "Average surface skin temperature [K]"},
+      /* 149 */ {"RADT", "Effective radiative skin temperature [K]"},
+      /* 150 */ {"SSTOR", "Surface water storage [Kg/m^2]"},
+      /* 151 */ {"LSOIL", "Liquid soil moisture content (non-frozen) [Kg/m^2]"},
+      /* 152 */ {"EWATR", "Open water evaporation (standing water) [W/m^2]"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"LSPA", "Land Surface Precipitation Accumulation [kg/m^2]"},
+      /* 155 */ {"GFLUX", "Ground Heat Flux [W/m^2]"},
+      /* 156 */ {"CIN", "Convective inhibition [J/Kg]"},
+      /* 157 */ {"CAPE", "Convective available potential energy [J/Kg]"},
+      /* 158 */ {"TKE", "Turbulent Kinetic Energy [J/Kg]"},
+      /* 159 */ {"MXSALB", "Maximum snow albedo [%]"},
+      /* 160 */ {"SOILL", "Liquid volumetric soil moisture (non-frozen) [fraction]"},
+      /* 161 */ {"ASNOW", "Frozen precipitation (e.g. snowfall) [Kg/m^2]"},
+      /* 162 */ {"ARAIN", "Liquid precipitation (rainfall) [Kg/m^2]"},
+      /* 163 */ {"GWREC", "Groundwater recharge [Kg/m^2]"},
+      /* 164 */ {"QREC", "Flood plain recharge [Kg/m^2]"},
+      /* 165 */ {"SNOWT", "Snow temperature, depth-avg [K]"},
+      /* 166 */ {"VBDSF", "Visible beam downward solar flux [W/m^2]"},
+      /* 167 */ {"VDDSF", "Visible diffuse downward solar flux [W/m^2]"},
+      /* 168 */ {"NBDSF", "Near IR beam downward solar flux [W/m^2]"},
+      /* 169 */ {"NDDSF", "Near IR diffuse downward solar flux [W/m^2]"},
+      /* 170 */ {"SNFALB", "Snow-free albedo [%]"},
+      /* 171 */ {"RLYRS", "Number of soil layers in root zone [non-dim]"},
+      /* 172 */ {"MFLX", "Momentum flux [N/m^2]"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"NLAT", "Latitude (-90 to +90) [deg]"},
+      /* 177 */ {"ELON", "East longitude (0-360) [deg]"},
+      /* 178 */ {"FLDCAP", "Field capacity [fraction]"},
+      /* 179 */ {"ACOND", "Aerodynamic conductance [m/s]"},
+      /* 180 */ {"SNOAG", "Snow age [s]"},
+      /* 181 */ {"CCOND", "Canopy conductance [m/s]"},
+      /* 182 */ {"LAI", "Leaf area index (0-9) [non-dim]"},
+      /* 183 */ {"SFCRH", "Roughness length for heat [m]"},
+      /* 184 */ {"SALBD", "Snow albedo (over snow cover area only) [%]"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"NDVI", "Normalized Difference Vegetation Index []"},
+      /* 188 */ {"DRIP", "Canopy drip [Kg/m^2]"},
+      /* 189 */ {"VBSALB", "Visible, black sky albedo [%]"},
+      /* 190 */ {"VWSALB", "Visible, white sky albedo [%]"},
+      /* 191 */ {"NBSALB", "Near IR, black sky albedo [%]"},
+      /* 192 */ {"NWSALB", "Near IR, white sky albedo [%]"},
+      /* 193 */ {"FRZR", "Freezing rain [kg/m^2]"},
+      /* 194 */ {"FROZR", "Frozen rain [kg/m^2]"},
+      /* 195 */ {"TSNOW", "Total snow [kg/m^2]"},
+      /* 196 */ {"MTERH", "Model terrain height [m]"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"SBSNO", "Sublimation (evaporation from snow) [W/m^2]"},
+      /* 199 */ {"EVBS", "Direct evaporation from bare soil [W/m^2]"},
+      /* 200 */ {"EVCW", "Canopy water evaporation [W/m^2]"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"RSMIN", "Minimal stomatal resistance [s/m]"},
+      /* 204 */ {"DSWRF", "Downward shortwave radiation flux [W/m^2]"},
+      /* 205 */ {"DLWRF", "Downward longwave radiation flux [W/m^2]"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"MSTAV", "Moisture availability [%]"},
+      /* 208 */ {"SFEXC", "Exchange coefficient [(Kg/m^3)(m/s)]"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"TRANS", "Transpiration [W/m^2]"},
+      /* 211 */ {"USWRF", "Upward short wave radiation flux [W/m^2]"},
+      /* 212 */ {"ULWRF", "Upward long wave radiation flux [W/m^2]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"WILT", "Wilting point [fraction]"},
+      /* 220 */ {"FLDCP", "Field Capacity [fraction]"},
+      /* 221 */ {"HPBL", "Planetary boundary layer height [m]"},
+      /* 222 */ {"SLTYP", "Surface slope type [Index]"},
+      /* 223 */ {"CNWAT", "Plant canopy surface water [Kg/m^2]"},
+      /* 224 */ {"SOTYP", "Soil type [Index]"},
+      /* 225 */ {"VGTYP", "Vegetation type [Index]"},
+      /* 226 */ {"BMIXL", "Blackadars mixing length scale [m]"},
+      /* 227 */ {"AMIXL", "Asymptotic mixing length scale [m]"},
+      /* 228 */ {"PEVAP", "Potential evaporation [Kg/m^2]"},
+      /* 229 */ {"SNOHF", "Snow phase-change heat flux [W/m^2]"},
+      /* 230 */ {"SMREF", "Transpiration stress-onset (soil moisture) [fraction]"},
+      /* 231 */ {"SMDRY", "Direct evaporation cease (soil moisture) [fraction]"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"BGRUN", "Subsurface runoff (baseflow) [Kg/m^2]"},
+      /* 235 */ {"SSRUN", "Surface runoff (non-infiltrating) [Kg/m^2]"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"SNOWC", "Snow cover [%]"},
+      /* 239 */ {"SNOT", "Snow temperature [K]"},
+      /* 240 */ {"POROS", "Soil porosity [fraction]"},
+      /* 241 */ {"SBT112", "Simulated brightness temp for GOES11, channel 2 [K]"},
+      /* 242 */ {"SBT113", "Simulated brightness temp for GOES11, channel 3 [K]"},
+      /* 243 */ {"SBT114", "Simulated brightness temp for GOES11, channel 4 [K]"},
+      /* 244 */ {"SBT115", "Simulated brightness temp for GOES11, channel 5 [K]"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"RCS", "Solar parameter in canopy conductance [fraction]"},
+      /* 247 */ {"RCT", "Temperature parameter in canopy conductance [fraction]"},
+      /* 248 */ {"RCQ", "Humidity parameter in canopy conductance [fraction]"},
+      /* 249 */ {"RCSOL", "Soil moisture parameter in canopy conductance [fraction]"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"CD", "Surface drag coefficient [non-dim]"},
+      /* 253 */ {"FRICV", "Surface friction velocity [m/s]"},
+      /* 254 */ {"RI", "Richardson number [non-dim]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_133[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land-sea coverage (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"POZT", "Ozone production from T term"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"OMGALF", "omega divided by density"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"COVZZ", "Covariance between u and u"},
+      /* 165 */ {"COVMM", "Covariance between v and v"},
+      /* 166 */ {"COVQZ", "Covariance between q and u"},
+      /* 167 */ {"COVQM", "Covariance between q and v"},
+      /* 168 */ {"COVTVV", "Covariance between T and omega"},
+      /* 169 */ {"COVQVV", "Covariance between q and omega"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"LRGMR", "Large scale moistening rate"},
+      /* 174 */ {"VDFOZ", "Ozone vertical diffusion"},
+      /* 175 */ {"POZ", "Ozone production"},
+      /* 176 */ {"AMSRE9", "Sim brightness tmp for AMSRE on Aqua channel 9 [K]"},
+      /* 177 */ {"AMSRE10", "Sim brightness tmp for AMSRE on Aqua channel 10 [K]"},
+      /* 178 */ {"AMSRE11", "Sim brightness tmp for AMSRE on Aqua channel 11 [K]"},
+      /* 179 */ {"AMSRE12", "Sim brightness tmp for AMSRE on Aqua channel 12 [K]"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"GWDU", "Gravity wave drag u acceleration"},
+      /* 182 */ {"GWDV", "Gravity wave drag v acceleration"},
+      /* 183 */ {"CNVU", "Convective u momentum mixing acceleration"},
+      /* 184 */ {"CNVV", "Convective v momentum mixing acceleration"},
+      /* 185 */ {"AKHS", "Sfc exchange coeff for T and Q divided by delta z"},
+      /* 186 */ {"AKMS", "Sfc exchange coeff for U and V divided by delta z"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"TOZ", "Ozone tendency"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"SUNSD", "Sunshine duration [s]"},
+      /* 192 */ {"MOSF", "Meridional overturning stream function [10^6m^3/s]"},
+      /* 193 */ {"EPSR", "Radiative emiissivity"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"QZ0", "q at top of viscous sublayer"},
+      /* 196 */ {"CNGWDU", "Convective gravity wave drag zonal acceleration"},
+      /* 197 */ {"CNGWDV", "Convective gravity wave drag meridional acceleration"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"THZ0", "Theta at top of viscous sublayer"},
+      /* 202 */ {"CNVUMF", "Convective updraft mass flux"},
+      /* 203 */ {"COVPSPS", "Covariance between psfc and psfc"},
+      /* 204 */ {"QMAX", "Maximum specific humidity at 2m"},
+      /* 205 */ {"QMIN", "Minimum specific humidity at 2m"},
+      /* 206 */ {"COVQQ", "Covariance between q and q"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"CNVDMF", "Convective downdraft mass flux"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"CNVDEMF", "Convective detrainment mass flux"},
+      /* 220 */ {"COVVVVV", "Covariance between omega and omega"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"COVTT", "Covariance between T and T"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"WTEND", "Tendency of vertical velocity"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"POZO", "Ozone production from col ozone term"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_128[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"AVDEPTH", "Ocean depth - mean [m]"},
+      /* 129 */ {"DEPTH", "Ocean depth - instantaneous [m]"},
+      /* 130 */ {"ELEV", "Ocean surface elevation relative to geoid [m]"},
+      /* 131 */ {"MXEL24", "Max ocean surface elevation in last 24 hours [m]"},
+      /* 132 */ {"MNEL24", "Min ocean surface elevation in last 24 hours [m]"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"O2", "Oxygen (O2 (aq)) []"},
+      /* 136 */ {"PO4", "PO4 [Mol/kg]"},
+      /* 137 */ {"NO3", "NO3 [Mol/kg]"},
+      /* 138 */ {"SiO4", "SiO4 [Mol/kg]"},
+      /* 139 */ {"CO2aq", "CO2 (aq) [Mol/kg]"},
+      /* 140 */ {"HCO3", "HCO3 - [Mol/kg]"},
+      /* 141 */ {"CO3", "CO3 -- [Mol/kg]"},
+      /* 142 */ {"TCO2", "TCO2 [Mol/kg]"},
+      /* 143 */ {"TALK", "TALK [Mol/kg]"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"S11", "S11 - 1,1 component of ice stress tensor []"},
+      /* 147 */ {"S12", "S12 - 1,2 component of ice stress tensor []"},
+      /* 148 */ {"S22", "S22 - 2,2 component of ice stress tensor []"},
+      /* 149 */ {"INV1", "T1 - First invariant of stress tensor []"},
+      /* 150 */ {"INV2", "T2 - Second invariant of stress tensor []"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"WVRGH", "Wave Roughness[ ]"},
+      /* 156 */ {"WVSTRS", "Wave Stresses []"},
+      /* 157 */ {"WHITE", "Whitecap coverage []"},
+      /* 158 */ {"SWDIRWID", "Swell direction width []"},
+      /* 159 */ {"SWFREWID", "Swell frequency width []"},
+      /* 160 */ {"WVAGE", "Wave age []"},
+      /* 161 */ {"PWVAGE", "Physical Wave age []"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"LTURB", "Master length scale (turbulence) [m]"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"AIHFLX", "Net Air-Ice heat flux [W/m^2]"},
+      /* 171 */ {"AOHFLX", "Net Air-Ocean heat flux [W/m^2]"},
+      /* 172 */ {"IOHFLX", "Net Ice-Ocean heat flux [W/m^2]"},
+      /* 173 */ {"IOSFLX", "Net Ice-Ocean salt flux kg/s]"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"OMLT", "Ocean Mixed Layer Temperature [K]"},
+      /* 176 */ {"OMLS", "Ocean Mixed Layer Salinity [kg/kg]"},
+      /* 177 */ {"OMLPOTDEN", "Ocean Mixed Layer Potential density (Referenced to 2000m) [kg/m^3]"},
+      /* 178 */ {"OMLU", "U Velocity in mixed layer [m/s]"},
+      /* 179 */ {"OMLV", "V Velocity in mixed layer [m/s]"},
+      /* 180 */ {"ASHFL", "Assimilative Heat Flux [W/m^2]"},
+      /* 181 */ {"ASSFL", "Assimilative Salt Flux [mm/day]"},
+      /* 182 */ {"BOTLD", "Bottom Layer Depth [m]"},
+      /* 183 */ {"UBARO", "Barotropic U Velocity [m/s]"},
+      /* 184 */ {"VBARO", "Barotropic V Velocity [m/s]"},
+      /* 185 */ {"INTFD", "Interface Depth [m]"},
+      /* 186 */ {"WTMPC", "Temperature [C]"},
+      /* 187 */ {"SALIN", "Salinity [psu]"},
+      /* 188 */ {"EMNP", "Evaporation - Precipitation [cm/day]"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"KENG", "Kinetic Energy [J/kg]"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"LAYTH", "Layer Thickness[m]"},
+      /* 193 */ {"SSTT", "Surface Temperature Trend [K/day]"},
+      /* 194 */ {"SSST", "Surface Salinity Trend [psu/day]"},
+      /* 195 */ {"OVHD", "Ocean vertical heat diffusivity [m^2/s]"},
+      /* 196 */ {"OVSD", "Ocean vertical salt diffusivity [m^2/s]"},
+      /* 197 */ {"OVMD", "Ocean vertical momementum diffusivity [m^2/s]"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"RERRVAR", "Relative Error Variance [pure number]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_ecmwf_128[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"STRF", "Stream function [m**2 s**-1]"},
+      /* 2 */ {"VPOT", "Velocity potential [m**2 s**-1]"},
+      /* 3 */ {"PT", "Potential temperature [K]"},
+      /* 4 */ {"EQPT", "Equivalent potential temperature [K]"},
+      /* 5 */ {"SEPT", "Saturated equivalent potential temperature [K]"},
+      /* 6 */ {"SSFR", "Soil sand fraction [(0 - 1)]"},
+      /* 7 */ {"SCFR", "Soil clay fraction [(0 - 1)]"},
+      /* 8 */ {"SRO", "Surface runoff [m]"},
+      /* 9 */ {"SSRO", "Sub-surface runoff [m]"},
+      /* 10 */ {"WIND", "Wind speed [m s**-1]"},
+      /* 11 */ {"UDVW", "U component of divergent wind [m s**-1]"},
+      /* 12 */ {"VDVW", "V component of divergent wind [m s**-1]"},
+      /* 13 */ {"URTW", "U component of rotational wind [m s**-1]"},
+      /* 14 */ {"VRTW", "V component of rotational wind [m s**-1]"},
+      /* 15 */ {"ALUVP", "UV visible albedo for direct radiation [(0 - 1)]"},
+      /* 16 */ {"ALUVD", "UV visible albedo for diffuse radiation [(0 - 1)]"},
+      /* 17 */ {"ALNIP", "Near IR albedo for direct radiation [(0 - 1)]"},
+      /* 18 */ {"ALNID", "Near IR albedo for diffuse radiation [(0 - 1)]"},
+      /* 19 */ {"UVCS", "Clear sky surface UV [W m**-2 s]"},
+      /* 20 */ {"PARCS", "Clear sky surface PAR [W m**-2 s]"},
+      /* 21 */ {"UCTP", "Unbalanced component of temperature [K]"},
+      /* 22 */ {"UCLN", "Unbalanced component of logarithm of surface pressure []"},
+      /* 23 */ {"UCDV", "Unbalanced component of divergence [s**-1]"},
+      /* 24 */ {"var24", "Reserved for future unbalanced components []"},
+      /* 25 */ {"var25", "Reserved for future unbalanced components []"},
+      /* 26 */ {"CL", "Lake cover [(0 - 1)]"},
+      /* 27 */ {"CVL", "Low vegetation cover [(0 - 1)]"},
+      /* 28 */ {"CVH", "High vegetation cover [(0 - 1)]"},
+      /* 29 */ {"TVL", "Type of low vegetation []"},
+      /* 30 */ {"TVH", "Type of high vegetation []"},
+      /* 31 */ {"CI", "Sea-ice cover [(0 - 1)]"},
+      /* 32 */ {"ASN", "Snow albedo [(0 - 1)]"},
+      /* 33 */ {"RSN", "Snow density [kg m**-3]"},
+      /* 34 */ {"SSTK", "Sea surface temperature [K]"},
+      /* 35 */ {"ISTL1", "Ice surface temperature layer 1 [K]"},
+      /* 36 */ {"ISTL2", "Ice surface temperature layer 2 [K]"},
+      /* 37 */ {"ISTL3", "Ice surface temperature layer 3 [K]"},
+      /* 38 */ {"ISTL4", "Ice surface temperature layer 4 [K]"},
+      /* 39 */ {"SWVL1", "Volumetric soil water layer 1 [m**3 m**-3]"},
+      /* 40 */ {"SWVL2", "Volumetric soil water layer 2 [m**3 m**-3]"},
+      /* 41 */ {"SWVL3", "Volumetric soil water layer 3 [m**3 m**-3]"},
+      /* 42 */ {"SWVL4", "Volumetric soil water layer 4 [m**3 m**-3]"},
+      /* 43 */ {"SLT", "Soil type []"},
+      /* 44 */ {"ES", "Snow evaporation [m of water]"},
+      /* 45 */ {"SMLT", "Snowmelt [m of water]"},
+      /* 46 */ {"SDUR", "Solar duration [s]"},
+      /* 47 */ {"DSRP", "Direct solar radiation [w m**-2]"},
+      /* 48 */ {"MAGSS", "Magnitude of surface stress [N m**-2 s]"},
+      /* 49 */ {"10FG", "10 metre wind gust [m s**-1]"},
+      /* 50 */ {"LSPF", "Large-scale precipitation fraction [s]"},
+      /* 51 */ {"MX2T24", "Maximum temperature at 2 metres since last 24 hours [K]"},
+      /* 52 */ {"MN2T24", "Minimum temperature at 2 metres since last 24 hours [K]"},
+      /* 53 */ {"MONT", "Montgomery potential [m**2 s**-2]"},
+      /* 54 */ {"PRES", "Pressure [Pa]"},
+      /* 55 */ {"MEAN2T24", "Mean temperature at 2 metres since last 24 hours [K]"},
+      /* 56 */ {"MN2D24", "Mean 2 metre dewpoint temperature in past 24 hours [K]"},
+      /* 57 */ {"UVB", "Downward UV radiation at the surface [w m**-2 s]"},
+      /* 58 */ {"PAR", "Photosynthetically active radiation at the surface [w m**-2 s]"},
+      /* 59 */ {"CAPE", "Convective available potential energy [J kg**-1]"},
+      /* 60 */ {"PV", "Potential vorticity [K m**2 kg**-1 s**-1]"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"OBCT", "Observation count []"},
+      /* 63 */ {"var63", "Start time for skin temperature difference [s]"},
+      /* 64 */ {"var64", "Finish time for skin temperature difference [s]"},
+      /* 65 */ {"var65", "Skin temperature difference [K]"},
+      /* 66 */ {"var66", "Leaf area index, low vegetation [m**2 / m**2]"},
+      /* 67 */ {"var67", "Leaf area index, high vegetation [m**2 / m**2]"},
+      /* 68 */ {"var68", "Minimum stomatal resistance, low vegetation [s m**-1]"},
+      /* 69 */ {"var69", "Minimum stomatal resistance, high vegetation [s m**-1]"},
+      /* 70 */ {"var70", "Biome cover, low vegetation [(0 - 1)]"},
+      /* 71 */ {"var71", "Biome cover, high vegetation [(0 - 1)]"},
+      /* 72 */ {"ISSRD", "Instantaneous surface solar radiation downwards [w m**-2]"},
+      /* 73 */ {"ISTRD", "Instantaneous surface thermal radiation downwards [w m**-2]"},
+      /* 74 */ {"SDFOR", "Standard deviation of filtered subgrid orography [m]"},
+      /* 75 */ {"CRWC", "Cloud rain water content [kg kg**-1]"},
+      /* 76 */ {"CSWC", "Cloud snow water content [kg kg**-1]"},
+      /* 77 */ {"ETADOT", "Eta-coordinate vertical velocity [s**-1]"},
+      /* 78 */ {"TCLW", "Total column liquid water [kg m**-2]"},
+      /* 79 */ {"TCIW", "Total column ice water [kg m**-2]"},
+      /* 80 */ {"var80", "Experimental product []"},
+      /* 81 */ {"var81", "Experimental product []"},
+      /* 82 */ {"var82", "Experimental product []"},
+      /* 83 */ {"var83", "Experimental product []"},
+      /* 84 */ {"var84", "Experimental product []"},
+      /* 85 */ {"var85", "Experimental product []"},
+      /* 86 */ {"var86", "Experimental product []"},
+      /* 87 */ {"var87", "Experimental product []"},
+      /* 88 */ {"var88", "Experimental product []"},
+      /* 89 */ {"var89", "Experimental product []"},
+      /* 90 */ {"var90", "Experimental product []"},
+      /* 91 */ {"var91", "Experimental product []"},
+      /* 92 */ {"var92", "Experimental product []"},
+      /* 93 */ {"var93", "Experimental product []"},
+      /* 94 */ {"var94", "Experimental product []"},
+      /* 95 */ {"var95", "Experimental product []"},
+      /* 96 */ {"var96", "Experimental product []"},
+      /* 97 */ {"var97", "Experimental product []"},
+      /* 98 */ {"var98", "Experimental product []"},
+      /* 99 */ {"var99", "Experimental product []"},
+      /* 100 */ {"var100", "Experimental product []"},
+      /* 101 */ {"var101", "Experimental product []"},
+      /* 102 */ {"var102", "Experimental product []"},
+      /* 103 */ {"var103", "Experimental product []"},
+      /* 104 */ {"var104", "Experimental product []"},
+      /* 105 */ {"var105", "Experimental product []"},
+      /* 106 */ {"var106", "Experimental product []"},
+      /* 107 */ {"var107", "Experimental product []"},
+      /* 108 */ {"var108", "Experimental product []"},
+      /* 109 */ {"var109", "Experimental product []"},
+      /* 110 */ {"var110", "Experimental product []"},
+      /* 111 */ {"var111", "Experimental product []"},
+      /* 112 */ {"var112", "Experimental product []"},
+      /* 113 */ {"var113", "Experimental product []"},
+      /* 114 */ {"var114", "Experimental product []"},
+      /* 115 */ {"var115", "Experimental product []"},
+      /* 116 */ {"var116", "Experimental product []"},
+      /* 117 */ {"var117", "Experimental product []"},
+      /* 118 */ {"var118", "Experimental product []"},
+      /* 119 */ {"var119", "Experimental product []"},
+      /* 120 */ {"var120", "Experimental product []"},
+      /* 121 */ {"MX2T6", "Maximum temperature at 2 metres since last 6 hours [K]"},
+      /* 122 */ {"MN2T6", "Minimum temperature at 2 metres since last 6 hours [K]"},
+      /* 123 */ {"10FG6", "10 metre wind gust in the past 6 hours [m s**-1]"},
+      /* 124 */ {"EMIS", "Surface emissivity [dimensionless]"},
+      /* 125 */ {"var125", "Vertically integrated total energy [J m**-2]"},
+      /* 126 */ {"var126", "Generic parameter for sensitive area prediction [Various]"},
+      /* 127 */ {"AT", "Atmospheric tide []"},
+      /* 128 */ {"BV", "Budget values []"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"SP", "Surface pressure [Pa]"},
+      /* 135 */ {"W", "Vertical velocity [Pa s**-1]"},
+      /* 136 */ {"TCW", "Total column water [kg m**-2]"},
+      /* 137 */ {"TCWV", "Total column water vapour [kg m**-2]"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"STL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"SWL1", "Soil wetness level 1 [m of water]"},
+      /* 141 */ {"SD", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"LSP", "Stratiform precipitation (Large-scale precipitation) [m]"},
+      /* 143 */ {"CP", "Convective precipitation [m]"},
+      /* 144 */ {"SF", "Snowfall [m of water equivalent]"},
+      /* 145 */ {"BLD", "Boundary layer dissipation [W m**-2 s]"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"CHNK", "Charnock []"},
+      /* 149 */ {"SNR", "Surface net radiation [W m**-2 s]"},
+      /* 150 */ {"TNR", "Top net radiation []"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"LNSP", "Logarithm of surface pressure []"},
+      /* 153 */ {"SWHR", "Short-wave heating rate [K]"},
+      /* 154 */ {"LWHR", "Long-wave heating rate [K]"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"GH", "Height [gpm]"},
+      /* 157 */ {"R", "Relative humidity [%]"},
+      /* 158 */ {"TSP", "Tendency of surface pressure [Pa s**-1]"},
+      /* 159 */ {"BLH", "Boundary layer height [m]"},
+      /* 160 */ {"SDOR", "Standard deviation of orography []"},
+      /* 161 */ {"ISOR", "Anisotropy of sub-gridscale orography []"},
+      /* 162 */ {"ANOR", "Angle of sub-gridscale orography [rad]"},
+      /* 163 */ {"SLOR", "Slope of sub-gridscale orography []"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"SSRD", "Surface solar radiation downwards [W m**-2 s]"},
+      /* 170 */ {"STL2", "Soil temperature level 2 [K]"},
+      /* 171 */ {"SWL2", "Soil wetness level 2 [m of water]"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"SR", "Surface roughness [m]"},
+      /* 174 */ {"AL", "Albedo [(0 - 1)]"},
+      /* 175 */ {"STRD", "Surface thermal radiation downwards [W m**-2 s]"},
+      /* 176 */ {"SSR", "Surface solar radiation [W m**-2 s]"},
+      /* 177 */ {"STR", "Surface thermal radiation [W m**-2 s]"},
+      /* 178 */ {"TSR", "Top solar radiation [W m**-2 s]"},
+      /* 179 */ {"TTR", "Top thermal radiation [W m**-2 s]"},
+      /* 180 */ {"EWSS", "East-West surface stress [N m**-2 s]"},
+      /* 181 */ {"NSSS", "North-South surface stress [N m**-2 s]"},
+      /* 182 */ {"E", "Evaporation [m of water]"},
+      /* 183 */ {"STL3", "Soil temperature level 3 [K]"},
+      /* 184 */ {"SWL3", "Soil wetness level 3 [m of water]"},
+      /* 185 */ {"CCC", "Convective cloud cover [(0 - 1)]"},
+      /* 186 */ {"LCC", "Low cloud cover [(0 - 1)]"},
+      /* 187 */ {"MCC", "Medium cloud cover [(0 - 1)]"},
+      /* 188 */ {"HCC", "High cloud cover [(0 - 1)]"},
+      /* 189 */ {"SUND", "Sunshine duration [s]"},
+      /* 190 */ {"EWOV", "East-West component of sub-gridscale orographic variance [m**2]"},
+      /* 191 */ {"NSOV", "North-South component of sub-gridscale orographic variance [m**2]"},
+      /* 192 */ {"NWOV", "North-West/South-East component of sub-gridscale orographic variance [m**2]"},
+      /* 193 */ {"NEOV", "North-East/South-West component of sub-gridscale orographic variance [m**2]"},
+      /* 194 */ {"BTMP", "Brightness temperature [K]"},
+      /* 195 */ {"LGWS", "Latitudinal component of gravity wave stress [N m**-2 s]"},
+      /* 196 */ {"MGWS", "Meridional component of gravity wave stress [N m**-2 s]"},
+      /* 197 */ {"GWD", "Gravity wave dissipation [W m**-2 s]"},
+      /* 198 */ {"SRC", "Skin reservoir content [m of water]"},
+      /* 199 */ {"VEG", "Vegetation fraction [(0 - 1)]"},
+      /* 200 */ {"VSO", "Variance of sub-gridscale orography [m**2]"},
+      /* 201 */ {"MX2T", "Maximum temperature at 2 metres since previous post-processing [K]"},
+      /* 202 */ {"MN2T", "Minimum temperature at 2 metres since previous post-processing [K]"},
+      /* 203 */ {"O3", "Ozone mass mixing ratio [kg kg**-1]"},
+      /* 204 */ {"PAW", "Precipitation analysis weights []"},
+      /* 205 */ {"RO", "Runoff [m]"},
+      /* 206 */ {"TCO3", "Total column ozone [kg m**-2]"},
+      /* 207 */ {"10SI", "10 metre wind speed [m s**-1]"},
+      /* 208 */ {"TSRC", "Top net solar radiation, clear sky [W m**-2 s]"},
+      /* 209 */ {"TTRC", "Top net thermal radiation, clear sky [W m**-2 s]"},
+      /* 210 */ {"SSRC", "Surface net solar radiation, clear sky [W m**-2 s]"},
+      /* 211 */ {"STRC", "Surface net thermal radiation, clear sky [W m**-2 s]"},
+      /* 212 */ {"TISR", "TOA incident solar radiation [W m**-2 s]"},
+      /* 213 */ {"VIMD", "Vertically integrated moisture divergence [kg m**-2]"},
+      /* 214 */ {"DHR", "Diabatic heating by radiation [K]"},
+      /* 215 */ {"DHVD", "Diabatic heating by vertical diffusion [K]"},
+      /* 216 */ {"DHCC", "Diabatic heating by cumulus convection [K]"},
+      /* 217 */ {"DHLC", "Diabatic heating large-scale condensation [K]"},
+      /* 218 */ {"VDZW", "Vertical diffusion of zonal wind [m s**-1]"},
+      /* 219 */ {"VDMW", "Vertical diffusion of meridional wind [m s**-1]"},
+      /* 220 */ {"EWGD", "East-West gravity wave drag tendency [m s**-1]"},
+      /* 221 */ {"NSGD", "North-South gravity wave drag tendency [m s**-1]"},
+      /* 222 */ {"CTZW", "Convective tendency of zonal wind [m s**-1]"},
+      /* 223 */ {"CTMW", "Convective tendency of meridional wind [m s**-1]"},
+      /* 224 */ {"VDH", "Vertical diffusion of humidity [kg kg**-1]"},
+      /* 225 */ {"HTCC", "Humidity tendency by cumulus convection [kg kg**-1]"},
+      /* 226 */ {"HTLC", "Humidity tendency by large-scale condensation [kg kg**-1]"},
+      /* 227 */ {"CRNH", "Change from removal of negative humidity [kg kg**-1]"},
+      /* 228 */ {"TP", "Total precipitation [m]"},
+      /* 229 */ {"IEWS", "Instantaneous X surface stress [N m**-2]"},
+      /* 230 */ {"INSS", "Instantaneous Y surface stress [N m**-2]"},
+      /* 231 */ {"ISHF", "Instantaneous surface heat flux [W m**-2]"},
+      /* 232 */ {"IE", "Instantaneous moisture flux [kg m**-2 s**-1]"},
+      /* 233 */ {"ASQ", "Apparent surface humidity [kg kg**-1]"},
+      /* 234 */ {"LSRH", "Logarithm of surface roughness length for heat []"},
+      /* 235 */ {"SKT", "Skin temperature [K]"},
+      /* 236 */ {"STL4", "Soil temperature level 4 [K]"},
+      /* 237 */ {"SWL4", "Soil wetness level 4 [m]"},
+      /* 238 */ {"TSN", "Temperature of snow layer [K]"},
+      /* 239 */ {"CSF", "Convective snowfall [m of water equivalent]"},
+      /* 240 */ {"LSF", "Large-scale snowfall [m of water equivalent]"},
+      /* 241 */ {"ACF", "Accumulated cloud fraction tendency [(-1 to 1)]"},
+      /* 242 */ {"ALW", "Accumulated liquid water tendency [(-1 to 1)]"},
+      /* 243 */ {"FAL", "Forecast albedo [(0 - 1)]"},
+      /* 244 */ {"FSR", "Forecast surface roughness [m]"},
+      /* 245 */ {"FLSR", "Forecast logarithm of surface roughness for heat []"},
+      /* 246 */ {"CLWC", "Cloud liquid water content [kg kg**-1]"},
+      /* 247 */ {"CIWC", "Cloud ice water content [kg kg**-1]"},
+      /* 248 */ {"CC", "Cloud cover [(0 - 1)]"},
+      /* 249 */ {"AIW", "Accumulated ice water tendency [(-1 to 1)]"},
+      /* 250 */ {"ICE", "Ice age [(0 - 1)]"},
+      /* 251 */ {"ATTE", "Adiabatic tendency of temperature [K]"},
+      /* 252 */ {"ATHE", "Adiabatic tendency of humidity [kg kg**-1]"},
+      /* 253 */ {"ATZE", "Adiabatic tendency of zonal wind [m s**-1]"},
+      /* 254 */ {"ATMW", "Adiabatic tendency of meridional wind [m s**-1]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_129[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"STRF", "Stream function [m**2 s**-1]"},
+      /* 2 */ {"VPOT", "Velocity potential [m**2 s**-1]"},
+      /* 3 */ {"PT", "Potential temperature [K]"},
+      /* 4 */ {"EQPT", "Equivalent potential temperature [K]"},
+      /* 5 */ {"SEPT", "Saturated equivalent potential temperature [K]"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"UDVW", "U component of divergent wind [m s**-1]"},
+      /* 12 */ {"VDVW", "V component of divergent wind [m s**-1]"},
+      /* 13 */ {"URTW", "U component of rotational wind [m s**-1]"},
+      /* 14 */ {"VRTW", "V component of rotational wind [m s**-1]"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"UCTP", "Unbalanced component of temperature [K]"},
+      /* 22 */ {"UCLN", "Unbalanced component of logarithm of surface pressure []"},
+      /* 23 */ {"UCDV", "Unbalanced component of divergence [s**-1]"},
+      /* 24 */ {"var24", "Reserved for future unbalanced components []"},
+      /* 25 */ {"var25", "Reserved for future unbalanced components []"},
+      /* 26 */ {"CL", "Lake cover [(0 - 1)]"},
+      /* 27 */ {"CVL", "Low vegetation cover [(0 - 1)]"},
+      /* 28 */ {"CVH", "High vegetation cover [(0 - 1)]"},
+      /* 29 */ {"TVL", "Type of low vegetation []"},
+      /* 30 */ {"TVH", "Type of high vegetation []"},
+      /* 31 */ {"CI", "Sea-ice cover [(0 - 1)]"},
+      /* 32 */ {"ASN", "Snow albedo [(0 - 1)]"},
+      /* 33 */ {"RSN", "Snow density [kg m**-3]"},
+      /* 34 */ {"SSTK", "Sea surface temperature [K]"},
+      /* 35 */ {"ISTL1", "Ice surface temperature layer 1 [K]"},
+      /* 36 */ {"ISTL2", "Ice surface temperature layer 2 [K]"},
+      /* 37 */ {"ISTL3", "Ice surface temperature layer 3 [K]"},
+      /* 38 */ {"ISTL4", "Ice surface temperature layer 4 [K]"},
+      /* 39 */ {"SWVL1", "Volumetric soil water layer 1 [m**3 m**-3]"},
+      /* 40 */ {"SWVL2", "Volumetric soil water layer 2 [m**3 m**-3]"},
+      /* 41 */ {"SWVL3", "Volumetric soil water layer 3 [m**3 m**-3]"},
+      /* 42 */ {"SWVL4", "Volumetric soil water layer 4 [m**3 m**-3]"},
+      /* 43 */ {"SLT", "Soil type []"},
+      /* 44 */ {"ES", "Snow evaporation [m of water]"},
+      /* 45 */ {"SMLT", "Snowmelt [m of water]"},
+      /* 46 */ {"SDUR", "Solar duration [s]"},
+      /* 47 */ {"DSRP", "Direct solar radiation [w m**-2]"},
+      /* 48 */ {"MAGSS", "Magnitude of surface stress [N m**-2 s]"},
+      /* 49 */ {"10FG", "10 metre wind gust [m s**-1]"},
+      /* 50 */ {"LSPF", "Large-scale precipitation fraction [s]"},
+      /* 51 */ {"MX2T24", "Maximum 2 metre temperature [K]"},
+      /* 52 */ {"MN2T24", "Minimum 2 metre temperature [K]"},
+      /* 53 */ {"MONT", "Montgomery potential [m**2 s**-2]"},
+      /* 54 */ {"PRES", "Pressure [Pa]"},
+      /* 55 */ {"MEAN2T24", "Mean 2 metre temperature in past 24 hours [K]"},
+      /* 56 */ {"MN2D24", "Mean 2 metre dewpoint temperature in past 24 hours [K]"},
+      /* 57 */ {"UVB", "Downward UV radiation at the surface [w m**-2 s]"},
+      /* 58 */ {"PAR", "Photosynthetically active radiation at the surface [w m**-2 s]"},
+      /* 59 */ {"CAPE", "Convective available potential energy [J kg**-1]"},
+      /* 60 */ {"PV", "Potential vorticity [K m**2 kg**-1 s**-1]"},
+      /* 61 */ {"TPO", "Total precipitation from observations [Millimetres*100 + number of stations]"},
+      /* 62 */ {"OBCT", "Observation count []"},
+      /* 63 */ {"var63", "Start time for skin temperature difference [s]"},
+      /* 64 */ {"var64", "Finish time for skin temperature difference [s]"},
+      /* 65 */ {"var65", "Skin temperature difference [K]"},
+      /* 66 */ {"var66", "Leaf area index, low vegetation [m**2 / m**2]"},
+      /* 67 */ {"var67", "Leaf area index, high vegetation [m**2 / m**2]"},
+      /* 68 */ {"var68", "Minimum stomatal resistance, low vegetation [s m**-1]"},
+      /* 69 */ {"var69", "Minimum stomatal resistance, high vegetation [s m**-1]"},
+      /* 70 */ {"var70", "Biome cover, low vegetation [(0 - 1)]"},
+      /* 71 */ {"var71", "Biome cover, high vegetation [(0 - 1)]"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "Total column liquid water [kg m**-2]"},
+      /* 79 */ {"var79", "Total column ice water [kg m**-2]"},
+      /* 80 */ {"var80", "Experimental product []"},
+      /* 81 */ {"var81", "Experimental product []"},
+      /* 82 */ {"var82", "Experimental product []"},
+      /* 83 */ {"var83", "Experimental product []"},
+      /* 84 */ {"var84", "Experimental product []"},
+      /* 85 */ {"var85", "Experimental product []"},
+      /* 86 */ {"var86", "Experimental product []"},
+      /* 87 */ {"var87", "Experimental product []"},
+      /* 88 */ {"var88", "Experimental product []"},
+      /* 89 */ {"var89", "Experimental product []"},
+      /* 90 */ {"var90", "Experimental product []"},
+      /* 91 */ {"var91", "Experimental product []"},
+      /* 92 */ {"var92", "Experimental product []"},
+      /* 93 */ {"var93", "Experimental product []"},
+      /* 94 */ {"var94", "Experimental product []"},
+      /* 95 */ {"var95", "Experimental product []"},
+      /* 96 */ {"var96", "Experimental product []"},
+      /* 97 */ {"var97", "Experimental product []"},
+      /* 98 */ {"var98", "Experimental product []"},
+      /* 99 */ {"var99", "Experimental product []"},
+      /* 100 */ {"var100", "Experimental product []"},
+      /* 101 */ {"var101", "Experimental product []"},
+      /* 102 */ {"var102", "Experimental product []"},
+      /* 103 */ {"var103", "Experimental product []"},
+      /* 104 */ {"var104", "Experimental product []"},
+      /* 105 */ {"var105", "Experimental product []"},
+      /* 106 */ {"var106", "Experimental product []"},
+      /* 107 */ {"var107", "Experimental product []"},
+      /* 108 */ {"var108", "Experimental product []"},
+      /* 109 */ {"var109", "Experimental product []"},
+      /* 110 */ {"var110", "Experimental product []"},
+      /* 111 */ {"var111", "Experimental product []"},
+      /* 112 */ {"var112", "Experimental product []"},
+      /* 113 */ {"var113", "Experimental product []"},
+      /* 114 */ {"var114", "Experimental product []"},
+      /* 115 */ {"var115", "Experimental product []"},
+      /* 116 */ {"var116", "Experimental product []"},
+      /* 117 */ {"var117", "Experimental product []"},
+      /* 118 */ {"var118", "Experimental product []"},
+      /* 119 */ {"var119", "Experimental product []"},
+      /* 120 */ {"var120", "Experimental product []"},
+      /* 121 */ {"MX2T6", "Maximum temperature at 2 metres [K]"},
+      /* 122 */ {"MN2T6", "Minimum temperature at 2 metres [K]"},
+      /* 123 */ {"10FG6", "10 metre wind gust in the past 6 hours [m s**-1]"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "Vertically integrated total energy [J m**-2]"},
+      /* 126 */ {"var126", "Generic parameter for sensitive area prediction [Various]"},
+      /* 127 */ {"AT", "Atmospheric tide []"},
+      /* 128 */ {"BV", "Budget values []"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"SP", "Surface pressure [Pa]"},
+      /* 135 */ {"W", "Vertical velocity [Pa s**-1]"},
+      /* 136 */ {"TCW", "Total column water [kg m**-2]"},
+      /* 137 */ {"TCWV", "Total column water vapour [kg m**-2]"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"STL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"SWL1", "Soil wetness level 1 [m of water]"},
+      /* 141 */ {"SD", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"LSP", "Stratiform precipitation (Large-scale precipitation) [m]"},
+      /* 143 */ {"CP", "Convective precipitation [m]"},
+      /* 144 */ {"SF", "Snowfall (convective + stratiform) [m of water equivalent]"},
+      /* 145 */ {"BLD", "Boundary layer dissipation [W m**-2 s]"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"CHNK", "Charnock []"},
+      /* 149 */ {"SNR", "Surface net radiation [W m**-2 s]"},
+      /* 150 */ {"TNR", "Top net radiation []"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"LNSP", "Logarithm of surface pressure []"},
+      /* 153 */ {"SWHR", "Short-wave heating rate [K]"},
+      /* 154 */ {"LWHR", "Long-wave heating rate [K]"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"GH", "Height [m]"},
+      /* 157 */ {"R", "Relative humidity [%]"},
+      /* 158 */ {"TSP", "Tendency of surface pressure [Pa s**-1]"},
+      /* 159 */ {"BLH", "Boundary layer height [m]"},
+      /* 160 */ {"SDOR", "Standard deviation of orography []"},
+      /* 161 */ {"ISOR", "Anisotropy of sub-gridscale orography []"},
+      /* 162 */ {"ANOR", "Angle of sub-gridscale orography [rad]"},
+      /* 163 */ {"SLOR", "Slope of sub-gridscale orography []"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"SSRD", "Surface solar radiation downwards [W m**-2 s]"},
+      /* 170 */ {"STL2", "Soil temperature level 2 [K]"},
+      /* 171 */ {"SWL2", "Soil wetness level 2 [m of water]"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"SR", "Surface roughness [m]"},
+      /* 174 */ {"AL", "Albedo [(0 - 1)]"},
+      /* 175 */ {"STRD", "Surface thermal radiation downwards [W m**-2 s]"},
+      /* 176 */ {"SSR", "Surface solar radiation [W m**-2 s]"},
+      /* 177 */ {"STR", "Surface thermal radiation [W m**-2 s]"},
+      /* 178 */ {"TSR", "Top solar radiation [W m**-2 s]"},
+      /* 179 */ {"TTR", "Top thermal radiation [W m**-2 s]"},
+      /* 180 */ {"EWSS", "East-West surface stress [N m**-2 s]"},
+      /* 181 */ {"NSSS", "North-South surface stress [N m**-2 s]"},
+      /* 182 */ {"E", "Evaporation [m of water]"},
+      /* 183 */ {"STL3", "Soil temperature level 3 [K]"},
+      /* 184 */ {"SWL3", "Soil wetness level 3 [m of water]"},
+      /* 185 */ {"CCC", "Convective cloud cover [(0 - 1)]"},
+      /* 186 */ {"LCC", "Low cloud cover [(0 - 1)]"},
+      /* 187 */ {"MCC", "Medium cloud cover [(0 - 1)]"},
+      /* 188 */ {"HCC", "High cloud cover [(0 - 1)]"},
+      /* 189 */ {"SUND", "Sunshine duration [s]"},
+      /* 190 */ {"EWOV", "East-West component of sub-gridscale orographic variance [m**2]"},
+      /* 191 */ {"NSOV", "North-South component of sub-gridscale orographic variance [m**2]"},
+      /* 192 */ {"NWOV", "North-West/South-East component of sub-gridscale orographic variance [m**2]"},
+      /* 193 */ {"NEOV", "North-East/South-West component of sub-gridscale orographic variance [m**2]"},
+      /* 194 */ {"BTMP", "Brightness temperature [K]"},
+      /* 195 */ {"LGWS", "Latitudinal component of gravity wave stress [N m**-2 s]"},
+      /* 196 */ {"MGWS", "Meridional component of gravity wave stress [N m**-2 s]"},
+      /* 197 */ {"GWD", "Gravity wave dissipation [W m**-2 s]"},
+      /* 198 */ {"SRC", "Skin reservoir content [m of water]"},
+      /* 199 */ {"VEG", "Vegetation fraction [(0 - 1)]"},
+      /* 200 */ {"VSO", "Variance of sub-gridscale orography [m**2]"},
+      /* 201 */ {"MX2T", "Maximum temperature at 2 metres since previous post-processing [K]"},
+      /* 202 */ {"MN2T", "Minimum temperature at 2 metres since previous post-processing [K]"},
+      /* 203 */ {"O3", "Ozone mass mixing ratio [kg kg**-1]"},
+      /* 204 */ {"PAW", "Precipitation analysis weights []"},
+      /* 205 */ {"RO", "Runoff [m]"},
+      /* 206 */ {"TCO3", "Total column ozone [kg m**-2]"},
+      /* 207 */ {"10SI", "10 metre wind speed [m s**-1]"},
+      /* 208 */ {"TSRC", "Top net solar radiation, clear sky [W m**-2 s]"},
+      /* 209 */ {"TTRC", "Top net thermal radiation, clear sky [W m**-2 s]"},
+      /* 210 */ {"SSRC", "Surface net solar radiation, clear sky [W m**-2 s]"},
+      /* 211 */ {"STRC", "Surface net thermal radiation, clear sky [W m**-2 s]"},
+      /* 212 */ {"TISR", "TOA incident solar radiation [W m**-2 s]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"DHR", "Diabatic heating by radiation [K]"},
+      /* 215 */ {"DHVD", "Diabatic heating by vertical diffusion [K]"},
+      /* 216 */ {"DHCC", "Diabatic heating by cumulus convection [K]"},
+      /* 217 */ {"DHLC", "Diabatic heating large-scale condensation [K]"},
+      /* 218 */ {"VDZW", "Vertical diffusion of zonal wind [m s**-1]"},
+      /* 219 */ {"VDMW", "Vertical diffusion of meridional wind [m s**-1]"},
+      /* 220 */ {"EWGD", "East-West gravity wave drag tendency [m s**-1]"},
+      /* 221 */ {"NSGD", "North-South gravity wave drag tendency [m s**-1]"},
+      /* 222 */ {"CTZW", "Convective tendency of zonal wind [m s**-1]"},
+      /* 223 */ {"CTMW", "Convective tendency of meridional wind [m s**-1]"},
+      /* 224 */ {"VDH", "Vertical diffusion of humidity [kg kg**-1]"},
+      /* 225 */ {"HTCC", "Humidity tendency by cumulus convection [kg kg**-1]"},
+      /* 226 */ {"HTLC", "Humidity tendency by large-scale condensation [kg kg**-1]"},
+      /* 227 */ {"CRNH", "Change from removal of negative humidity [kg kg**-1]"},
+      /* 228 */ {"TP", "Total precipitation [m]"},
+      /* 229 */ {"IEWS", "Instantaneous X surface stress [N m**-2]"},
+      /* 230 */ {"INSS", "Instantaneous Y surface stress [N m**-2]"},
+      /* 231 */ {"ISHF", "Instantaneous surface heat flux [W m**-2]"},
+      /* 232 */ {"IE", "Instantaneous moisture flux [kg m**-2 s]"},
+      /* 233 */ {"ASQ", "Apparent surface humidity [kg kg**-1]"},
+      /* 234 */ {"LSRH", "Logarithm of surface roughness length for heat []"},
+      /* 235 */ {"SKT", "Skin temperature [K]"},
+      /* 236 */ {"STL4", "Soil temperature level 4 [K]"},
+      /* 237 */ {"SWL4", "Soil wetness level 4 [m]"},
+      /* 238 */ {"TSN", "Temperature of snow layer [K]"},
+      /* 239 */ {"CSF", "Convective snowfall [m of water equivalent]"},
+      /* 240 */ {"LSF", "Large-scale snowfall [m of water equivalent]"},
+      /* 241 */ {"ACF", "Accumulated cloud fraction tendency [(-1 to 1)]"},
+      /* 242 */ {"ALW", "Accumulated liquid water tendency [(-1 to 1)]"},
+      /* 243 */ {"FAL", "Forecast albedo [(0 - 1)]"},
+      /* 244 */ {"FSR", "Forecast surface roughness [m]"},
+      /* 245 */ {"FLSR", "Forecast logarithm of surface roughness for heat []"},
+      /* 246 */ {"CLWC", "Cloud liquid water content [kg kg**-1]"},
+      /* 247 */ {"CIWC", "Cloud ice water content [kg kg**-1]"},
+      /* 248 */ {"CC", "Cloud cover [(0 - 1)]"},
+      /* 249 */ {"AIW", "Accumulated ice water tendency [(-1 to 1)]"},
+      /* 250 */ {"ICE", "Ice age [(0 - 1)]"},
+      /* 251 */ {"ATTE", "Adiabatic tendency of temperature [K]"},
+      /* 252 */ {"ATHE", "Adiabatic tendency of humidity [kg kg**-1]"},
+      /* 253 */ {"ATZE", "Adiabatic tendency of zonal wind [m s**-1]"},
+      /* 254 */ {"ATMW", "Adiabatic tendency of meridional wind [m s**-1]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_130[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"TSRU", "Top solar radiation upward [W m**-2]"},
+      /* 209 */ {"TTRU", "Top thermal radiation upward [W m**-2]"},
+      /* 210 */ {"TSUC", "Top solar radiation upward, clear sky [W m**-2]"},
+      /* 211 */ {"TTUC", "Top thermal radiation upward, clear sky [W m**-2]"},
+      /* 212 */ {"CLW", "Cloud liquid water [kg kg**-1]"},
+      /* 213 */ {"CF", "Cloud fraction [(0 - 1)]"},
+      /* 214 */ {"DHR", "Diabatic heating by radiation [K s**-1]"},
+      /* 215 */ {"DHVD", "Diabatic heating by vertical diffusion [K s**-1]"},
+      /* 216 */ {"DHCC", "Diabatic heating by cumulus convection [K s**-1]"},
+      /* 217 */ {"DHLC", "Diabatic heating by large-scale condensation [K s**-1]"},
+      /* 218 */ {"VDZW", "Vertical diffusion of zonal wind [m**2 s**-3]"},
+      /* 219 */ {"VDMW", "Vertical diffusion of meridional wind [m**2 s**-3]"},
+      /* 220 */ {"EWGD", "East-West gravity wave drag [m**2 s**-3]"},
+      /* 221 */ {"NSGD", "North-South gravity wave drag [m**2 s**-3]"},
+      /* 222 */ {"CTZW", "Convective tendency of zonal wind [m**2 s**-3]"},
+      /* 223 */ {"CTMW", "Convective tendency of meridional wind [m**2 s**-3]"},
+      /* 224 */ {"VDH", "Vertical diffusion of humidity [kg kg**-1 s**-1]"},
+      /* 225 */ {"HTCC", "Humidity tendency by cumulus convection [kg kg**-1 s**-1]"},
+      /* 226 */ {"HTLC", "Humidity tendency by large-scale condensation [kg kg**-1 s**-1]"},
+      /* 227 */ {"CRNH", "Change from removal of negative humidity [kg kg**-1 s**-1]"},
+      /* 228 */ {"ATT", "Adiabatic tendency of temperature [K s**-1]"},
+      /* 229 */ {"ATH", "Adiabatic tendency of humidity [kg kg**-1 s**-1]"},
+      /* 230 */ {"ATZW", "Adiabatic tendency of zonal wind [m**2 s**-3]"},
+      /* 231 */ {"ATMWAX", "Adiabatic tendency of meridional wind [m**2 s**-3]"},
+      /* 232 */ {"MVV", "Mean vertical velocity [Pa s**-1]"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_131[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"2TAG2", "2m temperature anomaly of at least +2K [%]"},
+      /* 2 */ {"2TAG1", "2m temperature anomaly of at least +1K [%]"},
+      /* 3 */ {"2TAG0", "2m temperature anomaly of at least 0K [%]"},
+      /* 4 */ {"2TALM1", "2m temperature anomaly of at most -1K [%]"},
+      /* 5 */ {"2TALM2", "2m temperature anomaly of at most -2K [%]"},
+      /* 6 */ {"TPAG20", "Total precipitation anomaly of at least 20 mm [%]"},
+      /* 7 */ {"TPAG10", "Total precipitation anomaly of at least 10 mm [%]"},
+      /* 8 */ {"TPAG0", "Total precipitation anomaly of at least 0 mm [%]"},
+      /* 9 */ {"STAG0", "Surface temperature anomaly of at least 0K [%]"},
+      /* 10 */ {"MSLAG0", "Mean sea level pressure anomaly of at least 0 Pa [%]"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"H0DIP", "Heigth of 0 degree isotherm probability [percentage]"},
+      /* 16 */ {"HSLP", "Heigth of snowfall limit probability [percentage]"},
+      /* 17 */ {"SAIP", "Showalter index probability [percentage]"},
+      /* 18 */ {"WHIP", "Whiting index probability [percentage]"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"TALM2K", "Temperature anomaly less than -2 K [%]"},
+      /* 21 */ {"TAG2K", "Temperature anomaly of at least +2 K [%]"},
+      /* 22 */ {"TALM8K", "Temperature anomaly less than -8 K [%]"},
+      /* 23 */ {"TALM4K", "Temperature anomaly less than -4 K [%]"},
+      /* 24 */ {"TAG4K", "Temperature anomaly greater than +4 K [%]"},
+      /* 25 */ {"TAG8K", "Temperature anomaly greater than +8 K [%]"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"10GP", "10 metre wind gust probability [percentage]"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"CAPEP", "Convective available potential energy probability [percentage]"},
+      /* 60 */ {"TPG1", "Total precipitation of at least 1 mm [%]"},
+      /* 61 */ {"TPG5", "Total precipitation of at least 5 mm [%]"},
+      /* 62 */ {"TPG10", "Total precipitation of at least 10 mm [%]"},
+      /* 63 */ {"TPG20", "Total precipitation of at least 20 mm [%]"},
+      /* 64 */ {"TPL01", "Total precipitation less than 0.1 mm [%]"},
+      /* 65 */ {"TPRL1", "Total precipitation rate less than 1 mm per day [%]"},
+      /* 66 */ {"TPRG3", "Total precipitation rate of at least 3 mm per day [%]"},
+      /* 67 */ {"TPRG5", "Total precipitation rate of at least 5 mm per day [%]"},
+      /* 68 */ {"10SPG10", "10 metre Wind speed of at least 10 metre per second [%]"},
+      /* 69 */ {"10SPG15", "10 metre Wind speed of at least 15 metre per second [%]"},
+      /* 70 */ {"10FGG15", "10 metre Wind gust of at least 15 metre per second [%]"},
+      /* 71 */ {"10FGG20", "10 metre Wind gust of at least 20 metre per second [%]"},
+      /* 72 */ {"10FGG25", "10 metre Wind gust of at least 25 metre per second [%]"},
+      /* 73 */ {"2TL273", "2 metre temperature less than 273.15 K [%]"},
+      /* 74 */ {"SWHG2", "Significant wave height of at least 2 m [%]"},
+      /* 75 */ {"SWHG4", "Significant wave height of at least 4 m [%]"},
+      /* 76 */ {"SWHG6", "Significant wave height of at least 6 m [%]"},
+      /* 77 */ {"SWHG8", "Significant wave height of at least 8 m [%]"},
+      /* 78 */ {"MWPG8", "Mean wave period of at least 8 s [%]"},
+      /* 79 */ {"MWPG10", "Mean wave period of at least 10 s [%]"},
+      /* 80 */ {"MWPG12", "Mean wave period of at least 12 s [%]"},
+      /* 81 */ {"MWPG15", "Mean wave period of at least 15 s [%]"},
+      /* 82 */ {"TPG40", "Total precipitation of at least 40 mm [%]"},
+      /* 83 */ {"TPG60", "Total precipitation of at least 60 mm [%]"},
+      /* 84 */ {"TPG80", "Total precipitation of at least 80 mm [%]"},
+      /* 85 */ {"TPG100", "Total precipitation of at least 100 mm [%]"},
+      /* 86 */ {"TPG150", "Total precipitation of at least 150 mm [%]"},
+      /* 87 */ {"TPG200", "Total precipitation of at least 200 mm [%]"},
+      /* 88 */ {"TPG300", "Total precipitation of at least 300 mm [%]"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"ZP", "Geopotential probability [%]"},
+      /* 130 */ {"TAP", "Temperature anomaly probability [percentage]"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "2 metre temperature probability [%]"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"SFP", "Snowfall probability [percentage]"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "Total precipitation probability [%]"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"TCCP", "Total cloud cover probability [percentage]"},
+      /* 165 */ {"10SP", "10 metre speed probability [percentage]"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"2TP", "2 metre temperature probability [percentage]"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"MX2TP", "Maximum 2 metre temperature probability [percentage]"},
+      /* 202 */ {"MN2TP", "Minimum 2 metre temperature probability [percentage]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TPP", "Total precipitation probability [percentage]"},
+      /* 229 */ {"SWHP", "Significant wave height probability [percentage]"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"MWPP", "Mean wave period probability [percentage]"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_132[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"10FGI", "10 metre wind gust index [(-1 to 1)]"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"SFI", "Snowfall index [(-1 to 1)]"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"10WSI", "10 metre speed index [(-1 to 1)]"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"2TI", "2 metre temperature index [(-1 to 1)]"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"MAXSWHI", "Maximum of significant wave height index [(-1 to 1)]"},
+      /* 201 */ {"MX2TI", "Maximum temperature at 2 metres index [(-1 to 1)]"},
+      /* 202 */ {"MN2TI", "Minimum temperature at 2 metres index [(-1 to 1)]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TPI", "Total precipitation index [(-1 to 1)]"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_133[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"2TPLM10", "2m temperature probability less than -10 C [%]"},
+      /* 2 */ {"2TPLM5", "2m temperature probability less than -5 C [%]"},
+      /* 3 */ {"2TPL0", "2m temperature probability less than 0 C [%]"},
+      /* 4 */ {"2TPL5", "2m temperature probability less than 5 C [%]"},
+      /* 5 */ {"2TPL10", "2m temperature probability less than 10 C [%]"},
+      /* 6 */ {"2TPG25", "2m temperature probability greater than 25 C [%]"},
+      /* 7 */ {"2TPG30", "2m temperature probability greater than 30 C [%]"},
+      /* 8 */ {"2TPG35", "2m temperature probability greater than 35 C [%]"},
+      /* 9 */ {"2TPG40", "2m temperature probability greater than 40 C [%]"},
+      /* 10 */ {"2TPG45", "2m temperature probability greater than 45 C [%]"},
+      /* 11 */ {"MN2TPLM10", "Minimum 2 metre temperature probability less than -10 C [%]"},
+      /* 12 */ {"MN2TPLM5", "Minimum 2 metre temperature probability less than -5 C [%]"},
+      /* 13 */ {"MN2TPL0", "Minimum 2 metre temperature probability less than 0 C [%]"},
+      /* 14 */ {"MN2TPL5", "Minimum 2 metre temperature probability less than 5 C [%]"},
+      /* 15 */ {"MN2TPL10", "Minimum 2 metre temperature probability less than 10 C [%]"},
+      /* 16 */ {"MX2TPG25", "Maximum 2 metre temperature probability greater than 25 C [%]"},
+      /* 17 */ {"MX2TPG30", "Maximum 2 metre temperature probability greater than 30 C [%]"},
+      /* 18 */ {"MX2TPG35", "Maximum 2 metre temperature probability greater than 35 C [%]"},
+      /* 19 */ {"MX2TPG40", "Maximum 2 metre temperature probability greater than 40 C [%]"},
+      /* 20 */ {"MX2TPG45", "Maximum 2 metre temperature probability greater than 45 C [%]"},
+      /* 21 */ {"10SPG10", "10 metre wind speed probability of at least 10 m/s [%]"},
+      /* 22 */ {"10SPG15", "10 metre wind speed probability of at least 15 m/s [%]"},
+      /* 23 */ {"10SPG20", "10 metre wind speed probability of at least 20 m/s [%]"},
+      /* 24 */ {"10SPG35", "10 metre wind speed probability of at least 35 m/s [%]"},
+      /* 25 */ {"10SPG50", "10 metre wind speed probability of at least 50 m/s [%]"},
+      /* 26 */ {"10GPG20", "10 metre wind gust probability of at least 20 m/s [%]"},
+      /* 27 */ {"10GPG35", "10 metre wind gust probability of at least 35 m/s [%]"},
+      /* 28 */ {"10GPG50", "10 metre wind gust probability of at least 50 m/s [%]"},
+      /* 29 */ {"10GPG75", "10 metre wind gust probability of at least 75 m/s [%]"},
+      /* 30 */ {"10GPG100", "10 metre wind gust probability of at least 100 m/s [%]"},
+      /* 31 */ {"TPPG1", "Total precipitation probability of at least 1 mm [%]"},
+      /* 32 */ {"TPPG5", "Total precipitation probability of at least 5 mm [%]"},
+      /* 33 */ {"TPPG10", "Total precipitation probability of at least 10 mm [%]"},
+      /* 34 */ {"TPPG20", "Total precipitation probability of at least 20 mm [%]"},
+      /* 35 */ {"TPPG40", "Total precipitation probability of at least 40 mm [%]"},
+      /* 36 */ {"TPPG60", "Total precipitation probability of at least 60 mm [%]"},
+      /* 37 */ {"TPPG80", "Total precipitation probability of at least 80 mm [%]"},
+      /* 38 */ {"TPPG100", "Total precipitation probability of at least 100 mm [%]"},
+      /* 39 */ {"TPPG150", "Total precipitation probability of at least 150 mm [%]"},
+      /* 40 */ {"TPPG200", "Total precipitation probability of at least 200 mm [%]"},
+      /* 41 */ {"TPPG300", "Total precipitation probability of at least 300 mm [%]"},
+      /* 42 */ {"SFPG1", "Snowfall probability of at least 1 mm [%]"},
+      /* 43 */ {"SFPG5", "Snowfall probability of at least 5 mm [%]"},
+      /* 44 */ {"SFPG10", "Snowfall probability of at least 10 mm [%]"},
+      /* 45 */ {"SFPG20", "Snowfall probability of at least 20 mm [%]"},
+      /* 46 */ {"SFPG40", "Snowfall probability of at least 40 mm [%]"},
+      /* 47 */ {"SFPG60", "Snowfall probability of at least 60 mm [%]"},
+      /* 48 */ {"SFPG80", "Snowfall probability of at least 80 mm [%]"},
+      /* 49 */ {"SFPG100", "Snowfall probability of at least 100 mm [%]"},
+      /* 50 */ {"SFPG150", "Snowfall probability of at least 150 mm [%]"},
+      /* 51 */ {"SFPG200", "Snowfall probability of at least 200 mm [%]"},
+      /* 52 */ {"SFPG300", "Snowfall probability of at least 300 mm [%]"},
+      /* 53 */ {"TCCPG10", "Total Cloud Cover probability greater than 10% [%]"},
+      /* 54 */ {"TCCPG20", "Total Cloud Cover probability greater than 20% [%]"},
+      /* 55 */ {"TCCPG30", "Total Cloud Cover probability greater than 30% [%]"},
+      /* 56 */ {"TCCPG40", "Total Cloud Cover probability greater than 40% [%]"},
+      /* 57 */ {"TCCPG50", "Total Cloud Cover probability greater than 50% [%]"},
+      /* 58 */ {"TCCPG60", "Total Cloud Cover probability greater than 60% [%]"},
+      /* 59 */ {"TCCPG70", "Total Cloud Cover probability greater than 70% [%]"},
+      /* 60 */ {"TCCPG80", "Total Cloud Cover probability greater than 80% [%]"},
+      /* 61 */ {"TCCPG90", "Total Cloud Cover probability greater than 90% [%]"},
+      /* 62 */ {"TCCPG99", "Total Cloud Cover probability greater than 99% [%]"},
+      /* 63 */ {"HCCPG10", "High Cloud Cover probability greater than 10% [%]"},
+      /* 64 */ {"HCCPG20", "High Cloud Cover probability greater than 20% [%]"},
+      /* 65 */ {"HCCPG30", "High Cloud Cover probability greater than 30% [%]"},
+      /* 66 */ {"HCCPG40", "High Cloud Cover probability greater than 40% [%]"},
+      /* 67 */ {"HCCPG50", "High Cloud Cover probability greater than 50% [%]"},
+      /* 68 */ {"HCCPG60", "High Cloud Cover probability greater than 60% [%]"},
+      /* 69 */ {"HCCPG70", "High Cloud Cover probability greater than 70% [%]"},
+      /* 70 */ {"HCCPG80", "High Cloud Cover probability greater than 80% [%]"},
+      /* 71 */ {"HCCPG90", "High Cloud Cover probability greater than 90% [%]"},
+      /* 72 */ {"HCCPG99", "High Cloud Cover probability greater than 99% [%]"},
+      /* 73 */ {"MCCPG10", "Medium Cloud Cover probability greater than 10% [%]"},
+      /* 74 */ {"MCCPG20", "Medium Cloud Cover probability greater than 20% [%]"},
+      /* 75 */ {"MCCPG30", "Medium Cloud Cover probability greater than 30% [%]"},
+      /* 76 */ {"MCCPG40", "Medium Cloud Cover probability greater than 40% [%]"},
+      /* 77 */ {"MCCPG50", "Medium Cloud Cover probability greater than 50% [%]"},
+      /* 78 */ {"MCCPG60", "Medium Cloud Cover probability greater than 60% [%]"},
+      /* 79 */ {"MCCPG70", "Medium Cloud Cover probability greater than 70% [%]"},
+      /* 80 */ {"MCCPG80", "Medium Cloud Cover probability greater than 80% [%]"},
+      /* 81 */ {"MCCPG90", "Medium Cloud Cover probability greater than 90% [%]"},
+      /* 82 */ {"MCCPG99", "Medium Cloud Cover probability greater than 99% [%]"},
+      /* 83 */ {"LCCPG10", "Low Cloud Cover probability greater than 10% [%]"},
+      /* 84 */ {"LCCPG20", "Low Cloud Cover probability greater than 20% [%]"},
+      /* 85 */ {"LCCPG30", "Low Cloud Cover probability greater than 30% [%]"},
+      /* 86 */ {"LCCPG40", "Low Cloud Cover probability greater than 40% [%]"},
+      /* 87 */ {"LCCPG50", "Low Cloud Cover probability greater than 50% [%]"},
+      /* 88 */ {"LCCPG60", "Low Cloud Cover probability greater than 60% [%]"},
+      /* 89 */ {"LCCPG70", "Low Cloud Cover probability greater than 70% [%]"},
+      /* 90 */ {"LCCPG80", "Low Cloud Cover probability greater than 80% [%]"},
+      /* 91 */ {"LCCPG90", "Low Cloud Cover probability greater than 90% [%]"},
+      /* 92 */ {"LCCPG99", "Low Cloud Cover probability greater than 99% [%]"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_ecmwf_140[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"MAXSWH", "Maximum of significant wave height [m]"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"UST", "U-component stokes drift [m s**-1]"},
+      /* 216 */ {"VST", "V-component stokes drift [m s**-1]"},
+      /* 217 */ {"TMAX", "Period corresponding to maximum individual wave height [s]"},
+      /* 218 */ {"HMAX", "Maximum individual wave height [m]"},
+      /* 219 */ {"WMB", "Model bathymetry [m]"},
+      /* 220 */ {"MP1", "Mean wave period based on first moment [s]"},
+      /* 221 */ {"MP2", "Mean wave period based on second moment [s]"},
+      /* 222 */ {"WDW", "Wave spectral directional width []"},
+      /* 223 */ {"P1WW", "Mean wave period based on first moment for wind waves [s]"},
+      /* 224 */ {"P2WW", "Mean wave period based on second moment for wind waves [s]"},
+      /* 225 */ {"DWWW", "Wave spectral directional width for wind waves []"},
+      /* 226 */ {"P1PS", "Mean wave period based on first moment for swell [s]"},
+      /* 227 */ {"P2PS", "Mean wave period based on second moment for swell [s]"},
+      /* 228 */ {"DWPS", "Wave spectral directional width for swell []"},
+      /* 229 */ {"SWH", "Significant wave height [m]"},
+      /* 230 */ {"MWD", "Mean wave direction [degrees]"},
+      /* 231 */ {"PP1D", "Peak period of 1D spectra [s]"},
+      /* 232 */ {"MWP", "Mean wave period [s]"},
+      /* 233 */ {"CDWW", "Coefficient of drag with waves []"},
+      /* 234 */ {"SHWW", "Significant height of wind waves [m]"},
+      /* 235 */ {"MDWW", "Mean direction of wind waves [degrees]"},
+      /* 236 */ {"MPWW", "Mean period of wind waves [s]"},
+      /* 237 */ {"SHTS", "Significant height of total swell [m]"},
+      /* 238 */ {"MDTS", "Mean direction of total swell [degrees]"},
+      /* 239 */ {"MPTS", "Mean period of total swell [s]"},
+      /* 240 */ {"SDHS", "Standard deviation wave height [m]"},
+      /* 241 */ {"MU10", "Mean of 10 metre wind speed [m s**-1]"},
+      /* 242 */ {"MDWI", "Mean wind direction [degrees]"},
+      /* 243 */ {"SDU", "Standard deviation of 10 metre wind speed [m s**-1]"},
+      /* 244 */ {"MSQS", "Mean square slope of waves [dimensionless]"},
+      /* 245 */ {"WIND", "10 metre wind speed [m s**-1]"},
+      /* 246 */ {"AWH", "Altimeter wave height [m]"},
+      /* 247 */ {"ACWH", "Altimeter corrected wave height [m]"},
+      /* 248 */ {"ARRC", "Altimeter range relative correction []"},
+      /* 249 */ {"DWI", "10 metre wind direction [degrees]"},
+      /* 250 */ {"2DSP", "2D wave spectra (multiple) [m**2 s radian**-1]"},
+      /* 251 */ {"2DFD", "2D wave spectra (single) [m**2 s radian**-1]"},
+      /* 252 */ {"WSK", "Wave spectral kurtosis []"},
+      /* 253 */ {"BFI", "Benjamin-Feir index []"},
+      /* 254 */ {"WSP", "Wave spectral peakedness [s**-1]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_150[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "Ocean potential temperature [deg C]"},
+      /* 130 */ {"var130", "Ocean salinity [psu]"},
+      /* 131 */ {"var131", "Ocean potential density [kg m**-3 -1000]"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "Ocean U velocity [m s**-1]"},
+      /* 134 */ {"var134", "Ocean V velocity [m s**-1]"},
+      /* 135 */ {"var135", "Ocean W velocity [m s**-1]"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "Richardson number []"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "U*V product [m s**-2]"},
+      /* 140 */ {"var140", "U*T product [m s**-1 deg C]"},
+      /* 141 */ {"var141", "V*T product [m s**-1 deg C]"},
+      /* 142 */ {"var142", "U*U product [m s**-2]"},
+      /* 143 */ {"var143", "V*V product [m s**-2]"},
+      /* 144 */ {"var144", "UV - U~V~ [m s**-2]"},
+      /* 145 */ {"var145", "UT - U~T~ [m s**-1 deg C]"},
+      /* 146 */ {"var146", "VT - V~T~ [m s**-1 deg C]"},
+      /* 147 */ {"var147", "UU - U~U~ [m s**-2]"},
+      /* 148 */ {"var148", "VV - V~V~ [m s**-2]"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "Sea level [m]"},
+      /* 153 */ {"var153", "Barotropic stream function []"},
+      /* 154 */ {"var154", "Mixed layer depth [m]"},
+      /* 155 */ {"var155", "Depth [m]"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "U stress [Pa]"},
+      /* 169 */ {"var169", "V stress [Pa]"},
+      /* 170 */ {"var170", "Turbulent kinetic energy input []"},
+      /* 171 */ {"var171", "Net surface heat flux []"},
+      /* 172 */ {"var172", "Surface solar radiation []"},
+      /* 173 */ {"var173", "P-E []"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "Diagnosed sea surface temperature error [deg C]"},
+      /* 181 */ {"var181", "Heat flux correction [W m**-2]"},
+      /* 182 */ {"var182", "Observed sea surface temperature [deg C]"},
+      /* 183 */ {"var183", "Observed heat flux [W m**-2]"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_151[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "In situ Temperature [deg C]"},
+      /* 129 */ {"OCPT", "Ocean potential temperature [deg C]"},
+      /* 130 */ {"S", "Salinity [psu]"},
+      /* 131 */ {"OCU", "Ocean current zonal component [m s**-1]"},
+      /* 132 */ {"OCV", "Ocean current meridional component [m s**-1]"},
+      /* 133 */ {"OCW", "Ocean current vertical component [m s**-1]"},
+      /* 134 */ {"MST", "Modulus of strain rate tensor [s**-1]"},
+      /* 135 */ {"VVS", "Vertical viscosity [m**2 s**-1]"},
+      /* 136 */ {"VDF", "Vertical diffusivity [m**2 s**-1]"},
+      /* 137 */ {"DEP", "Bottom level Depth [m]"},
+      /* 138 */ {"STH", "Sigma-theta [kg m**-3]"},
+      /* 139 */ {"RN", "Richardson number []"},
+      /* 140 */ {"UV", "UV product [m**2 s**-2]"},
+      /* 141 */ {"UT", "UT product [m s**-1 degC]"},
+      /* 142 */ {"VT", "VT product [m s**-1 deg C]"},
+      /* 143 */ {"UU", "UU product [m**2 s**-2]"},
+      /* 144 */ {"VV", "VV product [m**2 s**-2]"},
+      /* 145 */ {"SL", "Sea level [m]"},
+      /* 146 */ {"SL_1", "Sea level previous timestep [m]"},
+      /* 147 */ {"BSF", "Barotropic stream function [m**3 s**-1]"},
+      /* 148 */ {"MLD", "Mixed layer depth [m]"},
+      /* 149 */ {"BTP", "Bottom Pressure (equivalent height) [m]"},
+      /* 150 */ {"SH", "Steric height [m]"},
+      /* 151 */ {"CRL", "Curl of Wind Stress [N m**-3]"},
+      /* 152 */ {"var152", "Divergence of wind stress [Nm**-3]"},
+      /* 153 */ {"TAX", "U stress [N m**-2]"},
+      /* 154 */ {"TAY", "V stress [N m**-2]"},
+      /* 155 */ {"TKI", "Turbulent kinetic energy input [W m**-2]"},
+      /* 156 */ {"NSF", "Net surface heat flux [W m**-2]"},
+      /* 157 */ {"ASR", "Absorbed solar radiation [W m**-2]"},
+      /* 158 */ {"PME", "Precipitation - evaporation [m s**-1]"},
+      /* 159 */ {"SST", "Specified sea surface temperature [deg C]"},
+      /* 160 */ {"SHF", "Specified surface heat flux [W m**-2]"},
+      /* 161 */ {"DTE", "Diagnosed sea surface temperature error [deg C]"},
+      /* 162 */ {"HFC", "Heat flux correction [W m**-2]"},
+      /* 163 */ {"20D", "20 degrees isotherm depth [m]"},
+      /* 164 */ {"TAV300", "Average potential temperature in the upper 300m [degrees C]"},
+      /* 165 */ {"UBA1", "Vertically integrated zonal velocity (previous time step) [m**2 s**-1]"},
+      /* 166 */ {"VBA1", "Vertically Integrated meridional velocity (previous time step) [m**2 s**-1]"},
+      /* 167 */ {"ZTR", "Vertically integrated zonal volume transport [m**2 s**-1]"},
+      /* 168 */ {"MTR", "Vertically integrated meridional volume transport [m**2 s**-1]"},
+      /* 169 */ {"ZHT", "Vertically integrated zonal heat transport [J m**-1 s**-1]"},
+      /* 170 */ {"MHT", "Vertically integrated meridional heat transport [J m**-1 s**-1]"},
+      /* 171 */ {"UMAX", "U velocity maximum [m s**-1]"},
+      /* 172 */ {"DUMAX", "Depth of the velocity maximum [m]"},
+      /* 173 */ {"SMAX", "Salinity maximum [psu]"},
+      /* 174 */ {"DSMAX", "Depth of salinity maximum [m]"},
+      /* 175 */ {"SAV300", "Average salinity in the upper 300m [psu]"},
+      /* 176 */ {"LDP", "Layer Thickness at scalar points [m]"},
+      /* 177 */ {"LDU", "Layer Thickness at vector points [m]"},
+      /* 178 */ {"PTI", "Potential temperature increment [deg C]"},
+      /* 179 */ {"PTAE", "Potential temperature analysis error [deg C]"},
+      /* 180 */ {"BPT", "Background potential temperature [deg C]"},
+      /* 181 */ {"APT", "Analysed potential temperature [deg C]"},
+      /* 182 */ {"PTBE", "Potential temperature background error [deg C]"},
+      /* 183 */ {"AS", "Analysed salinity [psu]"},
+      /* 184 */ {"SALI", "Salinity increment [psu]"},
+      /* 185 */ {"EBT", "Estimated Bias in Temperature [deg C]"},
+      /* 186 */ {"EBS", "Estimated Bias in Salinity [psu]"},
+      /* 187 */ {"UVI", "Zonal Velocity increment (from balance operator) [m/s per time step]"},
+      /* 188 */ {"VVI", "Meridional Velocity increment (from balance operator) []"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"SUBI", "Salinity increment (from salinity data) [psu per time step]"},
+      /* 191 */ {"SALE", "Salinity analysis error [psu]"},
+      /* 192 */ {"BSAL", "Background Salinity [psu]"},
+      /* 193 */ {"var193", "Reserved []"},
+      /* 194 */ {"SALBE", "Salinity background error [psu]"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"EBTA", "Estimated temperature bias from assimilation [deg C]"},
+      /* 200 */ {"EBSA", "Estimated salinity bias from assimilation [psu]"},
+      /* 201 */ {"LTI", "Temperature increment from relaxation term [deg C per time step]"},
+      /* 202 */ {"LSI", "Salinity increment from relaxation term []"},
+      /* 203 */ {"BZPGA", "Bias in the zonal pressure gradient (applied) [Pa**m-1]"},
+      /* 204 */ {"BMPGA", "Bias in the meridional pressure gradient (applied) [Pa**m-1]"},
+      /* 205 */ {"EBTL", "Estimated temperature bias from relaxation [deg C]"},
+      /* 206 */ {"EBSL", "Estimated salinity bias from relaxation [psu]"},
+      /* 207 */ {"FGBT", "First guess bias in temperature [deg C]"},
+      /* 208 */ {"FGBS", "First guess bias in salinity [psu]"},
+      /* 209 */ {"BPA", "Applied bias in pressure [Pa]"},
+      /* 210 */ {"FGBP", "FG bias in pressure [Pa]"},
+      /* 211 */ {"PTA", "Bias in temperature(applied) [deg C]"},
+      /* 212 */ {"PSA", "Bias in salinity (applied) [psu]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", " []"},
+};
+
+const struct ParmTable parm_table_ecmwf_160[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"10FG", "10 metre wind gust during averaging time [m s**-1]"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"AT", "Atmospheric tide []"},
+      /* 128 */ {"BV", "Budget values []"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"SP", "Surface pressure [Pa]"},
+      /* 135 */ {"W", "Vertical velocity [Pa s**-1]"},
+      /* 136 */ {"TCW", "Total column water [kg m**-2]"},
+      /* 137 */ {"PWC", "Precipitable water content [kg m**-2]"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"STL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"SWL1", "Soil wetness level 1 [m]"},
+      /* 141 */ {"SD", "Snow depth [m of water]"},
+      /* 142 */ {"LSP", "Large-scale precipitation [kg m**-2 s**-1]"},
+      /* 143 */ {"CP", "Convective precipitation [kg m**-2 s**-1]"},
+      /* 144 */ {"SF", "Snowfall [kg m**-2 s**-1]"},
+      /* 145 */ {"BLD", "Boundary layer dissipation [W m**-2]"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2]"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"LNSP", "Logarithm of surface pressure []"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"GH", "Height [m]"},
+      /* 157 */ {"R", "Relative humidity [(0 - 1)]"},
+      /* 158 */ {"TSP", "Tendency of surface pressure [Pa s**-1]"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"STL2", "Soil temperature level 2 [K]"},
+      /* 171 */ {"SWL2", "Soil wetness level 2 [m]"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"SR", "Surface roughness [m]"},
+      /* 174 */ {"AL", "Albedo [(0 - 1)]"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"SSR", "Surface solar radiation [W m**-2]"},
+      /* 177 */ {"STR", "Surface thermal radiation [W m**-2]"},
+      /* 178 */ {"TSR", "Top solar radiation [W m**-2]"},
+      /* 179 */ {"TTR", "Top thermal radiation [W m**-2]"},
+      /* 180 */ {"EWSS", "East-West surface stress [N m**-2 s**-1]"},
+      /* 181 */ {"NSSS", "North-South surface stress [N m**-2 s**-1]"},
+      /* 182 */ {"E", "Evaporation [kg m**-2 s**-1]"},
+      /* 183 */ {"STL3", "Soil temperature level 3 [K]"},
+      /* 184 */ {"SWL3", "Soil wetness level 3 [m]"},
+      /* 185 */ {"CCC", "Convective cloud cover [(0 - 1)]"},
+      /* 186 */ {"LCC", "Low cloud cover [(0 - 1)]"},
+      /* 187 */ {"MCC", "Medium cloud cover [(0 - 1)]"},
+      /* 188 */ {"HCC", "High cloud cover [(0 - 1)]"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"EWOV", "East-West component of sub-gridscale orographic variance [m**2]"},
+      /* 191 */ {"NSOV", "North-South component of sub-gridscale orographic variance [m**2]"},
+      /* 192 */ {"NWOV", "North-West/South-East component of sub-gridscale orographic variance [m**2]"},
+      /* 193 */ {"NEOV", "North-East/South-West component of sub-gridscale orographic variance [m**2]"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"LGWS", "Latitudinal component of gravity wave stress [N m**-2 s]"},
+      /* 196 */ {"MGWS", "Meridional component of gravity wave stress [N m**-2 s]"},
+      /* 197 */ {"GWD", "Gravity wave dissipation [W m**-2 s]"},
+      /* 198 */ {"SRC", "Skin reservoir content [m of water]"},
+      /* 199 */ {"VEG", "Percentage of vegetation [%]"},
+      /* 200 */ {"VSO", "Variance of sub-gridscale orography [m**2]"},
+      /* 201 */ {"MX2T", "Maximum temperature at 2 metres during averaging time [K]"},
+      /* 202 */ {"MN2T", "Minimium temperature at 2 metres during averaging time [K]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"PAW", "Precipitation analysis weights []"},
+      /* 205 */ {"RO", "Runoff [kg m**-2 s**-1]"},
+      /* 206 */ {"ZZ", "Standard deviation of geopotential [m**2 s**-2]"},
+      /* 207 */ {"TZ", "Covariance of temperature and geopotential [K m**2 s**-2]"},
+      /* 208 */ {"TT", "Standard deviation of temperature [K]"},
+      /* 209 */ {"QZ", "Covariance of specific humidity and geopotential [m**2 s**-2]"},
+      /* 210 */ {"QT", "Covariance of specific humidity and temperature [K]"},
+      /* 211 */ {"QQ", "Standard deviation of specific humidity [(0 - 1)]"},
+      /* 212 */ {"UZ", "Covariance of U component and geopotential [m**3 s**-3]"},
+      /* 213 */ {"UT", "Covariance of U component and temperature [K m s**-1]"},
+      /* 214 */ {"UQ", "Covariance of U component and specific humidity [m s**-1]"},
+      /* 215 */ {"UU", "Standard deviation of U velocity [m s**-1]"},
+      /* 216 */ {"VZ", "Covariance of V component and geopotential [m**3 s**-3]"},
+      /* 217 */ {"VT", "Covariance of V component and temperature [K m s**-1]"},
+      /* 218 */ {"VQ", "Covariance of V component and specific humidity [m s**-1]"},
+      /* 219 */ {"VU", "Covariance of V component and U component [m**2 s**-2]"},
+      /* 220 */ {"VV", "Standard deviation of V component [m s**-1]"},
+      /* 221 */ {"WZ", "Covariance of W component and geopotential [Pa m**2 s**-3]"},
+      /* 222 */ {"WT", "Covariance of W component and temperature [K Pa s**-1]"},
+      /* 223 */ {"WQ", "Covariance of W component and specific humidity [Pa s**-1]"},
+      /* 224 */ {"WU", "Covariance of W component and U component [Pa m s**-2]"},
+      /* 225 */ {"WV", "Covariance of W component and V component [Pa m s**-2]"},
+      /* 226 */ {"WW", "Standard deviation of vertical velocity [Pa s**-1]"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TP", "Total precipitation [m]"},
+      /* 229 */ {"IEWS", "Instantaneous X surface stress [N m**-2]"},
+      /* 230 */ {"INSS", "Instantaneous Y surface stress [N m**-2]"},
+      /* 231 */ {"ISHF", "Instantaneous surface heat flux [W m**-2]"},
+      /* 232 */ {"IE", "Instantaneous moisture flux [kg m**-2 s**-1]"},
+      /* 233 */ {"ASQ", "Apparent surface humidity [kg kg**-1]"},
+      /* 234 */ {"LSRH", "Logarithm of surface roughness length for heat []"},
+      /* 235 */ {"SKT", "Skin temperature [K]"},
+      /* 236 */ {"STL4", "Soil temperature level 4 [K]"},
+      /* 237 */ {"SWL4", "Soil wetness level 4 [m]"},
+      /* 238 */ {"TSN", "Temperature of snow layer [K]"},
+      /* 239 */ {"CSF", "Convective snowfall [kg m**-2 s**-1]"},
+      /* 240 */ {"LSF", "Large-scale snowfall [kg m**-2 s**-1]"},
+      /* 241 */ {"CLWCER", "Cloud liquid water content [kg kg**-1]"},
+      /* 242 */ {"CC", "Cloud cover [(0 - 1)]"},
+      /* 243 */ {"FAL", "Forecast albedo []"},
+      /* 244 */ {"FSR", "Forecast surface roughness [m]"},
+      /* 245 */ {"FLSR", "Forecast logarithm of surface roughness for heat []"},
+      /* 246 */ {"10WS", "10 metre wind speed [m s**-1]"},
+      /* 247 */ {"MOFL", "Momentum flux [N m**-2]"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "Gravity wave dissipation flux [W m**-2]"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"HSD", "Heaviside beta function [(0 - 1)]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_162[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "Surface geopotential [m**2 s**-2]"},
+      /* 52 */ {"var52", "Surface pressure [Pa]"},
+      /* 53 */ {"var53", "Vertical integral of mass of atmosphere [kg m**-2]"},
+      /* 54 */ {"var54", "Vertical integral of temperature [K kg m**-2]"},
+      /* 55 */ {"var55", "Vertical integral of total column water vapour [kg m**-2]"},
+      /* 56 */ {"var56", "Vertical integral of total column liquid cloud water [kg m**-2]"},
+      /* 57 */ {"var57", "Vertical integral of total column frozen cloud water [kg m**-2]"},
+      /* 58 */ {"var58", "Vertical integral of total column ozone [kg m**-2]"},
+      /* 59 */ {"var59", "Vertical integral of kinetic energy [J m**-2]"},
+      /* 60 */ {"var60", "Vertical integral of thermal energy [J m**-2]"},
+      /* 61 */ {"var61", "Vertical integral of dry static energy [J m**-2]"},
+      /* 62 */ {"var62", "Vertical integral of moist static energy [J m**-2]"},
+      /* 63 */ {"var63", "Vertical integral of total energy [J m**-2]"},
+      /* 64 */ {"var64", "Vertical integral of energy conversion [W m**-2]"},
+      /* 65 */ {"var65", "Vertical integral of eastward mass flux [kg m**-1 s**-1]"},
+      /* 66 */ {"var66", "Vertical integral of northward mass flux [kg m**-1 s**-1]"},
+      /* 67 */ {"var67", "Vertical integral of eastward kinetic energy flux [W m**-2]"},
+      /* 68 */ {"var68", "Vertical integral of northward kinetic energy flux [W m**-2]"},
+      /* 69 */ {"var69", "Vertical integral of eastward heat flux [W m**-2]"},
+      /* 70 */ {"var70", "Vertical integral of northward heat flux [W m**-2]"},
+      /* 71 */ {"var71", "Vertical integral of eastward water vapour flux [kg m**-1 s**-1]"},
+      /* 72 */ {"var72", "Vertical integral of northward water vapour flux [kg m**-1 s**-1]"},
+      /* 73 */ {"var73", "Vertical integral of eastward geopotential flux [W m**-2]"},
+      /* 74 */ {"var74", "Vertical integral of northward geopotential flux [W m**-2]"},
+      /* 75 */ {"var75", "Vertical integral of eastward total energy flux [W m**-2]"},
+      /* 76 */ {"var76", "Vertical integral of northward total energy flux [W m**-2]"},
+      /* 77 */ {"var77", "Vertical integral of eastward ozone flux [kg m**-1 s**-1]"},
+      /* 78 */ {"var78", "Vertical integral of northward ozone flux [kg m**-1 s**-1]"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "Vertical integral of divergence of mass flux [kg m**-2 s**-1]"},
+      /* 82 */ {"var82", "Vertical integral of divergence of kinetic energy flux [W m**-2]"},
+      /* 83 */ {"var83", "Vertical integral of divergence of thermal energy flux [W m**-2]"},
+      /* 84 */ {"var84", "Vertical integral of divergence of moisture flux [kg m**-2 s**-1]"},
+      /* 85 */ {"var85", "Vertical integral of divergence of geopotential flux [W m**-2]"},
+      /* 86 */ {"var86", "Vertical integral of divergence of total energy flux [W m**-2]"},
+      /* 87 */ {"var87", "Vertical integral of divergence of ozone flux [kg m**-2 s**-1]"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "Tendency of short wave radiation [K]"},
+      /* 101 */ {"var101", "Tendency of long wave radiation [K]"},
+      /* 102 */ {"var102", "Tendency of clear sky short wave radiation [K]"},
+      /* 103 */ {"var103", "Tendency of clear sky long wave radiation [K]"},
+      /* 104 */ {"var104", "Updraught mass flux [kg m**-2]"},
+      /* 105 */ {"var105", "Downdraught mass flux [kg m**-2]"},
+      /* 106 */ {"var106", "Updraught detrainment rate [kg m**-3]"},
+      /* 107 */ {"var107", "Downdraught detrainment rate [kg m**-3]"},
+      /* 108 */ {"var108", "Total precipitation flux [kg m**-2]"},
+      /* 109 */ {"var109", "Turbulent diffusion coefficient for heat [m**2]"},
+      /* 110 */ {"var110", "Tendency of temperature due to physics [K]"},
+      /* 111 */ {"var111", "Tendency of specific humidity due to physics [kg kg**-1]"},
+      /* 112 */ {"var112", "Tendency of u component due to physics [m s**-1]"},
+      /* 113 */ {"var113", "Tendency of v component due to physics [m s**-1]"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "Variance of geopotential [m**4 s**-4]"},
+      /* 207 */ {"var207", "Covariance of geopotential/temperature [m**2 K s**-2]"},
+      /* 208 */ {"var208", "Variance of temperature [K**2]"},
+      /* 209 */ {"var209", "Covariance of geopotential/specific humidity [m**2 s**-2]"},
+      /* 210 */ {"var210", "Covariance of temperature/specific humidity [K]"},
+      /* 211 */ {"var211", "Variance of specific humidity []"},
+      /* 212 */ {"var212", "Covariance of u component/geopotential [M**3 s**-3]"},
+      /* 213 */ {"var213", "Covariance of u component/temperature [m s**-1 K]"},
+      /* 214 */ {"var214", "Covariance of u component/specific humidity [m s**-1]"},
+      /* 215 */ {"var215", "Variance of u component [m**2 s**-2]"},
+      /* 216 */ {"var216", "Covariance of v component/geopotential [M**3 s**-3]"},
+      /* 217 */ {"var217", "Covariance of v component/temperaure [m s**-1 K]"},
+      /* 218 */ {"var218", "Covariance of v component/specific humidity [m s**-1]"},
+      /* 219 */ {"var219", "Covariance of v component/u component [m**2 s**-2]"},
+      /* 220 */ {"var220", "Variance of v component [m**2 s**-2]"},
+      /* 221 */ {"var221", "Covariance of omega/geopotential [m**2 Pa s**-3]"},
+      /* 222 */ {"var222", "Covariance of omega/temperature [Pa s**-1 K]"},
+      /* 223 */ {"var223", "Covariance of omega/specific humidity [Pa s**-1]"},
+      /* 224 */ {"var224", "Covariance of omega/u component [m Pa s**-2]"},
+      /* 225 */ {"var225", "Covariance of omega/v component [m Pa s**-2]"},
+      /* 226 */ {"var226", "Variance of omega [Pa**2 s**-2]"},
+      /* 227 */ {"var227", "Variance of surface pressure [Pa**2]"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "Variance of relative humidity [dimensionless]"},
+      /* 230 */ {"var230", "Covariance of u component/ozone [m s**-1]"},
+      /* 231 */ {"var231", "Covariance of v component/ozone [m s**-1]"},
+      /* 232 */ {"var232", "Covariance of omega/ozone [Pa s**-1]"},
+      /* 233 */ {"var233", "Variance of ozone [dimensionless]"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_170[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"SWL1", "Soil wetness level 1 [m]"},
+      /* 141 */ {"SD", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"TSW", "Total soil moisture [m]"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"SWL2", "Soil wetness level 2 [m]"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"TTR", "Top thermal radiation [W m-2]"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"SWL3", "Soil wetness level 3 [m]"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"MX2T", "Maximum temperature at 2 metres [K]"},
+      /* 202 */ {"MN2T", "Minimum temperature at 2 metres [K]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TP", "Total precipitation [m]"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_171[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"STRFA", "Stream function anomaly [m**2 s**-1]"},
+      /* 2 */ {"VPOTA", "Velocity potential anomaly [m**2 s**-1]"},
+      /* 3 */ {"var3", "Potential temperature [K]"},
+      /* 4 */ {"var4", "Equivalent potential temperature [K]"},
+      /* 5 */ {"var5", "Saturated equivalent potential temperature [K]"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "U component of divergent wind [m s**-1]"},
+      /* 12 */ {"var12", "V component of divergent wind [m s**-1]"},
+      /* 13 */ {"var13", "U component of rotational wind [m s**-1]"},
+      /* 14 */ {"var14", "V component of rotational wind [m s**-1]"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "Unbalanced component of temperature [K]"},
+      /* 22 */ {"var22", "Unbalanced component of logarithm of surface pressure []"},
+      /* 23 */ {"var23", "Unbalanced component of divergence [s**-1]"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "Lake cover [(0 - 1)]"},
+      /* 27 */ {"var27", "Low vegetation cover [(0 - 1)]"},
+      /* 28 */ {"var28", "High vegetation cover [(0 - 1)]"},
+      /* 29 */ {"var29", "Type of low vegetation []"},
+      /* 30 */ {"var30", "Type of high vegetation []"},
+      /* 31 */ {"var31", "Sea-ice cover [(0 - 1)]"},
+      /* 32 */ {"var32", "Snow albedo [(0 - 1)]"},
+      /* 33 */ {"var33", "Snow density [kg m**-3]"},
+      /* 34 */ {"var34", "Sea surface temperature [K]"},
+      /* 35 */ {"var35", "Ice surface temperature layer 1 [K]"},
+      /* 36 */ {"var36", "Ice surface temperature layer 2 [K]"},
+      /* 37 */ {"var37", "Ice surface temperature layer 3 [K]"},
+      /* 38 */ {"var38", "Ice surface temperature layer 4 [K]"},
+      /* 39 */ {"var39", "Volumetric soil water layer 1 [m**3 m**-3]"},
+      /* 40 */ {"var40", "Volumetric soil water layer 2 [m**3 m**-3]"},
+      /* 41 */ {"var41", "Volumetric soil water layer 3 [m**3 m**-3]"},
+      /* 42 */ {"var42", "Volumetric soil water layer 4 [m**3 m**-3]"},
+      /* 43 */ {"var43", "Soil type []"},
+      /* 44 */ {"var44", "Snow evaporation [m of water]"},
+      /* 45 */ {"var45", "Snowmelt [m of water]"},
+      /* 46 */ {"var46", "Solar duration [s]"},
+      /* 47 */ {"var47", "Direct solar radiation [w m**-2]"},
+      /* 48 */ {"var48", "Magnitude of surface stress [N m**-2 s]"},
+      /* 49 */ {"var49", "10 metre wind gust [m s**-1]"},
+      /* 50 */ {"var50", "Large-scale precipitation fraction [s]"},
+      /* 51 */ {"var51", "Maximum 2 metre temperature [K]"},
+      /* 52 */ {"var52", "Minimum 2 metre temperature [K]"},
+      /* 53 */ {"var53", "Montgomery potential [m**2 s**-2]"},
+      /* 54 */ {"var54", "Pressure [Pa]"},
+      /* 55 */ {"var55", "Mean 2 metre temperature in past 24 hours [K]"},
+      /* 56 */ {"var56", "Mean 2 metre dewpoint temperature in past 24 hours [K]"},
+      /* 57 */ {"var57", "Downward UV radiation at the surface [w m**-2]"},
+      /* 58 */ {"var58", "Photosynthetically active radiation at the surface [w m**-2]"},
+      /* 59 */ {"var59", "Convective available potential energy [J kg**-1]"},
+      /* 60 */ {"var60", "Potential vorticity [K m**2 kg**-1 s**-1]"},
+      /* 61 */ {"var61", "Total precipitation from observations [Millimetres*100 + number of stations]"},
+      /* 62 */ {"var62", "Observation count []"},
+      /* 63 */ {"var63", "Start time for skin temperature difference [s]"},
+      /* 64 */ {"var64", "Finish time for skin temperature difference [s]"},
+      /* 65 */ {"var65", "Skin temperature difference [K]"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"TCLWA", "Total column liquid water anomaly [kg m**-2]"},
+      /* 79 */ {"TCIWA", "Total column ice water anomaly [kg m**-2]"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "Vertically integrated total energy [J m**-2]"},
+      /* 126 */ {"var126", "Generic parameter for sensitive area prediction [Various]"},
+      /* 127 */ {"var127", "Atmospheric tide []"},
+      /* 128 */ {"var128", "Budget values []"},
+      /* 129 */ {"ZA", "Geopotential anomaly [m**2 s**-2]"},
+      /* 130 */ {"TA", "Temperature anomaly [K]"},
+      /* 131 */ {"UA", "U velocity anomaly [m s**-1]"},
+      /* 132 */ {"VA", "V velocity anomaly [m s**-1]"},
+      /* 133 */ {"var133", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"var134", "Surface pressure [Pa]"},
+      /* 135 */ {"var135", "Vertical velocity [Pa s**-1]"},
+      /* 136 */ {"TCWA", "Total column water [kg m**-2]"},
+      /* 137 */ {"TCWVA", "Total column water vapour [kg m**-2]"},
+      /* 138 */ {"var138", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"STAL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"var140", "Soil wetness level 1 [m of water]"},
+      /* 141 */ {"var141", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"var142", "Stratiform precipitation (Large-scale precipitation) [m]"},
+      /* 143 */ {"var143", "Convective precipitation [m]"},
+      /* 144 */ {"var144", "Snowfall (convective + stratiform) [m of water equivalent]"},
+      /* 145 */ {"var145", "Boundary layer dissipation [W m**-2 s]"},
+      /* 146 */ {"var146", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"var147", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"var148", "Charnock []"},
+      /* 149 */ {"var149", "Surface net radiation [W m**-2 s]"},
+      /* 150 */ {"var150", "Top net radiation []"},
+      /* 151 */ {"MSLA", "Mean sea level pressure anomaly [Pa]"},
+      /* 152 */ {"var152", "Logarithm of surface pressure []"},
+      /* 153 */ {"var153", "Short-wave heating rate [K]"},
+      /* 154 */ {"var154", "Long-wave heating rate [K]"},
+      /* 155 */ {"var155", "Divergence [s**-1]"},
+      /* 156 */ {"var156", "Height [m]"},
+      /* 157 */ {"var157", "Relative humidity [%]"},
+      /* 158 */ {"var158", "Tendency of surface pressure [Pa s**-1]"},
+      /* 159 */ {"var159", "Boundary layer height [m]"},
+      /* 160 */ {"var160", "Standard deviation of orography []"},
+      /* 161 */ {"var161", "Anisotropy of sub-gridscale orography []"},
+      /* 162 */ {"var162", "Angle of sub-gridscale orography [rad]"},
+      /* 163 */ {"var163", "Slope of sub-gridscale orography []"},
+      /* 164 */ {"TCCA", "Total cloud cover anomaly [(0 - 1)]"},
+      /* 165 */ {"10UA", "10 metre U wind component anomaly [m s**-1]"},
+      /* 166 */ {"10VA", "10 metre V wind component anomaly [m s**-1]"},
+      /* 167 */ {"2TA", "2 metre temperature anomaly [K]"},
+      /* 168 */ {"var168", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"var169", "Surface solar radiation downwards [W m**-2 s]"},
+      /* 170 */ {"var170", "Soil temperature level 2 [K]"},
+      /* 171 */ {"var171", "Soil wetness level 2 [m of water]"},
+      /* 172 */ {"var172", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"var173", "Surface roughness [m]"},
+      /* 174 */ {"var174", "Albedo [(0 - 1)]"},
+      /* 175 */ {"var175", "Surface thermal radiation downwards [W m**-2 s]"},
+      /* 176 */ {"var176", "Surface solar radiation [W m**-2 s]"},
+      /* 177 */ {"var177", "Surface thermal radiation [W m**-2 s]"},
+      /* 178 */ {"var178", "Top solar radiation [W m**-2 s]"},
+      /* 179 */ {"var179", "Top thermal radiation [W m**-2 s]"},
+      /* 180 */ {"var180", "East-West surface stress [N m**-2 s]"},
+      /* 181 */ {"var181", "North-South surface stress [N m**-2 s]"},
+      /* 182 */ {"var182", "Evaporation [m of water]"},
+      /* 183 */ {"var183", "Soil temperature level 3 [K]"},
+      /* 184 */ {"var184", "Soil wetness level 3 [m of water]"},
+      /* 185 */ {"var185", "Convective cloud cover [(0 - 1)]"},
+      /* 186 */ {"var186", "Low cloud cover [(0 - 1)]"},
+      /* 187 */ {"var187", "Medium cloud cover [(0 - 1)]"},
+      /* 188 */ {"var188", "High cloud cover [(0 - 1)]"},
+      /* 189 */ {"SUNDA", "Sunshine duration anomaly [s]"},
+      /* 190 */ {"var190", "East-West component of sub-gridscale orographic variance [m**2]"},
+      /* 191 */ {"var191", "North-South component of sub-gridscale orographic variance [m**2]"},
+      /* 192 */ {"var192", "North-West/South-East component of sub-gridscale orographic variance [m**2]"},
+      /* 193 */ {"var193", "North-East/South-West component of sub-gridscale orographic variance [m**2]"},
+      /* 194 */ {"var194", "Brightness temperature [K]"},
+      /* 195 */ {"var195", "Latitudinal component of gravity wave stress [N m**-2 s]"},
+      /* 196 */ {"var196", "Meridional component of gravity wave stress [N m**-2 s]"},
+      /* 197 */ {"var197", "Gravity wave dissipation [W m**-2 s]"},
+      /* 198 */ {"var198", "Skin reservoir content [m of water]"},
+      /* 199 */ {"var199", "Vegetation fraction [(0 - 1)]"},
+      /* 200 */ {"var200", "Variance of sub-gridscale orography [m**2]"},
+      /* 201 */ {"MX2TA", "Maximum temperature at 2 metres anomaly [K]"},
+      /* 202 */ {"MN2TA", "Minimum temperature at 2 metres anomaly [K]"},
+      /* 203 */ {"var203", "Ozone mass mixing ratio [kg kg**-1]"},
+      /* 204 */ {"var204", "Precipitation analysis weights []"},
+      /* 205 */ {"var205", "Runoff [m]"},
+      /* 206 */ {"var206", "Total column ozone [kg m**-2]"},
+      /* 207 */ {"var207", "10 metre wind speed [m s**-1]"},
+      /* 208 */ {"var208", "Top net solar radiation, clear sky [W m**-2 s]"},
+      /* 209 */ {"var209", "Top net thermal radiation, clear sky [W m**-2 s]"},
+      /* 210 */ {"var210", "Surface net solar radiation, clear sky [W m**-2 s]"},
+      /* 211 */ {"var211", "Surface net thermal radiation, clear sky [W m**-2 s]"},
+      /* 212 */ {"var212", "Solar insolation [W m**-2]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "Diabatic heating by radiation [K]"},
+      /* 215 */ {"var215", "Diabatic heating by vertical diffusion [K]"},
+      /* 216 */ {"var216", "Diabatic heating by cumulus convection [K]"},
+      /* 217 */ {"var217", "Diabatic heating by large-scale condensation [K]"},
+      /* 218 */ {"var218", "Vertical diffusion of zonal wind [m s**-1]"},
+      /* 219 */ {"var219", "Vertical diffusion of meridional wind [m s**-1]"},
+      /* 220 */ {"var220", "East-West gravity wave drag tendency [m s**-1]"},
+      /* 221 */ {"var221", "North-South gravity wave drag tendency [m s**-1]"},
+      /* 222 */ {"var222", "Convective tendency of zonal wind [m s**-1]"},
+      /* 223 */ {"var223", "Convective tendency of meridional wind [m s**-1]"},
+      /* 224 */ {"var224", "Vertical diffusion of humidity [kg kg**-1]"},
+      /* 225 */ {"var225", "Humidity tendency by cumulus convection [kg kg**-1]"},
+      /* 226 */ {"var226", "Humidity tendency by large-scale condensation [kg kg**-1]"},
+      /* 227 */ {"var227", "Change from removal of negative humidity [kg kg**-1]"},
+      /* 228 */ {"TPA", "Total precipitation anomaly [m]"},
+      /* 229 */ {"var229", "Instantaneous X surface stress [N m**-2]"},
+      /* 230 */ {"var230", "Instantaneous Y surface stress [N m**-2]"},
+      /* 231 */ {"var231", "Instantaneous surface heat flux [W m**-2]"},
+      /* 232 */ {"var232", "Instantaneous moisture flux [kg m**-2 s]"},
+      /* 233 */ {"var233", "Apparent surface humidity [kg kg**-1]"},
+      /* 234 */ {"var234", "Logarithm of surface roughness length for heat []"},
+      /* 235 */ {"var235", "Skin temperature [K]"},
+      /* 236 */ {"var236", "Soil temperature level 4 [K]"},
+      /* 237 */ {"var237", "Soil wetness level 4 [m]"},
+      /* 238 */ {"var238", "Temperature of snow layer [K]"},
+      /* 239 */ {"var239", "Convective snowfall [m of water equivalent]"},
+      /* 240 */ {"var240", "Large-scale snowfall [m of water equivalent]"},
+      /* 241 */ {"var241", "Accumulated cloud fraction tendency [(-1 to 1)]"},
+      /* 242 */ {"var242", "Accumulated liquid water tendency [(-1 to 1)]"},
+      /* 243 */ {"var243", "Forecast albedo [(0 - 1)]"},
+      /* 244 */ {"var244", "Forecast surface roughness [m]"},
+      /* 245 */ {"var245", "Forecast logarithm of surface roughness for heat []"},
+      /* 246 */ {"var246", "Cloud liquid water content [kg kg**-1]"},
+      /* 247 */ {"var247", "Cloud ice water content [kg kg**-1]"},
+      /* 248 */ {"var248", "Cloud cover [(0 - 1)]"},
+      /* 249 */ {"var249", "Accumulated ice water tendency [(-1 to 1)]"},
+      /* 250 */ {"var250", "Ice age [(0 - 1)]"},
+      /* 251 */ {"var251", "Adiabatic tendency of temperature [K]"},
+      /* 252 */ {"var252", "Adiabatic tendency of humidity [kg kg**-1]"},
+      /* 253 */ {"var253", "Adiabatic tendency of zonal wind [m s**-1]"},
+      /* 254 */ {"var254", "Adiabatic tendency of meridional wind [m s**-1]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+/* ectable 172 from Geert Jan van Oldenborgh  */
+
+const struct ParmTable parm_table_ecmwf_172[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"var1", "undefined"},
+    /* 2 */ {"var2", "undefined"},
+    /* 3 */ {"var3", "undefined"},
+    /* 4 */ {"var4", "undefined"},
+    /* 5 */ {"var5", "undefined"},
+    /* 6 */ {"var6", "undefined"},
+    /* 7 */ {"var7", "undefined"},
+    /* 8 */ {"var8", "undefined"},
+    /* 9 */ {"var9", "undefined"},
+    /* 10 */ {"var10", "undefined"},
+    /* 11 */ {"var11", "undefined"},
+    /* 12 */ {"var12", "undefined"},
+    /* 13 */ {"var13", "undefined"},
+    /* 14 */ {"var14", "undefined"},
+    /* 15 */ {"var15", "undefined"},
+    /* 16 */ {"var16", "undefined"},
+    /* 17 */ {"var17", "undefined"},
+    /* 18 */ {"var18", "undefined"},
+    /* 19 */ {"var19", "undefined"},
+    /* 20 */ {"var20", "undefined"},
+    /* 21 */ {"var21", "undefined"},
+    /* 22 */ {"var22", "undefined"},
+    /* 23 */ {"var23", "undefined"},
+    /* 24 */ {"var24", "undefined"},
+    /* 25 */ {"var25", "undefined"},
+    /* 26 */ {"var26", "undefined"},
+    /* 27 */ {"var27", "undefined"},
+    /* 28 */ {"var28", "undefined"},
+    /* 29 */ {"var29", "undefined"},
+    /* 30 */ {"var30", "undefined"},
+    /* 31 */ {"var31", "undefined"},
+    /* 32 */ {"var32", "undefined"},
+    /* 33 */ {"var33", "undefined"},
+    /* 34 */ {"var34", "undefined"},
+    /* 35 */ {"var35", "undefined"},
+    /* 36 */ {"var36", "undefined"},
+    /* 37 */ {"var37", "undefined"},
+    /* 38 */ {"var38", "undefined"},
+    /* 39 */ {"var39", "undefined"},
+    /* 40 */ {"var40", "undefined"},
+    /* 41 */ {"var41", "undefined"},
+    /* 42 */ {"var42", "undefined"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"SNOE", "Snow evaporation m of water s**-1"},
+    /* 45 */ {"SNOM", "Snow melt m of water s**-1"},
+    /* 46 */ {"var46", "undefined"},
+    /* 47 */ {"var47", "undefined"},
+    /* 48 */ {"MSS", "magnitude of surface stress N m**-2"},
+    /* 49 */ {"var49", "undefined"},
+    /* 50 */ {"", "Large-scale precipitation fraction -"},
+    /* 51 */ {"var51", "undefined"},
+    /* 52 */ {"var52", "undefined"},
+    /* 53 */ {"var53", "undefined"},
+    /* 54 */ {"var54", "undefined"},
+    /* 55 */ {"var55", "undefined"},
+    /* 56 */ {"var56", "undefined"},
+    /* 57 */ {"var57", "undefined"},
+    /* 58 */ {"var58", "undefined"},
+    /* 59 */ {"var59", "undefined"},
+    /* 60 */ {"var60", "undefined"},
+    /* 61 */ {"var61", "undefined"},
+    /* 62 */ {"var62", "undefined"},
+    /* 63 */ {"var63", "undefined"},
+    /* 64 */ {"var64", "undefined"},
+    /* 65 */ {"var65", "undefined"},
+    /* 66 */ {"var66", "undefined"},
+    /* 67 */ {"var67", "undefined"},
+    /* 68 */ {"var68", "undefined"},
+    /* 69 */ {"var69", "undefined"},
+    /* 70 */ {"var70", "undefined"},
+    /* 71 */ {"var71", "undefined"},
+    /* 72 */ {"var72", "undefined"},
+    /* 73 */ {"var73", "undefined"},
+    /* 74 */ {"var74", "undefined"},
+    /* 75 */ {"var75", "undefined"},
+    /* 76 */ {"var76", "undefined"},
+    /* 77 */ {"var77", "undefined"},
+    /* 78 */ {"var78", "undefined"},
+    /* 79 */ {"var79", "undefined"},
+    /* 80 */ {"var80", "undefined"},
+    /* 81 */ {"var81", "undefined"},
+    /* 82 */ {"var82", "undefined"},
+    /* 83 */ {"var83", "undefined"},
+    /* 84 */ {"var84", "undefined"},
+    /* 85 */ {"var85", "undefined"},
+    /* 86 */ {"var86", "undefined"},
+    /* 87 */ {"var87", "undefined"},
+    /* 88 */ {"var88", "undefined"},
+    /* 89 */ {"var89", "undefined"},
+    /* 90 */ {"var90", "undefined"},
+    /* 91 */ {"var91", "undefined"},
+    /* 92 */ {"var92", "undefined"},
+    /* 93 */ {"var93", "undefined"},
+    /* 94 */ {"var94", "undefined"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"var99", "undefined"},
+    /* 100 */ {"var100", "undefined"},
+    /* 101 */ {"var101", "undefined"},
+    /* 102 */ {"var102", "undefined"},
+    /* 103 */ {"var103", "undefined"},
+    /* 104 */ {"var104", "undefined"},
+    /* 105 */ {"var105", "undefined"},
+    /* 106 */ {"var106", "undefined"},
+    /* 107 */ {"var107", "undefined"},
+    /* 108 */ {"var108", "undefined"},
+    /* 109 */ {"var109", "undefined"},
+    /* 110 */ {"var110", "undefined"},
+    /* 111 */ {"var111", "undefined"},
+    /* 112 */ {"var112", "undefined"},
+    /* 113 */ {"var113", "undefined"},
+    /* 114 */ {"var114", "undefined"},
+    /* 115 */ {"var115", "undefined"},
+    /* 116 */ {"var116", "undefined"},
+    /* 117 */ {"var117", "undefined"},
+    /* 118 */ {"var118", "undefined"},
+    /* 119 */ {"var119", "undefined"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"var121", "undefined"},
+    /* 122 */ {"var122", "undefined"},
+    /* 123 */ {"var123", "undefined"},
+    /* 124 */ {"var124", "undefined"},
+    /* 125 */ {"var125", "undefined"},
+    /* 126 */ {"var126", "undefined"},
+    /* 127 */ {"var127", "undefined"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"var129", "undefined"},
+    /* 130 */ {"var130", "undefined"},
+    /* 131 */ {"var131", "undefined"},
+    /* 132 */ {"var132", "undefined"},
+    /* 133 */ {"var133", "undefined"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"var139", "undefined"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"var141", "undefined"},
+    /* 142 */ {"LSP", "Large scale precipitation m s**-1"},
+    /* 143 */ {"CP", "Convective precipitation m s**-1"},
+    /* 144 */ {"SF", "Snowfall (convective + stratiform) m of water equivalent s**-1"},
+    /* 145 */ {"BLD", "Boundary layer dissipation W m**-2"},
+    /* 146 */ {"SSHF", "Surface sensible heat flux W m**-2"},
+    /* 147 */ {"SLHF", "Surface latent heat flux W m**-2"},
+    /* 148 */ {"SNR", "Surface net radiation W m**-2"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"var150", "undefined"},
+    /* 151 */ {"var151", "undefined"},
+    /* 152 */ {"var152", "undefined"},
+    /* 153 */ {"SWHR", "Short-wave heating rate	K s**-1"},
+    /* 154 */ {"LWHR", "Long-wave heating rate K s**-1"},
+    /* 155 */ {"var155", "undefined"},
+    /* 156 */ {"var156", "undefined"},
+    /* 157 */ {"var157", "undefined"},
+    /* 158 */ {"var158", "undefined"},
+    /* 159 */ {"var159", "undefined"},
+    /* 160 */ {"var160", "undefined"},
+    /* 161 */ {"var161", "undefined"},
+    /* 162 */ {"var162", "undefined"},
+    /* 163 */ {"var163", "undefined"},
+    /* 164 */ {"var164", "undefined"},
+    /* 165 */ {"var165", "undefined"},
+    /* 166 */ {"var166", "undefined"},
+    /* 167 */ {"var167", "undefined"},
+    /* 168 */ {"var168", "undefined"},
+    /* 169 */ {"SSRD", "Surface solar radiation downwards W m**-2"},
+    /* 170 */ {"var170", "undefined"},
+    /* 171 */ {"var171", "undefined"},
+    /* 172 */ {"var172", "undefined"},
+    /* 173 */ {"var173", "undefined"},
+    /* 174 */ {"var174", "undefined"},
+    /* 175 */ {"STRD", "Surface thermal radiation downwards W m**-2"},
+    /* 176 */ {"SSR", "Surface solar radiation W m**-2"},
+    /* 177 */ {"STR", "Surface thermal radiation W m**-2"},
+    /* 178 */ {"TSR", "Top solar radiation W m**-2"},
+    /* 179 */ {"TTR", "Top thermal radiation W m-2"},
+    /* 180 */ {"EWSS", "East-West surface stress N m**-2"},
+    /* 181 */ {"NSSS", "North-South surface stress N m**-2"},
+    /* 182 */ {"E", "Evaporation m of water s**-1"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"SUND", "Sunshine duration"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"LGWS", "Latitudinal component of gravity wave stress N m**-2"},
+    /* 196 */ {"MGWS", "Meridional component of gravity wave stress N m**-2"},
+    /* 197 */ {"GWD", "Gravity wave dissipation W m**-2"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"var200", "undefined"},
+    /* 201 */ {"var201", "undefined"},
+    /* 202 */ {"var202", "undefined"},
+    /* 203 */ {"var203", "undefined"},
+    /* 204 */ {"var204", "undefined"},
+    /* 205 */ {"RO", "Runoff m s**-1"},
+    /* 206 */ {"var206", "undefined"},
+    /* 207 */ {"var207", "undefined"},
+    /* 208 */ {"TSRC", "Top net solar radiation, clear sky 	W m**-2"},
+    /* 209 */ {"TTRC", "Top net thermal radiation, clear sky 	W m**-2"},
+    /* 210 */ {"SSRC", "Surface net solar radiation, clear sky W m**-2"},
+    /* 211 */ {"STRC", "Surface net thermal radiation, clear sky W m**-2"},
+    /* 212 */ {"SI", "Solar insolation W m**-2"},
+    /* 213 */ {"var213", "undefined"},
+    /* 214 */ {"var214", "undefined"},
+    /* 215 */ {"var215", "undefined"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"var217", "undefined"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"TP", "Total precipitation m s**-1"},
+    /* 229 */ {"var229", "undefined"},
+    /* 230 */ {"var230", "undefined"},
+    /* 231 */ {"var231", "undefined"},
+    /* 232 */ {"var232", "undefined"},
+    /* 233 */ {"var233", "undefined"},
+    /* 234 */ {"var234", "undefined"},
+    /* 235 */ {"var235", "undefined"},
+    /* 236 */ {"var236", "undefined"},
+    /* 237 */ {"var237", "undefined"},
+    /* 238 */ {"var238", "undefined"},
+    /* 239 */ {"CSF", "Convective snowfall m of water equivalent s**-1"},
+    /* 240 */ {"LSF", "Large-scale snowfall 	m of water equivalent s**-1"},
+    /* 241 */ {"var241", "undefined"},
+    /* 242 */ {"var242", "undefined"},
+    /* 243 */ {"var243", "undefined"},
+    /* 244 */ {"var244", "undefined"},
+    /* 245 */ {"var245", "undefined"},
+    /* 246 */ {"var246", "undefined"},
+    /* 247 */ {"var247", "undefined"},
+    /* 248 */ {"var248", "undefined"},
+    /* 249 */ {"var249", "undefined"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"var251", "undefined"},
+    /* 252 */ {"var252", "undefined"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"var254", "undefined"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+
+const struct ParmTable parm_table_ecmwf_173[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "Snow evaporation anomaly [m of water s**-1]"},
+      /* 45 */ {"var45", "Snowmelt anomaly [m of water s**-1]"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "Magnitude of surface stress anomaly [N m**-2]"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "Large-scale precipitation fraction anomaly []"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "Stratiform precipitation (Large-scale precipitation) anomaly [m s**-1]"},
+      /* 143 */ {"var143", "Convective precipitation anomaly [m s**-1]"},
+      /* 144 */ {"SFARA", "Snowfall (convective + stratiform) anomalous rate of accumulation [m of water equivalent s**-1]"},
+      /* 145 */ {"var145", "Boundary layer dissipation anomaly [W m**-2]"},
+      /* 146 */ {"var146", "Surface sensible heat flux anomaly [W m**-2]"},
+      /* 147 */ {"var147", "Surface latent heat flux anomaly [W m**-2]"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "Surface net radiation anomaly [W m**-2]"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "Short-wave heating rate anomaly [K s**-1]"},
+      /* 154 */ {"var154", "Long-wave heating rate anomaly [K s**-1]"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "Surface solar radiation downwards anomaly [W m**-2]"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "Surface thermal radiation downwards anomaly [W m**-2]"},
+      /* 176 */ {"var176", "Surface solar radiation anomaly [W m**-2]"},
+      /* 177 */ {"var177", "Surface thermal radiation anomaly [W m**-2]"},
+      /* 178 */ {"var178", "Top solar radiation anomaly [W m**-2]"},
+      /* 179 */ {"var179", "Top thermal radiation anomaly [W m**-2]"},
+      /* 180 */ {"var180", "East-West surface stress anomaly [N m**-2]"},
+      /* 181 */ {"var181", "North-South surface stress anomaly [N m**-2]"},
+      /* 182 */ {"var182", "Evaporation anomaly [m of water s**-1]"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"SUNDARA", "Sunshine duration anomalous rate of accumulation [dimensionless]"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "Latitudinal component of gravity wave stress anomaly [N m**-2]"},
+      /* 196 */ {"var196", "Meridional component of gravity wave stress anomaly [N m**-2]"},
+      /* 197 */ {"var197", "Gravity wave dissipation anomaly [W m**-2]"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "Runoff anomaly [m s**-1]"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "Top net solar radiation, clear sky anomaly [W m**-2]"},
+      /* 209 */ {"var209", "Top net thermal radiation, clear sky anomaly [W m**-2]"},
+      /* 210 */ {"var210", "Surface net solar radiation, clear sky anomaly [W m**-2]"},
+      /* 211 */ {"var211", "Surface net thermal radiation, clear sky anomaly [W m**-2]"},
+      /* 212 */ {"var212", "Solar insolation anomaly [W m**-2 s**-1]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TPARA", "Total precipitation anomalous rate of accumulation [m s**-1]"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "Convective snowfall anomaly [m of water equivalent s**-1]"},
+      /* 240 */ {"var240", "Large-scale snowfall anomaly [m of water equivalent s**-1]"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_174[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "Total soil moisture [m]"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"SRO", "Surface runoff [kg m**-2]"},
+      /* 9 */ {"SSRO", "Sub-surface runoff [kg m**-2]"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "Fraction of sea-ice in sea [(0 - 1)]"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "Open-sea surface temperature [K]"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "Volumetric soil water layer 1 [m**3 m**-3]"},
+      /* 40 */ {"var40", "Volumetric soil water layer 2 [m**3 m**-3]"},
+      /* 41 */ {"var41", "Volumetric soil water layer 3 [m**3 m**-3]"},
+      /* 42 */ {"var42", "Volumetric soil water layer 4 [m**3 m**-3]"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "10 metre wind gust over last 24 hours [m s**-1]"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "1.5m temperature - mean over last 24 hours [K]"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "Net primary productivity [kg C m**-2 s**-1]"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "10m U wind over land [m s**-1]"},
+      /* 86 */ {"var86", "10m V wind over land [m s**-1]"},
+      /* 87 */ {"var87", "1.5m temperature over land [K]"},
+      /* 88 */ {"var88", "1.5m dewpoint temperature over land [K]"},
+      /* 89 */ {"var89", "Top incoming solar radiation [W m**-2 s]"},
+      /* 90 */ {"var90", "Top outgoing solar radiation [W m**-2 s]"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "Mean sea surface temperature [K]"},
+      /* 95 */ {"var95", "1.5m specific humidity [kg kg**-1]"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "Sea-ice thickness [m]"},
+      /* 99 */ {"var99", "Liquid water potential temperature [K]"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "Ocean ice concentration [(0 - 1)]"},
+      /* 111 */ {"var111", "Ocean mean ice depth [m]"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "Soil temperature layer 1 [K]"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "Average potential temperature in upper 293.4m [degrees C]"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "1.5m temperature [K]"},
+      /* 168 */ {"var168", "1.5m dewpoint temperature [K]"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "Soil temperature layer 2 [K]"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "Fractional land mask [(0 - 1)]"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "Average salinity in upper 293.4m [psu]"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "Soil temperature layer 3 [K]"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "1.5m temperature - maximum over last 24 hours [K]"},
+      /* 202 */ {"var202", "1.5m temperature - minimum over last 24 hours [K]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "Soil temperature layer 4 [K]"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_180[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"SP", "Surface pressure [Pa]"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"TCWV", "Total column water vapour [kg m**-2]"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"SD", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"LSP", "Large-scale precipitation [m]"},
+      /* 143 */ {"CP", "Convective precipitation [m]"},
+      /* 144 */ {"SF", "Snowfall [m of water equivalent]"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"TSW", "Total soil wetness [m]"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"SSR", "Surface solar radiation [J m**-2 s]"},
+      /* 177 */ {"STR", "Surface thermal radiation [J m**-2 s]"},
+      /* 178 */ {"TSR", "Top solar radiation [J m**-2 s]"},
+      /* 179 */ {"TTR", "Top thermal radiation [J m**-2 s]"},
+      /* 180 */ {"EWSS", "East-West surface stress [N m**-2 s]"},
+      /* 181 */ {"NSSS", "North-South surface stress [N m**-2 s]"},
+      /* 182 */ {"E", "Evaporation [m of water]"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"RO", "Runoff [m]"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_190[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"STL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"SD", "Snow depth [m of water]"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"SSRD", "Downward surface solar radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 170 */ {"CAP", "Field capacity [(0 - 1)]"},
+      /* 171 */ {"WILT", "Wilting point [(0 - 1)]"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"SR", "Roughness length [(0 - 1)]"},
+      /* 174 */ {"AL", "Albedo [(0 - 1)]"},
+      /* 175 */ {"STRD", "Downward surface long wave radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 176 */ {"SSR", "Surface net solar radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 177 */ {"STR", "Surface net long wave radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 178 */ {"TSR", "Top net solar radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 179 */ {"TTR", "Top net long wave radiation [W m**-2 s (W m**-2 for monthly means)]"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"E", "Evaporation [m (m s**-1 for monthly means)]"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"MX2T", "Maximum 2 metre temperature [K]"},
+      /* 202 */ {"MN2T", "Minimum 2 metre temperature [K]"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TP", "Total precipitation [m (m s**-1 for monthly means)]"},
+      /* 229 */ {"TSM", "Total soil moisture [m**3 m**-3]"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", " []"},
+};
+
+const struct ParmTable parm_table_ecmwf_200[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"STRF", "Stream function [m**2 s**-1]"},
+      /* 2 */ {"VPOT", "Velocity potential [m**2 s**-1]"},
+      /* 3 */ {"PT", "Potential temperature [K]"},
+      /* 4 */ {"EQPT", "Equivalent potential temperature [K]"},
+      /* 5 */ {"SEPT", "Saturated equivalent potential temperature [K]"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"UDVW", "U component of divergent wind [m s**-1]"},
+      /* 12 */ {"VDVW", "V component of divergent wind [m s**-1]"},
+      /* 13 */ {"URTW", "U component of rotational wind [m s**-1]"},
+      /* 14 */ {"VRTW", "V component of rotational wind [m s**-1]"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"UCTP", "Unbalanced component of temperature [K]"},
+      /* 22 */ {"UCLN", "Unbalanced component of logarithm of surface pressure []"},
+      /* 23 */ {"UCDV", "Unbalanced component of divergence [s**-1]"},
+      /* 24 */ {"var24", "Reserved for future unbalanced components []"},
+      /* 25 */ {"var25", "Reserved for future unbalanced components []"},
+      /* 26 */ {"CL", "Lake cover [(0 - 1)]"},
+      /* 27 */ {"CVL", "Low vegetation cover [(0 - 1)]"},
+      /* 28 */ {"CVH", "High vegetation cover [(0 - 1)]"},
+      /* 29 */ {"TVL", "Type of low vegetation []"},
+      /* 30 */ {"TVH", "Type of high vegetation []"},
+      /* 31 */ {"CI", "Sea-ice cover [(0 - 1)]"},
+      /* 32 */ {"ASN", "Snow albedo [(0 - 1)]"},
+      /* 33 */ {"RSN", "Snow density [kg m**-3]"},
+      /* 34 */ {"SSTK", "Sea surface temperature [K]"},
+      /* 35 */ {"ISTL1", "Ice surface temperature layer 1 [K]"},
+      /* 36 */ {"ISTL2", "Ice surface temperature layer 2 [K]"},
+      /* 37 */ {"ISTL3", "Ice surface temperature layer 3 [K]"},
+      /* 38 */ {"ISTL4", "Ice surface temperature layer 4 [K]"},
+      /* 39 */ {"SWVL1", "Volumetric soil water layer 1 [m**3 m**-3]"},
+      /* 40 */ {"SWVL2", "Volumetric soil water layer 2 [m**3 m**-3]"},
+      /* 41 */ {"SWVL3", "Volumetric soil water layer 3 [m**3 m**-3]"},
+      /* 42 */ {"SWVL4", "Volumetric soil water layer 4 [m**3 m**-3]"},
+      /* 43 */ {"SLT", "Soil type []"},
+      /* 44 */ {"ES", "Snow evaporation [m of water]"},
+      /* 45 */ {"SMLT", "Snowmelt [m of water]"},
+      /* 46 */ {"SDUR", "Solar duration [s]"},
+      /* 47 */ {"DSRP", "Direct solar radiation [w m**-2]"},
+      /* 48 */ {"MAGSS", "Magnitude of surface stress [N m**-2 s]"},
+      /* 49 */ {"10FG", "10 metre wind gust [m s**-1]"},
+      /* 50 */ {"LSPF", "Large-scale precipitation fraction [s]"},
+      /* 51 */ {"MX2T24", "Maximum 2 metre temperature [K]"},
+      /* 52 */ {"MN2T24", "Minimum 2 metre temperature [K]"},
+      /* 53 */ {"MONT", "Montgomery potential [m**2 s**-2]"},
+      /* 54 */ {"PRES", "Pressure [Pa]"},
+      /* 55 */ {"MEAN2T24", "Mean 2 metre temperature in past 24 hours [K]"},
+      /* 56 */ {"MN2D24", "Mean 2 metre dewpoint temperature in past 24 hours [K]"},
+      /* 57 */ {"UVB", "Downward UV radiation at the surface [w m**-2 s]"},
+      /* 58 */ {"PAR", "Photosynthetically active radiation at the surface [w m**-2 s]"},
+      /* 59 */ {"CAPE", "Convective available potential energy [J kg**-1]"},
+      /* 60 */ {"PV", "Potential vorticity [K m**2 kg**-1 s**-1]"},
+      /* 61 */ {"TPO", "Total precipitation from observations [Millimetres*100 + number of stations]"},
+      /* 62 */ {"OBCT", "Observation count []"},
+      /* 63 */ {"var63", "Start time for skin temperature difference [s]"},
+      /* 64 */ {"var64", "Finish time for skin temperature difference [s]"},
+      /* 65 */ {"var65", "Skin temperature difference [K]"},
+      /* 66 */ {"var66", "Leaf area index, low vegetation [m**2 / m**2]"},
+      /* 67 */ {"var67", "Leaf area index, high vegetation [m**2 / m**2]"},
+      /* 68 */ {"var68", "Minimum stomatal resistance, low vegetation [s m**-1]"},
+      /* 69 */ {"var69", "Minimum stomatal resistance, high vegetation [s m**-1]"},
+      /* 70 */ {"var70", "Biome cover, low vegetation [(0 - 1)]"},
+      /* 71 */ {"var71", "Biome cover, high vegetation [(0 - 1)]"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "Total column liquid water [kg m**-2]"},
+      /* 79 */ {"var79", "Total column ice water [kg m**-2]"},
+      /* 80 */ {"var80", "Experimental product []"},
+      /* 81 */ {"var81", "Experimental product []"},
+      /* 82 */ {"var82", "Experimental product []"},
+      /* 83 */ {"var83", "Experimental product []"},
+      /* 84 */ {"var84", "Experimental product []"},
+      /* 85 */ {"var85", "Experimental product []"},
+      /* 86 */ {"var86", "Experimental product []"},
+      /* 87 */ {"var87", "Experimental product []"},
+      /* 88 */ {"var88", "Experimental product []"},
+      /* 89 */ {"var89", "Experimental product []"},
+      /* 90 */ {"var90", "Experimental product []"},
+      /* 91 */ {"var91", "Experimental product []"},
+      /* 92 */ {"var92", "Experimental product []"},
+      /* 93 */ {"var93", "Experimental product []"},
+      /* 94 */ {"var94", "Experimental product []"},
+      /* 95 */ {"var95", "Experimental product []"},
+      /* 96 */ {"var96", "Experimental product []"},
+      /* 97 */ {"var97", "Experimental product []"},
+      /* 98 */ {"var98", "Experimental product []"},
+      /* 99 */ {"var99", "Experimental product []"},
+      /* 100 */ {"var100", "Experimental product []"},
+      /* 101 */ {"var101", "Experimental product []"},
+      /* 102 */ {"var102", "Experimental product []"},
+      /* 103 */ {"var103", "Experimental product []"},
+      /* 104 */ {"var104", "Experimental product []"},
+      /* 105 */ {"var105", "Experimental product []"},
+      /* 106 */ {"var106", "Experimental product []"},
+      /* 107 */ {"var107", "Experimental product []"},
+      /* 108 */ {"var108", "Experimental product []"},
+      /* 109 */ {"var109", "Experimental product []"},
+      /* 110 */ {"var110", "Experimental product []"},
+      /* 111 */ {"var111", "Experimental product []"},
+      /* 112 */ {"var112", "Experimental product []"},
+      /* 113 */ {"var113", "Experimental product []"},
+      /* 114 */ {"var114", "Experimental product []"},
+      /* 115 */ {"var115", "Experimental product []"},
+      /* 116 */ {"var116", "Experimental product []"},
+      /* 117 */ {"var117", "Experimental product []"},
+      /* 118 */ {"var118", "Experimental product []"},
+      /* 119 */ {"var119", "Experimental product []"},
+      /* 120 */ {"var120", "Experimental product []"},
+      /* 121 */ {"MX2T6", "Maximum temperature at 2 metres [K]"},
+      /* 122 */ {"MN2T6", "Minimum temperature at 2 metres [K]"},
+      /* 123 */ {"10FG6", "10 metre wind gust in the past 6 hours [m s**-1]"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "Vertically integrated total energy [J m**-2]"},
+      /* 126 */ {"var126", "Generic parameter for sensitive area prediction [Various]"},
+      /* 127 */ {"AT", "Atmospheric tide []"},
+      /* 128 */ {"BV", "Budget values []"},
+      /* 129 */ {"Z", "Geopotential [m**2 s**-2]"},
+      /* 130 */ {"T", "Temperature [K]"},
+      /* 131 */ {"U", "U velocity [m s**-1]"},
+      /* 132 */ {"V", "V velocity [m s**-1]"},
+      /* 133 */ {"Q", "Specific humidity [kg kg**-1]"},
+      /* 134 */ {"SP", "Surface pressure [Pa]"},
+      /* 135 */ {"W", "Vertical velocity [Pa s**-1]"},
+      /* 136 */ {"TCW", "Total column water [kg m**-2]"},
+      /* 137 */ {"TCWV", "Total column water vapour [kg m**-2]"},
+      /* 138 */ {"VO", "Vorticity (relative) [s**-1]"},
+      /* 139 */ {"STL1", "Soil temperature level 1 [K]"},
+      /* 140 */ {"SWL1", "Soil wetness level 1 [m of water]"},
+      /* 141 */ {"SD", "Snow depth [m of water equivalent]"},
+      /* 142 */ {"LSP", "Stratiform precipitation (Large-scale precipitation) [m]"},
+      /* 143 */ {"CP", "Convective precipitation [m]"},
+      /* 144 */ {"SF", "Snowfall (convective + stratiform) [m of water equivalent]"},
+      /* 145 */ {"BLD", "Boundary layer dissipation [W m**-2 s]"},
+      /* 146 */ {"SSHF", "Surface sensible heat flux [W m**-2 s]"},
+      /* 147 */ {"SLHF", "Surface latent heat flux [W m**-2 s]"},
+      /* 148 */ {"CHNK", "Charnock []"},
+      /* 149 */ {"SNR", "Surface net radiation [W m**-2 s]"},
+      /* 150 */ {"TNR", "Top net radiation []"},
+      /* 151 */ {"MSL", "Mean sea level pressure [Pa]"},
+      /* 152 */ {"LNSP", "Logarithm of surface pressure []"},
+      /* 153 */ {"SWHR", "Short-wave heating rate [K]"},
+      /* 154 */ {"LWHR", "Long-wave heating rate [K]"},
+      /* 155 */ {"D", "Divergence [s**-1]"},
+      /* 156 */ {"GH", "Height [m]"},
+      /* 157 */ {"R", "Relative humidity [%]"},
+      /* 158 */ {"TSP", "Tendency of surface pressure [Pa s**-1]"},
+      /* 159 */ {"BLH", "Boundary layer height [m]"},
+      /* 160 */ {"SDOR", "Standard deviation of orography []"},
+      /* 161 */ {"ISOR", "Anisotropy of sub-gridscale orography []"},
+      /* 162 */ {"ANOR", "Angle of sub-gridscale orography [rad]"},
+      /* 163 */ {"SLOR", "Slope of sub-gridscale orography []"},
+      /* 164 */ {"TCC", "Total cloud cover [(0 - 1)]"},
+      /* 165 */ {"10U", "10 metre U wind component [m s**-1]"},
+      /* 166 */ {"10V", "10 metre V wind component [m s**-1]"},
+      /* 167 */ {"2T", "2 metre temperature [K]"},
+      /* 168 */ {"2D", "2 metre dewpoint temperature [K]"},
+      /* 169 */ {"SSRD", "Surface solar radiation downwards [W m**-2 s]"},
+      /* 170 */ {"STL2", "Soil temperature level 2 [K]"},
+      /* 171 */ {"SWL2", "Soil wetness level 2 [m of water]"},
+      /* 172 */ {"LSM", "Land-sea mask [(0 - 1)]"},
+      /* 173 */ {"SR", "Surface roughness [m]"},
+      /* 174 */ {"AL", "Albedo [(0 - 1)]"},
+      /* 175 */ {"STRD", "Surface thermal radiation downwards [W m**-2 s]"},
+      /* 176 */ {"SSR", "Surface solar radiation [W m**-2 s]"},
+      /* 177 */ {"STR", "Surface thermal radiation [W m**-2 s]"},
+      /* 178 */ {"TSR", "Top solar radiation [W m**-2 s]"},
+      /* 179 */ {"TTR", "Top thermal radiation [W m**-2 s]"},
+      /* 180 */ {"EWSS", "East-West surface stress [N m**-2 s]"},
+      /* 181 */ {"NSSS", "North-South surface stress [N m**-2 s]"},
+      /* 182 */ {"E", "Evaporation [m of water]"},
+      /* 183 */ {"STL3", "Soil temperature level 3 [K]"},
+      /* 184 */ {"SWL3", "Soil wetness level 3 [m of water]"},
+      /* 185 */ {"CCC", "Convective cloud cover [(0 - 1)]"},
+      /* 186 */ {"LCC", "Low cloud cover [(0 - 1)]"},
+      /* 187 */ {"MCC", "Medium cloud cover [(0 - 1)]"},
+      /* 188 */ {"HCC", "High cloud cover [(0 - 1)]"},
+      /* 189 */ {"SUND", "Sunshine duration [s]"},
+      /* 190 */ {"EWOV", "East-West component of sub-gridscale orographic variance [m**2]"},
+      /* 191 */ {"NSOV", "North-South component of sub-gridscale orographic variance [m**2]"},
+      /* 192 */ {"NWOV", "North-West/South-East component of sub-gridscale orographic variance [m**2]"},
+      /* 193 */ {"NEOV", "North-East/South-West component of sub-gridscale orographic variance [m**2]"},
+      /* 194 */ {"BTMP", "Brightness temperature [K]"},
+      /* 195 */ {"LGWS", "Latitudinal component of gravity wave stress [N m**-2 s]"},
+      /* 196 */ {"MGWS", "Meridional component of gravity wave stress [N m**-2 s]"},
+      /* 197 */ {"GWD", "Gravity wave dissipation [W m**-2 s]"},
+      /* 198 */ {"SRC", "Skin reservoir content [m of water]"},
+      /* 199 */ {"VEG", "Vegetation fraction [(0 - 1)]"},
+      /* 200 */ {"VSO", "Variance of sub-gridscale orography [m**2]"},
+      /* 201 */ {"MX2T", "Maximum temperature at 2 metres since previous post-processing [K]"},
+      /* 202 */ {"MN2T", "Minimum temperature at 2 metres since previous post-processing [K]"},
+      /* 203 */ {"O3", "Ozone mass mixing ratio [kg kg**-1]"},
+      /* 204 */ {"PAW", "Precipitation analysis weights []"},
+      /* 205 */ {"RO", "Runoff [m]"},
+      /* 206 */ {"TCO3", "Total column ozone [kg m**-2]"},
+      /* 207 */ {"10SI", "10 metre wind speed [m s**-1]"},
+      /* 208 */ {"TSRC", "Top net solar radiation, clear sky [W m**-2 s]"},
+      /* 209 */ {"TTRC", "Top net thermal radiation, clear sky [W m**-2 s]"},
+      /* 210 */ {"SSRC", "Surface net solar radiation, clear sky [W m**-2 s]"},
+      /* 211 */ {"STRC", "Surface net thermal radiation, clear sky [W m**-2 s]"},
+      /* 212 */ {"TISR", "TOA incident solar radiation [W m**-2 s]"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"DHR", "Diabatic heating by radiation [K]"},
+      /* 215 */ {"DHVD", "Diabatic heating by vertical diffusion [K]"},
+      /* 216 */ {"DHCC", "Diabatic heating by cumulus convection [K]"},
+      /* 217 */ {"DHLC", "Diabatic heating large-scale condensation [K]"},
+      /* 218 */ {"VDZW", "Vertical diffusion of zonal wind [m s**-1]"},
+      /* 219 */ {"VDMW", "Vertical diffusion of meridional wind [m s**-1]"},
+      /* 220 */ {"EWGD", "East-West gravity wave drag tendency [m s**-1]"},
+      /* 221 */ {"NSGD", "North-South gravity wave drag tendency [m s**-1]"},
+      /* 222 */ {"CTZW", "Convective tendency of zonal wind [m s**-1]"},
+      /* 223 */ {"CTMW", "Convective tendency of meridional wind [m s**-1]"},
+      /* 224 */ {"VDH", "Vertical diffusion of humidity [kg kg**-1]"},
+      /* 225 */ {"HTCC", "Humidity tendency by cumulus convection [kg kg**-1]"},
+      /* 226 */ {"HTLC", "Humidity tendency by large-scale condensation [kg kg**-1]"},
+      /* 227 */ {"CRNH", "Change from removal of negative humidity [kg kg**-1]"},
+      /* 228 */ {"TP", "Total precipitation [m]"},
+      /* 229 */ {"IEWS", "Instantaneous X surface stress [N m**-2]"},
+      /* 230 */ {"INSS", "Instantaneous Y surface stress [N m**-2]"},
+      /* 231 */ {"ISHF", "Instantaneous surface heat flux [W m**-2]"},
+      /* 232 */ {"IE", "Instantaneous moisture flux [kg m**-2 s]"},
+      /* 233 */ {"ASQ", "Apparent surface humidity [kg kg**-1]"},
+      /* 234 */ {"LSRH", "Logarithm of surface roughness length for heat []"},
+      /* 235 */ {"SKT", "Skin temperature [K]"},
+      /* 236 */ {"STL4", "Soil temperature level 4 [K]"},
+      /* 237 */ {"SWL4", "Soil wetness level 4 [m]"},
+      /* 238 */ {"TSN", "Temperature of snow layer [K]"},
+      /* 239 */ {"CSF", "Convective snowfall [m of water equivalent]"},
+      /* 240 */ {"LSF", "Large-scale snowfall [m of water equivalent]"},
+      /* 241 */ {"ACF", "Accumulated cloud fraction tendency [(-1 to 1)]"},
+      /* 242 */ {"ALW", "Accumulated liquid water tendency [(-1 to 1)]"},
+      /* 243 */ {"FAL", "Forecast albedo [(0 - 1)]"},
+      /* 244 */ {"FSR", "Forecast surface roughness [m]"},
+      /* 245 */ {"FLSR", "Forecast logarithm of surface roughness for heat []"},
+      /* 246 */ {"CLWC", "Cloud liquid water content [kg kg**-1]"},
+      /* 247 */ {"CIWC", "Cloud ice water content [kg kg**-1]"},
+      /* 248 */ {"CC", "Cloud cover [(0 - 1)]"},
+      /* 249 */ {"AIW", "Accumulated ice water tendency [(-1 to 1)]"},
+      /* 250 */ {"ICE", "Ice age [(0 - 1)]"},
+      /* 251 */ {"ATTE", "Adiabatic tendency of temperature [K]"},
+      /* 252 */ {"ATHE", "Adiabatic tendency of humidity [kg kg**-1]"},
+      /* 253 */ {"ATZE", "Adiabatic tendency of zonal wind [m s**-1]"},
+      /* 254 */ {"ATMW", "Adiabatic tendency of meridional wind [m s**-1]"},
+      /* 255 */ {"var255", "Indicates a missing value []"},
+};
+
+const struct ParmTable parm_table_ecmwf_210[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"AERMR01", "Sea Salt Aerosol (0.03 - 0.5 um) Mixing Ratio [kg kg**-1]"},
+      /* 2 */ {"AERMR02", "Sea Salt Aerosol (0.5 - 5 um) Mixing Ratio [kg kg**-1]"},
+      /* 3 */ {"AERMR03", "Sea Salt Aerosol (5 - 20 um) Mixing Ratio [kg kg**-1]"},
+      /* 4 */ {"AERMR04", "Dust Aerosol (0.03 - 0.55 um) Mixing Ratio [kg kg**-1]"},
+      /* 5 */ {"AERMR05", "Dust Aerosol (0.55 - 0.9 um) Mixing Ratio [kg kg**-1]"},
+      /* 6 */ {"AERMR06", "Dust Aerosol (0.9 - 20 um) Mixing Ratio [kg kg**-1]"},
+      /* 7 */ {"AERMR07", "Hydrophobic Organic Matter Aerosol Mixing Ratio [kg kg**-1]"},
+      /* 8 */ {"AERMR08", "Hydrophilic Organic Matter Aerosol Mixing Ratio [kg kg**-1]"},
+      /* 9 */ {"AERMR09", "Hydrophobic Black Carbon Aerosol Mixing Ratio [kg kg**-1]"},
+      /* 10 */ {"AERMR10", "Hydrophilic Black Carbon Aerosol Mixing Ratio [kg kg**-1]"},
+      /* 11 */ {"AERMR11", "Sulphate Aerosol Mixing Ratio [kg kg**-1]"},
+      /* 12 */ {"AERMR12", "Aerosol type 12 mixing ratio [kg kg**-1]"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"AERGN01", "Aerosol type 1 source/gain accumulated [kg m**-2]"},
+      /* 17 */ {"AERGN02", "Aerosol type 2 source/gain accumulated [kg m**-2]"},
+      /* 18 */ {"AERGN03", "Aerosol type 3 source/gain accumulated [kg m**-2]"},
+      /* 19 */ {"AERGN04", "Aerosol type 4 source/gain accumulated [kg m**-2]"},
+      /* 20 */ {"AERGN05", "Aerosol type 5 source/gain accumulated [kg m**-2]"},
+      /* 21 */ {"AERGN06", "Aerosol type 6 source/gain accumulated [kg m**-2]"},
+      /* 22 */ {"AERGN07", "Aerosol type 7 source/gain accumulated [kg m**-2]"},
+      /* 23 */ {"AERGN08", "Aerosol type 8 source/gain accumulated [kg m**-2]"},
+      /* 24 */ {"AERGN09", "Aerosol type 9 source/gain accumulated [kg m**-2]"},
+      /* 25 */ {"AERGN10", "Aerosol type 10 source/gain accumulated [kg m**-2]"},
+      /* 26 */ {"AERGN11", "Aerosol type 11 source/gain accumulated [kg m**-2]"},
+      /* 27 */ {"AERGN12", "Aerosol type 12 source/gain accumulated [kg m**-2]"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"AERLS01", "Aerosol type 1 sink/loss accumulated [kg m**-2]"},
+      /* 32 */ {"AERLS02", "Aerosol type 2 sink/loss accumulated [kg m**-2]"},
+      /* 33 */ {"AERLS03", "Aerosol type 3 sink/loss accumulated [kg m**-2]"},
+      /* 34 */ {"AERLS04", "Aerosol type 4 sink/loss accumulated [kg m**-2]"},
+      /* 35 */ {"AERLS05", "Aerosol type 5 sink/loss accumulated [kg m**-2]"},
+      /* 36 */ {"AERLS06", "Aerosol type 6 sink/loss accumulated [kg m**-2]"},
+      /* 37 */ {"AERLS07", "Aerosol type 7 sink/loss accumulated [kg m**-2]"},
+      /* 38 */ {"AERLS08", "Aerosol type 8 sink/loss accumulated [kg m**-2]"},
+      /* 39 */ {"AERLS09", "Aerosol type 9 sink/loss accumulated [kg m**-2]"},
+      /* 40 */ {"AERLS10", "Aerosol type 10 sink/loss accumulated [kg m**-2]"},
+      /* 41 */ {"AERLS11", "Aerosol type 11 sink/loss accumulated [kg m**-2]"},
+      /* 42 */ {"AERLS12", "Aerosol type 12 sink/loss accumulated [kg m**-2]"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"AERPR", "Aerosol precursor mixing ratio [kg kg**-1]"},
+      /* 47 */ {"AERSM", "Aerosol small mode mixing ratio [kg kg**-1]"},
+      /* 48 */ {"AERLG", "Aerosol large mode mixing ratio [kg kg**-1]"},
+      /* 49 */ {"AODPR", "Aerosol precursor optical depth [dimensionless]"},
+      /* 50 */ {"AODSM", "Aerosol small mode optical depth [dimensionless]"},
+      /* 51 */ {"AODLG", "Aerosol large mode optical depth [dimensionless]"},
+      /* 52 */ {"AERDEP", "Dust emission potential [kg s**2 m**-5]"},
+      /* 53 */ {"AERLTS", "Lifting threshold speed [m s**-1]"},
+      /* 54 */ {"AERSCC", "Soil clay content [%]"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"CO2", "Carbon Dioxide [kg kg**-1]"},
+      /* 62 */ {"CH4", "Methane [kg kg**-1]"},
+      /* 63 */ {"N2O", "Nitrous oxide [kg kg**-1]"},
+      /* 64 */ {"TCCO2", "Total column Carbon Dioxide [kg m**-2]"},
+      /* 65 */ {"TCCH4", "Total column Methane [kg m**-2]"},
+      /* 66 */ {"TCN2O", "Total column Nitrous oxide [kg m**-2]"},
+      /* 67 */ {"CO2OF", "Ocean flux of Carbon Dioxide [kg m**-2 s**-1]"},
+      /* 68 */ {"CO2NBF", "Natural biosphere flux of Carbon Dioxide [kg m**-2 s**-1]"},
+      /* 69 */ {"CO2APF", "Anthropogenic emissions of Carbon Dioxide [kg m**-2 s**-1]"},
+      /* 70 */ {"CH4F", "Methane Surface Fluxes [kg m**-2 s**-1]"},
+      /* 71 */ {"kCH4", "Methane loss rate due to radical hydroxyl (OH) [s**-1]"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"CO2FIRE", "Wildfire flux of Carbon Dioxide [kg m**-2 s**-1]"},
+      /* 81 */ {"COFIRE", "Wildfire flux of Carbon Monoxide [kg m**-2 s**-1]"},
+      /* 82 */ {"CH4FIRE", "Wildfire flux of Methane [kg m**-2 s**-1]"},
+      /* 83 */ {"NMHCFIRE", "Wildfire flux of Non-Methane Hydro-Carbons [kg m**-2 s**-1]"},
+      /* 84 */ {"H2FIRE", "Wildfire flux of Hydrogen [kg m**-2 s**-1]"},
+      /* 85 */ {"NOXFIRE", "Wildfire flux of Nitrogen Oxides NOx [kg m**-2 s**-1]"},
+      /* 86 */ {"N2OFIRE", "Wildfire flux of Nitrous Oxide [kg m**-2 s**-1]"},
+      /* 87 */ {"PM2P5FIRE", "Wildfire flux of Particulate Matter PM2.5 [kg m**-2 s**-1]"},
+      /* 88 */ {"TPMFIRE", "Wildfire flux of Total Particulate Matter [kg m**-2 s**-1]"},
+      /* 89 */ {"TCFIRE", "Wildfire flux of Total Carbon in Aerosols [kg m**-2 s**-1]"},
+      /* 90 */ {"OCFIRE", "Wildfire flux of Organic Carbon [kg m**-2 s**-1]"},
+      /* 91 */ {"BCFIRE", "Wildfire flux of Black Carbon [kg m**-2 s**-1]"},
+      /* 92 */ {"CFIRE", "Wildfire overall flux of burnt Carbon [kg m**-2 s**-1]"},
+      /* 93 */ {"C4FFIRE", "Wildfire fraction of C4 plants [dimensionless]"},
+      /* 94 */ {"VEGFIRE", "Wildfire vegetation map index [dimensionless]"},
+      /* 95 */ {"CCFIRE", "Wildfire Combustion Completeness [dimensionless]"},
+      /* 96 */ {"FLFIRE", "Wildfire Fuel Load"},
+      /* 97 */ {"BFFIRE", "Wildfire fraction of area burnt [dimensionless]"},
+      /* 98 */ {"OAFIRE", "Wildfire observed area [m**2]"},
+      /* 99 */ {"FRPFIRE", "Wildfire radiative power [W m**-2]"},
+      /* 100 */ {"CRFIRE", "Wildfire combustion rate [kg m**-2 s**-1]"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"NO2", "Nitrogen dioxide [kg kg**-1]"},
+      /* 122 */ {"SO2", "Sulphur dioxide [kg kg**-1]"},
+      /* 123 */ {"CO", "Carbon monoxide [kg kg**-1]"},
+      /* 124 */ {"HCHO", "Formaldehyde [kg kg**-1]"},
+      /* 125 */ {"TCNO2", "Total column Nitrogen dioxide [kg m**-2]"},
+      /* 126 */ {"TCSO2", "Total column Sulphur dioxide [kg m**-2]"},
+      /* 127 */ {"TCCO", "Total column Carbon monoxide [kg m**-2]"},
+      /* 128 */ {"TCHCHO", "Total column Formaldehyde [kg m**-2]"},
+      /* 129 */ {"NOX", "Nitrogen Oxides [kg kg**-1]"},
+      /* 130 */ {"TCNOX", "Total Column Nitrogen Oxides [kg m**-2]"},
+      /* 131 */ {"GRG1", "Reactive tracer 1 mass mixing ratio [kg kg**-1]"},
+      /* 132 */ {"TCGRG1", "Total column GRG tracer 1 [kg m**-2]"},
+      /* 133 */ {"GRG2", "Reactive tracer 2 mass mixing ratio [kg kg**-1]"},
+      /* 134 */ {"TCGRG2", "Total column GRG tracer 2 [kg m**-2]"},
+      /* 135 */ {"GRG3", "Reactive tracer 3 mass mixing ratio [kg kg**-1]"},
+      /* 136 */ {"TCGRG3", "Total column GRG tracer 3 [kg m**-2]"},
+      /* 137 */ {"GRG4", "Reactive tracer 4 mass mixing ratio [kg kg**-1]"},
+      /* 138 */ {"TCGRG4", "Total column GRG tracer 4 [kg m**-2]"},
+      /* 139 */ {"GRG5", "Reactive tracer 5 mass mixing ratio [kg kg**-1]"},
+      /* 140 */ {"TCGRG5", "Total column GRG tracer 5 [kg m**-2]"},
+      /* 141 */ {"GRG6", "Reactive tracer 6 mass mixing ratio [kg kg**-1]"},
+      /* 142 */ {"TCGRG6", "Total column GRG tracer 6 [kg m**-2]"},
+      /* 143 */ {"GRG7", "Reactive tracer 7 mass mixing ratio [kg kg**-1]"},
+      /* 144 */ {"TCGRG7", "Total column GRG tracer 7 [kg m**-2]"},
+      /* 145 */ {"GRG8", "Reactive tracer 8 mass mixing ratio [kg kg**-1]"},
+      /* 146 */ {"TCGRG8", "Total column GRG tracer 8 [kg m**-2]"},
+      /* 147 */ {"GRG9", "Reactive tracer 9 mass mixing ratio [kg kg**-1]"},
+      /* 148 */ {"TCGRG9", "Total column GRG tracer 9 [kg m**-2]"},
+      /* 149 */ {"GRG10", "Reactive tracer 10 mass mixing ratio [kg kg**-1]"},
+      /* 150 */ {"TCGRG10", "Total column GRG tracer 10 [kg m**-2]"},
+      /* 151 */ {"SFNOX", "Surface flux Nitrogen oxides [kg m**-2 s**-1]"},
+      /* 152 */ {"SFNO2", "Surface flux Nitrogen dioxide [kg m**-2 s**-1]"},
+      /* 153 */ {"SFSO2", "Surface flux Sulphur dioxide [kg m**-2 s**-1]"},
+      /* 154 */ {"SFCO2", "Surface flux Carbon monoxide [kg m**-2 s**-1]"},
+      /* 155 */ {"SFHCHO", "Surface flux Formaldehyde [kg m**-2 s**-1]"},
+      /* 156 */ {"SFGO3", "Surface flux GEMS Ozone [kg m**-2 s**-1]"},
+      /* 157 */ {"SFGR1", "Surface flux reactive tracer 1 [kg m**-2 s**-1]"},
+      /* 158 */ {"SFGR2", "Surface flux reactive tracer 2 [kg m**-2 s**-1]"},
+      /* 159 */ {"SFGR3", "Surface flux reactive tracer 3 [kg m**-2 s**-1]"},
+      /* 160 */ {"SFGR4", "Surface flux reactive tracer 4 [kg m**-2 s**-1]"},
+      /* 161 */ {"SFGR5", "Surface flux reactive tracer 5 [kg m**-2 s**-1]"},
+      /* 162 */ {"SFGR6", "Surface flux reactive tracer 6 [kg m**-2 s**-1]"},
+      /* 163 */ {"SFGR7", "Surface flux reactive tracer 7 [kg m**-2 s**-1]"},
+      /* 164 */ {"SFGR8", "Surface flux reactive tracer 8 [kg m**-2 s**-1]"},
+      /* 165 */ {"SFGR9", "Surface flux reactive tracer 9 [kg m**-2 s**-1]"},
+      /* 166 */ {"SFGR10", "Surface flux reactive tracer 10 [kg m**-2 s**-1]"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"Ra", "Radon [kg kg**-1]"},
+      /* 182 */ {"SF6", "Sulphur Hexafluoride [kg kg**-1]"},
+      /* 183 */ {"TCRa", "Total column Radon [kg m**-2]"},
+      /* 184 */ {"TCSF6", "Total column Sulphur Hexafluoride [kg m**-2]"},
+      /* 185 */ {"SF6APF", "Anthropogenic Emissions of Sulphur Hexafluoride [kg m**-2 s**-1]"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"GO3", "GEMS Ozone [kg kg**-1]"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"GTCO3", "GEMS Total column ozone [kg m**-2]"},
+      /* 207 */ {"AOD550", "Total Aerosol Optical Depth at 550nm [-]"},
+      /* 208 */ {"SSAOD550", "Sea Salt Aerosol Optical Depth at 550nm [-]"},
+      /* 209 */ {"DUAOD550", "Dust Aerosol Optical Depth at 550nm [-]"},
+      /* 210 */ {"OMAOD550", "Organic Matter Aerosol Optical Depth at 550nm [-]"},
+      /* 211 */ {"BCAOD550", "Black Carbon Aerosol Optical Depth at 550nm [-]"},
+      /* 212 */ {"SUAOD550", "Sulphate Aerosol Optical Depth at 550nm [-]"},
+      /* 213 */ {"AOD469", "Total Aerosol Optical Depth at 469nm [-]"},
+      /* 214 */ {"AOD670", "Total Aerosol Optical Depth at 670nm [-]"},
+      /* 215 */ {"AOD865", "Total Aerosol Optical Depth at 865nm [-]"},
+      /* 216 */ {"AOD1240", "Total Aerosol Optical Depth at 1240nm [-]"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_ecmwf_211[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"var1", "undefined"},
+      /* 2 */ {"var2", "undefined"},
+      /* 3 */ {"var3", "undefined"},
+      /* 4 */ {"var4", "undefined"},
+      /* 5 */ {"var5", "undefined"},
+      /* 6 */ {"var6", "undefined"},
+      /* 7 */ {"var7", "undefined"},
+      /* 8 */ {"var8", "undefined"},
+      /* 9 */ {"var9", "undefined"},
+      /* 10 */ {"var10", "undefined"},
+      /* 11 */ {"var11", "undefined"},
+      /* 12 */ {"var12", "undefined"},
+      /* 13 */ {"var13", "undefined"},
+      /* 14 */ {"var14", "undefined"},
+      /* 15 */ {"var15", "undefined"},
+      /* 16 */ {"var16", "undefined"},
+      /* 17 */ {"var17", "undefined"},
+      /* 18 */ {"var18", "undefined"},
+      /* 19 */ {"var19", "undefined"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"var39", "undefined"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"AERPR", "Aerosol precursor mixing ratio [kg kg**-1]"},
+      /* 47 */ {"AERSM", "Aerosol small mode mixing ratio [kg kg**-1]"},
+      /* 48 */ {"AERLG", "Aerosol large mode mixing ratio [kg kg**-1]"},
+      /* 49 */ {"AODPR", "Aerosol precursor optical depth [dimensionless]"},
+      /* 50 */ {"AODSM", "Aerosol small mode optical depth [dimensionless]"},
+      /* 51 */ {"AODLG", "Aerosol large mode optical depth [dimensionless]"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"CO2", "Carbon Dioxide [kg kg**-1]"},
+      /* 62 */ {"CH4", "Methane [kg kg**-1]"},
+      /* 63 */ {"N2O", "Nitrous oxide [kg kg**-1]"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"NO2", "Nitrogen dioxide [kg kg**-1]"},
+      /* 122 */ {"SO2", "Sulphur dioxide [kg kg**-1]"},
+      /* 123 */ {"CO", "Carbon monoxide [kg kg**-1]"},
+      /* 124 */ {"HCHO", "Formaldehyde [kg kg**-1]"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"GO3", "GEMS Ozone [kg kg**-1]"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_ecmwf_228[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"CIN", "Convective inhibition [J kg**-1]"},
+      /* 2 */ {"OROG", "Orography [m]"},
+      /* 3 */ {"ZUST", "Friction velocity [m s**-1]"},
+      /* 4 */ {"MEAN2T", "Mean temperature at 2 metres [K]"},
+      /* 5 */ {"MEAN10WS", "Mean of 10 metre wind speed [m s**-1]"},
+      /* 6 */ {"MEANTCC", "Mean total cloud cover [(0 - 1)]"},
+      /* 7 */ {"DL", "Lake depth [m]"},
+      /* 8 */ {"LMLT", "Lake mix-layer temperature [K]"},
+      /* 9 */ {"LMLD", "Lake mix-layer depth [m]"},
+      /* 10 */ {"LBLT", "Lake bottom temperature [K]"},
+      /* 11 */ {"LTLT", "Lake total layer temperature [K]"},
+      /* 12 */ {"LSHF", "Lake shape factor [dimensionless]"},
+      /* 13 */ {"LICT", "Lake ice temperature [K]"},
+      /* 14 */ {"LICD", "Lake ice depth [m]"},
+      /* 15 */ {"DNDZN", "Minimum vertical gradient of refractivity inside trapping layer [m**-1]"},
+      /* 16 */ {"DNDZA", "Mean vertical gradient of refractivity inside trapping layer [m**-1]"},
+      /* 17 */ {"DCTB", "Duct base height [m]"},
+      /* 18 */ {"TPLB", "Trapping layer base height [m]"},
+      /* 19 */ {"TPLT", "Trapping layer top height [m]"},
+      /* 20 */ {"var20", "undefined"},
+      /* 21 */ {"var21", "undefined"},
+      /* 22 */ {"var22", "undefined"},
+      /* 23 */ {"var23", "undefined"},
+      /* 24 */ {"var24", "undefined"},
+      /* 25 */ {"var25", "undefined"},
+      /* 26 */ {"var26", "undefined"},
+      /* 27 */ {"var27", "undefined"},
+      /* 28 */ {"var28", "undefined"},
+      /* 29 */ {"var29", "undefined"},
+      /* 30 */ {"var30", "undefined"},
+      /* 31 */ {"var31", "undefined"},
+      /* 32 */ {"var32", "undefined"},
+      /* 33 */ {"var33", "undefined"},
+      /* 34 */ {"var34", "undefined"},
+      /* 35 */ {"var35", "undefined"},
+      /* 36 */ {"var36", "undefined"},
+      /* 37 */ {"var37", "undefined"},
+      /* 38 */ {"var38", "undefined"},
+      /* 39 */ {"SM", "Soil Moisture [kg m**-3]"},
+      /* 40 */ {"var40", "undefined"},
+      /* 41 */ {"var41", "undefined"},
+      /* 42 */ {"var42", "undefined"},
+      /* 43 */ {"var43", "undefined"},
+      /* 44 */ {"var44", "undefined"},
+      /* 45 */ {"var45", "undefined"},
+      /* 46 */ {"var46", "undefined"},
+      /* 47 */ {"var47", "undefined"},
+      /* 48 */ {"var48", "undefined"},
+      /* 49 */ {"var49", "undefined"},
+      /* 50 */ {"var50", "undefined"},
+      /* 51 */ {"var51", "undefined"},
+      /* 52 */ {"var52", "undefined"},
+      /* 53 */ {"var53", "undefined"},
+      /* 54 */ {"var54", "undefined"},
+      /* 55 */ {"var55", "undefined"},
+      /* 56 */ {"var56", "undefined"},
+      /* 57 */ {"var57", "undefined"},
+      /* 58 */ {"var58", "undefined"},
+      /* 59 */ {"var59", "undefined"},
+      /* 60 */ {"var60", "undefined"},
+      /* 61 */ {"var61", "undefined"},
+      /* 62 */ {"var62", "undefined"},
+      /* 63 */ {"var63", "undefined"},
+      /* 64 */ {"var64", "undefined"},
+      /* 65 */ {"var65", "undefined"},
+      /* 66 */ {"var66", "undefined"},
+      /* 67 */ {"var67", "undefined"},
+      /* 68 */ {"var68", "undefined"},
+      /* 69 */ {"var69", "undefined"},
+      /* 70 */ {"var70", "undefined"},
+      /* 71 */ {"var71", "undefined"},
+      /* 72 */ {"var72", "undefined"},
+      /* 73 */ {"var73", "undefined"},
+      /* 74 */ {"var74", "undefined"},
+      /* 75 */ {"var75", "undefined"},
+      /* 76 */ {"var76", "undefined"},
+      /* 77 */ {"var77", "undefined"},
+      /* 78 */ {"var78", "undefined"},
+      /* 79 */ {"var79", "undefined"},
+      /* 80 */ {"var80", "undefined"},
+      /* 81 */ {"var81", "undefined"},
+      /* 82 */ {"var82", "undefined"},
+      /* 83 */ {"var83", "undefined"},
+      /* 84 */ {"var84", "undefined"},
+      /* 85 */ {"var85", "undefined"},
+      /* 86 */ {"var86", "undefined"},
+      /* 87 */ {"var87", "undefined"},
+      /* 88 */ {"var88", "undefined"},
+      /* 89 */ {"var89", "undefined"},
+      /* 90 */ {"var90", "undefined"},
+      /* 91 */ {"var91", "undefined"},
+      /* 92 */ {"var92", "undefined"},
+      /* 93 */ {"var93", "undefined"},
+      /* 94 */ {"var94", "undefined"},
+      /* 95 */ {"var95", "undefined"},
+      /* 96 */ {"var96", "undefined"},
+      /* 97 */ {"var97", "undefined"},
+      /* 98 */ {"var98", "undefined"},
+      /* 99 */ {"var99", "undefined"},
+      /* 100 */ {"var100", "undefined"},
+      /* 101 */ {"var101", "undefined"},
+      /* 102 */ {"var102", "undefined"},
+      /* 103 */ {"var103", "undefined"},
+      /* 104 */ {"var104", "undefined"},
+      /* 105 */ {"var105", "undefined"},
+      /* 106 */ {"var106", "undefined"},
+      /* 107 */ {"var107", "undefined"},
+      /* 108 */ {"var108", "undefined"},
+      /* 109 */ {"var109", "undefined"},
+      /* 110 */ {"var110", "undefined"},
+      /* 111 */ {"var111", "undefined"},
+      /* 112 */ {"var112", "undefined"},
+      /* 113 */ {"var113", "undefined"},
+      /* 114 */ {"var114", "undefined"},
+      /* 115 */ {"var115", "undefined"},
+      /* 116 */ {"var116", "undefined"},
+      /* 117 */ {"var117", "undefined"},
+      /* 118 */ {"var118", "undefined"},
+      /* 119 */ {"var119", "undefined"},
+      /* 120 */ {"var120", "undefined"},
+      /* 121 */ {"var121", "undefined"},
+      /* 122 */ {"var122", "undefined"},
+      /* 123 */ {"var123", "undefined"},
+      /* 124 */ {"var124", "undefined"},
+      /* 125 */ {"var125", "undefined"},
+      /* 126 */ {"var126", "undefined"},
+      /* 127 */ {"var127", "undefined"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"U10N", "Neutral wind at 10 m x-component [m s**-1]"},
+      /* 132 */ {"V10N", "Neutral wind at 10 m y-component [m s**-1]"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"VTNOWD", "V-tendency from non-orographic wave drag [m s**-2]"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"UTNOWD", "U-tendency from non-orographic wave drag [m s**-2]"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"ST", "Soil Temperature [K]"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"SD", "Snow Depth water equivalent [m]"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"SF", "Snow Fall water equivalent [kg m**-2]"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"TCC", "Total Cloud Cover [%]"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"var168", "undefined"},
+      /* 169 */ {"var169", "undefined"},
+      /* 170 */ {"CAP", "Field capacity [kg m**-3]"},
+      /* 171 */ {"WILT", "Wilting point [kg m**-3]"},
+      /* 172 */ {"var172", "undefined"},
+      /* 173 */ {"var173", "undefined"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"var177", "undefined"},
+      /* 178 */ {"var178", "undefined"},
+      /* 179 */ {"var179", "undefined"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"TP", "Total Precipitation [kg m**-2]"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_129[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"PAOT", "Probability anomaly of temp [%]"},
+      /* 129 */ {"PAOP", "Probability anomaly of precip [%]"},
+      /* 130 */ {"CWR", "Probability of wetting rain > 0.1 in [%]"},
+      /* 131 */ {"FRAIN", "Rain fraction of total liquid water []"},
+      /* 132 */ {"FICE", "Ice fraction of total condensate []"},
+      /* 133 */ {"FRIME", "Rime factor []"},
+      /* 134 */ {"CUEFI", "Convective cloud efficiency []"},
+      /* 135 */ {"TCOND", "Total condensate [kg/kg]"},
+      /* 136 */ {"TCOLW", "Total column cloud water [kg/m/m]"},
+      /* 137 */ {"TCOLI", "Total column cloud ice [kg/m/m]"},
+      /* 138 */ {"TCOLR", "Total column rain [kg/m/m]"},
+      /* 139 */ {"TCOLS", "Total column snow [kg/m/m]"},
+      /* 140 */ {"TCOLC", "Total column condensate [kg/m/m]"},
+      /* 141 */ {"PLPL", "Pressure of level from which parcel was lifted [Pa]"},
+      /* 142 */ {"HLPL", "Height of level from which parcel was lifted [m]"},
+      /* 143 */ {"CEMS", "Cloud Emissivity [fraction]"},
+      /* 144 */ {"COPD", "Cloud Optical Depth [non-dim]"},
+      /* 145 */ {"PSIZ", "Effective Particle size [microns]"},
+      /* 146 */ {"TCWAT", "Total Water Cloud [%]"},
+      /* 147 */ {"TCICE", "Total Ice Cloud [%]"},
+      /* 148 */ {"WDIF", "Wind Difference [m/s]"},
+      /* 149 */ {"WSTP", "Wave Steepness [non-dim]"},
+      /* 150 */ {"PTAN", "Probability of Temp. above normal [%]"},
+      /* 151 */ {"PTNN", "Probability of Temp. near normal [%]"},
+      /* 152 */ {"PTBN", "Probability of Temp. below normal [%]"},
+      /* 153 */ {"PPAN", "Probability of Precip. above normal [%]"},
+      /* 154 */ {"PPNN", "Probability of Precip. near normal [%]"},
+      /* 155 */ {"PPBN", "Probability of Precip. below normal [%]"},
+      /* 156 */ {"PMTC", "Particulate matter (coarse) [ug/m^3]"},
+      /* 157 */ {"PMTF", "Particulate matter (fine) [ug/m^3]"},
+      /* 158 */ {"AETMP", "Analysis Error of Temperature [K]"},
+      /* 159 */ {"AEDPT", "Analysis Error of Dew Point [K]"},
+      /* 160 */ {"AESPH", "Analysis Error of Specific Humidity [kg/kg] wne"},
+      /* 161 */ {"AEUWD", "Analysis Error of U-wind [m/s]"},
+      /* 162 */ {"AEVWD", "Analysis Error of V-wind [m/s]"},
+      /* 163 */ {"LPMTF", "Particulate matter (fine) [log10(ug/m^3)]"},
+      /* 164 */ {"LIPMF", "Integrated Column Particulate matter (fine) [log10(ug/m^2)] wne"},
+      /* 165 */ {"REFZR", "Derived radar reflectivity backscatter from rain [mm^6/m^3]"},
+      /* 166 */ {"REFZI", "Derived radar reflectivity backscatter from ice [mm^6/m^3]"},
+      /* 167 */ {"REFZC", "Derived radar reflectivity backscatter from parameterized convection [mm^6/m^3]"},
+      /* 168 */ {"TCLSW", "Integrated supercooled liquid water [kg/m^2]"},
+      /* 169 */ {"TCOLM", "Total Column Integrated Melting Ice [kg/m^2]"},
+      /* 170 */ {"ELRDI", "Ellrod Index [non-dim]"},
+      /* 171 */ {"TSEC", "Seconds prior to initial reference time [sec]"},
+      /* 172 */ {"TSECA", "Seconds after initial reference time [sec]"},
+      /* 173 */ {"NUM", "Number of samples/observations [non-dim]"},
+      /* 174 */ {"AEPRS", "Analysis Error of Pressure [Pa]"},
+      /* 175 */ {"ICSEV", "Icing Severity [non-dim]"},
+      /* 176 */ {"ICPRB", "Icing Probability [non-dim]"},
+      /* 177 */ {"LAVNI", "Low-level Aviation Interest [non-dim]"},
+      /* 178 */ {"HAVNI", "High-level Aviation Interest [non-dim]"},
+      /* 179 */ {"FLGHT", "Flight Category [non-dim]"},
+      /* 180 */ {"OZCON", "Ozone concentration [ppb]"},
+      /* 181 */ {"OZCAT", "Categorical ozone concentration [?]"},
+      /* 182 */ {"VEDH", "vertical heat eddy diffusivity [m^2/s]"},
+      /* 183 */ {"SIGV", "Sigma level value [non-dim]"},
+      /* 184 */ {"EWGT", "Ensemble Weight [non-dim]"},
+      /* 185 */ {"CICEL", "Confidence indicator - Ceiling [non-dim]"},
+      /* 186 */ {"CIVIS", "Confidence indicator - Visibility [non-dim]"},
+      /* 187 */ {"CIFLT", "Confidence indicator - Flight Category [non-dim]"},
+      /* 188 */ {"LAVV", "Latitude of V wind component of velocity [deg]"},
+      /* 189 */ {"LOVV", "Longitude of V wind component of velocity [deg]"},
+      /* 190 */ {"USCT", "Scatterometer est. U wind component [m/s]"},
+      /* 191 */ {"VSCT", "Scatterometer est. V wind component [m/s]"},
+      /* 192 */ {"LAUV", "Latitude of U wind component of velocity [deg]"},
+      /* 193 */ {"LOUV", "Longitude of U wind component of velocity [deg]"},
+      /* 194 */ {"TCHP", "Tropical Cyclone Heat Potential [J/m^2]"},
+      /* 195 */ {"DBSS", "Geometric Depth Below Sea Surface [m]"},
+      /* 196 */ {"ODHA", "Ocean Dynamic Heat Anomaly [dynamic m]"},
+      /* 197 */ {"OHC", "Ocean Heat Content [J/m^2]"},
+      /* 198 */ {"SSHG", "Sea Surface Height Relative to Geoid [m]"},
+      /* 199 */ {"SLTFL", "Salt flux [g/cm^2/s]"},
+      /* 200 */ {"DUVB", "UV-B Downward Solar Flux [W/m^2]"},
+      /* 201 */ {"CDUVB", "Clear Sky UV-B Downward Solar Flux [W/m^2]"},
+      /* 202 */ {"THFLX", "Total downward heat flux at surface [W/m^2]"},
+      /* 203 */ {"UVAR", "U velocity variance [m^2/s^2]"},
+      /* 204 */ {"VVAR", "V velocity variance [m^2/s^2]"},
+      /* 205 */ {"UVVCC", "UV Velocity Cross Correlation [m^2/s^2]"},
+      /* 206 */ {"MCLS", "Meteorological Correlation Length Scale [m]"},
+      /* 207 */ {"LAPP", "Latitude of pressure point [deg]"},
+      /* 208 */ {"LOPP", "Longitude of pressure point [deg]"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"REFO", "Observed radar reflectivity [dbZ]"},
+      /* 211 */ {"REFD", "Derived radar reflectivity [dbZ]"},
+      /* 212 */ {"REFC", "Maximum/Composite radar reflectivity [dbZ]"},
+      /* 213 */ {"SBT122", "Simulated Brightness Temperature for GOES12, Channel 2 [K]"},
+      /* 214 */ {"SBT123", "Simulated Brightness Temperature for GOES12, Channel 3 [K]"},
+      /* 215 */ {"SBT124", "Simulated Brightness Temperature for GOES12, Channel 4 [K]"},
+      /* 216 */ {"SBT125", "Simulated Brightness Temperature for GOES12, Channel 5 [K]"},
+      /* 217 */ {"MINRH", "Minimum Relative Humumidity [%]"},
+      /* 218 */ {"MAXRH", "Maximum Relative Humumidity [%]"},
+      /* 219 */ {"CEIL", "Ceiling [m]"},
+      /* 220 */ {"PBLREG", "Planetary boundary layer regime []"},
+      /* 221 */ {"SBC123", "Simulated brightness counts for GOES12, Channel 3 [byte]"},
+      /* 222 */ {"SBC124", "Simulated brightness counts for GOES12, Channel 4 [byte]"},
+      /* 223 */ {"RPRATE", "Rain precipitation rate [kg/m^2/s]"},
+      /* 224 */ {"SPRATE", "Snow precipitation rate [kg/m^2/s]"},
+      /* 225 */ {"FPRATE", "Freezing rain precipitation rate [kg/m^2/s]"},
+      /* 226 */ {"IPRATE", "Ice pellets precipitation rate [kg/m^2/s]"},
+      /* 227 */ {"UPHL", "Updraft Helicity [m^2/s^2]"},
+      /* 228 */ {"SURGE", "Storm Surge [m]"},
+      /* 229 */ {"ETSRG", "Extra-tropical storm Surge [m]"},
+      /* 230 */ {"RHPW", "Relative humidity with respect to precip water [%]"},
+      /* 231 */ {"OZMAX1", "Ozone daily max from 1-hour ave [ppbV]"},
+      /* 232 */ {"OZMAX8", "Ozone daily max from 8-hour ave [ppbV]"},
+      /* 233 */ {"PDMAX1", "PM 2.5 daily max from 1-hour ave [ug/m^3]"},
+      /* 234 */ {"PDMAX24", "PM 2.5 daily max from 24-hour ave [ug/m^3]"},
+      /* 235 */ {"MAXREF", "Hourly max of sim. reflect at 1km AGL [dbZ]"},
+      /* 236 */ {"MXUPHL", "Hourly max updraft helicity 2-5km AGL [m^2/s^2]"},
+      /* 237 */ {"MAXUVV", "Hourly max upward vert vel in lowest 400mb [m/s]"},
+      /* 238 */ {"MAXDVV", "Hourly max downward vert fel in lowest 400mb [m/s]"},
+      /* 239 */ {"MAXVIG", "Hourly max column graupel [kg/m^2]"},
+      /* 240 */ {"RETOP", "Radar echo top (18.3 dbZ) [m]"},
+      /* 241 */ {"VRATE", "Ventilation rate [m^2/s]"},
+      /* 242 */ {"TCSRG20", "20% tropical cyclone storm exceedance [m]"},
+      /* 243 */ {"TCSRG30", "30% tropical cyclone storm exceedance [m]"},
+      /* 244 */ {"TCSRG40", "40% tropical cyclone storm exceedance [m]"},
+      /* 245 */ {"TCSRG50", "50% tropical cyclone storm exceedance [m]"},
+      /* 246 */ {"TCSRG60", "60% tropical cyclone storm exceedance [m]"},
+      /* 247 */ {"TCSRG70", "70% tropical cyclone storm exceedance [m]"},
+      /* 248 */ {"TCSRG80", "80% tropical cyclone storm exceedance [m]"},
+      /* 249 */ {"TCSRG90", "90% tropical cyclone storm exceedance [m]"},
+      /* 250 */ {"HINDEX", "Haines index []"},
+      /* 251 */ {"DIFTEN", "Difference between 2 states in total energy norm [J/kg]"},
+      /* 252 */ {"PSPCP", "Pseudo-precipitation [kg/m^2]"},
+      /* 253 */ {"MAXUW", "U of hourly max 10m wind speed [m/s]"},
+      /* 254 */ {"MAXVW", "V of hourly max 10m wind speed [m/s]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_140[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"var128", "undefined"},
+      /* 129 */ {"var129", "undefined"},
+      /* 130 */ {"var130", "undefined"},
+      /* 131 */ {"var131", "undefined"},
+      /* 132 */ {"var132", "undefined"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"var140", "undefined"},
+      /* 141 */ {"var141", "undefined"},
+      /* 142 */ {"var142", "undefined"},
+      /* 143 */ {"var143", "undefined"},
+      /* 144 */ {"var144", "undefined"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"var146", "undefined"},
+      /* 147 */ {"var147", "undefined"},
+      /* 148 */ {"var148", "undefined"},
+      /* 149 */ {"var149", "undefined"},
+      /* 150 */ {"var150", "undefined"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"var159", "undefined"},
+      /* 160 */ {"var160", "undefined"},
+      /* 161 */ {"var161", "undefined"},
+      /* 162 */ {"var162", "undefined"},
+      /* 163 */ {"var163", "undefined"},
+      /* 164 */ {"var164", "undefined"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"var166", "undefined"},
+      /* 167 */ {"var167", "undefined"},
+      /* 168 */ {"MEIP", "Mean icing potential []"},
+      /* 169 */ {"MAIP", "Maximum icing potential []"},
+      /* 170 */ {"MECTP", "Mean in-cloud turbulence potential []"},
+      /* 171 */ {"MACTP", "Maximum in-cloud turbulence potential []"},
+      /* 172 */ {"MECAT", "Mean cloud air turbulence potential []"},
+      /* 173 */ {"MACAT", "Maximum cloud air turbulence potential []"},
+      /* 174 */ {"CBHE", "Cumulonimbus horizontal extent [%]"},
+      /* 175 */ {"PCBB", "Pressure at cumblonimbus base [Pa]"},
+      /* 176 */ {"PCBT", "Pressure at cumblonimbus top [Pa]"},
+      /* 177 */ {"PECBB", "Pressure at embedded cumblonimbus base [Pa]"},
+      /* 178 */ {"PECBT", "Pressure at embedded cumblonimbus top [Pa]"},
+      /* 179 */ {"HCBB", "ICAO height at cumblonimbus base [m]"},
+      /* 180 */ {"HCBT", "ICAO height at cumblonimbus top [m]"},
+      /* 181 */ {"HECBB", "ICAO height at embedded cumblonimbus base [m]"},
+      /* 182 */ {"HECBT", "ICAO height at embedded cumblonimbus top [m]"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"var186", "undefined"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"var188", "undefined"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"var200", "undefined"},
+      /* 201 */ {"var201", "undefined"},
+      /* 202 */ {"var202", "undefined"},
+      /* 203 */ {"var203", "undefined"},
+      /* 204 */ {"var204", "undefined"},
+      /* 205 */ {"var205", "undefined"},
+      /* 206 */ {"var206", "undefined"},
+      /* 207 */ {"var207", "undefined"},
+      /* 208 */ {"var208", "undefined"},
+      /* 209 */ {"var209", "undefined"},
+      /* 210 */ {"var210", "undefined"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"var216", "undefined"},
+      /* 217 */ {"var217", "undefined"},
+      /* 218 */ {"var218", "undefined"},
+      /* 219 */ {"var219", "undefined"},
+      /* 220 */ {"var220", "undefined"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"var222", "undefined"},
+      /* 223 */ {"var223", "undefined"},
+      /* 224 */ {"var224", "undefined"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"var228", "undefined"},
+      /* 229 */ {"var229", "undefined"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"var232", "undefined"},
+      /* 233 */ {"var233", "undefined"},
+      /* 234 */ {"var234", "undefined"},
+      /* 235 */ {"var235", "undefined"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"var240", "undefined"},
+      /* 241 */ {"var241", "undefined"},
+      /* 242 */ {"var242", "undefined"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"var244", "undefined"},
+      /* 245 */ {"var245", "undefined"},
+      /* 246 */ {"var246", "undefined"},
+      /* 247 */ {"var247", "undefined"},
+      /* 248 */ {"var248", "undefined"},
+      /* 249 */ {"var249", "undefined"},
+      /* 250 */ {"var250", "undefined"},
+      /* 251 */ {"var251", "undefined"},
+      /* 252 */ {"var252", "undefined"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_nceptab_141[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"EXTNC", "Aerosol Extinction Coefficient [1/km]"},
+      /* 129 */ {"AOD", "Aerosol Optical Depth [-]"},
+      /* 130 */ {"ASFTR", "Aerosol Asymmetry Factor [-]"},
+      /* 131 */ {"SSALBD", "Aerosol Single Scatter Albedo [-]"},
+      /* 132 */ {"BSCTRS", "Aerosol Back Scattering [1/km/sr]"},
+      /* 133 */ {"var133", "undefined"},
+      /* 134 */ {"var134", "undefined"},
+      /* 135 */ {"var135", "undefined"},
+      /* 136 */ {"var136", "undefined"},
+      /* 137 */ {"var137", "undefined"},
+      /* 138 */ {"var138", "undefined"},
+      /* 139 */ {"var139", "undefined"},
+      /* 140 */ {"NOy", "Total Inorganic and Organic Nitrates [ppbV]"},
+      /* 141 */ {"NO", "Nitrogen Oxide [ppbV]"},
+      /* 142 */ {"NO2", "Nitrogen Dioxide [ppbV]"},
+      /* 143 */ {"N2O5", "Nitrogen Pentoxide [ppbV]"},
+      /* 144 */ {"HNO3", "Nitric Acid [ppbV]"},
+      /* 145 */ {"NO3", "Nitrogen Trioxide [ppbV]"},
+      /* 146 */ {"PNA", "Peroxynitric Acid [ppbV]"},
+      /* 147 */ {"HONO", "Nitrous Acid [ppbV]"},
+      /* 148 */ {"CO", "Carbon Monoxide [ppbV]"},
+      /* 149 */ {"NH3", "Ammonia [ppbV]"},
+      /* 150 */ {"HCL", "Hydrogen Chloride [ppbV]"},
+      /* 151 */ {"var151", "undefined"},
+      /* 152 */ {"var152", "undefined"},
+      /* 153 */ {"var153", "undefined"},
+      /* 154 */ {"var154", "undefined"},
+      /* 155 */ {"var155", "undefined"},
+      /* 156 */ {"var156", "undefined"},
+      /* 157 */ {"var157", "undefined"},
+      /* 158 */ {"var158", "undefined"},
+      /* 159 */ {"PAR", "Lumped Single-Bond Carbon Specie [ppbV]"},
+      /* 160 */ {"ETHE", "Ethene [ppbV]"},
+      /* 161 */ {"OLE", "Lumped Double-Bond Carbon Species Less Ethene [ppbV]"},
+      /* 162 */ {"TOL", "Toluene [ppbV]"},
+      /* 163 */ {"XYL", "Xylene [ppbV]"},
+      /* 164 */ {"ISOP", "Isoprene [ppbV]"},
+      /* 165 */ {"var165", "undefined"},
+      /* 166 */ {"FORM", "Formaldehyde [ppbV]"},
+      /* 167 */ {"ALD2", "Acetaldehyde & Higher Aldehydes [ppbV]"},
+      /* 168 */ {"MGLY", "Methyl Glyoxal [ppbV]"},
+      /* 169 */ {"CRES", "Cresol and Higher Molecular Weight Phenols [ppbV]"},
+      /* 170 */ {"var170", "undefined"},
+      /* 171 */ {"var171", "undefined"},
+      /* 172 */ {"PAN", "Peroxyacyl Nitrate [ppbV]"},
+      /* 173 */ {"NTR", "Lumped Gaseous Organic Nitrate [ppbV]"},
+      /* 174 */ {"var174", "undefined"},
+      /* 175 */ {"var175", "undefined"},
+      /* 176 */ {"var176", "undefined"},
+      /* 177 */ {"ROOH", "Esters [ppbV]"},
+      /* 178 */ {"ETHOH", "Ethanol [ppbV]"},
+      /* 179 */ {"METHOH", "Methanol [ppbV]"},
+      /* 180 */ {"var180", "undefined"},
+      /* 181 */ {"var181", "undefined"},
+      /* 182 */ {"var182", "undefined"},
+      /* 183 */ {"var183", "undefined"},
+      /* 184 */ {"var184", "undefined"},
+      /* 185 */ {"var185", "undefined"},
+      /* 186 */ {"H2O2", "Hydrogen Peroxide [ppbV]"},
+      /* 187 */ {"OH", "Hydroxyl Radical [ppbV]"},
+      /* 188 */ {"HO2", "Hydroperoxyl Radical [ppbV]"},
+      /* 189 */ {"var189", "undefined"},
+      /* 190 */ {"var190", "undefined"},
+      /* 191 */ {"var191", "undefined"},
+      /* 192 */ {"var192", "undefined"},
+      /* 193 */ {"var193", "undefined"},
+      /* 194 */ {"var194", "undefined"},
+      /* 195 */ {"var195", "undefined"},
+      /* 196 */ {"var196", "undefined"},
+      /* 197 */ {"var197", "undefined"},
+      /* 198 */ {"var198", "undefined"},
+      /* 199 */ {"var199", "undefined"},
+      /* 200 */ {"ASO4", "Sulfate (SO4) Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 201 */ {"ANH4", "Ammonia (NH4) Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 202 */ {"ANO3", "Nitrate (NO3) Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 203 */ {"AORGA", "Organic Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 204 */ {"AORGPA", "Primarily Organic Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 205 */ {"AORGB", "Biogenically Originated Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 206 */ {"AEC", "Elemental Carbon Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 207 */ {"A25", "Unspecified Anthropogenic Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 208 */ {"AH2O", "Water Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 209 */ {"ANA", "Sodium Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 210 */ {"ACL", "Chloride Particulates ≤ 2.5 μm Diameter [μg/m^3]"},
+      /* 211 */ {"var211", "undefined"},
+      /* 212 */ {"var212", "undefined"},
+      /* 213 */ {"var213", "undefined"},
+      /* 214 */ {"var214", "undefined"},
+      /* 215 */ {"var215", "undefined"},
+      /* 216 */ {"ASO4K", "Sulfate (SO4) Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 217 */ {"ANAK", "Sodium (NA) Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 218 */ {"ACLK", "Chloride (CL) Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 219 */ {"ASEAS", "Sea Salt Originated Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 220 */ {"ASOIL", "Crustal Material Orginated Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 221 */ {"ACORS", "Particulates between 2.5 and 10 μm Diameter [μg/m^3]"},
+      /* 222 */ {"NUMATKN", "Number Concentration Particulates between 2.5 and 0.1 μm Diameter [number/m^3]"},
+      /* 223 */ {"NUMACC", "Number Concentration Particulates between 2.5 and 2.5 μm Diameter [number/m^3]"},
+      /* 224 */ {"NUMCOR", "Number Concentration Particulates between 2.5 and 10 μm Diameter [number/m^3]"},
+      /* 225 */ {"var225", "undefined"},
+      /* 226 */ {"var226", "undefined"},
+      /* 227 */ {"var227", "undefined"},
+      /* 228 */ {"SRFATKN", "Surface Area Contributed by Particulates ≤ 0.1 μm Diameter [m2/m^3]"},
+      /* 229 */ {"SRFACC", "Surface Area Contributed by Particulates between 0.1 and 2.5 μm Diameter [m2/m^3]"},
+      /* 230 */ {"var230", "undefined"},
+      /* 231 */ {"var231", "undefined"},
+      /* 232 */ {"SO2", "Sulfur Dioxide [ppbV]"},
+      /* 233 */ {"MSA", "Methanesulfonic Acid [Kg/Kg]"},
+      /* 234 */ {"TSO4", "Total Sulfate Particulates (Fine ands Coarse) [μg/m^3]"},
+      /* 235 */ {"DMS", "Dimethylsulfide [Kg/Kg]"},
+      /* 236 */ {"var236", "undefined"},
+      /* 237 */ {"var237", "undefined"},
+      /* 238 */ {"var238", "undefined"},
+      /* 239 */ {"var239", "undefined"},
+      /* 240 */ {"DU1", "Dust Particulates between 0.2 - 2.0 μm Diameter [Kg/Kg]"},
+      /* 241 */ {"DU2", "Dust Particulates between 2.0 - 3.6 μm Diameter [Kg/Kg]"},
+      /* 242 */ {"DU3", "Dust Particulates between 3.6 - 6.0 μm Diameter [Kg/Kg]"},
+      /* 243 */ {"DU4", "Dust Particulates between 6.0 - 12.0 μm Diameter [Kg/Kg]"},
+      /* 244 */ {"DU5", "Dust Particulates between 12.0 - 20.0 μm Diameter [Kg/Kg]"},
+      /* 245 */ {"SS1", "Sea Salt Particulates between 0.2 - 1.0 μm Diameter [Kg/Kg]"},
+      /* 246 */ {"SS2", "Sea Salt Particulates between 1.0 - 3.0 μm Diameter [Kg/Kg]"},
+      /* 247 */ {"SS3", "Sea Salt Particulates between 3.0 - 10.0 μm Diameter [Kg/Kg]"},
+      /* 248 */ {"SS4", "Sea Salt Particulates between 10.0 - 20.0 μm Diameter [Kg/Kg]"},
+      /* 249 */ {"OCDRY", "Hydrophobic Organic Carbon [Kg/Kg]"},
+      /* 250 */ {"OCWET", "Hydrophilic Organic Carbon [Kg/Kg]"},
+      /* 251 */ {"BCDRY", "Hydrophobic Black Carbon [Kg/Kg]"},
+      /* 252 */ {"BCWET", "Hydrophilic Black Carbon [Kg/Kg]"},
+      /* 253 */ {"var253", "undefined"},
+      /* 254 */ {"var254", "undefined"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_mdl_nceptab[256] = {
+      /* 0 */ {"var0", "undefined"},
+      /* 1 */ {"PRES", "Pressure [Pa]"},
+      /* 2 */ {"PRMSL", "Pressure reduced to MSL [Pa]"},
+      /* 3 */ {"PTEND", "Pressure tendency [Pa/s]"},
+      /* 4 */ {"PVORT", "Pot. vorticity [km^2/kg/s]"},
+      /* 5 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height [M]"},
+      /* 6 */ {"GP", "Geopotential [m^2/s^2]"},
+      /* 7 */ {"HGT", "Geopotential height [gpm]"},
+      /* 8 */ {"DIST", "Geometric height [m]"},
+      /* 9 */ {"HSTDV", "Std dev of height [m]"},
+      /* 10 */ {"TOZNE", "Total ozone [Dobson]"},
+      /* 11 */ {"TMP", "Temp. [K]"},
+      /* 12 */ {"VTMP", "Virtual temp. [K]"},
+      /* 13 */ {"POT", "Potential temp. [K]"},
+      /* 14 */ {"EPOT", "Pseudo-adiabatic pot. temp. [K]"},
+      /* 15 */ {"TMAX", "Max. temp. [K]"},
+      /* 16 */ {"TMIN", "Min. temp. [K]"},
+      /* 17 */ {"DPT", "Dew point temp. [K]"},
+      /* 18 */ {"DEPR", "Dew point depression [K]"},
+      /* 19 */ {"LAPR", "Lapse rate [K/m]"},
+      /* 20 */ {"VIS", "Visibility [m]"},
+      /* 21 */ {"RDSP1", "Radar spectra (1) [non-dim]"},
+      /* 22 */ {"RDSP2", "Radar spectra (2) [non-dim]"},
+      /* 23 */ {"RDSP3", "Radar spectra (3) [non-dim]"},
+      /* 24 */ {"PLI", "Parcel lifted index (to 500 hPa) [K]"},
+      /* 25 */ {"TMPA", "Temp. anomaly [K]"},
+      /* 26 */ {"PRESA", "Pressure anomaly [Pa]"},
+      /* 27 */ {"GPA", "Geopotential height anomaly [gpm]"},
+      /* 28 */ {"WVSP1", "Wave spectra (1) [non-dim]"},
+      /* 29 */ {"WVSP2", "Wave spectra (2) [non-dim]"},
+      /* 30 */ {"WVSP3", "Wave spectra (3) [non-dim]"},
+      /* 31 */ {"WDIR", "Wind direction [deg]"},
+      /* 32 */ {"WIND", "Wind speed [m/s]"},
+      /* 33 */ {"UGRD", "u wind [m/s]"},
+      /* 34 */ {"VGRD", "v wind [m/s]"},
+      /* 35 */ {"STRM", "Stream function [m^2/s]"},
+      /* 36 */ {"VPOT", "Velocity potential [m^2/s]"},
+      /* 37 */ {"MNTSF", "Montgomery stream function [m^2/s^2]"},
+      /* 38 */ {"SGCVV", "Sigma coord. vertical velocity [/s]"},
+      /* 39 */ {"VVEL", "Pressure vertical velocity [Pa/s]"},
+      /* 40 */ {"DZDT", "Geometric vertical velocity [m/s]"},
+      /* 41 */ {"ABSV", "Absolute vorticity [/s]"},
+      /* 42 */ {"ABSD", "Absolute divergence [/s]"},
+      /* 43 */ {"RELV", "Relative vorticity [/s]"},
+      /* 44 */ {"RELD", "Relative divergence [/s]"},
+      /* 45 */ {"VUCSH", "Vertical u shear [/s]"},
+      /* 46 */ {"VVCSH", "Vertical v shear [/s]"},
+      /* 47 */ {"DIRC", "Direction of current [deg]"},
+      /* 48 */ {"SPC", "Speed of current [m/s]"},
+      /* 49 */ {"UOGRD", "u of current [m/s]"},
+      /* 50 */ {"VOGRD", "v of current [m/s]"},
+      /* 51 */ {"SPFH", "Specific humidity [kg/kg]"},
+      /* 52 */ {"RH", "Relative humidity [%]"},
+      /* 53 */ {"MIXR", "Humidity mixing ratio [kg/kg]"},
+      /* 54 */ {"PWAT", "Precipitable water [kg/m^2]"},
+      /* 55 */ {"VAPP", "Vapor pressure [Pa]"},
+      /* 56 */ {"SATD", "Saturation deficit [Pa]"},
+      /* 57 */ {"EVP", "Evaporation [kg/m^2]"},
+      /* 58 */ {"CICE", "Cloud Ice [kg/m^2]"},
+      /* 59 */ {"PRATE", "Precipitation rate [kg/m^2/s]"},
+      /* 60 */ {"TSTM", "Thunderstorm probability [%]"},
+      /* 61 */ {"APCP", "Total precipitation [kg/m^2]"},
+      /* 62 */ {"NCPCP", "Large scale precipitation [kg/m^2]"},
+      /* 63 */ {"ACPCP", "Convective precipitation [kg/m^2]"},
+      /* 64 */ {"SRWEQ", "Snowfall rate water equiv. [kg/m^2/s]"},
+      /* 65 */ {"WEASD", "Accum. snow [kg/m^2]"},
+      /* 66 */ {"SNOD", "Snow depth [m]"},
+      /* 67 */ {"MIXHT", "Mixed layer depth [m]"},
+      /* 68 */ {"TTHDP", "Transient thermocline depth [m]"},
+      /* 69 */ {"MTHD", "Main thermocline depth [m]"},
+      /* 70 */ {"MTHA", "Main thermocline anomaly [m]"},
+      /* 71 */ {"TCDC", "Total cloud cover [%]"},
+      /* 72 */ {"CDCON", "Convective cloud cover [%]"},
+      /* 73 */ {"LCDC", "Low level cloud cover [%]"},
+      /* 74 */ {"MCDC", "Mid level cloud cover [%]"},
+      /* 75 */ {"HCDC", "High level cloud cover [%]"},
+      /* 76 */ {"CWAT", "Cloud water [kg/m^2]"},
+      /* 77 */ {"BLI", "Best lifted index (to 500 hPa) [K]"},
+      /* 78 */ {"SNOC", "Convective snow [kg/m^2]"},
+      /* 79 */ {"SNOL", "Large scale snow [kg/m^2]"},
+      /* 80 */ {"WTMP", "Water temp. [K]"},
+      /* 81 */ {"LAND", "Land cover (land=1;sea=0) [fraction]"},
+      /* 82 */ {"DSLM", "Deviation of sea level from mean [m]"},
+      /* 83 */ {"SFCR", "Surface roughness [m]"},
+      /* 84 */ {"ALBDO", "Albedo [%]"},
+      /* 85 */ {"TSOIL", "Soil temp. [K]"},
+      /* 86 */ {"SOILM", "Soil moisture content [kg/m^2]"},
+      /* 87 */ {"VEG", "Vegetation [%]"},
+      /* 88 */ {"SALTY", "Salinity [kg/kg]"},
+      /* 89 */ {"DEN", "Density [kg/m^3]"},
+      /* 90 */ {"WATR", "Water runoff [kg/m^2]"},
+      /* 91 */ {"ICEC", "Ice concentration (ice=1;no ice=0) [fraction]"},
+      /* 92 */ {"ICETK", "Ice thickness [m]"},
+      /* 93 */ {"DICED", "Direction of ice drift [deg]"},
+      /* 94 */ {"SICED", "Speed of ice drift [m/s]"},
+      /* 95 */ {"UICE", "u of ice drift [m/s]"},
+      /* 96 */ {"VICE", "v of ice drift [m/s]"},
+      /* 97 */ {"ICEG", "Ice growth rate [m/s]"},
+      /* 98 */ {"ICED", "Ice divergence [/s]"},
+      /* 99 */ {"SNOM", "Snow melt [kg/m^2]"},
+      /* 100 */ {"HTSGW", "Sig height of wind waves and swell [m]"},
+      /* 101 */ {"WVDIR", "Direction of wind waves [deg]"},
+      /* 102 */ {"WVHGT", "Sig height of wind waves [m]"},
+      /* 103 */ {"WVPER", "Mean period of wind waves [s]"},
+      /* 104 */ {"SWDIR", "Direction of swell waves [deg]"},
+      /* 105 */ {"SWELL", "Sig height of swell waves [m]"},
+      /* 106 */ {"SWPER", "Mean period of swell waves [s]"},
+      /* 107 */ {"DIRPW", "Primary wave direction [deg]"},
+      /* 108 */ {"PERPW", "Primary wave mean period [s]"},
+      /* 109 */ {"DIRSW", "Secondary wave direction [deg]"},
+      /* 110 */ {"PERSW", "Secondary wave mean period [s]"},
+      /* 111 */ {"NSWRS", "Net short wave (surface) [W/m^2]"},
+      /* 112 */ {"NLWRS", "Net long wave (surface) [W/m^2]"},
+      /* 113 */ {"NSWRT", "Net short wave (top) [W/m^2]"},
+      /* 114 */ {"NLWRT", "Net long wave (top) [W/m^2]"},
+      /* 115 */ {"LWAVR", "Long wave [W/m^2]"},
+      /* 116 */ {"SWAVR", "Short wave [W/m^2]"},
+      /* 117 */ {"GRAD", "Global radiation [W/m^2]"},
+      /* 118 */ {"BRTMP", "Brightness temperature [K]"},
+      /* 119 */ {"LWRAD", "Radiance with respect to wave no. [W/m/sr]"},
+      /* 120 */ {"SWRAD", "Radiance with respect ot wave len. [W/m^3/sr]"},
+      /* 121 */ {"LHTFL", "Latent heat flux [W/m^2]"},
+      /* 122 */ {"SHTFL", "Sensible heat flux [W/m^2]"},
+      /* 123 */ {"BLYDP", "Boundary layer dissipation [W/m^2]"},
+      /* 124 */ {"UFLX", "Zonal momentum flux [N/m^2]"},
+      /* 125 */ {"VFLX", "Meridional momentum flux [N/m^2]"},
+      /* 126 */ {"WMIXE", "Wind mixing energy [J]"},
+      /* 127 */ {"IMGD", "Image data []"},
+      /* 128 */ {"TMPF", "TEMPERATURE (Fahrenheit) [F]"},
+      /* 129 */ {"MAXK", "DAYTIME MAX TEMP (MAX) (Kelvin) [K]"},
+      /* 130 */ {"MAXF", "DAYTIME MAX TEMP (MAX) (deg F) [F]"},
+      /* 131 */ {"NMAXK", "NORMAL MAX TEMPERATURE (Kelvin) [K]"},
+      /* 132 */ {"NMAXF", "NORMAL MAX TEMPERATURE (deg F) [F]"},
+      /* 133 */ {"DMAXK", "DEPARTURE FROM NORMAL MAX (K) [K]"},
+      /* 134 */ {"DMAXF", "DEPARTURE FROM NORMAL MAX (deg F) [F]"},
+      /* 135 */ {"MINK", "NIGHTTIME MIN TEMP (MIN) (Kelvin) [K]"},
+      /* 136 */ {"MINF", "NIGHTTIME MIN TEMP (MIN) (deg F) [F]"},
+      /* 137 */ {"NMINK", "NORMAL MIN TEMPERATURE (Kelvin) [K]"},
+      /* 138 */ {"NMINF", "NORMAL NIGHTTIME MIN TEMP (deg F) [F]"},
+      /* 139 */ {"DMINK", "DEPARTURE FROM NORMAL MIN (K) [K]"},
+      /* 140 */ {"DMINF", "DEPARTURE FROM NORMAL MIN (deg F) [F]"},
+      /* 141 */ {"DWPF", "DEW POINT TEMPERATURE (deg F) [F]"},
+      /* 142 */ {"DPDF", "DEW POINT DEPRESSION (deg F) [F]"},
+      /* 143 */ {"HTINF", "HEAT INDEX (deg F) [F]"},
+      /* 144 */ {"WNCHF", "WIND CHILL (deg F) [F]"},
+      /* 145 */ {"var145", "undefined"},
+      /* 146 */ {"POP", "PROB OF 0.01 IN. OF PRECIP (PoP) [%]"},
+      /* 147 */ {"PQPF2", "PROB OF QPF >= 0.10 INCHES [%]"},
+      /* 148 */ {"PQPF3", "PROB OF QPF >= 0.25 INCHES [%]"},
+      /* 149 */ {"PQPF4", "PROB OF QPF >= 0.50 INCHES [%]"},
+      /* 150 */ {"PQPF5", "PROB OF QPF >= 1.00 INCHES [%]"},
+      /* 151 */ {"PQPF6", "PROB OF QPF >= 2.00 INCHES [%]"},
+      /* 152 */ {"PQPF7", "PROB OF QPF >= 3.00 INCHES FUTURE [%]"},
+      /* 153 */ {"BQPF", "BEST CATEGORY OF QPF [num]"},
+      /* 154 */ {"NPOP", "NML REL. FREQ. OF 0.01 IN OF PCP [%]"},
+      /* 155 */ {"DPOP", "DEPARTURE FROM NML OF 0.01 POP [%]"},
+      /* 156 */ {"PCPM", "EXPECTED VALUE OF PRECIPITATION [mm]"},
+      /* 157 */ {"PCPI", "EXPECTED VALUE OF PRECIPITATION [in]"},
+      /* 158 */ {"CPCPM", "CONDITIONAL EXPECTED PRECIP AMT [mm]"},
+      /* 159 */ {"CPCPI", "CONDITIONAL EXPECTED PRECIP AMT [in]"},
+      /* 160 */ {"PSNA1", "PROB OF SNOW AMOUNT >= 0.10 [%]"},
+      /* 161 */ {"PSNA2", "PROB OF SNOW AMOUNT >= 2 INCHES [%]"},
+      /* 162 */ {"PSNA3", "PROB OF SNOW AMOUNT >= 4 INCHES [%]"},
+      /* 163 */ {"PSNA4", "PROB OF SNOW AMOUNT >= 6 INCHES [%]"},
+      /* 164 */ {"PSNA5", "PROB OF SNOW AMOUNT >= 8 INCHES [%]"},
+      /* 165 */ {"BSNA", "BEST CATEGORY FOR SNOW AMOUNT [num]"},
+      /* 166 */ {"SNWM", "EXPECTED VALUE OF SNOW AMOUNT [mm]"},
+      /* 167 */ {"SNWI", "EXPECTED VALUE OF SNOW AMOUNT [in]"},
+      /* 168 */ {"MWSPK", "INFLATED MAX WIND SPEED (knots) [kts]"},
+      /* 169 */ {"IWSPM", "INFLATED WIND SPEED (meter/sec) [m/s]"},
+      /* 170 */ {"SKNT", "INFLATED WIND SPEED (knots) [kts]"},
+      /* 171 */ {"PWSP1", "PROB OF MAX WIND SPEED 0-12 kts [%]"},
+      /* 172 */ {"PWSP2", "PROB OF MAX WIND SPEED 13-21 kts [%]"},
+      /* 173 */ {"PWSP3", "PROB OF MAX WIND SPEED 22-31 kts [%]"},
+      /* 174 */ {"PWSP4", "PROB OF MAX WIND SPEED >=32 kts [%]"},
+      /* 175 */ {"WSPDC", "CATEGORICAL MAX WIND SPEED [num]"},
+      /* 176 */ {"XSPDM", "EXPECTED VALUE OF MAX WIND SPEED [m/s]"},
+      /* 177 */ {"XSPDK", "EXPECTED VALUE OF MAX WIND SPEED [kts]"},
+      /* 178 */ {"PWDRN", "PROB OF WIND DIRECTION NORTH [%]"},
+      /* 179 */ {"PWDRNE", "PROB OF WIND DIRECTION NORTHEAST [%]"},
+      /* 180 */ {"PWDRE", "PROB OF WIND DIRECTION EAST [%]"},
+      /* 181 */ {"PWDRSE", "PROB OF WIND DIRECTION SOUTHEAST [%]"},
+      /* 182 */ {"PWDRS", "PROB OF WIND DIRECTION SOUTH [%]"},
+      /* 183 */ {"PWDRSW", "PROB OF WIND DIRECTION SOUTHWEST [%]"},
+      /* 184 */ {"PWDRW", "PROB OF WIND DIRECTION WEST [%]"},
+      /* 185 */ {"PWDRNW", "PROB OF WIND DIRECTION NORTHWEST [%]"},
+      /* 186 */ {"WDIRC", "CATEGORICAL WIND DIRECTION [num]"},
+      /* 187 */ {"var187", "undefined"},
+      /* 188 */ {"PSKCL", "PROB OF TOTAL SKY"},
+      /* 189 */ {"PSKFW", "PROB OF TOTAL SKY"},
+      /* 190 */ {"PSKSC", "PROB OF TOTAL SKY"},
+      /* 191 */ {"PSKBK", "PROB OF TOTAL SKY"},
+      /* 192 */ {"PSKOV", "PROB OF TOTAL SKY"},
+      /* 193 */ {"SKYC", "CATEGORICAL TOTAL SKY COVER [num]"},
+      /* 194 */ {"MSKCL", "PROB MEAN SKY CVR"},
+      /* 195 */ {"MSKOV", "PROB MEAN SKY CVR"},
+      /* 196 */ {"MSKMC", "PROB MEAN SKY CVR"},
+      /* 197 */ {"MSKPC", "PROB MEAN SKY CVR"},
+      /* 198 */ {"MSKMO", "PROB MEAN SKY CVR"},
+      /* 199 */ {"MSKYC", "CATEGORICAL MEAN SKY COVER [num]"},
+      /* 200 */ {"PCIG1", "PROB OF CIG HGT < 200 FT [%]"},
+      /* 201 */ {"PCIG2", "PROB OF CIG HGT 200-400 FT [%]"},
+      /* 202 */ {"PCIG3", "PROB OF CIG HGT 500-900 FT [%]"},
+      /* 203 */ {"PCIG4", "PROB OF CIG HGT 1000-3000 FT [%]"},
+      /* 204 */ {"PCIG5", "PROB OF CIG HGT 3100-6500 FT [%]"},
+      /* 205 */ {"PCIG6", "PROB OF CIG HGT 6600-12000 FT [%]"},
+      /* 206 */ {"PCIG7", "PROB OF CIG HGT > 12000 FT [%]"},
+      /* 207 */ {"BCIG", "BEST CATEGORY OF CEILING HEIGHT [num]"},
+      /* 208 */ {"PVIS1", "PROB OF VIS <=1/4 MILE [%]"},
+      /* 209 */ {"PVIS2", "PROB OF VIS <=1/2 MILE [%]"},
+      /* 210 */ {"PVIS3", "PROB OF VIS <=7/8 MILE [%]"},
+      /* 211 */ {"PVIS4", "PROB OF VIS <=2 3/4 MILES [%]"},
+      /* 212 */ {"PVIS5", "PROB OF VIS <=5 MILES [%]"},
+      /* 213 */ {"PVIS6", "PROB OF VIS <=6 MILES [%]"},
+      /* 214 */ {"VISC", "CATEGORICAL VISIBILITY [num]"},
+      /* 215 */ {"POBVN", "PROB OF OBSTRUCTION TO VIS"},
+      /* 216 */ {"POBVH", "PROB OF OBSTRUCTION TO VIS"},
+      /* 217 */ {"POBVM", "PROB OF OBSTRUCTION TO VIS"},
+      /* 218 */ {"POBVF", "PROB OF OBSTRUCTION TO VIS"},
+      /* 219 */ {"POVBL", "PROB OF BLOWING OBVIS [%]"},
+      /* 220 */ {"OBVC", "BEST CATEGORY OF OBVIS [num]"},
+      /* 221 */ {"var221", "undefined"},
+      /* 222 */ {"NTSM", "NORMAL PROB OF THUNDERSTORMS [%]"},
+      /* 223 */ {"CSVR", "COND PROB OF SEVERE WEATHER [%]"},
+      /* 224 */ {"USVR", "UNCOND PROB OF SEVERE WX [%]"},
+      /* 225 */ {"NSVR", "NORMAL PROB OF SEVERE WX [%]"},
+      /* 226 */ {"UHAI", "UNCONDITIONAL PROB OF HAIL [%]"},
+      /* 227 */ {"UTOR", "UNCONDITIONAL PROB OF TORNADO [%]"},
+      /* 228 */ {"UTSW", "UNCOND PROB OF DAMAGING WIND [%]"},
+      /* 229 */ {"CFZI", "COND PROB FRZING PRECIP (INSTANT) [%]"},
+      /* 230 */ {"UFZI", "UNCND PROB FRZING PRECIP (INSTNT) [%]"},
+      /* 231 */ {"CZNI", "COND PROB FROZEN PRECIP (INSTANT) [%]"},
+      /* 232 */ {"UZNI", "UNCND PROB FROZEN PRECIP (INSTNT) [%]"},
+      /* 233 */ {"CLQI", "COND PROB LIQUID PRECIP (INSTANT) [%]"},
+      /* 234 */ {"ULQI", "UNCND PROB LIQUID PRECIP (INSTNT) [%]"},
+      /* 235 */ {"PTYPI", "CATEGORICAL PRECIP TYPE (INSTANT) [num]"},
+      /* 236 */ {"CPOZP", "COND PROB OF FRZING PRECIP [%]"},
+      /* 237 */ {"UPOZP", "UNCOND PROB OF FRZING PRECIP [%]"},
+      /* 238 */ {"CPOS", "COND PROB OF SNOW (CPoS) [%]"},
+      /* 239 */ {"UPOS", "UNCOND PROB OF SNOW (CPoS) [%]"},
+      /* 240 */ {"CPORS", "COND PROB OF RAIN/SNOW MIXED [%]"},
+      /* 241 */ {"UPORS", "UNCOND PROB OF RAIN/SNOW MIXED [%]"},
+      /* 242 */ {"CPORA", "COND PROB OF RAIN [%]"},
+      /* 243 */ {"var243", "undefined"},
+      /* 244 */ {"BPCPT", "BEST CATEGORY OF PRECIP TYPE [num]"},
+      /* 245 */ {"POPOH", "POPO PRECIP OCCURRING AT AN HOUR [%]"},
+      /* 246 */ {"POPOP", "POPO PRECIP DURING A PERIOD [%]"},
+      /* 247 */ {"CPDRZ", "COND PROB OF DRIZZLE [%]"},
+      /* 248 */ {"CPSTY", "COND PROB OF CONT (STEADY) PRECIP [%]"},
+      /* 249 */ {"CPSHW", "COND PROB OF SHOWERS [%]"},
+      /* 250 */ {"BPCHR", "BEST CAT PRECIP CHARACTERISTIC [num]"},
+      /* 251 */ {"SUNSH", "PERCENT OF POSSIBLE SUNSHINE [%]"},
+      /* 252 */ {"HRSUN", "HOURS OF SUNSHINE [hrs]"},
+      /* 253 */ {"SCQP", "SCAN 0-3H CATEGORICAL QPF [num]"},
+      /* 254 */ {"SCTS", "SCAN 0-3H C-G LIGHTNING PROB [%]"},
+      /* 255 */ {"var255", "undefined"},
+};
+
+
+/*
+ * EC_ext	v1.0 wesley ebisuzaki
+ *
+ * prints something readable from the EC stream parameter
+ *
+ * prefix and suffix are only printed if EC_ext has text
+ */
+
+void EC_ext(unsigned char *pds, char *prefix, char *suffix, int verbose) {
+
+    int local_id, ec_type, ec_class, ec_stream;
+    char string[200];
+
+    if (PDS_Center(pds) != ECMWF) return;
+
+    local_id = PDS_EcLocalId(pds);
+    if (local_id  == 0) return;
+    ec_class = PDS_EcClass(pds);
+    ec_type = PDS_EcType(pds);
+    ec_stream = PDS_EcStream(pds);
+
+    if (verbose == 2) printf("%sECext=%d%s", prefix, local_id, suffix);
+
+    if (verbose == 2) {
+	switch(ec_class) {
+	    case 1: strcpy(string, "operations"); break;
+	    case 2: strcpy(string, "research"); break;
+	    case 3: strcpy(string, "ERA-15"); break;
+	    case 4: strcpy(string, "Euro clim support network"); break;
+	    case 5: strcpy(string, "ERA-40"); break;
+	    case 6: strcpy(string, "DEMETER"); break;
+	    case 7: strcpy(string, "PROVOST"); break;
+	    case 8: strcpy(string, "ELDAS"); break;
+	     default: sprintf(string, "%d", ec_class); break;
+	}
+        printf("%sclass=%s%s",prefix,string,suffix);
+    }
+    /*
+     10/03/2000: R.Rudsar : subroutine changed.
+                 Tests for EcType and extra test for EcStream 1035
+    */
+
+
+/*    if (verbose == 2) { */
+        switch(ec_type) {
+            case 1: strcpy(string, "first guess"); break;
+            case 2: strcpy(string, "analysis"); break;
+            case 3: strcpy(string, "init analysis"); break;
+            case 4: strcpy(string, "OI analysis"); break;
+            /* case 10: strcpy(string, "Control forecast"); break; */
+            case 10: sprintf(string, "Control forecast %d",PDS_EcFcstNo(pds)); 
+		break;
+            case 11: 
+		if (ec_stream == 1035) 
+              	   sprintf(string, "Perturbed forecast %d",
+                   PDS_EcFcstNo(pds)); 
+		else
+		    strcpy(string, "Perturbed forecasts"); break;
+		break;
+            case 14: strcpy(string, "Cluster means"); break;
+            case 15: strcpy(string, "Cluster std. dev."); break;
+            case 16: strcpy(string, "Forecast probability"); break;
+            case 17: strcpy(string, "Ensemble means"); break;
+            case 18: strcpy(string, "Ensemble std. dev."); break;
+    	    case 20: strcpy(string, "Climatology"); break;
+            case 21: strcpy(string, "Climatology simulation"); break;
+            case 80: strcpy(string, "Fcst seasonal mean"); break;
+            default: sprintf(string, "%d", ec_type); break;
+        }
+        printf("%stype=%s%s",prefix,string,suffix);
+/*    }  */
+    if (verbose == 2) {
+        switch(ec_stream) {
+	    case 1035: strcpy(string, "ensemble forecasts"); break;
+	    case 1043: strcpy(string, "mon mean"); break;
+	    case 1070: strcpy(string, "mon (co)var"); break;
+	    case 1071: strcpy(string, "mon mean from daily"); break;
+	    case 1090: strcpy(string, "EC ensemble fcsts"); break;
+	    case 1091: strcpy(string, "EC seasonal fcst mon means"); break;
+	    default:   sprintf(string, "%d", ec_stream); break;
+        }
+        printf("%sstream=%s%s",prefix,string,suffix);
+    }
+    if (verbose == 2) {
+        printf("%sVersion=%c%c%c%c%s", prefix, *(PDS_Ec16Version(pds)), *(PDS_Ec16Version(pds)+1),
+		*(PDS_Ec16Version(pds)+2), *(PDS_Ec16Version(pds)+3), suffix);
+        if (local_id == 16) {
+	    printf("%sSysVersion=%d%s", prefix, PDS_Ec16SysNum(pds), suffix);
+	    printf("%sAvgPeriod=%d%s", prefix, PDS_Ec16AvePeriod(pds), suffix);
+	    printf("%sFcstMon=%d%s", prefix, PDS_Ec16FcstMon(pds), suffix);
+
+        }
+    }
+
+        if (local_id == 16) {
+	    printf("%sEnsem_mem=%d%s", prefix, PDS_Ec16Number(pds), suffix);
+	    printf("%sVerfDate=%d%s", prefix, PDS_Ec16VerfMon(pds), suffix);
+        }
+
+}
+
+/*
+ * get grid size from GDS
+ *
+ * added calculation of nxny of spectral data and clean up of triangular
+ * grid nnxny calculation     l. kornblueh 
+ * 7/25/03 wind fix Dusan Jovic
+ * 9/17/03 fix scan mode
+ */
+extern int ec_large_grib, len_ec_bds;
+
+int GDS_grid(unsigned char *gds, unsigned char *bds, int *nx, int *ny, 
+             long int *nxny) {
+
+    int i, d, ix, iy, pl;
+    long int isum;
+
+    *nx = ix = GDS_LatLon_nx(gds);
+    *ny = iy = GDS_LatLon_ny(gds);
+    *nxny = ix * iy;
+
+    /* thin grid */
+
+    if (GDS_Gaussian(gds) || GDS_LatLon(gds)) {
+	if (ix == 65535) {
+	    *nx = -1;
+	    /* reduced grid */
+	    isum = 0;
+	    pl = GDS_PL(gds);
+	    for (i = 0; i < iy; i++) {
+		isum += gds[pl+i*2]*256 + gds[pl+i*2+1];
+	    }
+	    *nxny = isum;
+	}
+	return 0;
+    }
+    if (GDS_Triangular(gds)) {
+        i = GDS_Triangular_ni(gds);
+        d = GDS_Triangular_nd(gds);
+	*nx = *nxny = d * (i + 1) * (i + 1);
+        *ny = 1;
+	return 0;
+    }
+    if (GDS_Harmonic(gds)) {
+	if (BDS_ComplexPacking(bds)) {
+	    *nx = BDS_NValues(bds);
+	    *ny = -1;
+	}
+	else {
+        /* this code assumes j, k, m are consistent with bds */
+            *nx = *nxny = (8*(BDS_LEN(bds)-15)-BDS_UnusedBits(bds))/
+		BDS_NumBits(bds)+1;
+            if ((8*(BDS_LEN(bds)-15)-BDS_UnusedBits(bds)) % BDS_NumBits(bds)) {
+	       fprintf(stderr,"inconsistent harmonic BDS\n");
+            }
+            *ny = 1;
+	}
+    }
+    return 0;
+}
+
+#define NCOL 15
+void GDS_prt_thin_lon(unsigned char *gds) {
+    int iy, i, col, pl;
+
+    iy = GDS_LatLon_ny(gds);
+    iy = (iy + 1) / 2;
+    iy = GDS_LatLon_ny(gds);
+
+    if ((pl = GDS_PL(gds)) == -1) {
+	fprintf(stderr,"\nprogram error: GDS_prt_thin\n");
+	return;
+    }
+    for (col = i = 0; i < iy; i++) {
+	if (col == 0) printf("   ");
+	printf("%5d", (gds[pl+i*2] << 8) + gds[pl+i*2+1]);
+	col++;
+	if (col == NCOL) {
+	    col = 0;
+	    printf("\n");
+	}
+    }
+    if (col != 0) printf("\n");
+}
+
+/*
+ * prints out wind rel to grid or earth
+ */
+
+static char *scan_mode[8] = {
+	"WE:NS",
+	"NS:WE",
+
+	"WE:SN",
+	"SN:WE",
+
+        "EW:NS",
+	"NS:EW",
+
+	"EW:SN",
+	"SN:EW" };
+
+
+void GDS_winds(unsigned char *gds, int verbose) {
+    int scan = -1, mode = -1;
+
+    if (gds != NULL) {
+        if (GDS_LatLon(gds)) {
+	    scan = GDS_LatLon_scan(gds);
+	    mode = GDS_LatLon_mode(gds);
+	}
+	else if (GDS_Mercator(gds)) {
+	    scan =GDS_Merc_scan(gds);
+	    mode =GDS_Merc_mode(gds);
+	}
+	/* else if (GDS_Gnomonic(gds)) { */
+	else if (GDS_Lambert(gds)) {
+	    scan = GDS_Lambert_scan(gds);
+	    mode = GDS_Lambert_mode(gds);
+	}
+	else if (GDS_Gaussian(gds)) {
+	    scan = GDS_LatLon_scan(gds);
+	    mode = GDS_LatLon_mode(gds);
+	}
+	else if (GDS_Polar(gds)) {
+	    scan = GDS_Polar_scan(gds);
+	    mode = GDS_Polar_mode(gds);
+	}
+	else if (GDS_RotLL(gds)) {
+	    scan = GDS_RotLL_scan(gds);
+	    mode = GDS_RotLL_mode(gds);
+	}
+	/* else if (GDS_Triangular(gds)) { */
+	else if (GDS_ssEgrid(gds)) {
+	    scan = GDS_ssEgrid_scan(gds);
+	    mode = GDS_ssEgrid_mode(gds);
+	}
+	else if (GDS_fEgrid(gds)) {
+	    scan = GDS_fEgrid_scan(gds);
+	    mode = GDS_fEgrid_mode(gds);
+	}
+	else if (GDS_ss2dEgrid(gds)) {
+	    scan = GDS_ss2dEgrid_scan(gds);
+	    mode = GDS_ss2dEgrid_mode(gds);
+	}
+        else if (GDS_ss2dBgrid(gds)) {
+           scan = GDS_ss2dBgrid_scan(gds);
+           mode = GDS_ss2dBgrid_mode(gds); 
+	}
+    }
+    if (verbose == 1) {
+	if (mode != -1) {
+	    if (mode & 8) printf("winds in grid direction:");
+	    else printf("winds are N/S:"); 
+	}
+    }
+    else if (verbose == 2) {
+	if (scan != -1) {
+	    printf(" scan: %s", scan_mode[(scan >> 5) & 7]);
+        }
+	if (mode != -1) {
+	    if (mode & 8) printf(" winds(grid) ");
+	    else printf(" winds(N/S) "); 
+	}
+    }
+}
+
+
+
+#define START -1
+
+static int user_center = 0, user_subcenter = 0, user_ptable = 0;
+static enum {filled, not_found, not_checked, no_file, init} status = init;
+
+struct ParmTable parm_table_user[256];
+
+/*
+ * sets up user parameter table
+ * v1.1 12/2005 w. ebisuzaki
+ * v1.2  3/2007 w. ebisuzaki add FAST_GRIBTAB option
+ */
+
+int setup_user_table(int center, int subcenter, int ptable) {
+
+    int i, j, c0, c1, c2;
+    static FILE *input;
+    static int file_open = 0;
+    char *filename, line[300];
+
+    if (status == init) {
+	for (i = 0; i < 256; i++) {
+	    parm_table_user[i].name = parm_table_user[i].comment = NULL;
+	}
+	status = not_checked;
+    }
+
+    if (status == no_file) return 0;
+
+    if ((user_center == -1 || center == user_center) &&
+	    (user_subcenter == -1 || subcenter == user_subcenter) &&
+	    (user_ptable == -1 || ptable == user_ptable)) {
+
+	if (status == filled) return 1;
+	if (status == not_found) return 0;
+    }
+
+    /* open gribtab file if not open */
+
+    if (!file_open) {
+#ifdef FAST_GRIBTAB
+        filename = getenv("GRIBTAB");
+#else
+        filename = getenv("GRIBTAB");
+        if (filename == NULL) filename = getenv("gribtab");
+        if (filename == NULL) filename = "gribtab";
+#endif
+        if (filename == NULL || (input = fopen(filename,"r")) == NULL) {
+            status = no_file;
+            return 0;
+        }
+	file_open = 1;
+    }
+    else {
+	rewind(input);
+    }
+
+    user_center = center;
+    user_subcenter = subcenter;
+    user_ptable = ptable;
+
+    /* scan for center & subcenter and ptable */
+    for (;;) {
+        if (fgets(line, 299, input) == NULL) {
+	    status = not_found;
+            return 0;
+        }
+	if (atoi(line) != START) continue;
+	i = sscanf(line,"%d:%d:%d:%d", &j, &center, &subcenter, &ptable);
+        if (i != 4) {
+	    fprintf(stderr,"illegal gribtab center/subcenter/ptable line: %s\n", line);
+            continue;
+        }
+	if ((center == -1 || center == user_center) &&
+	    (subcenter == -1 || subcenter == user_subcenter) &&
+	    (ptable == -1 || ptable == user_ptable)) break;
+    }
+
+    user_center = center;
+    user_subcenter = subcenter;
+    user_ptable = ptable;
+
+    /* free any used memory */
+    for (i = 0; i < 256; i++) {
+        if (parm_table_user[i].name != NULL) free(parm_table_user[i].name);
+        if (parm_table_user[i].comment != NULL) free(parm_table_user[i].comment);
+	parm_table_user[i].name = parm_table_user[i].comment = NULL;
+    }
+
+    /* read definitions */
+
+    for (;;) {
+        if (fgets(line, 299, input) == NULL) break;
+	if ((i = atoi(line)) == START) break;
+	line[299] = 0;
+
+	/* find the colons and end-of-line */
+	for (c0 = 0; line[c0] != ':' && line[c0] != 0; c0++) ;
+        /* skip blank lines */
+        if (line[c0] == 0) continue;
+
+	for (c1 = c0 + 1; line[c1] != ':' && line[c1] != 0; c1++) ;
+	c2 = strlen(line);
+        if (line[c2-1] == '\n') line[--c2] = '\0';
+        if (c2 <= c1) {
+	    fprintf(stderr,"illegal gribtab line:%s\n", line);
+	    continue;
+	}
+	line[c0] = 0;
+	line[c1] = 0;
+
+	parm_table_user[i].name = (char *) malloc(c1 - c0);
+	parm_table_user[i].comment = (char *) malloc(c2 - c1);
+	strcpy(parm_table_user[i].name, line+c0+1);
+	strcpy(parm_table_user[i].comment, line+c1+1);
+    }
+
+    /* now to fill in undefined blanks */
+    for (i = 0; i < 255; i++) {
+	if (parm_table_user[i].name == NULL) {
+	    parm_table_user[i].name = (char *) malloc(7);
+	    sprintf(parm_table_user[i].name, "var%d", i);
+	    parm_table_user[i].comment = (char *) malloc(strlen("undefined")+1);
+	    strcpy(parm_table_user[i].comment, "undefined");
+        }
+    }
+    status = filled;
+    return 1;
+}
+
+/*
+ * PDS_date.c  v1.2 wesley ebisuzaki
+ *
+ * prints a string with a date code
+ *
+ * PDS_date(pds,option, v_time)
+ *   options=0  .. 2 digit year
+ *   options=1  .. 4 digit year
+ *
+ *   v_time=0   .. initial time
+ *   v_time=1   .. verification time
+ *
+ * assumption: P1 and P2 are unsigned integers (not clear from doc)
+ *
+ * v1.2 years that are multiple of 400 are leap years, not 500
+ * v1.2.1  make the change to the source code for v1.2
+ * v1.2.2  add 3/6/12 hour forecast time units
+ * v1.2.3  Jan 31 + 1 month => Feb 31 .. change to Feb 28/29
+ */
+
+static int msg_count = 0;
+extern int minute;
+
+int PDS_date(unsigned char *pds, int option, int v_time) {
+
+    int year, month, day, hour, min;
+
+    if (v_time == 0) {
+        year = PDS_Year4(pds);
+        month = PDS_Month(pds);
+        day  = PDS_Day(pds);
+        hour = PDS_Hour(pds);
+    }
+    else {
+        if (verf_time(pds, &year, &month, &day, &hour) != 0) {
+	    if (msg_count++ < 5) fprintf(stderr, "PDS_date: problem\n");
+	}
+    }
+    min =  PDS_Minute(pds);
+
+    switch(option) {
+	case 0:
+	    printf("%2.2d%2.2d%2.2d%2.2d", year % 100, month, day, hour);
+	    if (minute) printf("-%2.2d", min);
+	    break;
+	case 1:
+	    printf("%4.4d%2.2d%2.2d%2.2d", year, month, day, hour);
+	    if (minute) printf("-%2.2d", min);
+	    break;
+	default:
+	    fprintf(stderr,"missing code\n");
+	    exit(8);
+    }
+    return 0;
+}
+
+#define  FEB29   (31+29)
+static int monthjday[13] = {
+        0,31,59,90,120,151,181,212,243,273,304,334,365};
+
+static int leap(int year) {
+	if (year % 4 != 0) return 0;
+	if (year % 100 != 0) return 1;
+	return (year % 400 == 0);
+}
+
+
+int add_time(int *year, int *month, int *day, int *hour, int dtime, int unit) {
+    int y, m, d, h, jday, i, days_in_month;
+
+    y = *year;
+    m = *month;
+    d = *day;
+    h = *hour;
+
+    if (unit == YEAR) {
+	*year = y + dtime;
+	return 0;
+    }
+    if (unit == DECADE) {
+	*year =  y + (10 * dtime);
+	return 0;
+    }
+    if (unit == CENTURY) {
+	*year = y + (100 * dtime);
+	return 0;
+    }
+    if (unit == NORMAL) {
+	*year = y + (30 * dtime);
+	return 0;
+    }
+    if (unit == MONTH) {
+        if (dtime < 0) {
+           i = (-dtime) / 12 + 1;
+           y -= i;
+           dtime += (i * 12);
+        }
+	dtime += (m - 1);
+	*year =  y = y + (dtime / 12);
+	*month = m = 1 + (dtime % 12);
+
+        /* check if date code if valid */
+	days_in_month = monthjday[m] - monthjday[m-1];
+	if (m == 2 && leap(y)) {
+	    days_in_month++;
+	}
+	if (days_in_month < d) *day = days_in_month;
+
+	return 0;
+    }
+
+    if (unit == SECOND) {
+	dtime /= 60;
+	unit = MINUTE;
+    }
+    if (unit == MINUTE) {
+	dtime /= 60;
+	unit = HOUR;
+    }
+
+    if (unit == HOURS3) {
+        dtime *= 3;
+        unit = HOUR;
+    }
+    else if (unit == HOURS6) {
+        dtime *= 6;
+        unit = HOUR;
+    }
+    else if (unit == HOURS12) {
+        dtime *= 12;
+        unit = HOUR;
+    }
+
+    if (unit == HOUR) {
+	dtime += h;
+
+        *hour = dtime % 24;
+        dtime = dtime / 24;
+        if (*hour < 0) {
+            *hour += 24;
+            dtime--;
+        }
+        unit = DAY;
+    }
+
+    /* this is the hard part */
+
+    if (unit == DAY) {
+	/* set m and day to Jan 0, and readjust dtime */
+	jday = d + monthjday[m-1];
+	if (leap(y) && m > 2) jday++;
+        dtime += jday;
+
+        while (dtime < 1) {
+            y--;
+	    dtime += 365 + leap(y);
+        }
+
+	/* one year chunks */
+	while (dtime > 365 + leap(y)) {
+	    dtime -= (365 + leap(y));
+	    y++;
+	}
+
+	/* calculate the month and day */
+
+	if (leap(y) && dtime == FEB29) {
+	    m = 2;
+	    d = 29;
+	}
+	else {
+	    if (leap(y) && dtime > FEB29) dtime--;
+	    for (i = 11; monthjday[i] >= dtime; --i);
+	    m = i + 1;
+	    d = dtime - monthjday[i];
+	}
+	*year = y;
+	*month = m;
+	*day = d;
+	return 0;
+   }
+   fprintf(stderr,"add_time: undefined time unit %d\n", unit);
+   return 1;
+}
+
+
+/*
+ * verf_time:
+ *
+ * this routine returns the "verification" time
+ * should have behavior similar to gribmap
+ *
+ */
+
+int verf_time(unsigned char *pds, int *year, int *month, int *day, int *hour) {
+    int tr, dtime, unit;
+
+    *year = PDS_Year4(pds);
+    *month = PDS_Month(pds);
+    *day  = PDS_Day(pds);
+    *hour = PDS_Hour(pds);
+
+    /* find time increment */
+
+    dtime = PDS_P1(pds);
+    tr = PDS_TimeRange(pds);
+    unit = PDS_ForecastTimeUnit(pds);
+
+    if (tr == 10) dtime = PDS_P1(pds) * 256 + PDS_P2(pds);
+    if (tr > 1 && tr < 6 ) dtime = PDS_P2(pds);
+    if (tr == 6 || tr == 7) dtime = - PDS_P1(pds);
+
+    if (dtime == 0) return 0;
+
+    return add_time(year, month, day, hour, dtime, unit);
+}
+
+
+/*
+ * ensemble.c   v0.1 wesley ebisuzaki
+ *
+ * prints ensemble meta-data
+ *
+ * only for NCEP and ECMWF
+ *
+ * output format:
+ *
+ *       ECMWF
+ *  ens=n/N:       n:  0=ctl, +/-ve
+ *                 N:  total number of members
+ *
+ *       NCEP
+ *  ens=n/type:    n:  0=ctl, +/-ve, CLUST, PROD/
+ *                 type: Mn, WtdMn, SDev, NSDev
+ *
+ * updated 8/06 w. ebisuzaki
+ */
+
+extern int ncep_ens;
+
+void ensemble(unsigned char *pds, int mode) {
+
+    int pdslen;
+    unsigned char ctmp;
+    char char_end;
+
+    pdslen = PDS_LEN(pds);
+    char_end = mode == 2 ? ' ' : ':';
+
+    if ((PDS_Center(pds) == NMC || ncep_ens) && pdslen >= 45 && pds[40] == 1) {
+
+	/* control run */
+
+	if (pds[41] == 1) {
+	    if (mode != 2) {
+		printf("ens%c0:%c", pds[42] == 1 ? '+' : '-', char_end);
+	    }
+	    else {
+		printf("%s-res_ens_control ", pds[42] == 1 ? "hi" : "low");
+	    }
+	}
+
+	/* perturbation run */
+
+	else if (pds[41] == 2 || pds[41] == 3) {
+	    if (mode != 2) {
+	        printf("ens%c%d%c", pds[41] == 3 ? '+' : '-', pds[42],char_end);
+	    }
+	    else {
+		printf("ens_perturbation=%c%d ",pds[41] == 3 ? '+' : '-', 
+		    pds[42]);
+	    }
+	}
+
+	/* cluster mean */
+
+	else if (pds[41] == 4) {
+	    if (mode != 2) printf("cluster%c", char_end);
+	    else printf("cluster(%d members) ",pds[60]);
+	}
+
+
+	/* ensemble mean */
+
+	else if (pds[41] == 5) {
+	    if (mode != 2) printf("ensemble%c", char_end);
+	    else printf("ensemble(%d members) ",pds[60]);
+	}
+
+	/* other case .. debug code */
+
+	else {
+		printf("ens %d/%d/%d/%d%c", pds[41],pds[42],pds[43],pds[44],char_end);
+	}
+
+
+	if (pdslen >= 44) {
+	    if (pds[43] == 1 && pds[41] >= 4) printf("mean%c", char_end);
+	    else if (pds[43] == 2) printf("weighted mean%c",char_end);
+	    else if (pds[43] == 3) printf("no bias%c",char_end);
+	    else if (pds[43] == 4) printf("weighted mean no bias%c",char_end);
+	    else if (pds[43] == 5) printf("weight%c",char_end);
+	    else if (pds[43] == 6) printf("climate percentile%c",char_end);
+	    else if (pds[43] == 7) printf("daily climate mean%c",char_end);
+	    else if (pds[43] == 8) printf("daily climate std dev%c",char_end);
+	    else if (pds[43] == 11) printf("std dev%c",char_end);
+	    else if (pds[43] == 12) printf("norm std dev%c",char_end);
+	    else if (pds[43] == 21) printf("max val%c",char_end);
+	    else if (pds[43] == 22) printf("min val%c",char_end);
+	}
+
+	/* NCEP probability limits */
+
+	if ((PDS_PARAM(pds) == 191 || PDS_PARAM(pds) == 192) && pdslen >= 47) {
+	    ctmp = PDS_PARAM(pds);
+	    PDS_PARAM(pds) = pds[45];
+	    if (pds[46] == 1 && pdslen >= 51) {
+		printf("prob(%s<%f)%c", k5toa(pds), ibm2flt(pds+47),char_end);
+	    }
+	    else if (pds[46] == 2 && pdslen >= 54) {
+		printf("prob(%s>%f)%c", k5toa(pds), ibm2flt(pds+51), char_end);
+	    }
+	    else if (pds[46] == 3 && pdslen >= 54) {
+		printf("prob(%f<%s<%f)%c", ibm2flt(pds+47), k5toa(pds), 
+			ibm2flt(pds+51), char_end);
+	    }
+            PDS_PARAM(pds) = ctmp;
+	}
+    }
+}
+
+/*
+ * GRIB table 2 at DWD
+ *     Helmut P. Frank, 30.08.2001
+ * updated 24.07.2003: PMSL, DD, FF, W, FR_ICE, H_ICE
+ * updated 28.11.2005: H_SNOW
+ */
+
+const struct ParmTable parm_table_dwd_002[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"PS", "pressure [Pa]"},
+    /* 2 */ {"PMSL", "pressure reduced to MSL [Pa]"},
+    /* 3 */ {"DPSDT", "pressure tendency [Pa/s]"},
+    /* 4 */ {"var4", "undefined"},
+    /* 5 */ {"var5", "undefined"},
+    /* 6 */ {"FI", "geopotential [(m**2)/(s**2)]"},
+    /* 7 */ {"geopot h", "geopotential height [gpm]"},
+    /* 8 */ {"HH", "geometrical height [m]"},
+    /* 9 */ {"dev of h", "standard deviation of height [m]"},
+    /* 10 */ {"TO3", "total ozone [Dobson Units]"},
+    /* 11 */ {"T", "temperature [K]"},
+    /* 12 */ {"virt.temp.", "virtual temperature [K]"},
+    /* 13 */ {"pot. temp.", "potential temperature [K]"},
+    /* 14 */ {"pseudo-pot", "pseudo-adiabatic potential temperature [K]"},
+    /* 15 */ {"TMAX", "maximum temperature [K]"},
+    /* 16 */ {"TMIN", "minimum temperature [K]"},
+    /* 17 */ {"TD", "dew-point temperature [K]"},
+    /* 18 */ {"dew-pnt de", "dew-point depression (or deficit) [K]"},
+    /* 19 */ {"lapse rate", "laps rate [K/m]"},
+    /* 20 */ {"visibility", "visibility [m]"},
+    /* 21 */ {"radar sp 1", "radar spectra (1) [non-dim]"},
+    /* 22 */ {"radar sp 2", "radar spectra (2) [non-dim]"},
+    /* 23 */ {"radar sp 3", "radar spectra (3) [non-dim]"},
+    /* 24 */ {"pli to 500", "parcel lifted index (to 500 hPa) [K]"},
+    /* 25 */ {"temp anom", "temperature anomaly [K]"},
+    /* 26 */ {"pres anom", "pressure anomaly [Pa]"},
+    /* 27 */ {"geop anom", "geopotential height anomaly [gpm]"},
+    /* 28 */ {"wave sp 1", "wave spaectra(1) [non-dim]"},
+    /* 29 */ {"wave sp 2", "wave spaectra(2) [non-dim]"},
+    /* 30 */ {"wave sp 3", "wave spaectra(3) [non-dim]"},
+    /* 31 */ {"DD", "wind direction [degree true]"},
+    /* 32 */ {"FF", "wind speed [m/s]"},
+    /* 33 */ {"U", "u-component (zonal) of wind [m/s]"},
+    /* 34 */ {"V", "v-component (merdional) of wind [m/s]"},
+    /* 35 */ {"stream fun", "stream function [(m**2)/s]"},
+    /* 36 */ {"vel potent", "velocity potential [(m**2)/s]"},
+    /* 37 */ {"M.stream f", "Montgomery stream function [(m**2)/(s**2)]"},
+    /* 38 */ {"sigma vert", "sigma co-ordinate vertical velocity [1/s]"},
+    /* 39 */ {"OMEGA", "vertical velocity [Pa/s]"},
+    /* 40 */ {"W", "vertical velocity [m/s]"},
+    /* 41 */ {"abs vortic", "absolute vorticity [1/s]"},
+    /* 42 */ {"abs diverg", "absolute divergence [1/s]"},
+    /* 43 */ {"rel vortic", "relative vorticity [1/s]"},
+    /* 44 */ {"rel diverg", "relative divergence [1/s]"},
+    /* 45 */ {"vert.u-shr", "vertical u-component shear [1/s]"},
+    /* 46 */ {"vert.v-shr", "vertical v-component shear [1/s]"},
+    /* 47 */ {"dir of cur", "direction of current [degree true]"},
+    /* 48 */ {"spd of cur", "speed of current [m/s]"},
+    /* 49 */ {"currcomp U", "u-component of current [m/s]"},
+    /* 50 */ {"currcomp V", "v-component of current [m/s]"},
+    /* 51 */ {"QV", "specific humidity [kg/kg]"},
+    /* 52 */ {"RELHUM", "relative humidity [%]"},
+    /* 53 */ {"hum mixrat", "humidity mixing ratio [kg/kg]"},
+    /* 54 */ {"TQV", "total precipitable water [kg/m**2]"},
+    /* 55 */ {"vapor pres", "vapor pressure [Pa]"},
+    /* 56 */ {"sat.defic.", "saturation deficit [Pa]"},
+    /* 57 */ {"AEVAP_S", "evaporation [kg/(m**2)]"},
+    /* 58 */ {"TQI", "total cloud ice content [kg/m**2]"},
+    /* 59 */ {"prec. rate", "precipitation rate [kg/((m**2)*s)]"},
+    /* 60 */ {"thunderst.", "thunderstorm probability [%]"},
+    /* 61 */ {"TOT_PREC", "total precipitation [kg/(m**2)]"},
+    /* 62 */ {"PREC_GSP", "large scale precipitation [kg/(m**2)]"},
+    /* 63 */ {"PREC_CON", "convective precipitation [kg/(m**2)]"},
+    /* 64 */ {"snowf.rate", "snowfall rate water equivalent [kg/((m**2)*s)]"},
+    /* 65 */ {"W_SNOW", "water equivalent of accumulated snow depth [kg/(m**2)]"},
+    /* 66 */ {"H_SNOW", "snow depth [m]"},
+    /* 67 */ {"mix lay de", "mixed layer depth [m]"},
+    /* 68 */ {"tr therm d", "transient thermocline depth [m]"},
+    /* 69 */ {"ma therm d", "main thermocline depth [m]"},
+    /* 70 */ {"m therm da", "main thermocline depth anomaly [m]"},
+    /* 71 */ {"CLCT", "total cloud cover [%]"},
+    /* 72 */ {"CLC_CON", "convective cloud cover [%]"},
+    /* 73 */ {"CLCL", "low cloud cover [%]"},
+    /* 74 */ {"CLCM", "medium cloud cover [%]"},
+    /* 75 */ {"CLCH", "high cloud cover [%]"},
+    /* 76 */ {"TQC", "total cloud water content [kg/m**2]"},
+    /* 77 */ {"bli to 500", "best lifted index (to 500 hPa) [K]"},
+    /* 78 */ {"SNOW_CON", "convective snow [kg/(m**2)]"},
+    /* 79 */ {"SNOW_GSP", "large scale snow [kg/(m**2)]"},
+    /* 80 */ {"water temp", "water temperature [K]"},
+    /* 81 */ {"FR_LAND", "land cover (1=land, 0=sea) [1]"},
+    /* 82 */ {"dev sea-le", "deviation of sea-level from mean [m]"},
+    /* 83 */ {"Z0", "surface roughness [m]"},
+    /* 84 */ {"ALB_RAD", "albedo [%]"},
+    /* 85 */ {"T_soil", "soil temperature [K]"},
+    /* 86 */ {"W_soil", "soil moisture content [kg/(m**2)]"},
+    /* 87 */ {"PLCOV", "vegetation (plant cover) [%]"},
+    /* 88 */ {"salinity", "salinity [kg/kg]"},
+    /* 89 */ {"density", "density [kg/(m**3)]"},
+    /* 90 */ {"RUNOFF", "water run-off [kg/(m**2)]"},
+    /* 91 */ {"FR_ICE", "ice cover (1=ice, 0=no ice) [1]"},
+    /* 92 */ {"H_ICE", "ice thickness [m]"},
+    /* 93 */ {"dir ice dr", "direction of ice drift [degree true]"},
+    /* 94 */ {"sp ice dr", "speed of ice drift [m/s]"},
+    /* 95 */ {"ice dr u", "u-component of ice drift [m/s]"},
+    /* 96 */ {"ice dr v", "v-component of ice drift [m/s]"},
+    /* 97 */ {"ice growth", "ice growth rate [m/s]"},
+    /* 98 */ {"ice diverg", "ice divergence [1/s]"},
+    /* 99 */ {"snow melt", "snow melt [kg/(m**2)]"},
+    /* 100 */ {"winwav/swe", "significant height of comb. wind waves and swell [m]"},
+    /* 101 */ {"dir of wav", "direction of wind waves [degree true]"},
+    /* 102 */ {"hei of wav", "significant height of wind waves [m]"},
+    /* 103 */ {"MP of wiwa", "mean period of wind waves [s]"},
+    /* 104 */ {"dir of swe", "direction of swell [degree true]"},
+    /* 105 */ {"hei of swe", "significant height of swell [m]"},
+    /* 106 */ {"MP of swel", "mean period of swell [s]"},
+    /* 107 */ {"pr wave di", "primary wave direction [degree true]"},
+    /* 108 */ {"pr wave pe", "primary wave period [s]"},
+    /* 109 */ {"se wave di", "secondary wave direction [degree true]"},
+    /* 110 */ {"se wave pe", "secondary wave period [s]"},
+    /* 111 */ {"ASOB_S", "net short-wave radiation (surface) [W/(m**2)]"},
+    /* 112 */ {"ATHB_S", "net long-wave radiation (surface) [W/(m**2)]"},
+    /* 113 */ {"ASOB_T", "net short-wave radiation (top of atmosphere) [W/(m**2)]"},
+    /* 114 */ {"ATHB_T", "net long-wave radiation (top of atmosphere) [W/(m**2)]"},
+    /* 115 */ {"l-w rad.", "long-wave radiation [W/(m**2)]"},
+    /* 116 */ {"s-w rad.", "short-wave radiation [W/(m**2)]"},
+    /* 117 */ {"global rad", "global radiation [W/(m**2)]"},
+    /* 118 */ {"var118", "undefined"},
+    /* 119 */ {"var119", "undefined"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"ALHFL_S", "latent heat flux [W/(m**2)]"},
+    /* 122 */ {"ASHFL_S", "sensible heat flux [W/(m**2)]"},
+    /* 123 */ {"bound l di", "boundary layer dissipation [W/(m**2)]"},
+    /* 124 */ {"AUMFL_S", "momentum flux, u component [N/(m**2)]"},
+    /* 125 */ {"AVMFL_S", "momentum flux, v component [N/(m**2)]"},
+    /* 126 */ {"wind mix e", "wind mixing energy [J]"},
+    /* 127 */ {"image data", "image data []"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"geopot h", "geopotential height (ECMF) [gpm]"},
+    /* 130 */ {"temperatur", "temperature (ECMF) [K]"},
+    /* 131 */ {"wind compU", "u-component of wind (ECMF) [m/s]"},
+    /* 132 */ {"wind compV", "v-component of wind (ECMF) [m/s]"},
+    /* 133 */ {"var133", "undefined"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"soil temp.", "soil temperature (ECMF) [K]"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"var141", "undefined"},
+    /* 142 */ {"ls precip.", "large scale precipitation (ECMF) [kg/(m**2)]"},
+    /* 143 */ {"conv prec.", "convective precipitation (ECMF) [kg/(m**2)]"},
+    /* 144 */ {"snowfall", "snowfall (ECMF) [m of water equivalent]"},
+    /* 145 */ {"var145", "undefined"},
+    /* 146 */ {"var146", "undefined"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"var148", "undefined"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"var150", "undefined"},
+    /* 151 */ {"pressure", "pressure reduced to MSL (ECMF) [Pa]"},
+    /* 152 */ {"var152", "undefined"},
+    /* 153 */ {"var153", "undefined"},
+    /* 154 */ {"var154", "undefined"},
+    /* 155 */ {"var155", "undefined"},
+    /* 156 */ {"geopot h", "geopotential height (ECMF) [gpm]"},
+    /* 157 */ {"rel. humid", "relative humidity (ECMF) [%]"},
+    /* 158 */ {"var158", "undefined"},
+    /* 159 */ {"var159", "undefined"},
+    /* 160 */ {"var160", "undefined"},
+    /* 161 */ {"var161", "undefined"},
+    /* 162 */ {"var162", "undefined"},
+    /* 163 */ {"var163", "undefined"},
+    /* 164 */ {"cloud cov.", "total cloud cover (ECMF) [%]"},
+    /* 165 */ {"10m-wind U", "u-component of 10m-wind (ECMF) [m/s]"},
+    /* 166 */ {"10m-wind V", "v-component of 10m-wind (ECMF) [m/s]"},
+    /* 167 */ {"2m temper", "2m temperature (ECMF) [K]"},
+    /* 168 */ {"2m due-p.", "2m due-point temperature (ECMF) [K]"},
+    /* 169 */ {"var169", "undefined"},
+    /* 170 */ {"var170", "undefined"},
+    /* 171 */ {"var171", "undefined"},
+    /* 172 */ {"var172", "undefined"},
+    /* 173 */ {"var173", "undefined"},
+    /* 174 */ {"var174", "undefined"},
+    /* 175 */ {"var175", "undefined"},
+    /* 176 */ {"var176", "undefined"},
+    /* 177 */ {"var177", "undefined"},
+    /* 178 */ {"var178", "undefined"},
+    /* 179 */ {"var179", "undefined"},
+    /* 180 */ {"var180", "undefined"},
+    /* 181 */ {"var181", "undefined"},
+    /* 182 */ {"var182", "undefined"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"var189", "undefined"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"var195", "undefined"},
+    /* 196 */ {"var196", "undefined"},
+    /* 197 */ {"var197", "undefined"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"var200", "undefined"},
+    /* 201 */ {"var201", "undefined"},
+    /* 202 */ {"var202", "undefined"},
+    /* 203 */ {"var203", "undefined"},
+    /* 204 */ {"var204", "undefined"},
+    /* 205 */ {"var205", "undefined"},
+    /* 206 */ {"var206", "undefined"},
+    /* 207 */ {"var207", "undefined"},
+    /* 208 */ {"var208", "undefined"},
+    /* 209 */ {"var209", "undefined"},
+    /* 210 */ {"var210", "undefined"},
+    /* 211 */ {"var211", "undefined"},
+    /* 212 */ {"var212", "undefined"},
+    /* 213 */ {"var213", "undefined"},
+    /* 214 */ {"var214", "undefined"},
+    /* 215 */ {"var215", "undefined"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"var217", "undefined"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"total prec", "total precipitation (ECMF) [m]"},
+    /* 229 */ {"seaway 01", "seaway 01 (ECMF) []"},
+    /* 230 */ {"seaway 02", "seaway 02 (ECMF) []"},
+    /* 231 */ {"seaway 03", "seaway 03 (ECMF) []"},
+    /* 232 */ {"seaway 04", "seaway 04 (ECMF) []"},
+    /* 233 */ {"seaway 05", "seaway 05 (ECMF) []"},
+    /* 234 */ {"seaway 06", "seaway 06 (ECMF) []"},
+    /* 235 */ {"seaway 07", "seaway 07 (ECMF) []"},
+    /* 236 */ {"seaway 08", "seaway 08 (ECMF) []"},
+    /* 237 */ {"seaway 09", "seaway 09 (ECMF) []"},
+    /* 238 */ {"seaway 10", "seaway 10 (ECMF) []"},
+    /* 239 */ {"seaway 11", "seaway 11 (ECMF) []"},
+    /* 240 */ {"var240", "undefined"},
+    /* 241 */ {"var241", "undefined"},
+    /* 242 */ {"var242", "undefined"},
+    /* 243 */ {"var243", "undefined"},
+    /* 244 */ {"var244", "undefined"},
+    /* 245 */ {"var245", "undefined"},
+    /* 246 */ {"var246", "undefined"},
+    /* 247 */ {"var247", "undefined"},
+    /* 248 */ {"var248", "undefined"},
+    /* 249 */ {"var249", "undefined"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"var251", "undefined"},
+    /* 252 */ {"var252", "undefined"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"var254", "undefined"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+/*
+ * GRIB table 201 at DWD
+ *     Helmut P. Frank, 30.08.2001
+ * updated 24.07.2003:  DQC_GSP, DQI_GSP, T_SO, W_SO, W_SO_ICE, T_ICE
+ *         19.10.2005:  SOTR_RA, QRS_GSP, RHO_SNOW to table 201, and others
+ */
+
+const struct ParmTable parm_table_dwd_201[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"dw sw flux", "downward shortwave radiant flux density [W/m**2]"},
+    /* 2 */ {"uw sw flux", "upward shortwave radiant flux density [W/m**2]"},
+    /* 3 */ {"dw lw flux", "downward longwave radiant flux density [W/m**2]"},
+    /* 4 */ {"uw lw flux", "upward longwave radiant flux density [W/m**2]"},
+    /* 5 */ {"APAB_S", "downwd photosynthetic active radiant flux density [W/m**2]"},
+    /* 6 */ {"net s flux", "net shortwave flux [W/m**2]"},
+    /* 7 */ {"net l flux", "net longwave flux [W/m**2]"},
+    /* 8 */ {"net flux", "total net radiative flux density [W/m**2]"},
+    /* 9 */ {"dw sw clfr", "downw shortw radiant flux density, cloudfree part [W/m**2]"},
+    /* 10 */ {"uw sw cldy", "upw shortw radiant flux density, cloudy part [W/m**2]"},
+    /* 11 */ {"dw lw clfr", "downw longw radiant flux density, cloudfree part [W/m**2]"},
+    /* 12 */ {"uw lw cldy", "upw longw radiant flux density, cloudy part [W/m**2]"},
+    /* 13 */ {"SOHR_RAD", "shortwave radiative heating rate [K/s]"},
+    /* 14 */ {"THHR_RAD", "longwave radiative heating rate [K/s]"},
+    /* 15 */ {"rad heat", "total radiative heating rate [K/s]"},
+    /* 16 */ {"soilheat S", "soil heat flux, surface [W/m**2]"},
+    /* 17 */ {"soilheat L", "soil heat flux, bottom of layer [W/m**2]"},
+    /* 18 */ {"var18", "undefined"},
+    /* 19 */ {"var19", "undefined"},
+    /* 20 */ {"var20", "undefined"},
+    /* 21 */ {"var21", "undefined"},
+    /* 22 */ {"var22", "undefined"},
+    /* 23 */ {"var23", "undefined"},
+    /* 24 */ {"var24", "undefined"},
+    /* 25 */ {"var25", "undefined"},
+    /* 26 */ {"var26", "undefined"},
+    /* 27 */ {"var27", "undefined"},
+    /* 28 */ {"var28", "undefined"},
+    /* 29 */ {"CLC", "cloud cover, grid scale + convective [1]"},
+    /* 30 */ {"clc gr sc", "cloud cover, grid scale  (0...1) [1]"},
+    /* 31 */ {"QC", "specific cloud water content, grid scale [kg/kg]"},
+    /* 32 */ {"clw gs vi", "cloud water content, grid scale, vert integrated [kg/m**2]"},
+    /* 33 */ {"QI", "specific cloud ice content, grid scale [kg/kg]"},
+    /* 34 */ {"cli gs vi", "cloud ice content, grid scale, vert integrated [kg/m**2]"},
+    /* 35 */ {"QR", "specific rainwater content, grid scale [kg/kg]"},
+    /* 36 */ {"QS", "specific snow content, grid scale [kg/kg]"},
+    /* 37 */ {"src gs vi", "specific rainwater content, gs, vert. integrated [kg/m**2]"},
+    /* 38 */ {"ssc gs vi", "specific snow content, gs, vert. integrated [kg/m**2]"},
+    /* 39 */ {"QG", "specific graupel content, grid scale [kg/kg]"},
+    /* 40 */ {"var40", "undefined"},
+    /* 41 */ {"TWATER", "vert. integral of humidity, cloud water (and ice) [kg/(m**2)]"},
+    /* 42 */ {"TDIV_HUM", "vert. integral of divergence of tot. water content [kg/(m**2)]"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"var44", "undefined"},
+    /* 45 */ {"var45", "undefined"},
+    /* 46 */ {"var46", "undefined"},
+    /* 47 */ {"var47", "undefined"},
+    /* 48 */ {"var48", "undefined"},
+    /* 49 */ {"var49", "undefined"},
+    /* 50 */ {"CH_CM_CL", "cloud covers CH_CM_CL (000...888) [1]"},
+    /* 51 */ {"cl cov. CH", "cloud cover CH (0..8) [1]"},
+    /* 52 */ {"cl cov. CM", "cloud cover CM (0..8) [1]"},
+    /* 53 */ {"cl cov. CL", "cloud cover CL (0..8) [1]"},
+    /* 54 */ {"cloud cov.", "total cloud cover (0..8) [1]"},
+    /* 55 */ {"fog", "fog (0..8) [1]"},
+    /* 56 */ {"fog", "fog [1]"},
+    /* 57 */ {"var57", "undefined"},
+    /* 58 */ {"var58", "undefined"},
+    /* 59 */ {"var59", "undefined"},
+    /* 60 */ {"clc con ci", "cloud cover, convective cirrus  (0...1) [1]"},
+    /* 61 */ {"CLW_CON", "specific cloud water content, convective clouds [kg/kg]"},
+    /* 62 */ {"clw con vi", "cloud water content, conv clouds, vert integrated [kg/m**2]"},
+    /* 63 */ {"cli con", "specific cloud ice content, convective clouds [kg/kg]"},
+    /* 64 */ {"cli con vi", "cloud ice content, conv clouds, vert integrated [kg/m**2]"},
+    /* 65 */ {"mass fl co", "convective mass flux [kg/(s*m**2)]"},
+    /* 66 */ {"upd vel co", "updraft velocity, convection [m/s]"},
+    /* 67 */ {"entr p co", "entrainment parameter, convection [m**(-1)]"},
+    /* 68 */ {"HBAS_CON", "cloud base, convective clouds (above msl) [m]"},
+    /* 69 */ {"HTOP_CON", "cloud top, convective clouds (above msl) [m]"},
+    /* 70 */ {"con layers", "convective layers (00...77)  (BKE) [1]"},
+    /* 71 */ {"KO-index", "KO-index [1]"},
+    /* 72 */ {"BAS_CON", "convection base index [1]"},
+    /* 73 */ {"TOP_CON", "convection top index [1]"},
+    /* 74 */ {"DT_CON", "convective temperature tendency [K/s]"},
+    /* 75 */ {"DQV_CON", "convective tendency of specific humidity [s**(-1)]"},
+    /* 76 */ {"H ten co", "convective tendency of total heat [J/(kg*s)]"},
+    /* 77 */ {"QDW ten co", "convective tendency of total water [s**(-1)]"},
+    /* 78 */ {"DU_CON", "convective momentum tendency (X-component) [m/s**2]"},
+    /* 79 */ {"DV_CON", "convective momentum tendency (Y-component) [m/s**2]"},
+    /* 80 */ {"vor ten co", "convective vorticity tendency [s**(-2)]"},
+    /* 81 */ {"div ten co", "convective divergence tendency [s**(-2)]"},
+    /* 82 */ {"HTOP_DC", "top of dry convection (above msl) [m]"},
+    /* 83 */ {"top ind dc", "dry convection top index [1]"},
+    /* 84 */ {"HZEROCL", "height of 0 degree Celsius isotherm above msl [m]"},
+    /* 85 */ {"SNOWLMT", "height of snowfall limit above msl [m]"},
+    /* 86 */ {"var86", "undefined"},
+    /* 87 */ {"var87", "undefined"},
+    /* 88 */ {"var88", "undefined"},
+    /* 89 */ {"var89", "undefined"},
+    /* 90 */ {"var90", "undefined"},
+    /* 91 */ {"var91", "undefined"},
+    /* 92 */ {"var92", "undefined"},
+    /* 93 */ {"var93", "undefined"},
+    /* 94 */ {"var94", "undefined"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"QRS_GSP", "spec water cont of rain/snow needed for w loading [kg/kg]"},
+    /* 100 */ {"PRR_GSP", "surface precipitation rate, rain, grid scale [kg/(s*m**2)]"},
+    /* 101 */ {"PRS_GSP", "surface precipitation rate, snow, grid scale [kg/(s*m**2)]"},
+    /* 102 */ {"RAIN_GSP", "surface precipitation amount, rain, grid scale [kg/m**2]"},
+    /* 103 */ {"condens gs", "condensation rate, grid scale [kg/(kg*s)]"},
+    /* 104 */ {"autocon gs", "autoconversion rate, grid scale   (C+C  --> R) [kg/(kg*s)]"},
+    /* 105 */ {"accret gs", "accretion rate, grid scale        (R+C  --> R) [kg/(kg*s)]"},
+    /* 106 */ {"nucleat gs", "nucleation rate, grid scale       (C+C  --> S) [kg/(kg*s)]"},
+    /* 107 */ {"riming gs", "riming rate, grid scale           (S+C  --> S) [kg/(kg*s)]"},
+    /* 108 */ {"deposit gs", "deposition rate, grid scale       (S+V <--> S) [kg/(kg*s)]"},
+    /* 109 */ {"melting gs", "melting rate, grid scale          (S    --> R) [kg/(kg*s)]"},
+    /* 110 */ {"evapor gs", "evaporation rate, grid scale      (R+V <--  R) [kg/(kg*s)]"},
+    /* 111 */ {"PRR_CON", "surface precipitation rate, rain, convective [kg/(s*m**2)]"},
+    /* 112 */ {"PRS_CON", "surface precipitation rate, snow, convective [kg/(s*m**2)]"},
+    /* 113 */ {"RAIN_CON", "surface precipitation amount, rain, convective [kg/m**2]"},
+    /* 114 */ {"condens co", "condensation rate, convective [kg/(kg*s)]"},
+    /* 115 */ {"autocon co", "autoconversion rate, convective [kg/(kg*s)]"},
+    /* 116 */ {"accret co", "accretion rate, convective [kg/(kg*s)]"},
+    /* 117 */ {"nucleat co", "nucleation rate, convective [kg/(kg*s)]"},
+    /* 118 */ {"riming co", "riming rate, convective [kg/(kg*s)]"},
+    /* 119 */ {"sublim co", "sublimation rate, convective [kg/(kg*s)]"},
+    /* 120 */ {"melting co", "melting rate, convective [kg/(kg*s)]"},
+    /* 121 */ {"evapor co", "evaporation rate, convective [kg/(kg*s)]"},
+    /* 122 */ {"rain am", "rain amount, grid-scale plus convective [kg/m**2]"},
+    /* 123 */ {"snow am", "snow amount, grid-scale plus convective [kg/m**2]"},
+    /* 124 */ {"DT_GSP", "temperature tendency, grid-scale condensation [K/s]"},
+    /* 125 */ {"DQV_GSP", "tendency of specific humidity, grid-scale condens [s**(-1)]"},
+    /* 126 */ {"H ten gs", "tendency of total heat, grid-scale condensation [J/(kg*s)]"},
+    /* 127 */ {"DQC_GSP", "tendency of total water, grid-scale condensation [s**(-1)]"},
+    /* 128 */ {"snowfall", "snowfall  (dimension"},
+    /* 129 */ {"FRESHSNW", "fresh snow factor [1]"},
+    /* 130 */ {"DQI_GSP", "tend of the sp cl ice cont due to gs precipitation [kg/(kg*s)]"},
+    /* 131 */ {"PRG_GSP", "surface precipitation rate, graupel, grid scale [kg/(s*m**2)]"},
+    /* 132 */ {"GRAU_GSP", "surface precipitation amount, graupel, grid scale [kg/(m**2)]"},
+    /* 133 */ {"RHO_SNOW", "snow density [kg/m**3"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"PP", "deviation of pressure from reference value [Pa]"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"var141", "undefined"},
+    /* 142 */ {"var142", "undefined"},
+    /* 143 */ {"var143", "undefined"},
+    /* 144 */ {"var144", "undefined"},
+    /* 145 */ {"var145", "undefined"},
+    /* 146 */ {"var146", "undefined"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"var148", "undefined"},
+    /* 149 */ {"KE", "kinetic energy ((u**2 + v**2) / 2) [(m**2/s**2)]"},
+    /* 150 */ {"hdi coeff", "coefficient of horizontal diffusion [m**2/s]"},
+    /* 151 */ {"dissp rate", "dissipation rate [W/(Pa*m**2)]"},
+    /* 152 */ {"TKE", "turbulent kinetic energy [(m/s)**2]"},
+    /* 153 */ {"TKVM", "coefficient of vertical diffusion, momentum [m**2/s]"},
+    /* 154 */ {"TKVH", "coefficient of vertical diffusion, heat [m**2/s]"},
+    /* 155 */ {"vdi coe cw", "coefficient of vertical diffusion, cloud water [m**2/s]"},
+    /* 156 */ {"vdi coe ci", "coefficient of vertical diffusion, cloud ice [m**2/s]"},
+    /* 157 */ {"vdi coe vp", "coefficient of vertical diffusion, water vapour [m**2/s]"},
+    /* 158 */ {"dis len m", "turbulent dissipation length for momentum [m]"},
+    /* 159 */ {"dis len h", "turbulent dissipation length for heat [m]"},
+    /* 160 */ {"var u mom", "variance of u-component of momentum [(m/s)**2]"},
+    /* 161 */ {"var v mom", "variance of v-component of momentum [(m/s)**2]"},
+    /* 162 */ {"var w mom", "variance of w-component of momentum [(m/s)**2]"},
+    /* 163 */ {"var temp", "variance of temperature [K**2]"},
+    /* 164 */ {"var cl wat", "variance of specific cloud water content [(kg/kg)**2]"},
+    /* 165 */ {"var cl ice", "variance of specific cloud ice content [(kg/kg)**2]"},
+    /* 166 */ {"var vap mr", "variance of water vapour mixing ratio [(kg/kg)**2]"},
+    /* 167 */ {"c wat flux", "turbulent vertical flux of spec cloud water [m/s]"},
+    /* 168 */ {"c ice flux", "turbulent vertical flux of spec cloud ice [m/s]"},
+    /* 169 */ {"w vap flux", "turbulent vertical flux of water vapour mix ratio [m/s]"},
+    /* 170 */ {"TCM", "drag coefficient CD [1]"},
+    /* 171 */ {"TCH", "transfer coefficient CH (sensible heat) [1]"},
+    /* 172 */ {"tr coef CQ", "transfer coefficient CQ (latent heat) [1]"},
+    /* 173 */ {"PBL-top h", "PBL-top h [m]"},
+    /* 174 */ {"T-jump  h", "temperature jump at PBL-top [K]"},
+    /* 175 */ {"q-jump  h", "specific humidity jump at PBL-top [kg/kg]"},
+    /* 176 */ {"entr at h", "entrainment at PBL-top [kg/(s*m**2)]"},
+    /* 177 */ {"mass fl h", "upward mass flux at PBL-top [kg/(s*m**2)]"},
+    /* 178 */ {"cl cov PBL", "cloud cover of PBL-clouds (0...1) [1]"},
+    /* 179 */ {"cl wat PBL", "specific cloud water content of PBL-clouds [kg/kg]"},
+    /* 180 */ {"cl top PBL", "cloud top of PBL-clouds [m]"},
+    /* 181 */ {"cl bas PBL", "cloud base of PBL-clouds [m]"},
+    /* 182 */ {"moun wav X", "vertical mountain wave momentum flux (X component) [kg/(m*s**2)]"},
+    /* 183 */ {"moun wav Y", "vertical mountain wave momentum flux (Y component) [kg/(m*s**2)]"},
+    /* 184 */ {"wave Ri", "wave Richardson number [1]"},
+    /* 185 */ {"wav div X", "mountain wave momentum flux divergence (X comp) [m/s**2]"},
+    /* 186 */ {"wav div Y", "mountain wave momentum flux divergence (Y comp) [m/s**2]"},
+    /* 187 */ {"VMAX_10M", "maximum wind velocity [m/s]"},
+    /* 188 */ {"wav dis vi", "mountain wave dissipation, vert integrated [W/m**2]"},
+    /* 189 */ {"wv en flux", "vertical wave energy flux [kg*m/s**4]"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"var195", "undefined"},
+    /* 196 */ {"var196", "undefined"},
+    /* 197 */ {"T_SO", "temperature of soil layers [K]"},
+    /* 198 */ {"W_SO", "water + ice content of soil layers [kg/(m**2)]"},
+    /* 199 */ {"W_SO_ICE", "ice content of soil layers [kg/(m**2)]"},
+    /* 200 */ {"W_I", "water content of interception store [kg/(m**2)]"},
+    /* 201 */ {"interc ice", "icebit for interception store [1]"},
+    /* 202 */ {"snow fract", "snow fraction [1]"},
+    /* 203 */ {"T_SNOW", "snow temperature [K]"},
+    /* 204 */ {"foliag tem", "foliage temperature [K]"},
+    /* 205 */ {"infiltrat", "infiltration [m/s]"},
+    /* 206 */ {"runoff", "runoff [m/s]"},
+    /* 207 */ {"soil evap", "bare soil evaporation [m/s]"},
+    /* 208 */ {"plant tran", "plant transpiration [m/s]"},
+    /* 209 */ {"inter evap", "interception store evaporation [m/s]"},
+    /* 210 */ {"water evap", "evaporation from water surfaces [m/s]"},
+    /* 211 */ {"aero resis", "aerodynamic resistance [s/m]"},
+    /* 212 */ {"plant res", "plant resistance [s/m]"},
+    /* 213 */ {"soil res", "soil resistance [s/m]"},
+    /* 214 */ {"total evap", "total evaporation (water, soil, plants) [m/s]"},
+    /* 215 */ {"T_ICE", "temperature of sea ice [K]"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"max wind m", "maximum wind velocity (modified) [m/s]"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"var228", "undefined"},
+    /* 229 */ {"var229", "undefined"},
+    /* 230 */ {"XYZ", "S1 [1]"},
+    /* 231 */ {"RHS_SI", "S2 [1]"},
+    /* 232 */ {"DTTDIV", "S3 [1]"},
+    /* 233 */ {"SOTR_RAD", "effective transmissivity of solar rad. [1]"},
+    /* 234 */ {"GEN_TEN1", "averaged tendencies [x/s]"},
+    /* 235 */ {"GEN_TEN2", "averaged tendencies [x/s]"},
+    /* 236 */ {"S7", "S7 [1]"},
+    /* 237 */ {"S8", "S8 [1]"},
+    /* 238 */ {"S9", "S9 [1]"},
+    /* 239 */ {"S10", "S10 [1]"},
+    /* 240 */ {"MFLX_CON", "cloud base mass flux kg/(s*m**2)"},
+    /* 241 */ {"CAPE_CON", "convective available potential energy [J/kg]"},
+    /* 242 */ {"QCVG_CON", "moisture convergence for Kuo-type closure [1/s]"},
+    /* 243 */ {"TKE_CON", "convective turbulent energy [J/kg]"},
+    /* 244 */ {"MOS pTS fq", "MOS Gewitter-Wahrscheinlichkeit (frequent) [1]"},
+    /* 245 */ {"MOS TS cov", "MOS Gewitteranteil (occasional - frequent (1 - 2)) [1]"},
+    /* 246 */ {"S17", "S17 [1]"},
+    /* 247 */ {"S18", "S18 [1]"},
+    /* 248 */ {"S19", "S19 [1]"},
+    /* 249 */ {"S20", "S20 [1]"},
+    /* 250 */ {"MOS TSISO1", "MOS Wahrscheinlichkeit mindestens ein Blitz [1]"},
+    /* 251 */ {"MOS TSISO2", "MOS Wahrscheinlichkeit mindestens zehn Blitze [1]"},
+    /* 252 */ {"MOS TSISO3", "MOS Wahrscheinlichkeit mindestens hundert Blitze [1]"},
+    /* 253 */ {"MOS TS DEN", "MOS Vorhersage der Blitzanzahl [1]"},
+    /* 254 */ {"MOS TS OCC", "MOS Gewitter-Wahrscheinlichkeit (occasional) [1]"},
+    /* 255 */ {"MOS TS FRQ", "MOS Gewitter-Wahrscheinlichkeit (frequent) [1]"},
+};
+
+/*
+ * GRIB table 202 at DWD
+ *     Helmut P. Frank, 30.08.2001
+ * updated 24.07.2003: UV_Ind_F_h, BasicUV_IF, UV_Ind_W_h, UV_IndmaxF,
+ *                     "gesamt O3", UV_IndmaxW, "h UV_IndMx"
+ *         19.10.2005: AER_SEA, AER_LAN, AER_URB, AER_DES, and others
+ *          2.11.2005: Use RLAT, RLON instead of PHI, RLA.
+ */
+
+const struct ParmTable parm_table_dwd_202[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"Seeg_peak", "jonswap parameter fm [s**(-1)]"},
+    /* 2 */ {"Seeg_alpha", "jonswap parameter alpha [1]"},
+    /* 3 */ {"Seeg_gamma", "jonswap parameter gamma [1]"},
+    /* 4 */ {"Seeg_dir", "Seegang direction [degree true]"},
+    /* 5 */ {"Seeg_energ", "Seegang energy densitiy [(m**2)*(s**2)]"},
+    /* 6 */ {"Seeg_icemk", "Seegang ice mask [1]"},
+    /* 7 */ {"peak p sw", "peak period of swell [s]"},
+    /* 8 */ {"peak p ww", "peak period of wind waves [s]"},
+    /* 9 */ {"var9", "undefined"},
+    /* 10 */ {"var10", "undefined"},
+    /* 11 */ {"var11", "undefined"},
+    /* 12 */ {"var12", "undefined"},
+    /* 13 */ {"var13", "undefined"},
+    /* 14 */ {"var14", "undefined"},
+    /* 15 */ {"var15", "undefined"},
+    /* 16 */ {"var16", "undefined"},
+    /* 17 */ {"var17", "undefined"},
+    /* 18 */ {"var18", "undefined"},
+    /* 19 */ {"var19", "undefined"},
+    /* 20 */ {"Var. Geop.", "Varianz Geopotential [(m/s)**4]"},
+    /* 21 */ {"Var. T", "Varianz Temperatur [K**2]"},
+    /* 22 */ {"Var. u", "Varianz Zonalwind [(m/s)**2]"},
+    /* 23 */ {"Var. v", "Varianz Meridionalwind [(m/s)**2]"},
+    /* 24 */ {"Var. q", "Varianz spezifische Feuchte [(kg/kg)**2]"},
+    /* 25 */ {"Mer. Imptr", "Meridionaler Impulstransport [(m/s)**2]"},
+    /* 26 */ {"Mer. TrEpt", "Meridionaler Transport potentieller Energie [(m/s)**3]"},
+    /* 27 */ {"Mer. TrsW", "Meridionaler Transport sensibler Waerme [K*(m/s)]"},
+    /* 28 */ {"Mer. TrlW", "Meridionaler Transport latenter Waerme [(kg/kg)*(m/s)]"},
+    /* 29 */ {"Ver. TrEpt", "Vertikaler Transport potentieller Energie [(m/s)**2*(Pa/s)]"},
+    /* 30 */ {"Ver. TrsW", "Vertikaler Transport sensibler Waerme [K*(Pa/s)]"},
+    /* 31 */ {"Ver.TrlW", "Vertikaler Transport latenter Waerme [(kg/kg)*(Pa/s)]"},
+    /* 32 */ {"var32", "undefined"},
+    /* 33 */ {"var33", "undefined"},
+    /* 34 */ {"var34", "undefined"},
+    /* 35 */ {"var35", "undefined"},
+    /* 36 */ {"var36", "undefined"},
+    /* 37 */ {"var37", "undefined"},
+    /* 38 */ {"var38", "undefined"},
+    /* 39 */ {"var39", "undefined"},
+    /* 40 */ {"VarAF Geop", "Varianz des Analyse-Fehlers Geopotential [(m/s)**4]"},
+    /* 41 */ {"VarAF u", "Varianz des Analyse-Fehlers Zonalwind [(m/s)**2]"},
+    /* 42 */ {"VarAF v", "Varianz des Analyse-Fehlers Meridionalwind [(m/s)**2]"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"DU_SSO", "undefined"},
+    /* 45 */ {"DV_SSO", "undefined"},
+    /* 46 */ {"SSO_STDH", "standard deviation of subgrid scale orogr. height [m]"},
+    /* 47 */ {"SSO_GAMMA", "anisotropy of topography [1]"},
+    /* 48 */ {"SSO_THETA", "angle betw. principal axis of orogr. and global E [1]"},
+    /* 49 */ {"SSO_SIGMA", "mean slope of subgrid scale orography [1]"},
+    /* 50 */ {"oro varian", "subgrid-scale variance of orography [m**2]"},
+    /* 51 */ {"E-W oro va", "E-W component of subgrid-scale variance of orogr [m**2]"},
+    /* 52 */ {"N-S oro va", "N-S component of subgrid-scale variance of orogr [m**2]"},
+    /* 53 */ {"NW-SE o va", "NW-SE component of subgrid-scale variance of orogr [m**2]"},
+    /* 54 */ {"NE-SW o va", "NE-SW component of subgrid-scale variance of orogr [m**2]"},
+    /* 55 */ {"inl w frac", "fraction of inland water [1]"},
+    /* 56 */ {"EMISS_RAD", "surface emissivity [1]"},
+    /* 57 */ {"SOILTYP", "soil texture [1]"},
+    /* 58 */ {"soil color", "soil color [1]"},
+    /* 59 */ {"soil drain", "soil drainage [1]"},
+    /* 60 */ {"ground wat", "ground water table [m]"},
+    /* 61 */ {"LAI", "leaf area index [1]"},
+    /* 62 */ {"ROOTDP", "root depth [m]"},
+    /* 63 */ {"root dens", "root density [1]"},
+    /* 64 */ {"HMO3", "height of maximum of ozone concentration [Pa]"},
+    /* 65 */ {"VIO3", "total vertically integrated ozone content [Pa]"},
+    /* 66 */ {"ld-sea msk", "land-sea mask [1]"},
+    /* 67 */ {"PLCOV_MX", "ground fraction covered by plants (vegetation p.) [1]"},
+    /* 68 */ {"PLCOV_MN", "ground fraction covered by plants (time of rest) [1]"},
+    /* 69 */ {"LAI_MX", "leaf area index (vegetation period) [1]"},
+    /* 70 */ {"LAI_MN", "leaf area index (time of rest) [1]"},
+    /* 71 */ {"Orographie", "Orographie + Land-Meer-Verteilung [m]"},
+    /* 72 */ {"r length m", "roughness length momentum [m]"},
+    /* 73 */ {"r length h", "roughness length heat [m]"},
+    /* 74 */ {"var smc", "variance of soil moisture content [kg**2/m**4]"},
+    /* 75 */ {"FOR_E", "ground fraction covered by evergreen forest [1]"},
+    /* 76 */ {"FOR_D", "ground fraction covered by deciduous forest [1]"},
+    /* 77 */ {"NDVI", "normalized differential vegetation index [1]"},
+    /* 78 */ {"NDVI_MAX", "annual max. of norm. differential vegetation index [1]"},
+    /* 79 */ {"NDVIRATIO", "proportion of act.value/max. norm.diff.veg.index [1]"},
+    /* 80 */ {"AER_SEA", "aerosol optical depth, type sea [1]"},
+    /* 81 */ {"AER_LAN", "aerosol optical depth, type land [1]"},
+    /* 82 */ {"AER_URB", "aerosol optical depth, type urban [1]"},
+    /* 83 */ {"AER_DES", "aerosol optical depth, type desert [1]"},
+    /* 84 */ {"var84", "undefined"},
+    /* 85 */ {"var85", "undefined"},
+    /* 86 */ {"var86", "undefined"},
+    /* 87 */ {"var87", "undefined"},
+    /* 88 */ {"var88", "undefined"},
+    /* 89 */ {"var89", "undefined"},
+    /* 90 */ {"var90", "undefined"},
+    /* 91 */ {"var91", "undefined"},
+    /* 92 */ {"var92", "undefined"},
+    /* 93 */ {"var93", "undefined"},
+    /* 94 */ {"var94", "undefined"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"var99", "undefined"},
+    /* 100 */ {"var100", "undefined"},
+    /* 101 */ {"tidal tend", "tidal tendencies [(m/s)**2]"},
+    /* 102 */ {"diab heatg", "sum of diabatic heating terms [K/s]"},
+    /* 103 */ {"adiab heat", "total adiabatic heating [K/s]"},
+    /* 104 */ {"adv q tend", "advective tendency of specific humidity [s**(-1)]"},
+    /* 105 */ {"nadv q ten", "non-advective tendency of specific humidity [s**(-1)]"},
+    /* 106 */ {"adv m te X", "advective momentum tendency (X component) [m/s**2]"},
+    /* 107 */ {"adv m te Y", "advective momentum tendency (Y component) [m/s**2]"},
+    /* 108 */ {"nad m te X", "non-advective momentum tendency (X component) [m/s**2]"},
+    /* 109 */ {"nad m te Y", "non-advective momentum tendency (Y component) [m/s**2]"},
+    /* 110 */ {"torque", "sum of mountain and frictional torque [kg*(m/s)**2]"},
+    /* 111 */ {"budget val", "budget values [1]"},
+    /* 112 */ {"scale fact", "scale factor [1]"},
+    /* 113 */ {"FC", "Coriolis parameter [s**(-1)]"},
+    /* 114 */ {"RLAT", "latitude [degr N]"},
+    /* 115 */ {"RLON", "longitude [degr E]"},
+    /* 116 */ {"relax fact", "relaxation factor (lateral boundary, LAM) [1]"},
+    /* 117 */ {"climsstint", "climatic sea surface temp interpolated in time [degr C]"},
+    /* 118 */ {"pot vortic", "potential vorticity [K*m**2/(s*kg)]"},
+    /* 119 */ {"ln ps", "log surface pressure [1]"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"ZTD", "delay of the GPS signal through the atmosphere [m]"},
+    /* 122 */ {"ZWD", "delay of the GPS signal through a wet atmosphere [m]"},
+    /* 123 */ {"ZHD", "delay of the GPS signal through a dry atmosphere [m]"},
+    /* 124 */ {"var124", "undefined"},
+    /* 125 */ {"var125", "undefined"},
+    /* 126 */ {"var126", "undefined"},
+    /* 127 */ {"var127", "undefined"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"var129", "undefined"},
+    /* 130 */ {"var130", "undefined"},
+    /* 131 */ {"var131", "undefined"},
+    /* 132 */ {"var132", "undefined"},
+    /* 133 */ {"var133", "undefined"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"var139", "undefined"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"var141", "undefined"},
+    /* 142 */ {"var142", "undefined"},
+    /* 143 */ {"var143", "undefined"},
+    /* 144 */ {"var144", "undefined"},
+    /* 145 */ {"var145", "undefined"},
+    /* 146 */ {"var146", "undefined"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"var148", "undefined"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"SO2-conc", "SO2-concentration [10**(-6)*g/m**3]"},
+    /* 151 */ {"SO2-dryd", "SO2-dry deposition [10**(-3)*g/m**2]"},
+    /* 152 */ {"SO2-wetd", "SO2-wet deposition [10**(-3)*g/m**2]"},
+    /* 153 */ {"SO4-conc", "SO4-concentration [10**(-6)*g/m**3]"},
+    /* 154 */ {"SO4-dryd", "SO4-dry deposition [10**(-3)*g/m**2]"},
+    /* 155 */ {"SO4-wetd", "SO4-wet deposition [10**(-3)*g/m**2]"},
+    /* 156 */ {"NO-conc", "NO-concentration [10**(-6)*g/m**3]"},
+    /* 157 */ {"NO-dryd", "NO-dry deposition [10**(-3)*g/m**2]"},
+    /* 158 */ {"NO-wetd", "NO-wet deposition [10**(-3)*g/m**2]"},
+    /* 159 */ {"NO2-conc", "NO2-concentration [10**(-6)*g/m**3]"},
+    /* 160 */ {"NO2-dryd", "NO2-dry deposition [10**(-3)*g/m**2]"},
+    /* 161 */ {"NO2-wetd", "NO2-wet deposition [10**(-3)*g/m**2]"},
+    /* 162 */ {"NO3-conc", "NO3-concentration [10**(-6)*g/m**3]"},
+    /* 163 */ {"NO3-dryd", "NO3-dry deposition [10**(-3)*g/m**2]"},
+    /* 164 */ {"NO3-wetd", "NO3-wet deposition [10**(-3)*g/m**2]"},
+    /* 165 */ {"HNO3-conc", "HNO3-concentration [10**(-6)*g/m**3]"},
+    /* 166 */ {"HNO3-dryd", "HNO3-dry deposition [10**(-3)*g/m**2]"},
+    /* 167 */ {"HNO3-wetd", "HNO3-wet deposition [10**(-3)*g/m**2]"},
+    /* 168 */ {"NH3-conc", "NH3-concentration [10**(-6)*g/m**3]"},
+    /* 169 */ {"NH3-dryd", "NH3-dry deposition [10**(-3)*g/m**2]"},
+    /* 170 */ {"NH3-wetd", "NH3-wet deposition [10**(-3)*g/m**2]"},
+    /* 171 */ {"NH4-conc", "NH4-concentration [10**(-6)*g/m**3]"},
+    /* 172 */ {"NH4-dryd", "NH4-dry deposition [10**(-3)*g/m**2]"},
+    /* 173 */ {"NH4-wetd", "NH4-wet deposition [10**(-3)*g/m**2]"},
+    /* 174 */ {"O3-conc", "O3-concentration [10**(-6)*g/m**3]"},
+    /* 175 */ {"PAN-conc", "PAN-concentration [10**(-6)*g/m**3]"},
+    /* 176 */ {"PAN-dryd", "PAN-dry deposition [10**(-3)*g/m**2]"},
+    /* 177 */ {"OH-conc", "OH-concentration [10**(-6)*g/m**3]"},
+    /* 178 */ {"O3-dryd", "O3-dry deposition [10**(-3)*g/m**2]"},
+    /* 179 */ {"O3-wetd", "O3-wet deposition [10**(-3)*g/m**2]"},
+    /* 180 */ {"O3", "O3-mixing ratio [kg/kg]"},
+    /* 181 */ {"var181", "undefined"},
+    /* 182 */ {"var182", "undefined"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"var189", "undefined"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"var195", "undefined"},
+    /* 196 */ {"var196", "undefined"},
+    /* 197 */ {"var197", "undefined"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"I131-conc", "I131-concentration [Bq/m**3]"},
+    /* 201 */ {"I131-dryd", "I131-dry deposition [Bq/m**2]"},
+    /* 202 */ {"I131-wetd", "I131-wet deposition [Bq/m**2]"},
+    /* 203 */ {"Cs137-conc", "Cs137-concentration [Bq/m**3]"},
+    /* 204 */ {"Cs137-dryd", "Cs1370dry deposition [Bq/m**2]"},
+    /* 205 */ {"Cs137-wetd", "Cs137-wet deposition [Bq/m**2]"},
+    /* 206 */ {"Te132-conc", "Te132-concentration [Bq/m**3]"},
+    /* 207 */ {"Te132-dryd", "Te132-dry deposition [Bq/m**2]"},
+    /* 208 */ {"Te132-wetd", "Te132-wet deposition [Bq/m**2]"},
+    /* 209 */ {"Zr95-conc", "Zr95-concentration [Bq/m**3]"},
+    /* 210 */ {"Zr95-dryd", "Zr95-dry deposition [Bq/m**2]"},
+    /* 211 */ {"Zr95-wetd", "Zr95-wet deposition [Bq/m**2]"},
+    /* 212 */ {"var212", "undefined"},
+    /* 213 */ {"var213", "undefined"},
+    /* 214 */ {"var214", "undefined"},
+    /* 215 */ {"var215", "undefined"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"var217", "undefined"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"var228", "undefined"},
+    /* 229 */ {"var229", "undefined"},
+    /* 230 */ {"var230", "undefined"},
+    /* 231 */ {"USTR_SSO", "Mom. flux, u component, due to SSO-effects [(N/(m**2)]"},
+    /* 232 */ {"VSTR_SSO", "Mom. flux, v component, due to SSO-effects [(N/(m**2)]"},
+    /* 233 */ {"VDIS_SSO", "Dissipation of kinetic energy due to SSO-effects [(W/(m**2)]"},
+    /* 234 */ {"var234", "undefined"},
+    /* 235 */ {"var235", "undefined"},
+    /* 236 */ {"var236", "undefined"},
+    /* 237 */ {"var237", "undefined"},
+    /* 238 */ {"var238", "undefined"},
+    /* 239 */ {"var239", "undefined"},
+    /* 240 */ {"UV_Ind_F_h", "UV_Index corr. for albedo+altitude,cloudless(F), h [1]"},
+    /* 241 */ {"BasicUV_IF", "Basic UV_Index m.s.l.,fixed albedo,cloudless(F), h [1]"},
+    /* 242 */ {"UV_Ind_W_h", "UV_Index corrected for albedo+altitude+clouds(W),h [1]"},
+    /* 243 */ {"UV_IndmaxF", "UV_Index cloudless (F), daily maximum [1]"},
+    /* 244 */ {"SB-Index", "Sonnenbrand-Index [(W*10**(-3))/m**2]"},
+    /* 245 */ {"SB-Index W", "Sonnenbrand-Index bei mittl. Bewoelkung (08z-12z) [(W*10**(-3))/m**2]"},
+    /* 246 */ {"Kan.UVB-WI", "Kanadischer UVB-Warnindex (bew|lkungsreduziert) [(W*10**(-3))/m**2]"},
+    /* 247 */ {"gesamt O3", "total column ozone (Gesamtozon) [Dobson Unit, DU]"},
+    /* 248 */ {"UV_IndmaxW", "UV_Index clouded (W), daily maximum [1]"},
+    /* 249 */ {"h UV_IndMx", "time of UV_Index maximum [h UTC]"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"var251", "undefined"},
+    /* 252 */ {"var252", "undefined"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"var254", "undefined"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+/*
+ * GRIB table 203 at DWD
+ *     Helmut P. Frank, 30.08.2001
+ *     updated: 19.10.2005
+ */
+
+const struct ParmTable parm_table_dwd_203[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"pressure", "pressure [hPa]"},
+    /* 2 */ {"geopot h", "geopotential height [10 * gpm]"},
+    /* 3 */ {"var3", "undefined"},
+    /* 4 */ {"temperatur", "temperature [1*degree Celsius]"},
+    /* 5 */ {"dew-pnt te", "dew-point temperature [1*degree Celsius]"},
+    /* 6 */ {"windcompXY", "wind components X/Y (X*100000 + ((Y*10)+5000)) [m/s]"},
+    /* 7 */ {"geomet h", "geometrical height [kft]"},
+    /* 8 */ {"geomet h", "geometrical height [hft]"},
+    /* 9 */ {"wind di/sp", "wind direction and speed (dd*1000 + ff) [1*degree, 1*kt]"},
+    /* 10 */ {"3 h pr cha", "3 hour pressure change [Pa/(3*h)]"},
+    /* 11 */ {"Schnee-Mge", "Schneemenge [mm]"},
+    /* 12 */ {"var12", "undefined"},
+    /* 13 */ {"Bod-Wass-G", "Bodenwassergehalt [mm]"},
+    /* 14 */ {"var14", "undefined"},
+    /* 15 */ {"stab. ind.", "stability index [K]"},
+    /* 16 */ {"var16", "undefined"},
+    /* 17 */ {"var17", "undefined"},
+    /* 18 */ {"max wind", "maximum wind velocity [km/h]"},
+    /* 19 */ {"max wind", "maximum wind velocity [kt]"},
+    /* 20 */ {"wind di/sp", "wind direction and speed (dd*1000 + ff) [5*degrees, 1*(m/s)]"},
+    /* 21 */ {"wind di/sp", "wind direction and speed (dd*1000 + ff) [5*degrees, 1*kt]"},
+    /* 22 */ {"wave di/he", "direction and height of wind waves (dd*1000 + h) [1*degree, 1*cm]"},
+    /* 23 */ {"swe. di/he", "direction and height of swell (dd*1000 + h) [1*degree, 1*cm]"},
+    /* 24 */ {"wave m d/h", "mean direction and height of waves (dd*1000 + h) [1*degree, 1*cm]"},
+    /* 25 */ {"wind speed", "wind speed [kt]"},
+    /* 26 */ {"var26", "undefined"},
+    /* 27 */ {"wind compX", "wind component X-direction [kt]"},
+    /* 28 */ {"wind compY", "wind component Y-direction [kt]"},
+    /* 29 */ {"var29", "undefined"},
+    /* 30 */ {"var30", "undefined"},
+    /* 31 */ {"var31", "undefined"},
+    /* 32 */ {"var32", "undefined"},
+    /* 33 */ {"abs voradv", "absolute vorticity advection [1/(s**2)]"},
+    /* 34 */ {"var34", "undefined"},
+    /* 35 */ {"var35", "undefined"},
+    /* 36 */ {"var36", "undefined"},
+    /* 37 */ {"var37", "undefined"},
+    /* 38 */ {"var38", "undefined"},
+    /* 39 */ {"var39", "undefined"},
+    /* 40 */ {"var40", "undefined"},
+    /* 41 */ {"var41", "undefined"},
+    /* 42 */ {"vert. vel.", "vertical velocity [hPa/h]"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"var44", "undefined"},
+    /* 45 */ {"var45", "undefined"},
+    /* 46 */ {"var46", "undefined"},
+    /* 47 */ {"var47", "undefined"},
+    /* 48 */ {"var48", "undefined"},
+    /* 49 */ {"var49", "undefined"},
+    /* 50 */ {"var50", "undefined"},
+    /* 51 */ {"var51", "undefined"},
+    /* 52 */ {"var52", "undefined"},
+    /* 53 */ {"var53", "undefined"},
+    /* 54 */ {"var54", "undefined"},
+    /* 55 */ {"max. temp.", "maximum temperature [1*degree Celsius]"},
+    /* 56 */ {"min. temp.", "minimum temperature [1*degree Celsius]"},
+    /* 57 */ {"sul_prob", "probability to perceive sultriness [1]"},
+    /* 58 */ {"clo", "value of isolation of clothes [1]"},
+    /* 59 */ {"pmva", "predected mean vote (angepasst) [1]"},
+    /* 60 */ {"feeled t", "feeled temperature [1*degree Celsius]"},
+    /* 61 */ {"sea temper", "sea temperature [1*degree Celsius]"},
+    /* 62 */ {"var62", "undefined"},
+    /* 63 */ {"var63", "undefined"},
+    /* 64 */ {"var64", "undefined"},
+    /* 65 */ {"var65", "undefined"},
+    /* 66 */ {"var66", "undefined"},
+    /* 67 */ {"var67", "undefined"},
+    /* 68 */ {"var68", "undefined"},
+    /* 69 */ {"var69", "undefined"},
+    /* 70 */ {"var70", "undefined"},
+    /* 71 */ {"var71", "undefined"},
+    /* 72 */ {"var72", "undefined"},
+    /* 73 */ {"var73", "undefined"},
+    /* 74 */ {"var74", "undefined"},
+    /* 75 */ {"var75", "undefined"},
+    /* 76 */ {"var76", "undefined"},
+    /* 77 */ {"var77", "undefined"},
+    /* 78 */ {"var78", "undefined"},
+    /* 79 */ {"var79", "undefined"},
+    /* 80 */ {"var80", "undefined"},
+    /* 81 */ {"var81", "undefined"},
+    /* 82 */ {"var82", "undefined"},
+    /* 83 */ {"var83", "undefined"},
+    /* 84 */ {"var84", "undefined"},
+    /* 85 */ {"var85", "undefined"},
+    /* 86 */ {"Globalstr.", "Summe der Globalstrahlung ueber einen Zeitraum [kWh/m**2]"},
+    /* 87 */ {"Nied-GW-GE", "Niederschlagsart+Gewitter+Glatteis (T23-i) (0..99) [1]"},
+    /* 88 */ {"NiedGW-Art", "Niederschlagsart+Gewitter (T23-intern)     (0..99) [1]"},
+    /* 89 */ {"NiedGE-Art", "Niederschlagsart+Glatteis (T23-intern)     (0..99) [1]"},
+    /* 90 */ {"NiedBewArt", "Kombination Niederschl.-Bew.-Blautherm. (283..407) [1]"},
+    /* 91 */ {"Konv.U-Gr.", "Hoehe der Konvektionsuntergrenze ueber Grund [m]"},
+    /* 92 */ {"Nied.-Art", "Niederschlagsart -ww- (T23-intern)         (0..99) [1]"},
+    /* 93 */ {"Konv.-Art", "Konvektionsart                              (0..4) [1]"},
+    /* 94 */ {"Konv.UG-nn", "Hoehe der Konvektionsuntergrenze ueber nn [m]"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"WW", "Wetter (verschluesselt nach ww-Tabelle"},
+    /* 100 */ {"geostr Vor", "geostrophische Vorticity [1/s]"},
+    /* 101 */ {"Geo VorAdv", "geostrophische  Vorticityadvektion [1/s**2]"},
+    /* 102 */ {"VerGraVoAd", "vert. Gradient der geostr. Vorticityadvektion [m/(kg*s)]"},
+    /* 103 */ {"Geo TemAdv", "geostrophische Schichtdickenadvektion [m**3/(kg*s)]"},
+    /* 104 */ {"Lap TemAdv", "Kruemmung der geostr. Schichtdickenadvektion [m/(kg*s)]"},
+    /* 105 */ {"Omega Forc", "Forcing rechte Seite Omegagleichung [m/(kg*s)]"},
+    /* 106 */ {"var106", "undefined"},
+    /* 107 */ {"Schichtd.A", "Schichtdicken-Advektion [m**3/(kg*s)]"},
+    /* 108 */ {"AdGeVoThWi", "Advektion von geostr. Vorticity mit dem therm Wind [m/(kg*s)]"},
+    /* 109 */ {"Wind-Div.", "Winddivergenz [1/s]"},
+    /* 110 */ {"Q", "Q-vector direction and speed (dd*1000 + fff*1E13) [5*deg,1E13*m**2/kg/s]"},
+    /* 111 */ {"Qx", "Q-Vektor X-Komponente [m**2/(kg*s)]"},
+    /* 112 */ {"Qy", "Q-Vektor Y-Komponente [m**2/(kg*s)]"},
+    /* 113 */ {"Div Q", "Divergenz Q [m/(kg*s)]"},
+    /* 114 */ {"FrontoGeQn", "Frontogenesefunktion, Q isother-senkrecht-Kompon. [m**2/(kg*s)]"},
+    /* 115 */ {"Qs (geo)", "Qs (geo),Komp. Q-Vektor parallel zu den Isothermen [m**2/(kg*s)]"},
+    /* 116 */ {"DivQn(geo)", "Divergenz Qn  geostrophisch [m/(kg*s)]"},
+    /* 117 */ {"DivQs(geo)", "Divergenz Qs  geostrophisch [m/(kg*s)]"},
+    /* 118 */ {"Fronto Gen", "Frontogenesefunktion [K**2/(m**2*s)]"},
+    /* 119 */ {"var119", "undefined"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"var121", "undefined"},
+    /* 122 */ {"var122", "undefined"},
+    /* 123 */ {"var123", "undefined"},
+    /* 124 */ {"FrontoGenP", "Frontogenese-Parameter [1]"},
+    /* 125 */ {"Qs-Vektor", "Qs, Komp. Q-Vektor parallel zu den Isothermen [m**2/(kg*s)]"},
+    /* 126 */ {"var126", "undefined"},
+    /* 127 */ {"Div Qs", "Divergenz Qs [m/(kg*s)]"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"var129", "undefined"},
+    /* 130 */ {"IPV", "Isentrope potentielle Vorticity [K*m**2/(s*kg)]"},
+    /* 131 */ {"Wind KompX", "Wind X-Komponente auf isentropen Flaechen [m/s]"},
+    /* 132 */ {"Wind KompY", "Wind Y-Komponente auf isentropen Flaechen [m/s]"},
+    /* 133 */ {"Druck-Ise.", "Druck einer isentropen Flaeche [hPa]"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"var139", "undefined"},
+    /* 140 */ {"KO-Index", "KO-Index [K]"},
+    /* 141 */ {"TT-Index", "Totals-Totals-Index [K]"},
+    /* 142 */ {"S-Index", "S-Index [K]"},
+    /* 143 */ {"Stein-Ind", "Steinbeck-Index [1]"},
+    /* 144 */ {"Baily-Ind", "Baily-Index [1]"},
+    /* 145 */ {"Microburst", "Microburst-Index [1]"},
+    /* 146 */ {"Cat-Index", "Clear Air Turbulence Index [1/s]"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"Lab-Energ", "Labilit{tsenergie [J/g]"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"Virt T", "Virtuelle Temperatur [K]"},
+    /* 151 */ {"Pseudo T", "Pseudo-Temperatur [K]"},
+    /* 152 */ {"Pseudo Pot", "Pseudopotentielle Temperatur [K]"},
+    /* 153 */ {"Aequi T", "Aequivalent-Temperatur [K]"},
+    /* 154 */ {"Aequi Pot", "Aequivalentpotentielle Temperatur [K]"},
+    /* 155 */ {"var155", "undefined"},
+    /* 156 */ {"var156", "undefined"},
+    /* 157 */ {"var157", "undefined"},
+    /* 158 */ {"var158", "undefined"},
+    /* 159 */ {"var159", "undefined"},
+    /* 160 */ {"Bas St Wol", "Untergrenze strat. Bew|lkung [hft]"},
+    /* 161 */ {"Bas St Wol", "Untergrenze strat. Bew|lkung [hPa]"},
+    /* 162 */ {"Bas Cu Wol", "Untergrenze cumul. Bew|lkung [hft]"},
+    /* 163 */ {"Bas Cu Wol", "Untergrenze cumul. Bew|lkung [hPa]"},
+    /* 164 */ {"Top St Wol", "Obergrenze strat. Bew|lkung [hft]"},
+    /* 165 */ {"Top St Wol", "Obergrenze strat. Bew|lkung [hPa]"},
+    /* 166 */ {"Top Cu Wol", "Obergrenze cumul. Bew|lkung [hft]"},
+    /* 167 */ {"Top Cu Wol", "Obergrenze cumul. Bew|lkung [hPa]"},
+    /* 168 */ {"var168", "undefined"},
+    /* 169 */ {"var169", "undefined"},
+    /* 170 */ {"Bas Tur Wo", "Untergrenze Wolkenturbulenz [hft]"},
+    /* 171 */ {"Bas Tur Wo", "Untergrenze Wolkenturbulenz [hPa]"},
+    /* 172 */ {"Top Tur Wo", "Obergrenze Wolkenturbulenz [hft]"},
+    /* 173 */ {"Top Tur Wo", "Obergrenze Wolkenturbulenz [hPa]"},
+    /* 174 */ {"Bas Eis Wo", "Untergrenze Vereisung in Wolken [hft]"},
+    /* 175 */ {"Bas Eis Wo", "Untergrenze Vereisung in Wolken [hPa]"},
+    /* 176 */ {"Top Eis Wo", "Obergrenze Vereisung in Wolken [hft]"},
+    /* 177 */ {"Top Eis Wo", "Obergrenze Vereisung in Wolken [hPa]"},
+    /* 178 */ {"Int Tur Wo", "Intensitaet der Turbulenz in Wolken  (0..4) [1]"},
+    /* 179 */ {"Int Eis Wo", "Intensitaet der Vereisung  (0..4) [1]"},
+    /* 180 */ {"var180", "undefined"},
+    /* 181 */ {"var181", "undefined"},
+    /* 182 */ {"var182", "undefined"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"var189", "undefined"},
+    /* 190 */ {"Sichtweite", "Sichtweite [m]"},
+    /* 191 */ {"PIP_degree", "Prognostic Icing"},
+    /* 192 */ {"PIP_scenar", "Prog Icing"},
+    /* 193 */ {"DIP_degree", "Diagnostic Icing"},
+    /* 194 */ {"DIP_scenar", "Diag Icing"},
+    /* 195 */ {"IcingGuess", "Icing Regime 1.Guess(1=gen,2=conv,3=strat,4=freez) [1]"},
+    /* 196 */ {"IcingGrade", "Icing Grade (1=LGT,2=MOD,3=SEV) [1]"},
+    /* 197 */ {"IcingRegim", "Icing Regime(1=general,2=convect,3=strat,4=freez) [1]"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"Gru Wetter", "Wetter - Grundzustand   (ww"},
+    /* 201 */ {"Lok Wetter", "Wetter - 1. lokale Abweichung  (ww"},
+    /* 202 */ {"Lok Wetter", "Wetter - 2. lokale Abweichung  (ww"},
+    /* 203 */ {"CLDEPTH", "cloud depth (grey scale"},
+    /* 204 */ {"CLCT_MOD", "modified total cloud cover  (0..1) [1]"},
+    /* 205 */ {"curr weath", "current weather (symbol number"},
+    /* 206 */ {"var206", "undefined"},
+    /* 207 */ {"var207", "undefined"},
+    /* 208 */ {"var208", "undefined"},
+    /* 209 */ {"var209", "undefined"},
+    /* 210 */ {"var210", "undefined"},
+    /* 211 */ {"Cu", "Cumulus  (0..1) [1]"},
+    /* 212 */ {"Cb", "Cumulimbus  (0..1) [1]"},
+    /* 213 */ {"Sc", "Stratocumulus  (0..1) [1]"},
+    /* 214 */ {"Ac", "Altocumulus  (0..1) [1]"},
+    /* 215 */ {"Ci", "Cirrus  (0..1) [1]"},
+    /* 216 */ {"St", "Stratus  (0..1) [1]"},
+    /* 217 */ {"As", "Altostratus  (0..1) [1]"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"Bedeckung", "Bedeckung in Stufen [1]"},
+    /* 222 */ {"Konvektion", "Konvektion  ja/nein [1]"},
+    /* 223 */ {"MN >90%", "Gesamtbedeckung > 90%  ja/nein [1]"},
+    /* 224 */ {"RF700 >89%", "relative Feuchte 700 hPa >= 90%  ja/nein [1]"},
+    /* 225 */ {"RR12 zentr", "Niederschlag 12 std. zentriert [mm]"},
+    /* 226 */ {"RR12 <=0.5", "Niederschlag 12 std. zentriert, Werte <= 0.5mm [mm]"},
+    /* 227 */ {"RR12 SA>60", "RR12 zentriert, Schneeanteil > 60%  ja/nein [1]"},
+    /* 228 */ {"RR12 Kv>60", "RR12 zentriert, konvektiver Anteil > 60%  ja/nein [1]"},
+    /* 229 */ {"SRR12ff", "Starkniederschlag in Stufen (12 std. Folgezeitr) [1]"},
+    /* 230 */ {"RRMAX/STD", "Maximaler Starkniederschlag / std [mm/h]"},
+    /* 231 */ {"RRMAX/MIN", "Maximaler Starkniederschlag / min [mm/min]"},
+    /* 232 */ {"SN12ff >15", "Schneefall (12std. Folgezeitraum) > 15 mm  ja/nein [1]"},
+    /* 233 */ {"RRgefr12ff", "gefrierender Regen (12std. Folgezeitraum)  ja/nein [1]"},
+    /* 234 */ {"FFboe", "Boeenstaerke in Stufen [1]"},
+    /* 235 */ {"Gewitter", "Gewitter in Stufen [1]"},
+    /* 236 */ {"Tx2m12h ze", "2m Maximumtemperatur 12h zentriert [Grad Celsius]"},
+    /* 237 */ {"Tn2m12h ze", "2m Minimumtemperatur 12h zentriert [Grad Celsius]"},
+    /* 238 */ {"var238", "undefined"},
+    /* 239 */ {"var239", "undefined"},
+    /* 240 */ {"var240", "undefined"},
+    /* 241 */ {"var241", "undefined"},
+    /* 242 */ {"var242", "undefined"},
+    /* 243 */ {"var243", "undefined"},
+    /* 244 */ {"var244", "undefined"},
+    /* 245 */ {"var245", "undefined"},
+    /* 246 */ {"var246", "undefined"},
+    /* 247 */ {"var247", "undefined"},
+    /* 248 */ {"var248", "undefined"},
+    /* 249 */ {"var249", "undefined"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"SCHWUELIND", "Schwuele-Index [1]"},
+    /* 252 */ {"SMOGSTUFEN", "Smog-Intensitaetsstufen [1]"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"SMOGHOEHE", "Obergrenze Smog  ( Inversionshoehe ) [m]"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+/*
+ * GRIB table 204 at DWD
+ *     Helmut P. Frank, 27.10.2004
+ */
+
+const struct ParmTable parm_table_dwd_204[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"p RMS fg-a", "pressure RMS-error first guess - analysis [Pa]"},
+    /* 2 */ {"p RMS ia-a", "pressure RMS-error initialised analysis - analysis [Pa]"},
+    /* 3 */ {"u RMS fg-a", "u RMS-error first guess - analysis [m/s]"},
+    /* 4 */ {"u RMS ia-a", "u RMS-error initialised analysis - analysis [m/s]"},
+    /* 5 */ {"v RMS fg-a", "v RMS-error first guess - analysis [m/s]"},
+    /* 6 */ {"v RMS ia-a", "v RMS-error initialised analysis - analysis [m/s]"},
+    /* 7 */ {"fi E fg-a", "geopotential RMS-error first guess - analysis [(m**2)/(s**2)]"},
+    /* 8 */ {"fi E ia-a", "geopotential RMS-error init. analysis - analysis [(m**2)/(s**2)]"},
+    /* 9 */ {"rh E fg-a", "relative humidity RMS-error first guess - analysis [1]"},
+    /* 10 */ {"rh E ia-a", "rel. hum. RMS-error init. analysis - analysis [1]"},
+    /* 11 */ {"t RMS fg-a", "temperature RMS-error first guess - analysis [K]"},
+    /* 12 */ {"t RMS ia-a", "temperature RMS-error init. analysis - analysis [K]"},
+    /* 13 */ {"om E fg-a", "omega RMS-error first guess - analysis [m/s]"},
+    /* 14 */ {"om E ia-a", "omega RMS-error initialised analysis - analysis [m/s]"},
+    /* 15 */ {"E fg-a KE", "kinetic energy RMS-error first guess - analysis [(m**2)/(s**2)]"},
+    /* 16 */ {"E ig-a KE", "kinetic energy RMS-error init. analysis [(m**2)/(s**2)]"},
+    /* 17 */ {"var17", "undefined"},
+    /* 18 */ {"var18", "undefined"},
+    /* 19 */ {"var19", "undefined"},
+    /* 20 */ {"var20", "undefined"},
+    /* 21 */ {"var21", "undefined"},
+    /* 22 */ {"var22", "undefined"},
+    /* 23 */ {"var23", "undefined"},
+    /* 24 */ {"var24", "undefined"},
+    /* 25 */ {"var25", "undefined"},
+    /* 26 */ {"var26", "undefined"},
+    /* 27 */ {"var27", "undefined"},
+    /* 28 */ {"var28", "undefined"},
+    /* 29 */ {"var29", "undefined"},
+    /* 30 */ {"var30", "undefined"},
+    /* 31 */ {"var31", "undefined"},
+    /* 32 */ {"var32", "undefined"},
+    /* 33 */ {"var33", "undefined"},
+    /* 34 */ {"var34", "undefined"},
+    /* 35 */ {"var35", "undefined"},
+    /* 36 */ {"var36", "undefined"},
+    /* 37 */ {"var37", "undefined"},
+    /* 38 */ {"var38", "undefined"},
+    /* 39 */ {"var39", "undefined"},
+    /* 40 */ {"var40", "undefined"},
+    /* 41 */ {"var41", "undefined"},
+    /* 42 */ {"var42", "undefined"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"var44", "undefined"},
+    /* 45 */ {"var45", "undefined"},
+    /* 46 */ {"var46", "undefined"},
+    /* 47 */ {"var47", "undefined"},
+    /* 48 */ {"var48", "undefined"},
+    /* 49 */ {"var49", "undefined"},
+    /* 50 */ {"var50", "undefined"},
+    /* 51 */ {"var51", "undefined"},
+    /* 52 */ {"var52", "undefined"},
+    /* 53 */ {"var53", "undefined"},
+    /* 54 */ {"var54", "undefined"},
+    /* 55 */ {"var55", "undefined"},
+    /* 56 */ {"var56", "undefined"},
+    /* 57 */ {"var57", "undefined"},
+    /* 58 */ {"var58", "undefined"},
+    /* 59 */ {"var59", "undefined"},
+    /* 60 */ {"var60", "undefined"},
+    /* 61 */ {"var61", "undefined"},
+    /* 62 */ {"var62", "undefined"},
+    /* 63 */ {"var63", "undefined"},
+    /* 64 */ {"var64", "undefined"},
+    /* 65 */ {"var65", "undefined"},
+    /* 66 */ {"var66", "undefined"},
+    /* 67 */ {"var67", "undefined"},
+    /* 68 */ {"var68", "undefined"},
+    /* 69 */ {"var69", "undefined"},
+    /* 70 */ {"var70", "undefined"},
+    /* 71 */ {"var71", "undefined"},
+    /* 72 */ {"var72", "undefined"},
+    /* 73 */ {"var73", "undefined"},
+    /* 74 */ {"var74", "undefined"},
+    /* 75 */ {"var75", "undefined"},
+    /* 76 */ {"var76", "undefined"},
+    /* 77 */ {"var77", "undefined"},
+    /* 78 */ {"var78", "undefined"},
+    /* 79 */ {"var79", "undefined"},
+    /* 80 */ {"var80", "undefined"},
+    /* 81 */ {"var81", "undefined"},
+    /* 82 */ {"var82", "undefined"},
+    /* 83 */ {"var83", "undefined"},
+    /* 84 */ {"var84", "undefined"},
+    /* 85 */ {"var85", "undefined"},
+    /* 86 */ {"var86", "undefined"},
+    /* 87 */ {"var87", "undefined"},
+    /* 88 */ {"var88", "undefined"},
+    /* 89 */ {"var89", "undefined"},
+    /* 90 */ {"var90", "undefined"},
+    /* 91 */ {"var91", "undefined"},
+    /* 92 */ {"var92", "undefined"},
+    /* 93 */ {"var93", "undefined"},
+    /* 94 */ {"var94", "undefined"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"var99", "undefined"},
+    /* 100 */ {"var100", "undefined"},
+    /* 101 */ {"var101", "undefined"},
+    /* 102 */ {"var102", "undefined"},
+    /* 103 */ {"var103", "undefined"},
+    /* 104 */ {"var104", "undefined"},
+    /* 105 */ {"var105", "undefined"},
+    /* 106 */ {"var106", "undefined"},
+    /* 107 */ {"var107", "undefined"},
+    /* 108 */ {"var108", "undefined"},
+    /* 109 */ {"var109", "undefined"},
+    /* 110 */ {"var110", "undefined"},
+    /* 111 */ {"var111", "undefined"},
+    /* 112 */ {"var112", "undefined"},
+    /* 113 */ {"var113", "undefined"},
+    /* 114 */ {"var114", "undefined"},
+    /* 115 */ {"var115", "undefined"},
+    /* 116 */ {"var116", "undefined"},
+    /* 117 */ {"var117", "undefined"},
+    /* 118 */ {"var118", "undefined"},
+    /* 119 */ {"var119", "undefined"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"var121", "undefined"},
+    /* 122 */ {"var122", "undefined"},
+    /* 123 */ {"var123", "undefined"},
+    /* 124 */ {"var124", "undefined"},
+    /* 125 */ {"var125", "undefined"},
+    /* 126 */ {"var126", "undefined"},
+    /* 127 */ {"var127", "undefined"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"var129", "undefined"},
+    /* 130 */ {"var130", "undefined"},
+    /* 131 */ {"RR20", "probability of total precipitation > 20mm [1]"},
+    /* 132 */ {"RR50", "probability of total precipitation > 50mm [1]"},
+    /* 133 */ {"RR100", "probability of total precipitation > 100mm [1]"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"var139", "undefined"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"FF10", "probability of maximum wind speed > 10m/s [1]"},
+    /* 142 */ {"FF15", "probability of maximum wind speed > 15m/s [1]"},
+    /* 143 */ {"FF20", "probability of maximum wind speed > 20m/s [1]"},
+    /* 144 */ {"var144", "undefined"},
+    /* 145 */ {"var145", "undefined"},
+    /* 146 */ {"var146", "undefined"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"var148", "undefined"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"var150", "undefined"},
+    /* 151 */ {"var151", "undefined"},
+    /* 152 */ {"var152", "undefined"},
+    /* 153 */ {"var153", "undefined"},
+    /* 154 */ {"var154", "undefined"},
+    /* 155 */ {"var155", "undefined"},
+    /* 156 */ {"var156", "undefined"},
+    /* 157 */ {"var157", "undefined"},
+    /* 158 */ {"var158", "undefined"},
+    /* 159 */ {"var159", "undefined"},
+    /* 160 */ {"var160", "undefined"},
+    /* 161 */ {"var161", "undefined"},
+    /* 162 */ {"var162", "undefined"},
+    /* 163 */ {"var163", "undefined"},
+    /* 164 */ {"var164", "undefined"},
+    /* 165 */ {"var165", "undefined"},
+    /* 166 */ {"var166", "undefined"},
+    /* 167 */ {"var167", "undefined"},
+    /* 168 */ {"var168", "undefined"},
+    /* 169 */ {"var169", "undefined"},
+    /* 170 */ {"var170", "undefined"},
+    /* 171 */ {"var171", "undefined"},
+    /* 172 */ {"var172", "undefined"},
+    /* 173 */ {"var173", "undefined"},
+    /* 174 */ {"var174", "undefined"},
+    /* 175 */ {"var175", "undefined"},
+    /* 176 */ {"var176", "undefined"},
+    /* 177 */ {"var177", "undefined"},
+    /* 178 */ {"var178", "undefined"},
+    /* 179 */ {"var179", "undefined"},
+    /* 180 */ {"var180", "undefined"},
+    /* 181 */ {"var181", "undefined"},
+    /* 182 */ {"var182", "undefined"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"var189", "undefined"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"var195", "undefined"},
+    /* 196 */ {"var196", "undefined"},
+    /* 197 */ {"var197", "undefined"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"var200", "undefined"},
+    /* 201 */ {"var201", "undefined"},
+    /* 202 */ {"var202", "undefined"},
+    /* 203 */ {"var203", "undefined"},
+    /* 204 */ {"var204", "undefined"},
+    /* 205 */ {"var205", "undefined"},
+    /* 206 */ {"var206", "undefined"},
+    /* 207 */ {"var207", "undefined"},
+    /* 208 */ {"var208", "undefined"},
+    /* 209 */ {"var209", "undefined"},
+    /* 210 */ {"var210", "undefined"},
+    /* 211 */ {"var211", "undefined"},
+    /* 212 */ {"var212", "undefined"},
+    /* 213 */ {"var213", "undefined"},
+    /* 214 */ {"var214", "undefined"},
+    /* 215 */ {"var215", "undefined"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"var217", "undefined"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"var228", "undefined"},
+    /* 229 */ {"var229", "undefined"},
+    /* 230 */ {"var230", "undefined"},
+    /* 231 */ {"var231", "undefined"},
+    /* 232 */ {"var232", "undefined"},
+    /* 233 */ {"var233", "undefined"},
+    /* 234 */ {"var234", "undefined"},
+    /* 235 */ {"var235", "undefined"},
+    /* 236 */ {"var236", "undefined"},
+    /* 237 */ {"var237", "undefined"},
+    /* 238 */ {"var238", "undefined"},
+    /* 239 */ {"var239", "undefined"},
+    /* 240 */ {"var240", "undefined"},
+    /* 241 */ {"var241", "undefined"},
+    /* 242 */ {"var242", "undefined"},
+    /* 243 */ {"var243", "undefined"},
+    /* 244 */ {"var244", "undefined"},
+    /* 245 */ {"var245", "undefined"},
+    /* 246 */ {"var246", "undefined"},
+    /* 247 */ {"var247", "undefined"},
+    /* 248 */ {"var248", "undefined"},
+    /* 249 */ {"var249", "undefined"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"var251", "undefined"},
+    /* 252 */ {"var252", "undefined"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"var254", "undefined"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+/*
+ * GRIB table 205 at DWD
+ *     Helmut P. Frank, 27.10.2004
+ * updated 19.10.2005
+ */
+
+const struct ParmTable parm_table_dwd_205[256] = {
+    /* 0 */ {"var0", "undefined"},
+    /* 1 */ {"SYNME5", "METEOSAT-5 mit Instrument MVIRI [1]"},
+    /* 2 */ {"SYNME6", "METEOSAT-6 mit Instrument MVIRI [1]"},
+    /* 3 */ {"SYNME7", "METEOSAT-7 mit Instrument MVIRI [1]"},
+    /* 4 */ {"SYNMSG", "MSG mit Instrument SEVIRI [1]"},
+    /* 5 */ {"var5", "undefined"},
+    /* 6 */ {"var6", "undefined"},
+    /* 7 */ {"var7", "undefined"},
+    /* 8 */ {"var8", "undefined"},
+    /* 9 */ {"var9", "undefined"},
+    /* 10 */ {"var10", "undefined"},
+    /* 11 */ {"var11", "undefined"},
+    /* 12 */ {"var12", "undefined"},
+    /* 13 */ {"var13", "undefined"},
+    /* 14 */ {"var14", "undefined"},
+    /* 15 */ {"var15", "undefined"},
+    /* 16 */ {"var16", "undefined"},
+    /* 17 */ {"var17", "undefined"},
+    /* 18 */ {"var18", "undefined"},
+    /* 19 */ {"var19", "undefined"},
+    /* 20 */ {"var20", "undefined"},
+    /* 21 */ {"var21", "undefined"},
+    /* 22 */ {"var22", "undefined"},
+    /* 23 */ {"var23", "undefined"},
+    /* 24 */ {"var24", "undefined"},
+    /* 25 */ {"var25", "undefined"},
+    /* 26 */ {"var26", "undefined"},
+    /* 27 */ {"var27", "undefined"},
+    /* 28 */ {"var28", "undefined"},
+    /* 29 */ {"var29", "undefined"},
+    /* 30 */ {"var30", "undefined"},
+    /* 31 */ {"var31", "undefined"},
+    /* 32 */ {"var32", "undefined"},
+    /* 33 */ {"var33", "undefined"},
+    /* 34 */ {"var34", "undefined"},
+    /* 35 */ {"var35", "undefined"},
+    /* 36 */ {"var36", "undefined"},
+    /* 37 */ {"var37", "undefined"},
+    /* 38 */ {"var38", "undefined"},
+    /* 39 */ {"var39", "undefined"},
+    /* 40 */ {"var40", "undefined"},
+    /* 41 */ {"var41", "undefined"},
+    /* 42 */ {"var42", "undefined"},
+    /* 43 */ {"var43", "undefined"},
+    /* 44 */ {"var44", "undefined"},
+    /* 45 */ {"var45", "undefined"},
+    /* 46 */ {"var46", "undefined"},
+    /* 47 */ {"var47", "undefined"},
+    /* 48 */ {"var48", "undefined"},
+    /* 49 */ {"var49", "undefined"},
+    /* 50 */ {"var50", "undefined"},
+    /* 51 */ {"var51", "undefined"},
+    /* 52 */ {"var52", "undefined"},
+    /* 53 */ {"var53", "undefined"},
+    /* 54 */ {"var54", "undefined"},
+    /* 55 */ {"var55", "undefined"},
+    /* 56 */ {"var56", "undefined"},
+    /* 57 */ {"var57", "undefined"},
+    /* 58 */ {"var58", "undefined"},
+    /* 59 */ {"var59", "undefined"},
+    /* 60 */ {"var60", "undefined"},
+    /* 61 */ {"var61", "undefined"},
+    /* 62 */ {"var62", "undefined"},
+    /* 63 */ {"var63", "undefined"},
+    /* 64 */ {"var64", "undefined"},
+    /* 65 */ {"var65", "undefined"},
+    /* 66 */ {"var66", "undefined"},
+    /* 67 */ {"var67", "undefined"},
+    /* 68 */ {"var68", "undefined"},
+    /* 69 */ {"var69", "undefined"},
+    /* 70 */ {"var70", "undefined"},
+    /* 71 */ {"var71", "undefined"},
+    /* 72 */ {"var72", "undefined"},
+    /* 73 */ {"var73", "undefined"},
+    /* 74 */ {"var74", "undefined"},
+    /* 75 */ {"var75", "undefined"},
+    /* 76 */ {"var76", "undefined"},
+    /* 77 */ {"var77", "undefined"},
+    /* 78 */ {"var78", "undefined"},
+    /* 79 */ {"var79", "undefined"},
+    /* 80 */ {"var80", "undefined"},
+    /* 81 */ {"var81", "undefined"},
+    /* 82 */ {"var82", "undefined"},
+    /* 83 */ {"var83", "undefined"},
+    /* 84 */ {"var84", "undefined"},
+    /* 85 */ {"var85", "undefined"},
+    /* 86 */ {"var86", "undefined"},
+    /* 87 */ {"var87", "undefined"},
+    /* 88 */ {"var88", "undefined"},
+    /* 89 */ {"var89", "undefined"},
+    /* 90 */ {"var90", "undefined"},
+    /* 91 */ {"var91", "undefined"},
+    /* 92 */ {"var92", "undefined"},
+    /* 93 */ {"var93", "undefined"},
+    /* 94 */ {"var94", "undefined"},
+    /* 95 */ {"var95", "undefined"},
+    /* 96 */ {"var96", "undefined"},
+    /* 97 */ {"var97", "undefined"},
+    /* 98 */ {"var98", "undefined"},
+    /* 99 */ {"var99", "undefined"},
+    /* 100 */ {"var100", "undefined"},
+    /* 101 */ {"var101", "undefined"},
+    /* 102 */ {"var102", "undefined"},
+    /* 103 */ {"var103", "undefined"},
+    /* 104 */ {"var104", "undefined"},
+    /* 105 */ {"var105", "undefined"},
+    /* 106 */ {"var106", "undefined"},
+    /* 107 */ {"var107", "undefined"},
+    /* 108 */ {"var108", "undefined"},
+    /* 109 */ {"var109", "undefined"},
+    /* 110 */ {"var110", "undefined"},
+    /* 111 */ {"var111", "undefined"},
+    /* 112 */ {"var112", "undefined"},
+    /* 113 */ {"var113", "undefined"},
+    /* 114 */ {"var114", "undefined"},
+    /* 115 */ {"var115", "undefined"},
+    /* 116 */ {"var116", "undefined"},
+    /* 117 */ {"var117", "undefined"},
+    /* 118 */ {"var118", "undefined"},
+    /* 119 */ {"var119", "undefined"},
+    /* 120 */ {"var120", "undefined"},
+    /* 121 */ {"var121", "undefined"},
+    /* 122 */ {"var122", "undefined"},
+    /* 123 */ {"var123", "undefined"},
+    /* 124 */ {"var124", "undefined"},
+    /* 125 */ {"var125", "undefined"},
+    /* 126 */ {"var126", "undefined"},
+    /* 127 */ {"var127", "undefined"},
+    /* 128 */ {"var128", "undefined"},
+    /* 129 */ {"var129", "undefined"},
+    /* 130 */ {"var130", "undefined"},
+    /* 131 */ {"var131", "undefined"},
+    /* 132 */ {"var132", "undefined"},
+    /* 133 */ {"var133", "undefined"},
+    /* 134 */ {"var134", "undefined"},
+    /* 135 */ {"var135", "undefined"},
+    /* 136 */ {"var136", "undefined"},
+    /* 137 */ {"var137", "undefined"},
+    /* 138 */ {"var138", "undefined"},
+    /* 139 */ {"var139", "undefined"},
+    /* 140 */ {"var140", "undefined"},
+    /* 141 */ {"var141", "undefined"},
+    /* 142 */ {"var142", "undefined"},
+    /* 143 */ {"var143", "undefined"},
+    /* 144 */ {"var144", "undefined"},
+    /* 145 */ {"var145", "undefined"},
+    /* 146 */ {"var146", "undefined"},
+    /* 147 */ {"var147", "undefined"},
+    /* 148 */ {"var148", "undefined"},
+    /* 149 */ {"var149", "undefined"},
+    /* 150 */ {"var150", "undefined"},
+    /* 151 */ {"var151", "undefined"},
+    /* 152 */ {"var152", "undefined"},
+    /* 153 */ {"var153", "undefined"},
+    /* 154 */ {"var154", "undefined"},
+    /* 155 */ {"var155", "undefined"},
+    /* 156 */ {"var156", "undefined"},
+    /* 157 */ {"var157", "undefined"},
+    /* 158 */ {"var158", "undefined"},
+    /* 159 */ {"var159", "undefined"},
+    /* 160 */ {"var160", "undefined"},
+    /* 161 */ {"var161", "undefined"},
+    /* 162 */ {"var162", "undefined"},
+    /* 163 */ {"var163", "undefined"},
+    /* 164 */ {"var164", "undefined"},
+    /* 165 */ {"var165", "undefined"},
+    /* 166 */ {"var166", "undefined"},
+    /* 167 */ {"var167", "undefined"},
+    /* 168 */ {"var168", "undefined"},
+    /* 169 */ {"var169", "undefined"},
+    /* 170 */ {"var170", "undefined"},
+    /* 171 */ {"var171", "undefined"},
+    /* 172 */ {"var172", "undefined"},
+    /* 173 */ {"var173", "undefined"},
+    /* 174 */ {"var174", "undefined"},
+    /* 175 */ {"var175", "undefined"},
+    /* 176 */ {"var176", "undefined"},
+    /* 177 */ {"var177", "undefined"},
+    /* 178 */ {"var178", "undefined"},
+    /* 179 */ {"var179", "undefined"},
+    /* 180 */ {"var180", "undefined"},
+    /* 181 */ {"var181", "undefined"},
+    /* 182 */ {"var182", "undefined"},
+    /* 183 */ {"var183", "undefined"},
+    /* 184 */ {"var184", "undefined"},
+    /* 185 */ {"var185", "undefined"},
+    /* 186 */ {"var186", "undefined"},
+    /* 187 */ {"var187", "undefined"},
+    /* 188 */ {"var188", "undefined"},
+    /* 189 */ {"var189", "undefined"},
+    /* 190 */ {"var190", "undefined"},
+    /* 191 */ {"var191", "undefined"},
+    /* 192 */ {"var192", "undefined"},
+    /* 193 */ {"var193", "undefined"},
+    /* 194 */ {"var194", "undefined"},
+    /* 195 */ {"var195", "undefined"},
+    /* 196 */ {"var196", "undefined"},
+    /* 197 */ {"var197", "undefined"},
+    /* 198 */ {"var198", "undefined"},
+    /* 199 */ {"var199", "undefined"},
+    /* 200 */ {"var200", "undefined"},
+    /* 201 */ {"var201", "undefined"},
+    /* 202 */ {"var202", "undefined"},
+    /* 203 */ {"var203", "undefined"},
+    /* 204 */ {"var204", "undefined"},
+    /* 205 */ {"var205", "undefined"},
+    /* 206 */ {"var206", "undefined"},
+    /* 207 */ {"var207", "undefined"},
+    /* 208 */ {"var208", "undefined"},
+    /* 209 */ {"var209", "undefined"},
+    /* 210 */ {"var210", "undefined"},
+    /* 211 */ {"var211", "undefined"},
+    /* 212 */ {"var212", "undefined"},
+    /* 213 */ {"var213", "undefined"},
+    /* 214 */ {"var214", "undefined"},
+    /* 215 */ {"var215", "undefined"},
+    /* 216 */ {"var216", "undefined"},
+    /* 217 */ {"var217", "undefined"},
+    /* 218 */ {"var218", "undefined"},
+    /* 219 */ {"var219", "undefined"},
+    /* 220 */ {"var220", "undefined"},
+    /* 221 */ {"var221", "undefined"},
+    /* 222 */ {"var222", "undefined"},
+    /* 223 */ {"var223", "undefined"},
+    /* 224 */ {"var224", "undefined"},
+    /* 225 */ {"var225", "undefined"},
+    /* 226 */ {"var226", "undefined"},
+    /* 227 */ {"var227", "undefined"},
+    /* 228 */ {"var228", "undefined"},
+    /* 229 */ {"var229", "undefined"},
+    /* 230 */ {"var230", "undefined"},
+    /* 231 */ {"var231", "undefined"},
+    /* 232 */ {"var232", "undefined"},
+    /* 233 */ {"var233", "undefined"},
+    /* 234 */ {"var234", "undefined"},
+    /* 235 */ {"var235", "undefined"},
+    /* 236 */ {"var236", "undefined"},
+    /* 237 */ {"var237", "undefined"},
+    /* 238 */ {"var238", "undefined"},
+    /* 239 */ {"var239", "undefined"},
+    /* 240 */ {"var240", "undefined"},
+    /* 241 */ {"var241", "undefined"},
+    /* 242 */ {"var242", "undefined"},
+    /* 243 */ {"var243", "undefined"},
+    /* 244 */ {"var244", "undefined"},
+    /* 245 */ {"var245", "undefined"},
+    /* 246 */ {"var246", "undefined"},
+    /* 247 */ {"var247", "undefined"},
+    /* 248 */ {"var248", "undefined"},
+    /* 249 */ {"var249", "undefined"},
+    /* 250 */ {"var250", "undefined"},
+    /* 251 */ {"var251", "undefined"},
+    /* 252 */ {"var252", "undefined"},
+    /* 253 */ {"var253", "undefined"},
+    /* 254 */ {"var254", "undefined"},
+    /* 255 */ {"var255", "undefined"},
+};
+
+const struct ParmTable parm_table_cptec_254[256] = {
+   /* 0 */ {"var0", "undefined"},
+   /* 1 */ {"PRES", "Pressure [hPa]"},
+   /* 2 */ {"psnm", "Pressure reduced to MSL [hPa]"},
+   /* 3 */ {"tsps", "Pressure tendency [Pa/s]"},
+   /* 4 */ {"var4", "undefined"},
+   /* 5 */ {"var5", "undefined"},
+   /* 6 */ {"geop", "Geopotential [dam]"},
+   /* 7 */ {"zgeo", "Geopotential height [gpm]"},
+   /* 8 */ {"gzge", "Geometric height [m]"},
+   /* 9 */ {"var9", "undefined"},
+   /* 10 */ {"var10", "undefined"},
+   /* 11 */ {"temp", "ABSOLUTE TEMPERATURE [K]"},
+   /* 12 */ {"vtmp", "VIRTUAL TEMPERATURE [K]"},
+   /* 13 */ {"ptmp", "POTENTIAL TEMPERATURE [K]"},
+   /* 14 */ {"psat", "PSEUDO-ADIABATIC POTENTIAL TEMPERATURE [K]"},
+   /* 15 */ {"mxtp", "MAXIMUM TEMPERATURE [K]"},
+   /* 16 */ {"mntp", "MINIMUM TEMPERATURE [K]"},
+   /* 17 */ {"tpor", "DEW POINT TEMPERATURE [K]"},
+   /* 18 */ {"dptd", "DEW POINT DEPRESSION [K]"},
+   /* 19 */ {"lpsr", "LAPSE RATE [K/m]"},
+   /* 20 */ {"var20", "undefined"},
+   /* 21 */ {"rds1", "RADAR SPECTRA(1) [non-dim]"},
+   /* 22 */ {"rds2", "RADAR SPECTRA(2) [non-dim]"},
+   /* 23 */ {"rds3", "RADAR SPECTRA(3) [non-dim]"},
+   /* 24 */ {"var24", "undefined"},
+   /* 25 */ {"tpan", "TEMPERATURE ANOMALY [K]"},
+   /* 26 */ {"psan", "PRESSURE ANOMALY [Pa hPa]"},
+   /* 27 */ {"zgan", "GEOPOT HEIGHT ANOMALY [m]"},
+   /* 28 */ {"wvs1", "WAVE SPECTRA(1) [non-dim]"},
+   /* 29 */ {"wvs2", "WAVE SPECTRA(2) [non-dim]"},
+   /* 30 */ {"wvs3", "WAVE SPECTRA(3) [non-dim]"},
+   /* 31 */ {"wind", "WIND DIRECTION  [deg]"},
+   /* 32 */ {"wins", "WIND SPEED [m/s]"},
+   /* 33 */ {"uvel", "ZONAL WIND (U) [m/s]"},
+   /* 34 */ {"vvel", "MERIDIONAL WIND (V) [m/s]"},
+   /* 35 */ {"fcor", "STREAM FUNCTION [m2/s]"},
+   /* 36 */ {"potv", "VELOCITY POTENTIAL [m2/s]"},
+   /* 37 */ {"var37", "undefined"},
+   /* 38 */ {"sgvv", "SIGMA COORD VERT VEL [sec/sec]"},
+   /* 39 */ {"omeg", "OMEGA [Pa/s]"},
+   /* 40 */ {"omg2", "VERTICAL VELOCITY [m/s]"},
+   /* 41 */ {"abvo", "ABSOLUTE VORTICITY        [10**5/sec]"},
+   /* 42 */ {"abdv", "ABSOLUTE DIVERGENCE [10**5/sec]"},
+   /* 43 */ {"vort", "VORTICITY  [1/s]"},
+   /* 44 */ {"divg", "DIVERGENCE [1/s]"},
+   /* 45 */ {"vucs", "VERTICAL U-COMP SHEAR [1/sec]"},
+   /* 46 */ {"vvcs", "VERT V-COMP SHEAR [1/sec]"},
+   /* 47 */ {"dirc", "DIRECTION OF CURRENT [deg]"},
+   /* 48 */ {"spdc", "SPEED OF CURRENT [m/s]"},
+   /* 49 */ {"ucpc", "U-COMPONENT OF CURRENT [m/s]"},
+   /* 50 */ {"vcpc", "V-COMPONENT OF CURRENT [m/s]"},
+   /* 51 */ {"umes", "SPECIFIC HUMIDITY [kg/kg]"},
+   /* 52 */ {"umrl", "RELATIVE HUMIDITY [no Dim]"},
+   /* 53 */ {"hmxr", "HUMIDITY MIXING RATIO [kg/kg]"},
+   /* 54 */ {"agpl", "INST. PRECIPITABLE WATER [Kg/m2]"},
+   /* 55 */ {"vapp", "VAPOUR PRESSURE [Pa hpa]"},
+   /* 56 */ {"sadf", "SATURATION DEFICIT        [Pa hPa]"},
+   /* 57 */ {"evap", "EVAPORATION [Kg/m2/day]"},
+   /* 58 */ {"var58", "undefined"},
+   /* 59 */ {"prcr", "PRECIPITATION RATE        [kg/m2/day]"},
+   /* 60 */ {"thpb", "THUNDER PROBABILITY [%]"},
+   /* 61 */ {"prec", "TOTAL PRECIPITATION [Kg/m2/day]"},
+   /* 62 */ {"prge", "LARGE SCALE PRECIPITATION [Kg/m2/day]"},
+   /* 63 */ {"prcv", "CONVECTIVE PRECIPITATION [Kg/m2/day]"},
+   /* 64 */ {"neve", "SNOWFALL [Kg/m2/day]"},
+   /* 65 */ {"wenv", "WAT EQUIV ACC SNOW DEPTH [kg/m2]"},
+   /* 66 */ {"nvde", "SNOW DEPTH        [cm]"},
+   /* 67 */ {"mxld", "MIXED LAYER DEPTH [m cm]"},
+   /* 68 */ {"tthd", "TRANS THERMOCLINE DEPTH [m cm]"},
+   /* 69 */ {"mthd", "MAIN THERMOCLINE DEPTH [m cm]"},
+   /* 70 */ {"mtha", "MAIN THERMOCLINE ANOM [m cm]"},
+   /* 71 */ {"cbnv", "CLOUD COVER [0-1]"},
+   /* 72 */ {"cvnv", "CONVECTIVE CLOUD COVER [0-1]"},
+   /* 73 */ {"lwnv", "LOW CLOUD COVER [0-1]"},
+   /* 74 */ {"mdnv", "MEDIUM CLOUD COVER        [0-1]"},
+   /* 75 */ {"hinv", "HIGH CLOUD COVER [0-1]"},
+   /* 76 */ {"wtnv", "CLOUD WATER [kg/m2]"},
+   /* 77 */ {"bli", "BEST LIFTED INDEX (TO 500 HPA) [K]"},
+   /* 78 */ {"var78", "undefined"},
+   /* 79 */ {"var79", "undefined"},
+   /* 80 */ {"var80", "undefined"},
+   /* 81 */ {"lsmk", "LAND SEA MASK [0,1]"},
+   /* 82 */ {"dslm", "DEV SEA_LEV FROM MEAN [m]"},
+   /* 83 */ {"zorl", "ROUGHNESS LENGTH [m]"},
+   /* 84 */ {"albe", "ALBEDO [%]"},
+   /* 85 */ {"dstp", "DEEP SOIL TEMPERATURE [K]"},
+   /* 86 */ {"soic", "SOIL MOISTURE CONTENT [Kg/m2]"},
+   /* 87 */ {"vege", "VEGETATION        [%]"},
+   /* 88 */ {"var88", "undefined"},
+   /* 89 */ {"dens", "DENSITY [kg/m3]"},
+   /* 90 */ {"var90", "Undefined"},
+   /* 91 */ {"icec", "ICE CONCENTRATION [fraction]"},
+   /* 92 */ {"icet", "ICE THICKNESS [m]"},
+   /* 93 */ {"iced", "DIRECTION OF ICE DRIFT [deg]"},
+   /* 94 */ {"ices", "SPEED OF ICE DRIFT        [m/s]"},
+   /* 95 */ {"iceu", "U-COMP OF ICE DRIFT [m/s]"},
+   /* 96 */ {"icev", "V-COMP OF ICE DRIFT [m/s]"},
+   /* 97 */ {"iceg", "ICE GROWTH        [m]"},
+   /* 98 */ {"icdv", "ICE DIVERGENCE [sec/sec]"},
+   /* 99 */ {"var99", "undefined"},
+   /* 100 */ {"shcw", "SIG HGT COM WAVE/SWELL [m]"},
+   /* 101 */ {"wwdi", "DIRECTION OF WIND WAVE [deg]"},
+   /* 102 */ {"wwsh", "SIG HGHT OF WIND WAVES [m]"},
+   /* 103 */ {"wwmp", "MEAN PERIOD WIND WAVES [sec]"},
+   /* 104 */ {"swdi", "DIRECTION OF SWELL WAVE [deg]"},
+   /* 105 */ {"swsh", "SIG HEIGHT SWELL WAVES [m]"},
+   /* 106 */ {"swmp", "MEAN PERIOD SWELL WAVES [sec]"},
+   /* 107 */ {"prwd", "PRIMARY WAVE DIRECTION [deg]"},
+   /* 108 */ {"prmp", "PRIM WAVE MEAN PERIOD [s]"},
+   /* 109 */ {"swdi", "SECOND WAVE DIRECTION [deg]"},
+   /* 110 */ {"swmp", "SECOND WAVE MEAN PERIOD [s]"},
+   /* 111 */ {"ocas", "SHORT WAVE ABSORBED AT GROUND [W/m2]"},
+   /* 112 */ {"slds", "NET LONG WAVE AT BOTTOM [W/m2]"},
+   /* 113 */ {"nswr", "NET SHORT-WAV RAD(TOP) [W/m2]"},
+   /* 114 */ {"role", "OUTGOING LONG WAVE AT TOP [W/m2]"},
+   /* 115 */ {"lwrd", "LONG-WAV RAD [W/m2]"},
+   /* 116 */ {"swea", "SHORT WAVE ABSORBED BY EARTH/ATMOSPHERE  [W/m2]"},
+   /* 117 */ {"glbr", "GLOBAL RADIATION [W/m2 ]"},
+   /* 118 */ {"var118", "undefined"},
+   /* 119 */ {"var119", "undefined"},
+   /* 120 */ {"var120", "undefined"},
+   /* 121 */ {"clsf", "LATENT HEAT FLUX FROM SURFACE [W/m2]"},
+   /* 122 */ {"cssf", "SENSIBLE HEAT FLUX FROM SURFACE [W/m2]"},
+   /* 123 */ {"blds", "BOUND LAYER DISSIPATION [W/m2]"},
+   /* 124 */ {"var124", "undefined"},
+   /* 125 */ {"var125", "undefined"},
+   /* 126 */ {"var126", "undefined"},
+   /* 127 */ {"imag", "IMAGE [image^data]"},
+   /* 128 */ {"tp2m", "2 METRE TEMPERATURE [K]"},
+   /* 129 */ {"dp2m", "2 METRE DEWPOINT TEMPERATURE [K]"},
+   /* 130 */ {"u10m", "10 METRE U-WIND COMPONENT [m/s]"},
+   /* 131 */ {"v10m", "10 METRE V-WIND COMPONENT [m/s]"},
+   /* 132 */ {"topo", "TOPOGRAPHY [m]"},
+   /* 133 */ {"gsfp", "GEOMETRIC MEAN SURFACE PRESSURE [hPa]"},
+   /* 134 */ {"lnsp", "LN SURFACE PRESSURE [hPa]"},
+   /* 135 */ {"pslc", "SURFACE PRESSURE [hPa]"},
+   /* 136 */ {"pslm", "M S L PRESSURE (MESINGER METHOD) [hPa]"},
+   /* 137 */ {"mask", "MASK  [-/+]"},
+   /* 138 */ {"mxwu", "MAXIMUM U-WIND [m/s]"},
+   /* 139 */ {"mxwv", "MAXIMUM V-WIND [m/s]"},
+   /* 140 */ {"cape", "CONVECTIVE AVAIL. POT.ENERGY [m2/s2]"},
+   /* 141 */ {"cine", "CONVECTIVE INHIB. ENERGY [m2/s2]"},
+   /* 142 */ {"lhcv", "CONVECTIVE LATENT HEATING [K/s]"},
+   /* 143 */ {"mscv", "CONVECTIVE MOISTURE SOURCE [1/s]"},
+   /* 144 */ {"scvm", "SHALLOW CONV. MOISTURE SOURCE [1/s]"},
+   /* 145 */ {"scvh", "SHALLOW CONVECTIVE HEATING [K/s]"},
+   /* 146 */ {"mxwp", "MAXIMUM WIND PRESS. LVL  [hPa]"},
+   /* 147 */ {"ustr", "STORM MOTION U-COMPONENT [m/s]"},
+   /* 148 */ {"vstr", "STORM MOTION V-COMPONENT [m/s]"},
+   /* 149 */ {"cbnt", "MEAN CLOUD COVER [0-1]"},
+   /* 150 */ {"pcbs", "PRESSURE AT CLOUD BASE [hPa]"},
+   /* 151 */ {"pctp", "PRESSURE AT CLOUD TOP [hPa]"},
+   /* 152 */ {"fzht", "FREEZING LEVEL HEIGHT [m]"},
+   /* 153 */ {"fzrh", "FREEZING LEVEL RELATIVE HUMIDITY [%]"},
+   /* 154 */ {"fdlt", "FLIGHT LEVELS TEMPERATURE [K]"},
+   /* 155 */ {"fdlu", "FLIGHT LEVELS U-WIND [m/s]"},
+   /* 156 */ {"fdlv", "FLIGHT LEVELS V-WIND [m/s]"},
+   /* 157 */ {"tppp", "TROPOPAUSE PRESSURE   [hPa]"},
+   /* 158 */ {"tppt", "TROPOPAUSE TEMPERATURE [K]"},
+   /* 159 */ {"tppu", "TROPOPAUSE U-WIND COMPONENT [m/s]"},
+   /* 160 */ {"tppv", "TROPOPAUSE v-WIND COMPONENT [m/s]"},
+   /* 161 */ {"var161", "undefined"},
+   /* 162 */ {"gvdu", "GRAVITY WAVE DRAG DU/DT [m/s2]"},
+   /* 163 */ {"gvdv", "GRAVITY WAVE DRAG DV/DT [m/s2]"},
+   /* 164 */ {"gvus", "GRAVITY WAVE DRAG SFC ZONAL STRESS  [Pa]"},
+   /* 165 */ {"gvvs", "GRAVITY WAVE DRAG SFC MERIDIONAL STRESS [Pa]"},
+   /* 166 */ {"var166", "undefined"},
+   /* 167 */ {"dvsh", "DIVERGENCE OF SPECIFIC HUMIDITY [1/s]"},
+   /* 168 */ {"hmfc", "HORIZ. MOISTURE FLUX CONV.  [1/s]"},
+   /* 169 */ {"vmfl", "VERT. INTEGRATED MOISTURE FLUX CONV. [kg/(m2*s)]"},
+   /* 170 */ {"vadv", "VERTICAL MOISTURE ADVECTION  [kg/(kg*s)]"},
+   /* 171 */ {"nhcm", "NEG. HUM. CORR. MOISTURE SOURCE [kg/(kg*s)]"},
+   /* 172 */ {"lglh", "LARGE SCALE LATENT HEATING   [K/s]"},
+   /* 173 */ {"lgms", "LARGE SCALE MOISTURE SOURCE  [1/s]"},
+   /* 174 */ {"smav", "SOIL MOISTURE AVAILABILITY  [0-1]"},
+   /* 175 */ {"tgrz", "SOIL TEMPERATURE OF ROOT ZONE [K]"},
+   /* 176 */ {"bslh", "BARE SOIL LATENT HEAT [Ws/m2]"},
+   /* 177 */ {"evpp", "POTENTIAL SFC EVAPORATION [m]"},
+   /* 178 */ {"rnof", "RUNOFF [kg/m2/s)]"},
+   /* 179 */ {"pitp", "INTERCEPTION LOSS [W/m2]"},
+   /* 180 */ {"vpca", "VAPOR PRESSURE OF CANOPY AIR SPACE [mb]"},
+   /* 181 */ {"qsfc", "SURFACE SPEC HUMIDITY   [kg/kg]"},
+   /* 182 */ {"ussl", "SOIL WETNESS OF SURFACE [0-1]"},
+   /* 183 */ {"uzrs", "SOIL WETNESS OF ROOT ZONE [0-1]"},
+   /* 184 */ {"uzds", "SOIL WETNESS OF DRAINAGE ZONE [0-1]"},
+   /* 185 */ {"amdl", "STORAGE ON CANOPY [m]"},
+   /* 186 */ {"amsl", "STORAGE ON GROUND [m]"},
+   /* 187 */ {"tsfc", "SURFACE TEMPERATURE [K]"},
+   /* 188 */ {"tems", "SURFACE ABSOLUTE TEMPERATURE [K]"},
+   /* 189 */ {"tcas", "TEMPERATURE OF CANOPY AIR SPACE [K]"},
+   /* 190 */ {"ctmp", "TEMPERATURE AT CANOPY [K]"},
+   /* 191 */ {"tgsc", "GROUND/SURFACE COVER TEMPERATURE [K]"},
+   /* 192 */ {"uves", "SURFACE ZONAL WIND (U) [m/s]"},
+   /* 193 */ {"usst", "SURFACE ZONAL WIND STRESS [Pa]"},
+   /* 194 */ {"vves", "SURFACE MERIDIONAL WIND (V) [m/s]"},
+   /* 195 */ {"vsst", "SURFACE MERIDIONAL WIND STRESS [Pa]"},
+   /* 196 */ {"suvf", "SURFACE MOMENTUM FLUX [W/m2]"},
+   /* 197 */ {"iswf", "INCIDENT SHORT WAVE FLUX [W/m2]"},
+   /* 198 */ {"ghfl", "TIME AVE GROUND HT FLX   [W/m2]"},
+   /* 199 */ {"var199", "undefined"},
+   /* 200 */ {"lwbc", "NET LONG WAVE AT BOTTOM (CLEAR) [W/m2]"},
+   /* 201 */ {"lwtc", "OUTGOING LONG WAVE AT TOP (CLEAR) [W/m2]"},
+   /* 202 */ {"swec", "SHORT WV ABSRBD BY EARTH/ATMOS (CLEAR) [W/m2]"},
+   /* 203 */ {"ocac", "SHORT WAVE ABSORBED AT GROUND (CLEAR) [W/m2]"},
+   /* 204 */ {"var204", "undefined"},
+   /* 205 */ {"lwrh", "LONG WAVE RADIATIVE HEATING  [K/s]"},
+   /* 206 */ {"swrh", "SHORT WAVE RADIATIVE HEATING [K/s]"},
+   /* 207 */ {"olis", "DOWNWARD LONG WAVE AT BOTTOM [W/m2]"},
+   /* 208 */ {"olic", "DOWNWARD LONG WAVE AT BOTTOM (CLEAR) [W/m2]"},
+   /* 209 */ {"ocis", "DOWNWARD SHORT WAVE AT GROUND [W/m2]"},
+   /* 210 */ {"ocic", "DOWNWARD SHORT WAVE AT GROUND (CLEAR) [W/m2]"},
+   /* 211 */ {"oles", "UPWARD LONG WAVE AT BOTTOM [W/m2]"},
+   /* 212 */ {"oces", "UPWARD SHORT WAVE AT GROUND [W/m2]"},
+   /* 213 */ {"swgc", "UPWARD SHORT WAVE AT GROUND (CLEAR) [W/m2]"},
+   /* 214 */ {"roce", "UPWARD SHORT WAVE AT TOP [W/m2]"},
+   /* 215 */ {"swtc", "UPWARD SHORT WAVE AT TOP (CLEAR) [W/m2]"},
+   /* 216 */ {"var216", "undefined"},
+   /* 217 */ {"var217", "undefined"},
+   /* 218 */ {"hhdf", "HORIZONTAL HEATING DIFFUSION [K/s]"},
+   /* 219 */ {"hmdf", "HORIZONTAL MOISTURE DIFFUSION [1/s]"},
+   /* 220 */ {"hddf", "HORIZONTAL DIVERGENCE DIFFUSION [1/s2]"},
+   /* 221 */ {"hvdf", "HORIZONTAL VORTICITY DIFFUSION [1/s2]"},
+   /* 222 */ {"vdms", "VERTICAL DIFF. MOISTURE SOURCE [1/s]"},
+   /* 223 */ {"vdfu", "VERTICAL DIFFUSION DU/DT [m/s2]"},
+   /* 224 */ {"vdfv", "VERTICAL DIFFUSION DV/DT [m/s2]"},
+   /* 225 */ {"vdfh", "VERTICAL DIFFUSION HEATING [K/s]"},
+   /* 226 */ {"umrs", "SURFACE RELATIVE HUMIDITY [no Dim]"},
+   /* 227 */ {"vdcc", "VERTICAL DIST TOTAL CLOUD COVER [no Dim]"},
+   /* 228 */ {"var228", "undefined"},
+   /* 229 */ {"var229", "undefined"},
+   /* 230 */ {"usmt", "TIME MEAN SURFACE ZONAL WIND (U) [m/s]"},
+   /* 231 */ {"vsmt", "TIME MEAN SURFACE MERIDIONAL WIND (V) [m/s]"},
+   /* 232 */ {"tsmt", "TIME MEAN SURFACE ABSOLUTE TEMPERATURE [K]"},
+   /* 233 */ {"rsmt", "TIME MEAN SURFACE RELATIVE HUMIDITY [no Dim]"},
+   /* 234 */ {"atmt", "TIME MEAN ABSOLUTE TEMPERATURE [K]"},
+   /* 235 */ {"stmt", "TIME MEAN DEEP SOIL TEMPERATURE [K]"},
+   /* 236 */ {"ommt", "TIME MEAN DERIVED OMEGA [Pa/s]"},
+   /* 237 */ {"dvmt", "TIME MEAN DIVERGENCE [1/s]"},
+   /* 238 */ {"zhmt", "TIME MEAN GEOPOTENTIAL HEIGHT [m]"},
+   /* 239 */ {"lnmt", "TIME MEAN LOG SURFACE PRESSURE [ln(cbar)]"},
+   /* 240 */ {"mkmt", "TIME MEAN MASK [-/+]"},
+   /* 241 */ {"vvmt", "TIME MEAN MERIDIONAL WIND (V) [m/s]"},
+   /* 242 */ {"omtm", "TIME MEAN OMEGA  [cbar/s]"},
+   /* 243 */ {"ptmt", "TIME MEAN POTENTIAL TEMPERATURE [K]"},
+   /* 244 */ {"pcmt", "TIME MEAN PRECIP. WATER  [kg/m2]"},
+   /* 245 */ {"rhmt", "TIME MEAN RELATIVE HUMIDITY [%]"},
+   /* 246 */ {"mpmt", "TIME MEAN SEA LEVEL PRESSURE [hPa]"},
+   /* 247 */ {"simt", "TIME MEAN SIGMADOT [1/s]"},
+   /* 248 */ {"uemt", "TIME MEAN SPECIFIC HUMIDITY [kg/kg]"},
+   /* 249 */ {"fcmt", "TIME MEAN STREAM FUNCTION| m2/s]"},
+   /* 250 */ {"psmt", "TIME MEAN SURFACE PRESSURE [hPa]"},
+   /* 251 */ {"tmmt", "TIME MEAN SURFACE TEMPERATURE [K]"},
+   /* 252 */ {"pvmt", "TIME MEAN VELOCITY POTENTIAL [m2/s]"},
+   /* 253 */ {"tvmt", "TIME MEAN VIRTUAL TEMPERATURE [K]"},
+   /* 254 */ {"vtmt", "TIME MEAN VORTICITY [1/s]"},
+   /* 255 */ {"uvmt", "TIME MEAN ZONAL WIND (U) [m/s]"},
+};
+
+
+/*
+ * support for complex packing
+ *  determine the number of data points in the BDS
+ *  does not handle matrix values
+ */
+
+extern int ec_large_grib,  len_ec_bds;
+
+
+int BDS_NValues(unsigned char *bds) {
+
+    /* returns number of grid points as determined from the BDS */
+
+    int i = 0;
+
+    if (BDS_SimplePacking(bds) && BDS_Grid(bds)) {
+	i = ((BDS_LEN(bds) - BDS_DataStart(bds))*8 -
+		BDS_UnusedBits(bds)) / (BDS_NumBits(bds));
+    }
+    else if (BDS_ComplexPacking(bds) && BDS_Grid(bds)) {
+	i = BDS_P2(bds);
+    }
+    return i;
+}
diff --git a/src/wx.h b/src/wx.h
new file mode 100644
index 0000000..0de41a9
--- /dev/null
+++ b/src/wx.h
@@ -0,0 +1,115 @@
+/*  Copyright (C) 1988-2011 by Brian Doty and the 
+    Institute of Global Environment and Society (IGES).  
+    See file COPYRIGHT for more information.   */
+
+/*  Constants for generating wx symbols */
+
+gaint stype[83] =
+    { 11, 8, 8, 2, 8, 1, 8,16, 8, 6, 9, 9, 2, 9, 1,
+       9,16, 9, 6,10, 2, 2,10, 2, 5, 2, 4, 2, 2, 2,
+       2, 2, 2, 2, 2, 2, 2, 4, 1, 5, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 7, 2, 7, 2,10, 3, 3,10, 3, 3,
+       3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 5, 6,13,12,14,
+      15, 2, 1,17,18,19,19,20};
+gadouble sxpos[83] =
+    {   0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  , -0.175,
+        0.175,  0.0  , -0.175,  0.0  ,  0.0  ,  0.0  ,  0.0,
+       -0.150,  0.150, -0.150,  0.150,  0.0  , -0.150,  0.150,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  , -0.200,
+        0.200, -0.200,  0.200,  0.0  , -0.200,  0.200,  0.0,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  , -0.175,
+        0.175,  0.0  , -0.175, -0.150,  0.150, -0.150,  0.150,
+        0.0  , -0.150,  0.150,  0.0  ,  0.0  ,  0.0  ,  0.0,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0,
+        0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0};
+gadouble sypos[83] =
+    {   0.0  ,  0.0  , -0.1  ,  0.375, -0.1  ,  0.400, -0.1,
+        0.350, -0.1  ,  0.375,  0.0  ,  0.0  ,  0.475,  0.0,
+        0.500,  0.0  ,  0.450,  0.0  ,  0.475,  0.0  , -0.10,
+        0.10 ,  0.0  , -0.1  , -0.1 ,  0.275, -0.1  ,  0.275,
+        0.0  ,  0.0  , -0.100, -0.100,  0.150,  0.0  ,  0.0,
+        0.250, -0.250, -0.2  ,  0.250, -0.2  ,  0.250,  0.0,
+        0.0  , -0.150, -0.150,  0.200,  0.0  ,  0.0  ,  0.300,
+       -0.300,  0.0  , -0.100,  0.0  , -0.100,  0.0  , -0.150,
+        0.150,  0.0  , -0.150,  0.0  ,  0.0  , -0.100, -0.100,
+        0.150,  0.0  ,  0.0  ,  0.250, -0.250, -0.15 ,  0.300,
+       -0.15 ,  0.300,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.200,
+       -0.200,  0.0  ,  0.0  ,  0.0  ,  0.0  ,  0.0};
+gaint strt[43] = {1,2,3,5,7,9,11,12,14,16,18,20,23,25,27,29,31,
+       34,38,40,42,44,47,51,53,55,58,60,62,65,69,71,73,74,75,
+       76,77,79,80,81,82,83,83};
+gaint scnt[43] = {1,1,2,2,2,2,1,2,2,2,2,3,2,2,2,2,3,4,2,2,
+       2,3,4,2,2,3,2,2,3,4,2,2,1,1,1,1,2,1,1,1,1,1,1};
+gadouble symin[39] = {-.35,-.3,-.4,-.4,-.4,-.4,-.45,-.45,-.45,-.45,-.45,
+       -.2,-.2,-.3,-.3,-.1,-.25,-.35,-.45,
+       -.45,-.15,-.30,-.45,-.3,-.3,-.25,-.25,-.15,-.25,-.4,-.35,
+       -.35,-.15,-.15,-.25,-.35,-.35,-.25,-.2};
+gadouble symax[39] = {.35,.3,.45,.5,.45,.45,.3,.55,.6,.55,.55,
+       .2,.2,.35,.35,.1,.25,.35,.4,.4,.15,.35,.45,.3,.3,.25,.2,
+       .15,.3,.4,.40,.40,.15,.15,.25,.35,.4,.25,.25};
+gadouble sxwid[39] = {.4,.5,.5,.5,.5,.5,.5,.5,.5,.5,.5,
+       .7,.7,.4,.4,.5,.5,.5,.5,.5,.7,.7,.7,.7,.7,.7,.7,
+       .5,.5,.5,.4,.4,.6,.5,.5,.3,.3,.3,.4};
+gaint soff[20] =  {1,7,20,35,39,45,49,53,61,70,84,92,96,104,
+                         114,131,139,145,157,171};
+gaint slen[20] =  {6,13,15,4,6,4,4,8,9,14,8,4,8,10,17,8,6,12,14,14};
+gaint scol[20] =  {2,1,1,1,1,0,0,0,0,0,0,3,4,4,4,0,0,4,0,0};
+gadouble xpts[184] =
+       { -0.150, 0.150,-0.150, 0.150, 0.0  , 0.0  ,-0.100,-0.087,
+         -0.050, 0.0  , 0.050, 0.087, 0.100, 0.087, 0.050, 0.0  ,
+         -0.050,-0.087,-0.100, 0.030,-0.050,-0.100,-0.087,-0.050,
+          0.0  , 0.050, 0.087, 0.100, 0.100, 0.087, 0.050, 0.0  ,
+          0.030, 0.030,-0.200, 0.200, 0.0  ,-0.200,-0.200, 0.200,
+          0.0  ,-0.200,-0.150, 0.150,-0.150, 0.0  , 0.150,-0.150,
+         -0.350, 0.0  , 0.350,-0.350,-0.250,-0.250, 0.250,-0.150,
+          0.250, 0.200, 0.250, 0.100,-0.250,-0.250, 0.250,-0.150,
+          0.250, 0.050, 0.100, 0.050, 0.200,-0.350,-0.350,-0.320,
+         -0.250,-0.175,-0.100,-0.050, 0.050, 0.100, 0.175, 0.250,
+          0.320, 0.350, 0.350,-0.200,-0.100,-0.100,-0.200, 0.200,
+          0.100, 0.100, 0.200,-0.250, 0.250,-0.250, 0.250,-0.175,
+         -0.300,-0.175,-0.300, 0.300, 0.175, 0.300, 0.175,-0.250,
+          0.250, 0.150, 0.250, 0.150, 0.0  , 0.0  ,-0.100, 0.0  ,
+          0.100, 0.0  , 0.0  ,-0.100, 0.0  , 0.100, 0.150, 0.050,
+         -0.050,-0.130,-0.150,-0.120, 0.120, 0.150, 0.130, 0.050,
+         -0.050,-0.150,-0.150,-0.150,-0.100,-0.050, 0.050, 0.100,
+          0.150, 0.150, 0.150,-0.150, 0.150, 0.110, 0.150, 0.000,
+         -0.150,-0.150,-0.130,-0.100,-0.070,-0.030, 0.000, 0.030,
+          0.070, 0.100, 0.130, 0.170,-0.200,-0.200,-0.180,-0.150,
+         -0.100,-0.030, 0.050, 0.200, 0.200, 0.180, 0.150, 0.100,
+          0.030,-0.050,-0.200,-0.200,-0.180,-0.150,-0.100,-0.030,
+          0.050, 0.200, 0.200, 0.180, 0.150, 0.100, 0.030,-0.050};
+gadouble ypts[184] =
+       { 0.100,-0.100,-0.100, 0.100, 0.175,-0.175, 0.0  , 0.050,
+         0.087, 0.100, 0.087, 0.050, 0.0  ,-0.050,-0.087,-0.100,
+        -0.087,-0.050, 0.0  , 0.0  , 0.0  , 0.050, 0.100, 0.137,
+         0.150, 0.137, 0.100, 0.050, 0.0  ,-0.050,-0.100,-0.150,
+        -0.075, 0.0  , 0.200, 0.200,-0.200, 0.200, 0.200, 0.200,
+        -0.200, 0.200, 0.100, 0.100,-0.100, 0.100,-0.100,-0.100,
+        -0.300, 0.300,-0.300,-0.300,-0.300, 0.300, 0.300, 0.0  ,
+        -0.300,-0.150,-0.300,-0.280,-0.300, 0.300, 0.300, 0.0  ,
+        -0.300,-0.450,-0.300,-0.450,-0.430,-0.150, 0.0  , 0.100,
+         0.160, 0.175, 0.160, 0.100,-0.100,-0.160,-0.175,-0.160,
+        -0.100, 0.0  , 0.150, 0.350, 0.250,-0.250,-0.350, 0.350,
+         0.250,-0.250,-0.350, 0.100, 0.100,-0.100,-0.100, 0.125,
+         0.0  ,-0.125, 0.0  , 0.0  , 0.125, 0.0  ,-0.125, 0.0  ,
+         0.0  , 0.100, 0.0  ,-0.100,-0.250, 0.250, 0.150, 0.250,
+         0.150,-0.350, 0.350, 0.200, 0.350, 0.200, 0.100, 0.150,
+         0.150, 0.100, 0.050, 0.0  ,-0.100,-0.150,-0.200,-0.250,
+        -0.250,-0.200,-0.075, 0.0  , 0.075, 0.075,-0.075,-0.075,
+         0.0  , 0.075, 0.250, 0.0  ,-0.250,-0.100,-0.250,-0.220,
+        -0.200, 0.200, 0.240, 0.255, 0.240, 0.160, 0.145, 0.160,
+         0.240, 0.255, 0.240, 0.160, 0.000, 0.200, 0.300, 0.380,
+         0.430, 0.470, 0.500, 0.000,-0.200,-0.300,-0.380,-0.430,
+        -0.470,-0.500, 0.000,-0.200,-0.300,-0.380,-0.430,-0.470,
+        -0.500, 0.000, 0.200, 0.300, 0.380, 0.430, 0.470, 0.500};
+gaint spens[184] =
+      { 3,2,3,2,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,
+        2,2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,3,2,2,2,3,2,
+        2,2,3,2,2,2,2,2,3,2,3,2,2,2,2,2,2,3,2,3,2,2,2,2,2,
+        2,2,2,2,2,2,2,2,3,2,2,2,3,2,2,2,3,2,3,2,3,2,2,3,2,
+        3,2,2,3,2,3,2,2,3,2,3,2,2,3,2,3,2,2,3,2,2,2,2,2,2,
+        2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,2,2,3,2,3,2,2,2,2,2,
+        2,2,2,2,2,2,3,2,2,2,2,2,2,3,2,2,2,2,2,2,3,2,2,2,2,
+        2,2,3,2,2,2,2,2,2};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/grads.git



More information about the debian-science-commits mailing list