[cdo] 08/14: upstream 1.9.2

Alastair McKinstry mckinstry at moszumanska.debian.org
Tue Dec 12 12:46:30 UTC 2017


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

mckinstry pushed a commit to branch debian/master
in repository cdo.

commit 68f08c4b05d01070f4de0c0b1e63188af19217b3
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Sat Dec 9 07:29:48 2017 +0000

    upstream 1.9.2
---
 ChangeLog                         |   5 +
 NEWS                              |   3 +-
 cdo.spec                          |   2 +-
 configure                         |  20 +-
 configure.ac                      |   2 +-
 doc/cdo.pdf                       | Bin 2721828 -> 2721828 bytes
 doc/cdo_refcard.pdf               | Bin 97632 -> 98545 bytes
 libcdi/ChangeLog                  |   2 +-
 libcdi/src/Makefile.in            |   2 +-
 libcdi/src/cdi.inc                |  14 +-
 src/._getMemorySize.c             | Bin 561 -> 0 bytes
 src/CMOR.cc                       |   8 +-
 src/Change_e5slm.cc               |   8 +-
 src/Consecstat.cc                 |   6 +-
 src/Copy.cc                       |   4 -
 src/Exprf.cc                      |  86 ++++++++-
 src/Fillmiss.cc                   |   4 -
 src/Remap.cc                      |   9 +-
 src/Samplegridicon.cc             |   4 -
 src/Selmulti.cc                   |   4 -
 src/Setmiss.cc                    |  35 ++--
 src/Verifygrid.cc                 | 102 +++++-----
 src/WindTrans.cc                  |   4 -
 src/YAR.cc                        |   4 -
 src/after_sptrans.cc              |   4 -
 src/after_vertint.h               |   8 -
 src/cdo.cc                        |   4 -
 src/compare.h                     |   3 +-
 src/expr.cc                       |  86 ++++++++-
 src/expr.h                        |   2 -
 src/expr_lex.cc                   | 387 +++++++++++++++++++-------------------
 src/expr_yacc.cc                  | 299 +++++++++++++++--------------
 src/expr_yacc.h                   |   4 +-
 src/grid_area.cc                  |   4 -
 src/grid_proj.h                   |  12 +-
 src/grid_search.cc                | 100 ++++++----
 src/grid_search.h                 |  12 +-
 src/modules.cc                    | 129 +++++++------
 src/nanoflann.hpp                 |   4 +-
 src/process.cc                    |   7 +-
 src/remap_conserv.cc              |   4 -
 src/remaplib.cc                   |  11 +-
 test/data/tsurf_spain_dis_off_ref | Bin 1488 -> 1488 bytes
 43 files changed, 775 insertions(+), 633 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bd47157..036228a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,11 @@
 	* Using CDI library version 1.9.2
 	* Version 1.9.2 release
 
+2017-11-21  Uwe Schulzweida
+
+	* expr: added variable name template _T
+	* expr: added operator ! (NOT)
+
 2017-11-17  Uwe Schulzweida
 
 	* rotuvb changed behavior in different versions [Bug #8084]
diff --git a/NEWS b/NEWS
index 09510bb..b8b482c 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,8 @@ Version 1.9.2 (23 November 2017):
    Fixed bugs:
      * sign of grid size increment changes [Bug #7974]
      * compilation fails on OpenBSD [Bug #7961]
-     * expr: nesting of ?: operator lost in cdo-1.9.1 [Bug #7992]
+     * expr: nesting of ternary operator lost in cdo-1.9.1 [Bug #7992]
+     * rotuvb changed behavior in different versions [Bug #8084]
      * select with start=end range aborts with 'Invalid character' [Bug #7976]
 
 Version 1.9.1 (27 September 2017):
diff --git a/cdo.spec b/cdo.spec
index 7e94b3b..c265ee9 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.9.2rc2
+Version:        1.9.2
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/configure b/configure
index 6d04830..7663049 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdo 1.9.2rc2.
+# Generated by GNU Autoconf 2.68 for cdo 1.9.2.
 #
 # Report bugs to <http://mpimet.mpg.de/cdo>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdo'
 PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.9.2rc2'
-PACKAGE_STRING='cdo 1.9.2rc2'
+PACKAGE_VERSION='1.9.2'
+PACKAGE_STRING='cdo 1.9.2'
 PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdo'
 PACKAGE_URL=''
 
@@ -1414,7 +1414,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cdo 1.9.2rc2 to adapt to many kinds of systems.
+\`configure' configures cdo 1.9.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1484,7 +1484,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.9.2rc2:";;
+     short | recursive ) echo "Configuration of cdo 1.9.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1640,7 +1640,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.9.2rc2
+cdo configure 1.9.2
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2359,7 +2359,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cdo $as_me 1.9.2rc2, which was
+It was created by cdo $as_me 1.9.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3308,7 +3308,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.9.2rc2'
+ VERSION='1.9.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -26467,7 +26467,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdo $as_me 1.9.2rc2, which was
+This file was extended by cdo $as_me 1.9.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -26533,7 +26533,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdo config.status 1.9.2rc2
+cdo config.status 1.9.2
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 38cc6d0..47e0daa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 #  autoconf 2.68
 #  libtool  2.4.2
 
-AC_INIT([cdo], [1.9.2rc2], [http://mpimet.mpg.de/cdo])
+AC_INIT([cdo], [1.9.2], [http://mpimet.mpg.de/cdo])
 
 AC_DEFINE_UNQUOTED(CDO, ["$PACKAGE_VERSION"], [CDO version])
 
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index 49ee6c7..7251845 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index 673f350..7798691 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index a8cfcf8..dea3313 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,4 +1,4 @@
-2017-11-23  Uwe Schulzweida
+2017-11-21  Uwe Schulzweida
 
 	* Version 1.9.2 released
 
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 176506f..4990e5f 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -947,8 +947,8 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
- at ENABLE_CDI_LIB_FALSE@install-exec-local:
 @ENABLE_CDI_LIB_FALSE at uninstall-local:
+ at ENABLE_CDI_LIB_FALSE@install-exec-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index 88507ca..aaa6302 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -1,10 +1,10 @@
 ! This file was automatically generated, don't edit!
 !
-! Fortran interface for CDI library version 1.9.1
+! Fortran interface for CDI library version 1.9.2
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   October 2017
+! Uwe Schulzweida, MPI-MET, Hamburg,   November 2017
 !
 
       INTEGER    CDI_MAX_NAME
@@ -103,14 +103,12 @@
       PARAMETER (CDI_COMPRESS_NONE      =  0)
       INTEGER    CDI_COMPRESS_SZIP
       PARAMETER (CDI_COMPRESS_SZIP      =  1)
-      INTEGER    CDI_COMPRESS_GZIP
-      PARAMETER (CDI_COMPRESS_GZIP      =  2)
-      INTEGER    CDI_COMPRESS_BZIP2
-      PARAMETER (CDI_COMPRESS_BZIP2     =  3)
+      INTEGER    CDI_COMPRESS_AEC
+      PARAMETER (CDI_COMPRESS_AEC       =  2)
       INTEGER    CDI_COMPRESS_ZIP
-      PARAMETER (CDI_COMPRESS_ZIP       =  4)
+      PARAMETER (CDI_COMPRESS_ZIP       =  3)
       INTEGER    CDI_COMPRESS_JPEG
-      PARAMETER (CDI_COMPRESS_JPEG      =  5)
+      PARAMETER (CDI_COMPRESS_JPEG      =  4)
 !
 !  external data types
 !
diff --git a/src/._getMemorySize.c b/src/._getMemorySize.c
deleted file mode 100644
index b511a4d..0000000
Binary files a/src/._getMemorySize.c and /dev/null differ
diff --git a/src/CMOR.cc b/src/CMOR.cc
index a868db2..d8fc22c 100644
--- a/src/CMOR.cc
+++ b/src/CMOR.cc
@@ -9,13 +9,9 @@
 #include "uthash.h"
 #include "util.h"
 
-#ifdef __cplusplus
-  extern "C" {
-#endif
+extern "C" {
 #include "cmor.h"
-#ifdef __cplusplus
-  }
-#endif
+}
 
 #include "netcdf.h"
 #include "pmlist.h"
diff --git a/src/Change_e5slm.cc b/src/Change_e5slm.cc
index dbbe0e1..e5700df 100644
--- a/src/Change_e5slm.cc
+++ b/src/Change_e5slm.cc
@@ -130,19 +130,19 @@ void *Change_e5slm(void *argument)
 	  if ( code == 172 )
 	    {
 	      cdoPrint("SLM changed!");
-	      for ( long i = 0; i < gridsize; ++i )
+	      for ( size_t i = 0; i < gridsize; ++i )
 		array[i] = cland[i];
 	    }
 	  else if ( code == 99 )
 	    {
 	      cdoPrint("ALAKE set all values to zero!");
-	      for ( long i = 0; i < gridsize; ++i )
+	      for ( size_t i = 0; i < gridsize; ++i )
 		array[i] = 0;
 	    }
 	  else if ( code == 232 )
 	    {
 	      cdoPrint("GLAC set sea points to %g!", array[0]);
-	      for ( long i = 0; i < gridsize; ++i )
+	      for ( size_t i = 0; i < gridsize; ++i )
 		if ( cland[i] < 0.5 ) array[i] = array[0];
 	    }
 	  else if ( code ==  70 || code ==  71 || code == 140 ||
@@ -151,7 +151,7 @@ void *Change_e5slm(void *argument)
 		    code == 229 )
 	    {
 	      cdoPrint("Code %d set sea points to %g!", code, array[0]);
-	      for ( long i = 0; i < gridsize; ++i )
+	      for ( size_t i = 0; i < gridsize; ++i )
 		if ( lsea[i] ) array[i] = array[0];
 	    }
 
diff --git a/src/Consecstat.cc b/src/Consecstat.cc
index 3c4cd9d..8580632 100644
--- a/src/Consecstat.cc
+++ b/src/Consecstat.cc
@@ -40,7 +40,7 @@ enum {CONSECSUM, CONSECTS};
 
 static void selEndOfPeriod(field_type *periods, field_type history, field_type current, int isLastTimestep)
 {
-  long   i;
+  size_t i;
   double pmissval = periods->missval;
   double  *parray = periods->ptr;
   double hmissval = history.missval;
@@ -48,7 +48,7 @@ static void selEndOfPeriod(field_type *periods, field_type history, field_type c
   double cmissval = current.missval;
   double  *carray = current.ptr;
 
-  long len = gridInqSize(periods->grid);
+  size_t len = gridInqSize(periods->grid);
   if ( len != gridInqSize(current.grid) || (gridInqSize(current.grid) != gridInqSize(history.grid)) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
@@ -218,7 +218,7 @@ void *Consecstat(void *argument)
           }
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared) schedule(static)
-          for ( int i = 0; i < gridInqSize(vars[varID][levelID].grid); i++ )
+          for ( size_t i = 0; i < gridInqSize(vars[varID][levelID].grid); i++ )
             hist[varID][levelID].ptr[i] = vars[varID][levelID].ptr[i];
 #else
           memcpy(hist[varID][levelID].ptr,
diff --git a/src/Copy.cc b/src/Copy.cc
index 12ea8ac..7db7580 100644
--- a/src/Copy.cc
+++ b/src/Copy.cc
@@ -28,13 +28,9 @@
 #include "pstream.h"
 
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 int streamGrbInqDataScanningMode(void);
-#if defined (__cplusplus)
 }
-#endif
 
 void *Copy(void *argument)
 {
diff --git a/src/Exprf.cc b/src/Exprf.cc
index e114278..1c1afef 100644
--- a/src/Exprf.cc
+++ b/src/Exprf.cc
@@ -87,6 +87,79 @@ char *exprs_from_file(const char *exprf)
 
 #define MAX_PARAMS 4096
 
+char *str_replace(char *target, const char *needle, const char *replacement)
+{
+  char buffer[1024] = { 0 };
+  char *insert_point = &buffer[0];
+  const char *tmp = target;
+  size_t needle_len = strlen(needle);
+  size_t repl_len = strlen(replacement);
+
+  while (1)
+    {
+      const char *p = strstr(tmp, needle);
+
+      // walked past last occurrence of needle; copy remaining part
+      if (p == NULL)
+        {
+          strcpy(insert_point, tmp);
+          break;
+        }
+
+      // copy part before needle
+      memcpy(insert_point, tmp, p - tmp);
+      insert_point += p - tmp;
+
+      // copy replacement string
+      memcpy(insert_point, replacement, repl_len);
+      insert_point += repl_len;
+
+      // adjust pointers, move on
+      tmp = p + needle_len;
+    }
+
+  // write altered string back to target
+  strcpy(target, buffer);
+
+  return target;
+}
+
+static
+char *exprs_expand(char *exprs, int vlistID)
+{
+  size_t len = strlen(exprs);
+  unsigned nequal = 0, nsemi = 0;
+  for ( size_t i = 0; i < len; ++i )
+    {
+      if ( exprs[i] == '=' ) nequal++;
+      if ( exprs[i] == ';' ) nsemi++;
+    }
+
+  const char *needle = "_T";
+  if ( nequal == 0 && nsemi == 1 && strstr(exprs, needle) )
+    {
+      char varname[CDI_MAX_NAME];
+      int nvars = vlistNvars(vlistID);
+      const size_t bufsize = 1024;
+      char *sbuf = (char*) Malloc(bufsize);
+      char *buf = (char*) Malloc(nvars*bufsize);
+      buf[0] = 0;
+      for ( int varID = 0; varID < nvars; ++varID )
+        {
+          vlistInqVarName(vlistID, varID, varname);
+          strcpy(sbuf, exprs);
+          str_replace(sbuf, needle, varname);
+          strcat(buf, varname);
+          strcat(buf, "=");
+          strcat(buf, sbuf);
+        }
+      Free(sbuf);
+      Free(exprs);
+      exprs = buf;
+    }
+
+  return exprs;
+}
 
 static
 paramType *params_new(int vlistID)
@@ -268,16 +341,15 @@ void *Expr(void *argument)
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
-  char *exprs = NULL;
-  if ( READS_COMMAND_LINE(operatorID) )
-    exprs = exprs_from_arg(operatorArgv()[0]);
-  else
-    exprs = exprs_from_file(operatorArgv()[0]);
-
-  if ( cdoVerbose ) cdoPrint(exprs);
+  char *exprs = READS_COMMAND_LINE(operatorID) ?
+    exprs_from_arg(operatorArgv()[0]) : exprs_from_file(operatorArgv()[0]);
 
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
   int vlistID1 = pstreamInqVlist(streamID1);
+
+  exprs = exprs_expand(exprs, vlistID1);
+  if ( cdoVerbose ) cdoPrint(exprs);
+
   int nvars1 = vlistNvars(vlistID1);
   int ngrids = vlistNgrids(vlistID1);
   int nzaxis = vlistNzaxis(vlistID1);
diff --git a/src/Fillmiss.cc b/src/Fillmiss.cc
index 64f15dd..3a943d2 100644
--- a/src/Fillmiss.cc
+++ b/src/Fillmiss.cc
@@ -29,13 +29,9 @@
 #include "grid.h"
 #include "grid_search.h"
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "clipping/geometry.h"
-#ifdef __cplusplus
 }
-#endif
 
 
 void fillmiss(field_type *field1, field_type *field2, int nfill)
diff --git a/src/Remap.cc b/src/Remap.cc
index ffd21f3..69267af 100644
--- a/src/Remap.cc
+++ b/src/Remap.cc
@@ -599,8 +599,7 @@ int get_norm_opt(void)
 static
 void remap_normalize(int norm_opt, size_t gridsize, double *array, double missval, remapgrid_t *tgt_grid)
 {
-  /* used only to check the result of remapcon */
-  double grid_err;
+  // used only to check the result of remapcon
 
   if ( norm_opt == NORM_OPT_NONE )
     {
@@ -608,7 +607,7 @@ void remap_normalize(int norm_opt, size_t gridsize, double *array, double missva
 	{
 	  if ( !DBL_IS_EQUAL(array[i], missval) )
 	    {
-	      grid_err = tgt_grid->cell_frac[i]*tgt_grid->cell_area[i];
+	      double grid_err = tgt_grid->cell_frac[i]*tgt_grid->cell_area[i];
 
 	      if ( fabs(grid_err) > 0 )
 		array[i] /= grid_err;
@@ -770,7 +769,6 @@ void sort_remap_add(remapvars_t *remapvars)
 void *Remap(void *argument)
 {
   bool remap_genweights = REMAP_genweights;
-  bool need_gradiants = false;
   int streamID2 = -1;
   int nrecs;
   int varID, levelID;
@@ -958,6 +956,7 @@ void *Remap(void *argument)
 
   size_t grid1sizemax = vlistGridsizeMax(vlistID1);
 
+  bool need_gradiants = false;
   if ( map_type == MAP_TYPE_BICUBIC ) need_gradiants = true;
   if ( map_type == MAP_TYPE_CONSERV && remap_order == 2 )
     {
@@ -1209,7 +1208,7 @@ void *Remap(void *argument)
 
 	  if ( operfunc == REMAPCON || operfunc == REMAPCON2 || operfunc == REMAPYCON )
 	    {
-	      /* used only to check the result of remapcon */
+	      // used only to check the result of remapcon
 	      if ( 0 ) remap_normalize(remaps[r].vars.norm_opt, gridsize2, array2, missval, &remaps[r].tgt_grid);
 
 	      remap_set_frac_min(gridsize2, array2, missval, &remaps[r].tgt_grid);
diff --git a/src/Samplegridicon.cc b/src/Samplegridicon.cc
index 8915b9d..3a948c9 100644
--- a/src/Samplegridicon.cc
+++ b/src/Samplegridicon.cc
@@ -3,13 +3,9 @@
 #include "grid.h"
 #include "grid_search.h"
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "clipping/geometry.h"
-#ifdef __cplusplus
 }
-#endif
 
 constexpr int MAX_CHILDS = 9;
 
diff --git a/src/Selmulti.cc b/src/Selmulti.cc
index a121447..04b99de 100644
--- a/src/Selmulti.cc
+++ b/src/Selmulti.cc
@@ -23,13 +23,9 @@
 
 // NOTE: All operators in this module works only on GRIB edition 1 files!
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 void streamGrbChangeParameterIdentification(int code, int ltype, int lev);
-#if defined (__cplusplus)
 }
-#endif
 
 /*
 Supported notations:
diff --git a/src/Setmiss.cc b/src/Setmiss.cc
index f81d2dd..8ca38fd 100644
--- a/src/Setmiss.cc
+++ b/src/Setmiss.cc
@@ -26,13 +26,10 @@
 */
 
 
-#if defined(HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#if defined(HAVE_ISNAN) && ! defined(__cplusplus)
-int isnan(const double x);
-#endif
 
 #include <cdi.h>
 #include "cdo.h"
@@ -45,8 +42,7 @@ void *Setmiss(void *argument)
   int nrecs;
   int varID, levelID;
   size_t nmiss;
-  int i;
-  double missval, missval2 = 0;
+  double missval2 = 0;
   double rconst = 0, rmin = 0, rmax = 0;
 
   cdoInitialize(argument);
@@ -108,7 +104,7 @@ void *Setmiss(void *argument)
       int nvars = vlistNvars(vlistID2);
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  missval = vlistInqVarMissval(vlistID2, varID);
+	  double missval = vlistInqVarMissval(vlistID2, varID);
 	  if ( DBL_IS_EQUAL(rconst, missval) )
 	    {
 	      cdoWarning("Missing value and constant have the same value!");
@@ -132,9 +128,8 @@ void *Setmiss(void *argument)
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
   pstreamDefVlist(streamID2, vlistID2);
 
-  int gridsize = vlistGridsizeMax(vlistID1);
-
-  double *array = (double*) Malloc(gridsize*sizeof(double));
+  size_t gridsizemax = vlistGridsizeMax(vlistID1);
+  double *array = (double*) Malloc(gridsizemax*sizeof(double));
 
   int tsID = 0;
   while ( (nrecs = pstreamInqTimestep(streamID1, tsID)) )
@@ -147,13 +142,13 @@ void *Setmiss(void *argument)
 	  pstreamInqRecord(streamID1, &varID, &levelID);
 	  pstreamReadRecord(streamID1, array, &nmiss);
 
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-	  missval = vlistInqVarMissval(vlistID1, varID);
+	  size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+	  double missval = vlistInqVarMissval(vlistID1, varID);
 
 	  if ( operatorID == SETMISSVAL )
 	    {
 	      nmiss = 0;
-	      for ( i = 0; i < gridsize; i++ )
+	      for ( size_t i = 0; i < gridsize; i++ )
 		if ( DBL_IS_EQUAL(array[i], missval)  || DBL_IS_EQUAL(array[i], (float)missval) ||
 		     DBL_IS_EQUAL(array[i], missval2) || DBL_IS_EQUAL(array[i], (float)missval2) )
 		  {
@@ -166,7 +161,7 @@ void *Setmiss(void *argument)
 #if defined(HAVE_ISNAN)
 	      if ( isnan(rconst) )
 		{
-		  for ( i = 0; i < gridsize; i++ )
+		  for ( size_t i = 0; i < gridsize; i++ )
 		    if ( isnan(array[i]) )
 		      {
 			array[i] = missval;
@@ -176,7 +171,7 @@ void *Setmiss(void *argument)
 	      else
 #endif
 		{
-		  for ( i = 0; i < gridsize; i++ )
+		  for ( size_t i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(array[i], rconst) || DBL_IS_EQUAL(array[i], (float)rconst) )
 		      {
 			array[i] = missval;
@@ -187,7 +182,7 @@ void *Setmiss(void *argument)
 	  else if ( operatorID == SETMISSTOC )
 	    {
 	      nmiss = 0;
-	      for ( i = 0; i < gridsize; i++ )
+	      for ( size_t i = 0; i < gridsize; i++ )
 		if ( DBL_IS_EQUAL(array[i], missval) || DBL_IS_EQUAL(array[i], (float)missval) )
 		  {
 		    array[i] = rconst;
@@ -195,7 +190,7 @@ void *Setmiss(void *argument)
 	    }
 	  else if ( operatorID == SETRTOMISS )
 	    {
-	      for ( i = 0; i < gridsize; i++ )
+	      for ( size_t i = 0; i < gridsize; i++ )
 		if ( array[i] >= rmin && array[i] <= rmax )
 		  {
 		    array[i] = missval;
@@ -204,11 +199,11 @@ void *Setmiss(void *argument)
 	    }
 	  else if ( operatorID == SETVRANGE )
 	    {
-	      for ( i = 0; i < gridsize; i++ )
+	      for ( size_t i = 0; i < gridsize; i++ )
 		if ( array[i] < rmin || array[i] > rmax ) array[i] = missval;
 
 	      nmiss = 0;
-	      for ( i = 0; i < gridsize; i++ )
+	      for ( size_t i = 0; i < gridsize; i++ )
 		if ( DBL_IS_EQUAL(array[i], missval) ) nmiss++;
 	    }
 
diff --git a/src/Verifygrid.cc b/src/Verifygrid.cc
index 2caad05..53eaa11 100644
--- a/src/Verifygrid.cc
+++ b/src/Verifygrid.cc
@@ -24,20 +24,16 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "pstream.h"
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "clipping/geometry.h"
-#ifdef __cplusplus
 }
-#endif
 #include "time.h"
 
 /* Quicksort is called with a pointer to the array to be sorted and an integer indicating its length. */
 static
-void quick_sort(double * array, int array_length)
+void quick_sort(double * array, size_t array_length)
 {
-  int i, j;
+  size_t i, j;
   double temp;
   
   if (array_length < 2) return;
@@ -57,14 +53,14 @@ void quick_sort(double * array, int array_length)
 
 /* Quicksort is called with a pointer to the array of center points to be sorted and an integer indicating its length. It sorts the array by its longitude coordinates */
 static
-void quick_sort_by_lon(double * array, int array_length)
+void quick_sort_by_lon(double * array, size_t array_length)
 {
   if ( array_length < 4 ) return;
 
   double p = ((array_length / 2) % 2) ?  array[(array_length / 2) + 1] : array[array_length / 2];      
       
   double temp_lon, temp_lat;
-  int i, j;
+  size_t i, j;
   for ( i = 0, j = array_length - 2;; i += 2, j -= 2 )
     {
       while (array[i] < p) i += 2;
@@ -87,13 +83,13 @@ void quick_sort_by_lon(double * array, int array_length)
 
 /* This uses quicksort to sort the latitude coordinates in a subarray of all coordinates. */
 static
-void quick_sort_of_subarray_by_lat(double * array, int subarray_start, int subarray_end)
+void quick_sort_of_subarray_by_lat(double * array, size_t subarray_start, size_t subarray_end)
 {
-  int subarray_length = (subarray_end - subarray_start) / 2 + 1;     
+  size_t subarray_length = (subarray_end - subarray_start) / 2 + 1;     
   double *subarray = (double*) Malloc(subarray_length*sizeof(double));
-  int subarray_index = 0;
+  size_t subarray_index = 0;
   
-  for(int index = subarray_start + 1; index <= subarray_end + 1; index += 2){	 
+  for(size_t index = subarray_start + 1; index <= subarray_end + 1; index += 2){	 
     subarray[subarray_index] = array[index];
     subarray_index += 1;	  
   }
@@ -102,7 +98,7 @@ void quick_sort_of_subarray_by_lat(double * array, int subarray_start, int subar
   
   subarray_index = 0;
   
-  for(int index = subarray_start + 1; index <= subarray_end + 1; index += 2){
+  for(size_t index = subarray_start + 1; index <= subarray_end + 1; index += 2){
     array[index] = subarray[subarray_index];
     subarray_index += 1;	  
   }
@@ -182,22 +178,22 @@ int find_coordinate_to_ignore(double *cell_corners_xyz)
 
   return coordinate_to_ignore;
 }
-
+/*
 static
-int no_of_duplicates_in_this_list_of_vertices(double cell_corners[], int array_length)
+size_t no_of_duplicates_in_this_list_of_vertices(double cell_corners[], size_t array_length)
 {
-  /* Returns the number of coordinate duplicates found in a list of Cartesian coordinates, the cell corners or vertices. */
+  // Returns the number of coordinate duplicates found in a list of Cartesian coordinates, the cell corners or vertices.
   
-  /* Ensure that the lenght of the array is a multiple of 3. */
+  // Ensure that the lenght of the array is a multiple of 3.
 
   if ( (array_length % 3) != 0 ) return -1;
 
-  /* A brute force search for duplicate Cartesian coordinates. */
+  // A brute force search for duplicate Cartesian coordinates.
 
-  int no_duplicates = 0;
+  size_t no_duplicates = 0;
 
-  for (int i = 0; i < array_length; i = i + 3){
-    for (int j = i + 3; j < array_length; j = j + 3 ){
+  for (size_t i = 0; i < array_length; i = i + 3){
+    for (size_t j = i + 3; j < array_length; j = j + 3 ){
       if ( IS_EQUAL(cell_corners[i + 0], cell_corners[j])     &&
            IS_EQUAL(cell_corners[i + 1], cell_corners[j + 1]) &&
            IS_EQUAL(cell_corners[i + 2], cell_corners[j + 2]) ){
@@ -207,7 +203,7 @@ int no_of_duplicates_in_this_list_of_vertices(double cell_corners[], int array_l
   }
   return no_duplicates;
 }
-
+*/
 static
 double is_point_left_of_edge(double point_on_line_1[2], double point_on_line_2[2], double point[2])
 {
@@ -325,7 +321,7 @@ bool are_polygon_vertices_arranged_in_clockwise_order(double cell_area)
 }
 
 static
-void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner, double *grid_center_lon, double *grid_center_lat, double *grid_corner_lon, double *grid_corner_lat)
+void verify_grid(int gridtype, size_t gridsize, int gridno, int ngrids, int ncorner, double *grid_center_lon, double *grid_center_lat, double *grid_corner_lon, double *grid_corner_lat)
 {
   /* 
      First, this function performs the following test:
@@ -346,13 +342,13 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
   double corner_coordinates[3];
   double center_point_plane_projection[2];
 
-  int no_of_cells_with_duplicates = 0;
-  int no_usable_cells = 0;
-  int no_convex_cells = 0;
-  int no_clockwise_cells = 0;
-  int no_counterclockwise_cells = 0;
-  int no_of_cells_with_center_points_out_of_bounds = 0;
-  int no_unique_center_points = 1;
+  size_t no_of_cells_with_duplicates = 0;
+  size_t no_usable_cells = 0;
+  size_t no_convex_cells = 0;
+  size_t no_clockwise_cells = 0;
+  size_t no_counterclockwise_cells = 0;
+  size_t no_of_cells_with_center_points_out_of_bounds = 0;
+  size_t no_unique_center_points = 1;
 
   int *no_cells_with_a_specific_no_of_corners = (int*) Malloc(ncorner*sizeof(int));
 
@@ -360,16 +356,16 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
     no_cells_with_a_specific_no_of_corners[i] = 0;
 
   if ( ngrids == 1 )
-    cdoPrintBlue("Grid consists of %d cells (type: %s), of which", gridsize, gridNamePtr(gridtype));
+    cdoPrintBlue("Grid consists of %zu cells (type: %s), of which", gridsize, gridNamePtr(gridtype));
   else
-    cdoPrintBlue("Grid no %u (of %u) consists of %d cells (type: %s), of which", gridno + 1, ngrids, gridsize, gridNamePtr(gridtype));
+    cdoPrintBlue("Grid no %u (of %u) consists of %zu cells (type: %s), of which", gridno + 1, ngrids, gridsize, gridNamePtr(gridtype));
   //cdoPrint("");
 
   /* For performing the first test, an array of all center point coordinates is built. */
 
   double *center_point_array = (double *)Malloc(gridsize * 2 * sizeof(double));
   
-  for ( int cell_no = 0; cell_no < gridsize; cell_no++ )
+  for ( size_t cell_no = 0; cell_no < gridsize; cell_no++ )
     {
       center_point_array[cell_no * 2 + 0] = grid_center_lon[cell_no];
       center_point_array[cell_no * 2 + 1] = grid_center_lat[cell_no];
@@ -384,7 +380,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
   int subarray_start = 0;
   int subarray_end = 0;
 
-  for ( int cell_no = 0; cell_no < gridsize - 1; cell_no++ )
+  for ( size_t cell_no = 0; cell_no < gridsize - 1; cell_no++ )
     {
       if ( cell_no == gridsize - 2 )
         {    
@@ -404,7 +400,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
 
   /* Now checking for the number of unique center point coordinates. */
 
-  for ( int cell_no = 0; cell_no < gridsize - 1; cell_no++ )
+  for ( size_t cell_no = 0; cell_no < gridsize - 1; cell_no++ )
     {
       if ( fabs(center_point_array[cell_no * 2 + 0] - center_point_array[(cell_no + 1) * 2 + 0]) < 0.0001 )
         {
@@ -432,7 +428,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
      This is first done for the presumed center point of the cell and then for all the corners of the cell. LLtoXYZ is defined in clipping/geometry.h 
   */
 
-  for ( int cell_no = 0; cell_no < gridsize; cell_no++ )
+  for ( size_t cell_no = 0; cell_no < gridsize; cell_no++ )
     {    
       /* Conversion of center point spherical coordinates to Cartesian coordinates. */
 
@@ -479,7 +475,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
       if ( actual_number_of_corners < 3 )
         {
           if ( cdoVerbose )
-            fprintf(stdout,"Less than three vertices found in cell no %u. This cell is considered degenerate and will be omitted from further computation!\n", cell_no + 1);
+            fprintf(stdout,"Less than three vertices found in cell no %zu. This cell is considered degenerate and will be omitted from further computation!\n", cell_no + 1);
           
           continue;
         }
@@ -499,7 +495,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
                fabs(cell_corners_xyz_open_cell[i + 2] - cell_corners_xyz_open_cell[j + 2]) < 0.000001 )
             {
               if ( cdoVerbose )
-                fprintf(stdout,"The duplicate vertex %f, %f, %f was found in cell no %u.\n",
+                fprintf(stdout,"The duplicate vertex %f, %f, %f was found in cell no %zu.\n",
                         cell_corners_xyz_open_cell[j],  cell_corners_xyz_open_cell[j + 1],  cell_corners_xyz_open_cell[j + 2], cell_no + 1);
 
               no_duplicates += 1;
@@ -532,7 +528,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
       if ( actual_number_of_corners < 3 )
         {
           if ( cdoVerbose )
-            fprintf(stdout,"Less than three vertices found in cell no %u. This cell is considered degenerate and will be omitted from further computation!\n", cell_no + 1);
+            fprintf(stdout,"Less than three vertices found in cell no %zu. This cell is considered degenerate and will be omitted from further computation!\n", cell_no + 1);
 
           continue;
         }
@@ -624,7 +620,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
 
       if ( cdoVerbose && winding_number == 0 )
         {
-          printf("cell_no %d: ", cell_no+1);
+          printf("cell_no %zu: ", cell_no+1);
           printf(" lon=%g lat=%g : ", grid_center_lon[cell_no], grid_center_lat[cell_no]);
           for ( int corner_no = 0; corner_no < ncorner; corner_no++ )
             printf(" %g/%g ", grid_corner_lon[cell_no * ncorner + corner_no], grid_corner_lat[cell_no * ncorner + corner_no]);
@@ -637,31 +633,31 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
   Free(cell_corners_xyz);
   Free(cell_corners_xyz_without_duplicates);
 
-  int no_nonunique_cells = gridsize - no_unique_center_points;
-  int no_nonconvex_cells = (int) gridsize - no_convex_cells;
-  int no_nonusable_cells = (int) gridsize - no_usable_cells;
+  size_t no_nonunique_cells = gridsize - no_unique_center_points;
+  size_t no_nonconvex_cells = gridsize - no_convex_cells;
+  size_t no_nonusable_cells = gridsize - no_usable_cells;
 
   for ( int i = 2; i < ncorner; i++ )
     if ( no_cells_with_a_specific_no_of_corners[i] )
       cdoPrintBlue("%9d cells have %d vertices", no_cells_with_a_specific_no_of_corners[i], i + 1);
 
   if ( no_of_cells_with_duplicates )
-    cdoPrintBlue("%9d cells have duplicate vertices", no_of_cells_with_duplicates);
+    cdoPrintBlue("%9zu cells have duplicate vertices", no_of_cells_with_duplicates);
 
   if ( no_nonusable_cells )
-    cdoPrintRed("%9d cells have unusable vertices", no_nonusable_cells);
+    cdoPrintRed("%9zu cells have unusable vertices", no_nonusable_cells);
 
   if ( no_nonunique_cells )
-    cdoPrintRed("%9d cells are not unique", no_nonunique_cells);
+    cdoPrintRed("%9zu cells are not unique", no_nonunique_cells);
   
   if ( no_nonconvex_cells )
-    cdoPrintRed("%9d cells are non-convex", no_nonconvex_cells);
+    cdoPrintRed("%9zu cells are non-convex", no_nonconvex_cells);
 
   if ( no_clockwise_cells )
-    cdoPrintRed("%9d cells have their vertices arranged in a clockwise order", no_clockwise_cells);
+    cdoPrintRed("%9zu cells have their vertices arranged in a clockwise order", no_clockwise_cells);
   
   if ( no_of_cells_with_center_points_out_of_bounds )
-    cdoPrintRed("%9d cells have their center points located outside their boundaries", no_of_cells_with_center_points_out_of_bounds);
+    cdoPrintRed("%9zu cells have their center points located outside their boundaries", no_of_cells_with_center_points_out_of_bounds);
 
   // cdoPrint("");
 
@@ -708,7 +704,7 @@ void *Verifygrid(void *argument)
             }
         }
 
-      int gridsize = gridInqSize(gridID);
+      size_t gridsize = gridInqSize(gridID);
       /*
         if ( gridInqMaskGME(gridID, NULL) )
         {
@@ -739,7 +735,7 @@ void *Verifygrid(void *argument)
           if ( luse_grid_corner )
             {
               if ( ncorner == 0 ) cdoAbort("grid corner missing!");
-              int nalloc = ncorner*gridsize;
+              size_t nalloc = ncorner*gridsize;
               grid_corner_lat = (double*) Realloc(grid_corner_lat, nalloc*sizeof(double));
               grid_corner_lon = (double*) Realloc(grid_corner_lon, nalloc*sizeof(double));
           
@@ -777,9 +773,9 @@ void *Verifygrid(void *argument)
       else
         {
           if ( ngrids == 1 )
-            cdoPrintBlue("Grid consists of %d points (type: %s)", gridsize, gridNamePtr(gridtype));
+            cdoPrintBlue("Grid consists of %zu points (type: %s)", gridsize, gridNamePtr(gridtype));
           else
-            cdoPrintBlue("Grid no %u (of %u) consists of %d points (type: %s)", gridno + 1, ngrids, gridsize, gridNamePtr(gridtype));
+            cdoPrintBlue("Grid no %u (of %u) consists of %zu points (type: %s)", gridno + 1, ngrids, gridsize, gridNamePtr(gridtype));
           // cdoPrint("");
         }
     }
diff --git a/src/WindTrans.cc b/src/WindTrans.cc
index eb193ff..9ff348f 100644
--- a/src/WindTrans.cc
+++ b/src/WindTrans.cc
@@ -36,13 +36,9 @@
 
 #define  MAXARG 10
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 void streamGrbChangeModeUvRelativeToGrid(int mode);
-#if defined (__cplusplus)
 }
-#endif
 
 int UVDESTAG;
 int ROTUVNORTH;
diff --git a/src/YAR.cc b/src/YAR.cc
index 87c2c2b..69bf58c 100644
--- a/src/YAR.cc
+++ b/src/YAR.cc
@@ -24,9 +24,7 @@
 #include "remap.h"
 
 #if defined(HAVE_LIBYAC)
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "points.h"
 #include "grid_reg2d.h"
 #include "grid_search.h"
@@ -34,10 +32,8 @@ extern "C" {
 #include "search.h"
 #include "clipping.h"
 #include "area.h"
-#ifdef __cplusplus
 }
 #endif
-#endif
 
 int timer_yar_remap, timer_yar_remap_init, timer_yar_remap_sort, timer_yar_remap_con, timer_yar_remap_bil;
 
diff --git a/src/after_sptrans.cc b/src/after_sptrans.cc
index 5fe1e58..22776ad 100644
--- a/src/after_sptrans.cc
+++ b/src/after_sptrans.cc
@@ -18,13 +18,9 @@
 #define  HAVE_OPENMP4  1
 #endif
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 void gaussaw(double *pa, double *pw, size_t nlat);
-#if defined (__cplusplus)
 }
-#endif
 
 static
 void jspleg1(double *pleg, double plat, int ktrunc, double *work)
diff --git a/src/after_vertint.h b/src/after_vertint.h
index 4b23175..6b7805a 100644
--- a/src/after_vertint.h
+++ b/src/after_vertint.h
@@ -3,10 +3,6 @@
 
 #include <stdbool.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
 void height2pressure(double *restrict phlev, const double *restrict hlev, long nphlev);
 
 void presh(double *restrict fullp, double *halfp, const double *restrict vct,
@@ -35,8 +31,4 @@ void vert_gen_weights3d(bool expol, int nlev1, int gridsize, double *lev1, int n
 void vert_gen_weights3d1d(bool expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
 			  int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2);
 
-#if defined(__cplusplus)
-}
-#endif
-
 #endif  /* VINTERP_H */
diff --git a/src/cdo.cc b/src/cdo.cc
index 1d0d47b..a4a63b7 100644
--- a/src/cdo.cc
+++ b/src/cdo.cc
@@ -83,13 +83,9 @@ static int CDO_netcdf_hdr_pad = 0;
 static int CDO_Rusage = 0;
 const char *CDO_username;
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 void streamGrbDefDataScanningMode(int scanmode);
-#if defined (__cplusplus)
 }
-#endif
 
 void gridsearch_set_method(const char *methodstr);
 
diff --git a/src/compare.h b/src/compare.h
index eb24cc2..1ff81b1 100644
--- a/src/compare.h
+++ b/src/compare.h
@@ -22,9 +22,10 @@
 #include "config.h"
 #endif
 
+#include <string.h>
 #include <math.h>
 
-#if defined(__xlC__) /* performance problems on IBM */
+#ifdef  __xlC__  /* performance problem on IBM */
 #ifndef DBL_IS_NAN
 #  define DBL_IS_NAN(x)     ((x) != (x))
 #endif
diff --git a/src/expr.cc b/src/expr.cc
index 5c1b51c..b3bb38a 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -726,6 +726,7 @@ nodeType *expr(int init, int oper, nodeType *p1, nodeType *p2)
         case LEG:  coper = "<=>"; break;
         case AND:  coper = "&&"; break;
         case OR:   coper = "||"; break;
+        default: cdoAbort("Internal error, expr operator >%c< not implemented!\n", oper);
         }
     }
 
@@ -944,7 +945,7 @@ nodeType *fun1c(int init, int funcID, nodeType *p1, double value, parse_param_t
 {  
   const char *funcname = fun_sym_tbl[funcID].name;            
   if ( p1->type != typeVar ) cdoAbort("Parameter of function %s() needs to be a variable!", funcname);
-  if ( p1->ltmpobj ) cdoAbort("Temorary objects not allowed in function %s()!", funcname);
+  if ( p1->ltmpobj ) cdoAbort("Temporary objects not allowed in function %s()!", funcname);
 
   size_t ngp   = p1->param.ngp;
   size_t nlev  = p1->param.nlev;
@@ -1030,7 +1031,7 @@ nodeType *coord_fun(int init, int funcID, nodeType *p1, parse_param_t *parse_arg
 {  
   const char *funcname = fun_sym_tbl[funcID].name;            
   if ( p1->type != typeVar ) cdoAbort("Parameter of function %s() needs to be a variable!", funcname);
-  if ( p1->ltmpobj ) cdoAbort("Temorary objects not allowed in function %s()!", funcname);
+  if ( p1->ltmpobj ) cdoAbort("Temporary objects not allowed in function %s()!", funcname);
             
   size_t len = 3 + strlen(p1->u.var.nm);
   char *cname = (char*) Calloc(len, 1);
@@ -1144,6 +1145,81 @@ nodeType *ex_uminus(int init, nodeType *p1)
 }
 
 static
+nodeType *ex_not_var(int init, nodeType *p1)
+{
+  size_t ngp   = p1->param.ngp;
+  size_t nlev  = p1->param.nlev;
+  size_t nmiss = p1->param.nmiss;
+  double missval = p1->param.missval;
+
+  nodeType *p = (nodeType*) Calloc(1, sizeof(nodeType));
+
+  p->type     = typeVar;
+  p->ltmpobj  = true;
+  p->u.var.nm = strdup(tmpvnm);
+  param_meta_copy(&p->param, &p1->param);
+  p->param.name = p->u.var.nm;
+
+  if ( ! init )
+    {
+      p->param.data = (double*) Malloc(ngp*nlev*sizeof(double));
+      double *restrict pdata = p->param.data;
+      const double *restrict p1data = p1->param.data;
+
+      if ( nmiss > 0 )
+        {
+          for ( size_t i = 0; i < ngp*nlev; ++i )
+            pdata[i] = DBL_IS_EQUAL(p1data[i], missval) ? missval : !(p1data[i]);
+        }
+      else
+        {
+          for ( size_t i = 0; i < ngp*nlev; ++i )
+            pdata[i] = !(p1data[i]);
+        }
+
+      p->param.nmiss = nmiss;
+    }
+
+  if ( p1->ltmpobj ) node_delete(p1);
+  
+  return p;
+}
+
+static
+nodeType *ex_not_con(nodeType *p1)
+{
+  nodeType *p = (nodeType*) Calloc(1, sizeof(nodeType));
+
+  p->type    = typeCon;
+  p->ltmpobj = true;
+
+  p->u.con.value = !(p1->u.con.value);
+
+  return p;
+}
+
+static
+nodeType *ex_not(int init, nodeType *p1)
+{
+  nodeType *p = NULL;
+
+  if ( p1->type == typeVar )
+    {
+      if ( cdoVerbose ) cdoPrint("\t%s\tnot\t! (%s)", ExIn[init], p1->u.var.nm);
+      p = ex_not_var(init, p1);
+    }
+  else if ( p1->type == typeCon )
+    {
+      if ( cdoVerbose ) cdoPrint("\t%s\tnot\t! (%g)", ExIn[init], p1->u.con.value);
+      p = ex_not_con(p1);
+    }
+  else
+    cdoAbort("Internal problem!");
+
+  return p;
+}
+
+static
 nodeType *ex_ifelse(int init, nodeType *p1, nodeType *p2, nodeType *p3)
 {
   if ( p1->type == typeCon ) cdoAbort("expr?expr:expr: First expression is a constant but must be a variable!");
@@ -1653,6 +1729,12 @@ nodeType *expr_run(nodeType *p, parse_param_t *parse_arg)
 
             break;
           }
+        case NOT:
+          {
+            rnode = ex_not(init, expr_run(p->u.opr.op[0], parse_arg));
+
+            break;
+          }
         case '?':
           {
             rnode = ex_ifelse(init,
diff --git a/src/expr.h b/src/expr.h
index 278c38b..e4dfdcb 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -18,11 +18,9 @@
 #include <stdio.h>
 #include <stdbool.h>
 
-#ifdef __cplusplus
 #ifndef fileno
 int fileno(FILE *stream);
 #endif
-#endif
 
 extern int CDO_parser_errorno;
 
diff --git a/src/expr_lex.cc b/src/expr_lex.cc
index 948162e..3d6ac82 100644
--- a/src/expr_lex.cc
+++ b/src/expr_lex.cc
@@ -1,6 +1,6 @@
-#line 1 "expr_lex.cc"
+#line 2 "expr_lex.cc"
 
-#line 3 "expr_lex.cc"
+#line 4 "expr_lex.cc"
 
 #define  YY_INT_ALIGNED short int
 
@@ -9,23 +9,11 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 4
+#define YY_FLEX_SUBMINOR_VERSION 1
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
-#ifdef yyget_lval
-#define yyget_lval_ALREADY_DEFINED
-#else
-#define yyget_lval yyget_lval
-#endif
-
-#ifdef yyset_lval
-#define yyset_lval_ALREADY_DEFINED
-#else
-#define yyset_lval yyset_lval
-#endif
-
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
@@ -96,16 +84,10 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
-#ifndef SIZE_MAX
-#define SIZE_MAX               (~(size_t)0)
-#endif
-
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
-/* begin standard C++ headers. */
-
 /* TODO: this is always defined, so inline it */
 #define yyconst const
 
@@ -118,10 +100,12 @@ typedef unsigned int flex_uint32_t;
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
-/* Promotes a possibly negative, possibly signed char to an
- *   integer in range [0..255] for use as an array index.
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
  */
-#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
 
 /* An opaque pointer. */
 #ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -145,16 +129,20 @@ typedef void* yyscan_t;
  * definition of BEGIN.
  */
 #define BEGIN yyg->yy_start = 1 + 2 *
+
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START ((yyg->yy_start - 1) / 2)
 #define YYSTATE YY_START
+
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin , yyscanner )
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -187,7 +175,7 @@ typedef size_t yy_size_t;
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
-    
+
     #define YY_LESS_LINENO(n)
     #define YY_LINENO_REWIND_TO(ptr)
     
@@ -204,6 +192,7 @@ typedef size_t yy_size_t;
 		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
+
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -246,7 +235,7 @@ struct yy_buffer_state
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-
+    
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
@@ -280,67 +269,73 @@ struct yy_buffer_state
 #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                           ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                           : NULL)
+
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
 
-void yyrestart ( FILE *input_file , yyscan_t yyscanner );
-void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
-void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-void yypop_buffer_state ( yyscan_t yyscanner );
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
 
-static void yyensure_buffer_stack ( yyscan_t yyscanner );
-static void yy_load_buffer_state ( yyscan_t yyscanner );
-static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
-#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
 
-YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
 
-void *yyalloc ( yy_size_t , yyscan_t yyscanner );
-void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
-void yyfree ( void * , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
 
 #define yy_new_buffer yy_create_buffer
+
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
         yyensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
+
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
         yyensure_buffer_stack (yyscanner); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
+
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
 /* Begin user sect3 */
 
 #define yywrap(yyscanner) (/*CONSTCOND*/1)
 #define YY_SKIP_YYWRAP
-typedef flex_uint8_t YY_CHAR;
+
+typedef unsigned char YY_CHAR;
 
 typedef int yy_state_type;
 
 #define yytext_ptr yytext_r
 
-static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  , yyscan_t yyscanner);
-static int yy_get_next_buffer ( yyscan_t yyscanner );
-static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
@@ -351,8 +346,9 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 25
-#define YY_END_OF_BUFFER 26
+
+#define YY_NUM_RULES 26
+#define YY_END_OF_BUFFER 27
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -360,41 +356,41 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_acclist[164] =
+static yyconst flex_int16_t yy_acclist[165] =
     {   0,
-        4,    4,   26,   24,   25,   23,   24,   25,   23,   25,
-       24,   25,    1,   24,   25,   24,   25,   11,   24,   25,
-        4,   11,   24,   25,    4,   24,   25,   22,   24,   25,
-       16,   24,   25,   11,   24,   25,   15,   24,   25,   21,
-       24,   25,    9,   10,   24,   25,16391,    4,    9,   10,
-       24,   25,16391,    9,   10,   24,   25,16391,    9,   10,
-       24,   25,16391,    9,   10,   24,   25,16391,    9,   10,
-       24,   25,16391,   24,   25,   23,   18,    1,   19,    4,
-        4,    4,    4,   10,    4,   10,   10,   14,   17,   13,
-     8199,    8,    9,   10,16391,    9,   10,16391,    4,    9,
-
-       10,16391,    9,   10,16391,    9,   10,16391,    9,   10,
-    16391,   20,    4,   10,   10,    4,   10,   12,    8,    4,
-        4,    9,   10,16391,    3,    9,   10,16391,    9,   10,
-    16391,    9,   10,16391,    9,   10,16391,    4,   10,    4,
-        2,    9,   10,16391,    9,   10,16391,    9,   10,16391,
-        9,   10,16391,    9,   10,16391,    6, 8199,    9,   10,
-    16391,    5, 8199
+        4,    4,   27,   25,   26,   24,   25,   26,   24,   26,
+       21,   25,   26,    1,   25,   26,   25,   26,   11,   25,
+       26,    4,   11,   25,   26,    4,   25,   26,   23,   25,
+       26,   16,   25,   26,   11,   25,   26,   15,   25,   26,
+       22,   25,   26,    9,   10,   25,   26,16391,    4,    9,
+       10,   25,   26,16391,    9,   10,   25,   26,16391,    9,
+       10,   25,   26,16391,    9,   10,   25,   26,16391,    9,
+       10,   25,   26,16391,   25,   26,   24,   18,    1,   19,
+        4,    4,    4,    4,   10,    4,   10,   10,   14,   17,
+       13, 8199,    8,    9,   10,16391,    9,   10,16391,    4,
+
+        9,   10,16391,    9,   10,16391,    9,   10,16391,    9,
+       10,16391,   20,    4,   10,   10,    4,   10,   12,    8,
+        4,    4,    9,   10,16391,    3,    9,   10,16391,    9,
+       10,16391,    9,   10,16391,    9,   10,16391,    4,   10,
+        4,    2,    9,   10,16391,    9,   10,16391,    9,   10,
+    16391,    9,   10,16391,    9,   10,16391,    6, 8199,    9,
+       10,16391,    5, 8199
     } ;
 
-static const flex_int16_t yy_accept[76] =
+static yyconst flex_int16_t yy_accept[76] =
     {   0,
-        1,    2,    3,    4,    6,    9,   11,   13,   16,   18,
-       21,   25,   28,   31,   34,   37,   40,   43,   48,   54,
-       59,   64,   69,   74,   76,   77,   78,   79,   80,   81,
-       82,   82,   83,   84,   85,   87,   88,   89,   90,   91,
-       91,   92,   93,   96,   99,   99,  103,  106,  109,  112,
-      113,  113,  114,  115,  116,  118,  119,  120,  121,  125,
-      129,  132,  135,  138,  140,  141,  145,  148,  151,  154,
-      157,  159,  162,  164,  164
+        1,    2,    3,    4,    6,    9,   11,   14,   17,   19,
+       22,   26,   29,   32,   35,   38,   41,   44,   49,   55,
+       60,   65,   70,   75,   77,   78,   79,   80,   81,   82,
+       83,   83,   84,   85,   86,   88,   89,   90,   91,   92,
+       92,   93,   94,   97,  100,  100,  104,  107,  110,  113,
+      114,  114,  115,  116,  117,  119,  120,  121,  122,  126,
+      130,  133,  136,  139,  141,  142,  146,  149,  152,  155,
+      158,  160,  163,  165,  165
     } ;
 
-static const YY_CHAR yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
@@ -426,7 +422,7 @@ static const YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[35] =
+static yyconst YY_CHAR yy_meta[35] =
     {   0,
         1,    1,    2,    3,    1,    1,    1,    3,    1,    1,
         4,    5,    1,    1,    1,    1,    1,    6,    6,    6,
@@ -434,7 +430,7 @@ static const YY_CHAR yy_meta[35] =
         6,    6,    6,    1
     } ;
 
-static const flex_int16_t yy_base[80] =
+static yyconst flex_uint16_t yy_base[80] =
     {   0,
         0,    0,  134,  135,   33,   36,  118,    0,  125,  135,
        29,   31,  135,  116,  115,  114,  135,   49,   51,   34,
@@ -446,7 +442,7 @@ static const flex_int16_t yy_base[80] =
       135,   50,  135,  135,   97,  100,  104,  106,   46
     } ;
 
-static const flex_int16_t yy_def[80] =
+static yyconst flex_int16_t yy_def[80] =
     {   0,
        74,    1,   74,   74,   74,   74,   74,   75,   74,   74,
        74,   76,   74,   74,   74,   74,   74,   77,   77,   19,
@@ -458,7 +454,7 @@ static const flex_int16_t yy_def[80] =
        74,   19,   74,    0,   74,   74,   74,   74,   74
     } ;
 
-static const flex_int16_t yy_nxt[170] =
+static yyconst flex_uint16_t yy_nxt[170] =
     {   0,
         4,    5,    6,    5,    7,    8,    9,   10,   10,   10,
        11,   12,   13,   14,   15,   16,   17,   18,   19,   20,
@@ -480,7 +476,7 @@ static const flex_int16_t yy_nxt[170] =
        74,   74,   74,   74,   74,   74,   74,   74,   74
     } ;
 
-static const flex_int16_t yy_chk[170] =
+static yyconst flex_int16_t yy_chk[170] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -536,7 +532,6 @@ goto find_rule; \
 #include "expr.h"
 #include "expr_yacc.h"
 
-#line 539 "expr_lex.cc"
 /* Definitions:  LMB92 p. 153
    Definitions are named regular expressions, e.g., DGT [0-9]
    Definitions enclosed in braces in rules section, e.g. {DGT}, are interpreted literally
@@ -544,7 +539,7 @@ goto find_rule; \
    LPH [A-Za-z_] Alphabetic character
    LPHDGT [A-Za-z0-9_] Alphanumeric character
    XPN [eE][+-]?[0-9]+ Real number Exponent */
-#line 547 "expr_lex.cc"
+#line 543 "expr_lex.cc"
 
 #define INITIAL 0
 
@@ -607,7 +602,7 @@ struct yyguts_t
 
     }; /* end struct yyguts_t */
 
-static int yy_init_globals ( yyscan_t yyscanner );
+static int yy_init_globals (yyscan_t yyscanner );
 
     /* This must go here because YYSTYPE and YYLTYPE are included
      * from bison output in section 1.*/
@@ -615,44 +610,44 @@ static int yy_init_globals ( yyscan_t yyscanner );
     
 int yylex_init (yyscan_t* scanner);
 
-int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int yylex_destroy ( yyscan_t yyscanner );
+int yylex_destroy (yyscan_t yyscanner );
 
-int yyget_debug ( yyscan_t yyscanner );
+int yyget_debug (yyscan_t yyscanner );
 
-void yyset_debug ( int debug_flag , yyscan_t yyscanner );
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
 
-YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
 
-void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
 
-FILE *yyget_in ( yyscan_t yyscanner );
+FILE *yyget_in (yyscan_t yyscanner );
 
-void yyset_in  ( FILE * _in_str , yyscan_t yyscanner );
+void yyset_in  (FILE * _in_str ,yyscan_t yyscanner );
 
-FILE *yyget_out ( yyscan_t yyscanner );
+FILE *yyget_out (yyscan_t yyscanner );
 
-void yyset_out  ( FILE * _out_str , yyscan_t yyscanner );
+void yyset_out  (FILE * _out_str ,yyscan_t yyscanner );
 
-			int yyget_leng ( yyscan_t yyscanner );
+			int yyget_leng (yyscan_t yyscanner );
 
-char *yyget_text ( yyscan_t yyscanner );
+char *yyget_text (yyscan_t yyscanner );
 
-int yyget_lineno ( yyscan_t yyscanner );
+int yyget_lineno (yyscan_t yyscanner );
 
-void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+void yyset_lineno (int _line_number ,yyscan_t yyscanner );
 
-int yyget_column  ( yyscan_t yyscanner );
+int yyget_column  (yyscan_t yyscanner );
 
-void yyset_column ( int _column_no , yyscan_t yyscanner );
+void yyset_column (int _column_no ,yyscan_t yyscanner );
 
-YYSTYPE * yyget_lval ( yyscan_t yyscanner );
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
 
-void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -660,9 +655,9 @@ void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap ( yyscan_t yyscanner );
+extern "C" int yywrap (yyscan_t yyscanner );
 #else
-extern int yywrap ( yyscan_t yyscanner );
+extern int yywrap (yyscan_t yyscanner );
 #endif
 #endif
 
@@ -671,18 +666,19 @@ extern int yywrap ( yyscan_t yyscanner );
 #endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 #endif
 
 #ifndef YY_NO_INPUT
+
 #ifdef __cplusplus
-static int yyinput ( yyscan_t yyscanner );
+static int yyinput (yyscan_t yyscanner );
 #else
-static int input ( yyscan_t yyscanner );
+static int input (yyscan_t yyscanner );
 #endif
 
 #endif
@@ -713,7 +709,7 @@ static int input ( yyscan_t yyscanner );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		int n; \
+		size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -726,7 +722,7 @@ static int input ( yyscan_t yyscanner );
 	else \
 		{ \
 		errno=0; \
-		while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
@@ -768,7 +764,7 @@ static int input ( yyscan_t yyscanner );
 #define YY_DECL_IS_OURS 1
 
 extern int yylex \
-               (YYSTYPE * yylval_param , yyscan_t yyscanner);
+               (YYSTYPE * yylval_param ,yyscan_t yyscanner);
 
 #define YY_DECL int yylex \
                (YYSTYPE * yylval_param , yyscan_t yyscanner)
@@ -810,7 +806,7 @@ YY_DECL
 
         /* Create the reject buffer large enough to save one state per allowed character. */
         if ( ! yyg->yy_state_buf )
-            yyg->yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE  , yyscanner);
+            yyg->yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE  ,yyscanner);
             if ( ! yyg->yy_state_buf )
                 YY_FATAL_ERROR( "out of dynamic memory in yylex()" );
 
@@ -826,17 +822,17 @@ YY_DECL
 		if ( ! YY_CURRENT_BUFFER ) {
 			yyensure_buffer_stack (yyscanner);
 			YY_CURRENT_BUFFER_LVALUE =
-				yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+				yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
 		}
 
-		yy_load_buffer_state( yyscanner );
+		yy_load_buffer_state(yyscanner );
 		}
 
 	{
 #line 36 "expr_lex.l"
 
 
-#line 839 "expr_lex.cc"
+#line 836 "expr_lex.cc"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -863,9 +859,9 @@ yy_match:
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
 				if ( yy_current_state >= 75 )
-					yy_c = yy_meta[yy_c];
+					yy_c = yy_meta[(unsigned int) yy_c];
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 			*yyg->yy_state_ptr++ = yy_current_state;
 			++yy_cp;
 			}
@@ -1047,30 +1043,35 @@ return OR;
 case 21:
 YY_RULE_SETUP
 #line 98 "expr_lex.l"
-return QUESTION;
+return NOT;
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
 #line 99 "expr_lex.l"
-return COLON;
+return QUESTION;
 	YY_BREAK
 case 23:
-/* rule 23 can match eol */
 YY_RULE_SETUP
-#line 101 "expr_lex.l"
-;       /* ignore whitespace */
+#line 100 "expr_lex.l"
+return COLON;
 	YY_BREAK
 case 24:
+/* rule 24 can match eol */
 YY_RULE_SETUP
-#line 103 "expr_lex.l"
-yyerror(NULL, NULL, "Unknown character");
+#line 102 "expr_lex.l"
+;       /* ignore whitespace */
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
 #line 104 "expr_lex.l"
+yyerror(NULL, NULL, "Unknown character");
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 105 "expr_lex.l"
 ECHO;
 	YY_BREAK
-#line 1073 "expr_lex.cc"
+#line 1075 "expr_lex.cc"
 			case YY_STATE_EOF(INITIAL):
 				yyterminate();
 
@@ -1148,7 +1149,7 @@ ECHO;
 				{
 				yyg->yy_did_buffer_switch_on_eof = 0;
 
-				if ( yywrap( yyscanner ) )
+				if ( yywrap(yyscanner ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
@@ -1216,7 +1217,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	char *source = yyg->yytext_ptr;
-	int number_to_move, i;
+	yy_size_t number_to_move, i;
 	int ret_val;
 
 	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1245,7 +1246,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	/* Try to read more data. */
 
 	/* First move last chars to start of buffer. */
-	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
+	number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
 
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
@@ -1284,7 +1285,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			yyrestart( yyin  , yyscanner);
+			yyrestart(yyin  ,yyscanner);
 			}
 
 		else
@@ -1298,15 +1299,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
-			(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-		/* "- 2" to take care of EOB's */
-		YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
 	}
 
 	yyg->yy_n_chars += number_to_move;
@@ -1338,9 +1336,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
 			if ( yy_current_state >= 75 )
-				yy_c = yy_meta[yy_c];
+				yy_c = yy_meta[(unsigned int) yy_c];
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 		*yyg->yy_state_ptr++ = yy_current_state;
 		}
 
@@ -1362,9 +1360,9 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
 		if ( yy_current_state >= 75 )
-			yy_c = yy_meta[yy_c];
+			yy_c = yy_meta[(unsigned int) yy_c];
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 	yy_is_jam = (yy_current_state == 74);
 	if ( ! yy_is_jam )
 		*yyg->yy_state_ptr++ = yy_current_state;
@@ -1402,7 +1400,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 		else
 			{ /* need more input */
-			int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
+			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
 			++yyg->yy_c_buf_p;
 
 			switch ( yy_get_next_buffer( yyscanner ) )
@@ -1419,13 +1417,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 					 */
 
 					/* Reset buffer status. */
-					yyrestart( yyin , yyscanner);
+					yyrestart(yyin ,yyscanner);
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( yywrap( yyscanner ) )
+					if ( yywrap(yyscanner ) )
 						return 0;
 
 					if ( ! yyg->yy_did_buffer_switch_on_eof )
@@ -1464,11 +1462,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	if ( ! YY_CURRENT_BUFFER ){
         yyensure_buffer_stack (yyscanner);
 		YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
 	}
 
-	yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
-	yy_load_buffer_state( yyscanner );
+	yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+	yy_load_buffer_state(yyscanner );
 }
 
 /** Switch to a different input buffer.
@@ -1497,7 +1495,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	yy_load_buffer_state( yyscanner );
+	yy_load_buffer_state(yyscanner );
 
 	/* We don't actually know whether we did this switch during
 	 * EOF (yywrap()) processing, but the only time this flag
@@ -1526,22 +1524,22 @@ static void yy_load_buffer_state  (yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
-	b->yy_buf_size = size;
+	b->yy_buf_size = (yy_size_t)size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 */
-	b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
+	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
 	if ( ! b->yy_ch_buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	yy_init_buffer( b, file , yyscanner);
+	yy_init_buffer(b,file ,yyscanner);
 
 	return b;
 }
@@ -1561,9 +1559,9 @@ static void yy_load_buffer_state  (yyscan_t yyscanner)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		yyfree( (void *) b->yy_ch_buf , yyscanner );
+		yyfree((void *) b->yy_ch_buf ,yyscanner );
 
-	yyfree( (void *) b , yyscanner );
+	yyfree((void *) b ,yyscanner );
 }
 
 /* Initializes or reinitializes a buffer.
@@ -1576,7 +1574,7 @@ static void yy_load_buffer_state  (yyscan_t yyscanner)
 	int oerrno = errno;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-	yy_flush_buffer( b , yyscanner);
+	yy_flush_buffer(b ,yyscanner);
 
 	b->yy_input_file = file;
 	b->yy_fill_buffer = 1;
@@ -1620,7 +1618,7 @@ static void yy_load_buffer_state  (yyscan_t yyscanner)
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		yy_load_buffer_state( yyscanner );
+		yy_load_buffer_state(yyscanner );
 }
 
 /** Pushes the new state onto the stack. The new state becomes
@@ -1652,7 +1650,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
 	/* copied from yy_switch_to_buffer. */
-	yy_load_buffer_state( yyscanner );
+	yy_load_buffer_state(yyscanner );
 	yyg->yy_did_buffer_switch_on_eof = 1;
 }
 
@@ -1666,13 +1664,13 @@ void yypop_buffer_state (yyscan_t yyscanner)
 	if (!YY_CURRENT_BUFFER)
 		return;
 
-	yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
+	yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
 	YY_CURRENT_BUFFER_LVALUE = NULL;
 	if (yyg->yy_buffer_stack_top > 0)
 		--yyg->yy_buffer_stack_top;
 
 	if (YY_CURRENT_BUFFER) {
-		yy_load_buffer_state( yyscanner );
+		yy_load_buffer_state(yyscanner );
 		yyg->yy_did_buffer_switch_on_eof = 1;
 	}
 }
@@ -1682,7 +1680,7 @@ void yypop_buffer_state (yyscan_t yyscanner)
  */
 static void yyensure_buffer_stack (yyscan_t yyscanner)
 {
-	yy_size_t num_to_alloc;
+	int num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	if (!yyg->yy_buffer_stack) {
@@ -1697,9 +1695,9 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
 								, yyscanner);
 		if ( ! yyg->yy_buffer_stack )
 			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
+								  
 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+				
 		yyg->yy_buffer_stack_max = num_to_alloc;
 		yyg->yy_buffer_stack_top = 0;
 		return;
@@ -1728,7 +1726,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object. 
  */
 YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
 {
@@ -1740,11 +1738,11 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscann
 		/* They forgot to leave room for the EOB's. */
 		return NULL;
 
-	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
-	b->yy_buf_size = (int) (size - 2);	/* "- 2" to take care of EOB's */
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
 	b->yy_input_file = NULL;
@@ -1754,7 +1752,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscann
 	b->yy_fill_buffer = 0;
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
-	yy_switch_to_buffer( b , yyscanner );
+	yy_switch_to_buffer(b ,yyscanner );
 
 	return b;
 }
@@ -1767,10 +1765,10 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscann
  * @note If you want to scan bytes that may contain NUL values, then use
  *       yy_scan_bytes() instead.
  */
-YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 {
     
-	return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
+	return yy_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
 }
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -1780,16 +1778,16 @@ YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
 	char *buf;
 	yy_size_t n;
-	int i;
+	yy_size_t i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = (yy_size_t) (_yybytes_len + 2);
-	buf = (char *) yyalloc( n , yyscanner );
+	n = (yy_size_t) _yybytes_len + 2;
+	buf = (char *) yyalloc(n ,yyscanner );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
@@ -1798,7 +1796,7 @@ YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len , yyscan
 
 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
-	b = yy_scan_buffer( buf, n , yyscanner);
+	b = yy_scan_buffer(buf,n ,yyscanner);
 	if ( ! b )
 		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -1814,11 +1812,11 @@ YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len , yyscan
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
 {
 	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	(void)yyg;
-	fprintf( stderr, "%s\n", msg );
+	(void) fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 }
 
@@ -1856,7 +1854,7 @@ YY_EXTRA_TYPE yyget_extra  (yyscan_t yyscanner)
 int yyget_lineno  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -1869,7 +1867,7 @@ int yyget_lineno  (yyscan_t yyscanner)
 int yyget_column  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -2003,7 +2001,9 @@ void yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
  * the ONLY reentrant function that doesn't take the scanner as the last argument.
  * That's why we explicitly handle the declaration, instead of using our macros.
  */
+
 int yylex_init(yyscan_t* ptr_yy_globals)
+
 {
     if (ptr_yy_globals == NULL){
         errno = EINVAL;
@@ -2030,7 +2030,9 @@ int yylex_init(yyscan_t* ptr_yy_globals)
  * The user defined value in the first argument will be available to yyalloc in
  * the yyextra field.
  */
-int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
 {
     struct yyguts_t dummy_yyguts;
 
@@ -2040,20 +2042,20 @@ int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
         errno = EINVAL;
         return 1;
     }
-
+	
     *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+	
     if (*ptr_yy_globals == NULL){
         errno = ENOMEM;
         return 1;
     }
-
+    
     /* By setting to 0xAA, we expose bugs in
     yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+    
     yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+    
     return yy_init_globals ( *ptr_yy_globals );
 }
 
@@ -2102,17 +2104,17 @@ int yylex_destroy  (yyscan_t yyscanner)
 
     /* Pop the buffer stack, destroying each element. */
 	while(YY_CURRENT_BUFFER){
-		yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
+		yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
 		YY_CURRENT_BUFFER_LVALUE = NULL;
 		yypop_buffer_state(yyscanner);
 	}
 
 	/* Destroy the stack itself. */
-	yyfree(yyg->yy_buffer_stack , yyscanner);
+	yyfree(yyg->yy_buffer_stack ,yyscanner);
 	yyg->yy_buffer_stack = NULL;
 
     /* Destroy the start condition stack. */
-        yyfree( yyg->yy_start_stack , yyscanner );
+        yyfree(yyg->yy_start_stack ,yyscanner );
         yyg->yy_start_stack = NULL;
 
     yyfree ( yyg->yy_state_buf , yyscanner);
@@ -2133,7 +2135,7 @@ int yylex_destroy  (yyscan_t yyscanner)
  */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
 {
 	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	(void)yyg;
@@ -2145,7 +2147,7 @@ static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscann
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 {
 	int n;
 	for ( n = 0; s[n]; ++n )
@@ -2186,6 +2188,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 104 "expr_lex.l"
+#line 105 "expr_lex.l"
+
 
 
diff --git a/src/expr_yacc.cc b/src/expr_yacc.cc
index e692378..99d3565 100644
--- a/src/expr_yacc.cc
+++ b/src/expr_yacc.cc
@@ -142,7 +142,8 @@ extern int yydebug;
     NE = 271,
     GT = 272,
     LT = 273,
-    UMINUS = 274
+    UMINUS = 274,
+    NOT = 275
   };
 #endif
 /* Tokens.  */
@@ -163,6 +164,7 @@ extern int yydebug;
 #define GT 272
 #define LT 273
 #define UMINUS 274
+#define NOT 275
 
 /* Value type.  */
 
@@ -174,7 +176,7 @@ int yyparse (parse_param_t *parse_arg, void *scanner);
 
 /* Copy the second part of user declarations.  */
 
-#line 178 "expr_yacc.cc" /* yacc.c:358  */
+#line 180 "expr_yacc.cc" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -419,18 +421,18 @@ union yyalloc
 #define YYLAST   204
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  32
+#define YYNTOKENS  33
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  7
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  37
+#define YYNRULES  38
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  79
+#define YYNSTATES  81
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   274
+#define YYMAXUTOK   275
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -443,15 +445,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      30,    27,    21,    19,    31,    20,     2,    22,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    25,
-       2,    26,     2,     2,     2,     2,     2,     2,     2,     2,
+      31,    28,    21,    19,    32,    20,     2,    22,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    26,
+       2,    27,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    24,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,    25,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    28,     2,    29,     2,     2,     2,     2,
+       2,     2,     2,    29,     2,    30,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -466,7 +468,7 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    23
+      15,    16,    17,    18,    23,    24
 };
 
 #if YYDEBUG
@@ -476,7 +478,7 @@ static const yytype_uint8 yyrline[] =
        0,    60,    60,    64,    65,    69,    70,    71,    72,    73,
       74,    75,    76,    80,    81,    85,    86,    87,    88,    89,
       90,    91,    92,    93,    94,    95,    96,    97,    98,    99,
-     100,   101,   102,   103,   104,   105,   106,   109
+     100,   101,   102,   103,   104,   105,   106,   107,   110
 };
 #endif
 
@@ -487,9 +489,9 @@ static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "CONSTANT", "VARIABLE", "FUNCTION",
   "QUESTION", "COLON", "REMOVE", "PRINT", "AND", "OR", "LEG", "GE", "LE",
-  "EQ", "NE", "GT", "LT", "'+'", "'-'", "'*'", "'/'", "UMINUS", "'^'",
-  "';'", "'='", "')'", "'{'", "'}'", "'('", "','", "$accept", "program",
-  "function", "stmt", "stmt_list", "expr", "ternary", YY_NULLPTR
+  "EQ", "NE", "GT", "LT", "'+'", "'-'", "'*'", "'/'", "UMINUS", "NOT",
+  "'^'", "';'", "'='", "')'", "'{'", "'}'", "'('", "','", "$accept",
+  "program", "function", "stmt", "stmt_list", "expr", "ternary", YY_NULLPTR
 };
 #endif
 
@@ -500,15 +502,15 @@ static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,    43,
-      45,    42,    47,   274,    94,    59,    61,    41,   123,   125,
-      40,    44
+      45,    42,    47,   274,   275,    94,    59,    61,    41,   123,
+     125,    40,    44
 };
 # endif
 
-#define YYPACT_NINF -25
+#define YYPACT_NINF -27
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-25)))
+  (!!((Yystate) == (-27)))
 
 #define YYTABLE_NINF -1
 
@@ -519,14 +521,15 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     -25,     2,    41,   -25,   -25,   -21,   -24,     7,    10,    59,
-     -25,    41,    59,   -25,   151,   -25,    59,    59,   -11,     8,
-     -25,    14,   -25,    28,    80,    13,    59,    59,    59,    59,
-      59,    59,    59,    59,    59,    59,    59,    59,    59,    59,
-     -25,   120,    16,    98,    17,    18,   -25,   -25,    59,   -25,
-     -25,   180,   180,    53,    53,    53,    53,    53,    53,    53,
-     -12,   -12,    14,    14,    14,   -25,   -25,   -25,    31,   -25,
-     -25,   136,    20,    12,    59,   -25,    25,   167,   -25
+     -27,     3,    44,   -27,   -27,    10,   -26,    12,    14,    73,
+      73,   -27,    44,    73,   -27,   148,   -27,    73,    73,    15,
+      16,   -27,    17,    17,   -27,    30,    95,    18,    73,    73,
+      73,    73,    73,    73,    73,    73,    73,    73,    73,    73,
+      73,    73,   -27,   115,    19,    70,    25,    29,   -27,   -27,
+      73,   -27,   -27,   179,   179,    -8,    -8,    -8,    -8,    -8,
+      -8,    -8,   -15,   -15,    17,    17,    17,   -27,   -27,   -27,
+      37,   -27,   -27,   132,    34,    55,    73,   -27,    35,   165,
+     -27
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -535,25 +538,26 @@ static const yytype_int16 yypact[] =
 static const yytype_uint8 yydefact[] =
 {
        4,     0,     2,     1,    15,    16,     0,     0,     0,     0,
-       5,     0,     0,     3,     0,     9,     0,     0,     0,     0,
-      16,    17,    13,     0,     0,     0,     0,     0,     0,     0,
+       0,     5,     0,     0,     3,     0,     9,     0,     0,     0,
+       0,    16,    17,    18,    13,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       6,     0,     0,     0,     0,     0,    12,    14,     0,    32,
-      33,    30,    31,    29,    25,    26,    28,    27,    23,    22,
-      18,    19,    20,    21,    24,     7,     8,    36,     0,    10,
-      11,     0,     0,     0,     0,    35,     0,    37,    34
+       0,     0,     6,     0,     0,     0,     0,     0,    12,    14,
+       0,    33,    34,    31,    32,    30,    26,    27,    29,    28,
+      24,    23,    19,    20,    21,    22,    25,     7,     8,    37,
+       0,    10,    11,     0,     0,     0,     0,    36,     0,    38,
+      35
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -25,   -25,   -25,   -10,   -25,    -9,    38
+     -27,   -27,   -27,   -10,   -27,    -9,    48
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     1,     2,    13,    23,    14,    25
+      -1,     1,     2,    14,    25,    15,    27
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -561,84 +565,85 @@ static const yytype_int8 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
-      21,    22,     3,    24,    15,    16,    17,    41,    43,    37,
-      38,    18,    39,    47,    19,    76,    44,    51,    52,    53,
+      22,    23,    24,     3,    26,    18,    39,    40,    43,    45,
+      41,    37,    38,    39,    40,    49,    19,    41,    20,    53,
       54,    55,    56,    57,    58,    59,    60,    61,    62,    63,
-      64,     4,     5,     6,    72,    45,     7,     8,    39,    71,
-      50,    66,    69,    70,     4,     5,     6,    75,     9,     7,
-       8,    73,    78,    10,    42,     0,    11,    46,    12,     0,
-       0,     9,     4,    20,     6,    77,    10,     0,     0,    11,
-       0,    12,    35,    36,    37,    38,     0,    39,     0,     9,
-       0,     0,     0,     0,     0,     0,    48,     0,     0,    12,
-      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
-      36,    37,    38,     0,    39,     0,     0,    49,    26,    27,
+      64,    65,    66,     4,     5,     6,    16,    17,     7,     8,
+      74,    73,    41,    46,    47,    68,    52,     4,     5,     6,
+       9,    71,     7,     8,    10,    72,    11,    75,    78,    12,
+      48,    13,    77,    80,     9,    44,     0,    79,    10,     0,
+      11,     0,     0,    12,     0,    13,     4,    21,     6,     0,
       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,     0,    39,     0,     0,    67,    48,     0,     0,    68,
-      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
-      36,    37,    38,    74,    39,    65,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    36,    37,    38,     0,
-      39,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,     0,    39,    40,    26,    27,    28,
-      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
-       0,    39,    28,    29,    30,    31,    32,    33,    34,    35,
-      36,    37,    38,     0,    39
+      38,    39,    40,     9,     0,    41,     0,    10,    69,     0,
+       0,    50,    70,     0,    13,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,    40,     0,     0,
+      41,    50,     0,    51,     0,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,    40,     0,    76,
+      41,    67,    28,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    40,     0,     0,    41,    28,    29,
+      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
+      40,     0,     0,    41,    42,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    38,    39,    40,     0,     0,
+      41,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,    40,     0,     0,    41
 };
 
 static const yytype_int8 yycheck[] =
 {
-       9,    11,     0,    12,    25,    26,    30,    16,    17,    21,
-      22,     4,    24,    23,     4,     3,    27,    26,    27,    28,
+       9,    10,    12,     0,    13,    31,    21,    22,    17,    18,
+      25,    19,    20,    21,    22,    25,     4,    25,     4,    28,
       29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
-      39,     3,     4,     5,     3,    27,     8,     9,    24,    48,
-      27,    25,    25,    25,     3,     4,     5,    27,    20,     8,
-       9,    20,    27,    25,    16,    -1,    28,    29,    30,    -1,
-      -1,    20,     3,     4,     5,    74,    25,    -1,    -1,    28,
-      -1,    30,    19,    20,    21,    22,    -1,    24,    -1,    20,
-      -1,    -1,    -1,    -1,    -1,    -1,     6,    -1,    -1,    30,
+      39,    40,    41,     3,     4,     5,    26,    27,     8,     9,
+       3,    50,    25,    28,    28,    26,    28,     3,     4,     5,
+      20,    26,     8,     9,    24,    26,    26,    20,     3,    29,
+      30,    31,    28,    28,    20,    17,    -1,    76,    24,    -1,
+      26,    -1,    -1,    29,    -1,    31,     3,     4,     5,    -1,
       10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    -1,    24,    -1,    -1,    27,    10,    11,
+      20,    21,    22,    20,    -1,    25,    -1,    24,    28,    -1,
+      -1,     6,    32,    -1,    31,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    -1,    -1,
+      25,     6,    -1,    28,    -1,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    -1,     7,
+      25,    26,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    -1,    -1,    25,    10,    11,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    -1,    24,    -1,    -1,    27,     6,    -1,    -1,    31,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,     7,    24,    25,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,    -1,
-      24,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    22,    -1,    24,    25,    10,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      -1,    24,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    -1,    24
+      22,    -1,    -1,    25,    26,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    -1,    -1,
+      25,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    -1,    -1,    25
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    33,    34,     0,     3,     4,     5,     8,     9,    20,
-      25,    28,    30,    35,    37,    25,    26,    30,     4,     4,
-       4,    37,    35,    36,    37,    38,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,    22,    24,
-      25,    37,    38,    37,    27,    27,    29,    35,     6,    27,
-      27,    37,    37,    37,    37,    37,    37,    37,    37,    37,
-      37,    37,    37,    37,    37,    25,    25,    27,    31,    25,
-      25,    37,     3,    20,     7,    27,     3,    37,    27
+       0,    34,    35,     0,     3,     4,     5,     8,     9,    20,
+      24,    26,    29,    31,    36,    38,    26,    27,    31,     4,
+       4,     4,    38,    38,    36,    37,    38,    39,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    25,    26,    38,    39,    38,    28,    28,    30,    36,
+       6,    28,    28,    38,    38,    38,    38,    38,    38,    38,
+      38,    38,    38,    38,    38,    38,    38,    26,    26,    28,
+      32,    26,    26,    38,     3,    20,     7,    28,     3,    38,
+      28
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    32,    33,    34,    34,    35,    35,    35,    35,    35,
-      35,    35,    35,    36,    36,    37,    37,    37,    37,    37,
-      37,    37,    37,    37,    37,    37,    37,    37,    37,    37,
-      37,    37,    37,    37,    37,    37,    37,    38
+       0,    33,    34,    35,    35,    36,    36,    36,    36,    36,
+      36,    36,    36,    37,    37,    38,    38,    38,    38,    38,
+      38,    38,    38,    38,    38,    38,    38,    38,    38,    38,
+      38,    38,    38,    38,    38,    38,    38,    38,    39
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     1,     2,     0,     1,     2,     4,     4,     2,
-       4,     4,     3,     1,     2,     1,     1,     2,     3,     3,
+       4,     4,     3,     1,     2,     1,     1,     2,     2,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     7,     6,     4,     5
+       3,     3,     3,     3,     3,     7,     6,     4,     5
 };
 
 
@@ -1325,215 +1330,221 @@ yyreduce:
         case 2:
 #line 60 "expr_yacc.y" /* yacc.c:1646  */
     { return 0; }
-#line 1329 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1334 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 3:
 #line 64 "expr_yacc.y" /* yacc.c:1646  */
     { expr_run((yyvsp[0].nPtr), (parse_param_t *) parse_arg); freeNode((yyvsp[0].nPtr)); }
-#line 1335 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1340 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 5:
 #line 69 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr(';', 2, NULL, NULL); }
-#line 1341 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1346 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 6:
 #line 70 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1347 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1352 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 7:
 #line 71 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-3].varnm)), (yyvsp[-1].nPtr)); }
-#line 1353 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1358 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 8:
 #line 72 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-3].varnm)), (yyvsp[-1].nPtr)); }
-#line 1359 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1364 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 9:
 #line 73 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[-1].varnm)), expr_var((yyvsp[-1].varnm))); }
-#line 1365 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1370 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 10:
 #line 74 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_com("remove", (yyvsp[-2].varnm)); }
-#line 1371 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1376 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 11:
 #line 75 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_com("print", (yyvsp[-2].varnm)); }
-#line 1377 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1382 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 12:
 #line 76 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1383 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1388 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 13:
 #line 80 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = (yyvsp[0].nPtr); }
-#line 1389 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1394 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 14:
 #line 81 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr(';', 2, (yyvsp[-1].nPtr), (yyvsp[0].nPtr)); }
-#line 1395 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1400 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 15:
 #line 85 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_con((yyvsp[0].cvalue)); }
-#line 1401 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1406 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 16:
 #line 86 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_var((yyvsp[0].varnm)); }
-#line 1407 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1412 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 17:
 #line 87 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(UMINUS, 1, (yyvsp[0].nPtr)); }
-#line 1413 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(UMINUS,  1, (yyvsp[0].nPtr)); }
+#line 1418 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 18:
 #line 88 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr('+', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1419 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(NOT,     1, (yyvsp[0].nPtr)); }
+#line 1424 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 19:
 #line 89 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr('-', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1425 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr('+', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1430 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 20:
 #line 90 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr('*', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1431 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr('-', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1436 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 21:
 #line 91 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr('/', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1437 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr('*', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1442 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 22:
 #line 92 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(LT,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1443 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr('/', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1448 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 23:
 #line 93 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(GT,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1449 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(LT,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1454 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 24:
 #line 94 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr('^', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1455 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(GT,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1460 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 25:
 #line 95 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(GE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1461 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr('^', 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1466 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 26:
 #line 96 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(LE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1467 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(GE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1472 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 27:
 #line 97 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(NE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1473 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(LE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1478 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 28:
 #line 98 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(EQ,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1479 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(NE,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1484 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 29:
 #line 99 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(LEG, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1485 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(EQ,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1490 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 30:
 #line 100 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(AND, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1491 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(LEG, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1496 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 31:
 #line 101 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_opr(OR,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1497 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(AND, 2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1502 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 32:
 #line 102 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1503 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_opr(OR,  2, (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
+#line 1508 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 33:
 #line 103 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = (yyvsp[-1].nPtr); }
-#line 1509 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1514 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 34:
 #line 104 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_fun1c((yyvsp[-6].fname), (yyvsp[-4].nPtr), - (yyvsp[-1].cvalue)); }
-#line 1515 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = (yyvsp[-1].nPtr); }
+#line 1520 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 35:
 #line 105 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_fun1c((yyvsp[-5].fname), (yyvsp[-3].nPtr), (yyvsp[-1].cvalue)); }
-#line 1521 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_fun1c((yyvsp[-6].fname), (yyvsp[-4].nPtr), - (yyvsp[-1].cvalue)); }
+#line 1526 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 36:
 #line 106 "expr_yacc.y" /* yacc.c:1646  */
-    { (yyval.nPtr) = expr_fun((yyvsp[-3].fname), (yyvsp[-1].nPtr)); }
-#line 1527 "expr_yacc.cc" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_fun1c((yyvsp[-5].fname), (yyvsp[-3].nPtr), (yyvsp[-1].cvalue)); }
+#line 1532 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
   case 37:
-#line 109 "expr_yacc.y" /* yacc.c:1646  */
+#line 107 "expr_yacc.y" /* yacc.c:1646  */
+    { (yyval.nPtr) = expr_fun((yyvsp[-3].fname), (yyvsp[-1].nPtr)); }
+#line 1538 "expr_yacc.cc" /* yacc.c:1646  */
+    break;
+
+  case 38:
+#line 110 "expr_yacc.y" /* yacc.c:1646  */
     { (yyval.nPtr) = expr_opr('?', 3, (yyvsp[-4].nPtr), (yyvsp[-2].nPtr), (yyvsp[0].nPtr)); }
-#line 1533 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1544 "expr_yacc.cc" /* yacc.c:1646  */
     break;
 
 
-#line 1537 "expr_yacc.cc" /* yacc.c:1646  */
+#line 1548 "expr_yacc.cc" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1761,7 +1772,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 112 "expr_yacc.y" /* yacc.c:1906  */
+#line 113 "expr_yacc.y" /* yacc.c:1906  */
 
 
 #define SIZEOF_NODETYPE ((char *)&p->u.con - (char *)p)
diff --git a/src/expr_yacc.h b/src/expr_yacc.h
index e3bac12..c8f3653 100644
--- a/src/expr_yacc.h
+++ b/src/expr_yacc.h
@@ -61,7 +61,8 @@ extern int yydebug;
     NE = 271,
     GT = 272,
     LT = 273,
-    UMINUS = 274
+    UMINUS = 274,
+    NOT = 275
   };
 #endif
 /* Tokens.  */
@@ -82,6 +83,7 @@ extern int yydebug;
 #define GT 272
 #define LT 273
 #define UMINUS 274
+#define NOT 275
 
 /* Value type.  */
 
diff --git a/src/grid_area.cc b/src/grid_area.cc
index 3586eb8..2cbae71 100644
--- a/src/grid_area.cc
+++ b/src/grid_area.cc
@@ -29,15 +29,11 @@ void lonlat_to_xyz(double lon, double lat, double *xyz)
 }
 
 /*
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "clipping/grid.h"
 #include "clipping/grid_cell.h"
 #include "clipping/area.h"
-#ifdef __cplusplus
 }
-#endif
 
 static
 double yac_huiliers_area(int num_corners, double *cell_corner_lon, double *cell_corner_lat)
diff --git a/src/grid_proj.h b/src/grid_proj.h
index 9bca934..7f18e9f 100644
--- a/src/grid_proj.h
+++ b/src/grid_proj.h
@@ -1,5 +1,5 @@
-#ifndef _GRID_PROJ_H
-#define _GRID_PROJ_H
+#ifndef  GRID_PROJ_H
+#define  GRID_PROJ_H
 
 
 int cdo_lonlat_to_lcc(int gridID, size_t nvals, double *xvals, double *yvals);
@@ -10,15 +10,9 @@ void cdo_laea_to_lonlat(int gridID, size_t nvals, double *xvals, double *yvals);
 
 void cdo_proj_to_lonlat(char *proj4param, size_t nvals, double *xvals, double *yvals);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 int proj_lonlat_to_lcc(double missval, double lon_0, double lat_0, double lat_1, double lat_2,
                        double a, double rf, size_t nvals, double *xvals, double *yvals);
 int proj_lcc_to_lonlat(double missval, double lon_0, double lat_0, double lat_1, double lat_2,
                        double a, double rf, double x_0, double y_0, size_t nvals, double *xvals, double *yvals);
-#if defined (__cplusplus)
-}
-#endif
 
-#endif  /* _GRID_PROJ_H */
+#endif  /* GRID_PROJ_H */
diff --git a/src/grid_search.cc b/src/grid_search.cc
index 6085168..74c4ff6 100644
--- a/src/grid_search.cc
+++ b/src/grid_search.cc
@@ -136,8 +136,16 @@ struct gridsearch *gridsearch_create_reg2d(bool is_cyclic, size_t dims[2], const
   return gs;
 }
 
+#ifdef  TEST_BBOX
+static inline void XYZtoLL (kdata_t p_in[], double * lon, double * lat) {
+
+   *lon = atan2(p_in[1] , p_in[0]);
+   *lat = M_PI_2 - acos(p_in[2]);
+}
+#endif
+
 static
-kdTree_t *gs_create_kdtree(size_t n, const double *restrict lons, const double *restrict lats)
+kdTree_t *gs_create_kdtree(size_t n, const double *restrict lons, const double *restrict lats, struct gridsearch *gs)
 {
   struct kd_point *pointlist = (struct kd_point *) Malloc(n*sizeof(struct kd_point));  
   // see  example_cartesian.c
@@ -145,13 +153,13 @@ kdTree_t *gs_create_kdtree(size_t n, const double *restrict lons, const double *
   kdata_t min[3], max[3];
   min[0] = min[1] = min[2] =  1e9;
   max[0] = max[1] = max[2] = -1e9;
-  kdata_t *restrict point;
 #if defined(HAVE_OPENMP4)
-#pragma omp simd
+  // failed with INTEL CC: error: 'min' has invalid type for 'reduction'
+  // #pragma omp parallel for reduction(min: min) reduction(max: max)
 #endif
   for ( size_t i = 0; i < n; i++ ) 
     {
-      point = pointlist[i].point;
+      kdata_t *restrict point = pointlist[i].point;
       LLtoXYZ_kd(lons[i], lats[i], point);
       for ( unsigned j = 0; j < 3; ++j )
         {
@@ -161,6 +169,26 @@ kdTree_t *gs_create_kdtree(size_t n, const double *restrict lons, const double *
       pointlist[i].index = i;
     }
 
+#ifdef  TEST_BBOX
+  for ( unsigned j = 0; j < 3; ++j )
+    {
+      gs->min[j] = min[j];
+      gs->max[j] = max[j];
+    }
+  double lon1, lat1, lon2, lat2;
+  float point1[3], point2[3];
+  LLtoXYZ_kd(-29.8*DEG2RAD, 30.2*DEG2RAD, point1);
+  LLtoXYZ_kd(59.8*DEG2RAD, 79.8*DEG2RAD, point2);
+  printf("1: min %g %g %g  max %g %g %g\n", point1[0], point1[1], point1[2], point2[0], point2[1], point2[2]);
+  XYZtoLL(point1, &lon1, &lat1);
+  XYZtoLL(point2, &lon2, &lat2);
+  printf("lon1=%g, lat1=%g, lon2=%g, lat2=%g\n", lon1*RAD2DEG, lat1*RAD2DEG, lon2*RAD2DEG, lat2*RAD2DEG);
+  printf("2: min %g %g %g  max %g %g %g\n", min[0], min[1], min[2], max[0], max[1], max[2]);
+  XYZtoLL(min, &lon1, &lat1);
+  XYZtoLL(max, &lon2, &lat2);
+  printf("lon1=%g, lat1=%g, lon2=%g, lat2=%g\n", lon1*RAD2DEG, lat1*RAD2DEG, lon2*RAD2DEG, lat2*RAD2DEG);
+#endif
+  
   kdTree_t *kdt = kd_buildTree(pointlist, n, min, max, 3, ompNumThreads);
   if ( pointlist ) Free(pointlist);
   if ( kdt == NULL ) cdoAbort("kd_buildTree failed!");
@@ -178,13 +206,14 @@ nfTree_t *gs_create_nanoflann(size_t n, const double *restrict lons, const doubl
   min[0] = min[1] = min[2] =  1e9;
   max[0] = max[1] = max[2] = -1e9;
   // Generating  Point Cloud
-  float restrict point[3];
   pointcloud->pts.resize(n);
 #if defined(HAVE_OPENMP4)
-#pragma omp simd
+  // failed with INTEL CC: error: 'min' has invalid type for 'reduction'
+  // #pragma omp parallel for reduction(min: min) reduction(max: max)
 #endif
   for ( size_t i = 0; i < n; i++ ) 
     {
+      float point[3];
       LLtoXYZ_f(lons[i], lats[i], point);
       pointcloud->pts[i].x = point[0];
       pointcloud->pts[i].y = point[1];
@@ -214,7 +243,7 @@ kdTree_t *gs_create_kdsph(size_t n, const double *restrict lons, const double *r
   max[0] = max[1] = -1e9;
   kdata_t *restrict point;
 #if defined(HAVE_OPENMP4)
-#pragma omp simd
+  //#pragma omp simd
 #endif
   for ( size_t i = 0; i < n; i++ ) 
     {
@@ -348,7 +377,7 @@ void cal_bound_box(struct gridsearch *gs, size_t n, const double *restrict lons,
       int64_t ii = (int64_t) llround(fi);
       int64_t jj = (int64_t) llround(fj);
       if ( i < 1000 )
-        printf("lon=%g/lat=%g  ii=%ld  jj=%ld  fi=%g fj=%g\n", lons[i]*RAD2DEG, lats[i]*RAD2DEG, ii, jj, fi, fj);
+        printf("lon=%g/lat=%g  ii=%ld  jj=%ld  fi=%g fj=%g\n", lons[i]*RAD2DEG, lats[i]*RAD2DEG, (long)ii, (long)jj, fi, fj);
       mask1[jj*mlon+ii] = 1;
     }
 
@@ -480,7 +509,7 @@ struct gridsearch *gridsearch_create(size_t n, const double *restrict lons, cons
   gs->n = n;
   if ( n == 0 ) return gs;
 
-  gs->kdt = gs_create_kdtree(n, lons, lats);
+  gs->kdt = gs_create_kdtree(n, lons, lats, gs);
 
   gs->search_radius = cdo_default_search_radius();
 
@@ -496,7 +525,7 @@ struct gridsearch *gridsearch_create_nn(size_t n, const double *restrict lons, c
   gs->n = n;
   if ( n == 0 ) return gs;
 
-  if      ( gs->method_nn == GS_KDTREE    ) gs->kdt  = gs_create_kdtree(n, lons, lats);
+  if      ( gs->method_nn == GS_KDTREE    ) gs->kdt  = gs_create_kdtree(n, lons, lats, gs);
   else if ( gs->method_nn == GS_NANOFLANN ) gs->nft  = gs_create_nanoflann(n, lons, lats, gs);
   else if ( gs->method_nn == GS_KDSPH     ) gs->kdt  = gs_create_kdsph(n, lons, lats);
   else if ( gs->method_nn == GS_NEARPT3   ) gs->near = gs_create_nearpt3(n, lons, lats);
@@ -549,7 +578,7 @@ double gs_set_range(double *prange)
 }
 
 static
-size_t gs_nearest_kdtree(kdTree_t *kdt, double lon, double lat, double *prange)
+size_t gs_nearest_kdtree(kdTree_t *kdt, double lon, double lat, double *prange, struct gridsearch *gs)
 {
   size_t index = GS_NOT_FOUND;
   if ( kdt == NULL ) return index;
@@ -557,10 +586,15 @@ size_t gs_nearest_kdtree(kdTree_t *kdt, double lon, double lat, double *prange)
   float range0 = gs_set_range(prange);
   kdata_t range = KDATA_SCALE(range0);
 
-  kdata_t point[3];
-  LLtoXYZ_kd(lon, lat, point);
+  kdata_t query_pt[3];
+  LLtoXYZ_kd(lon, lat, query_pt);
 
-  kdNode *node = kd_nearest(kdt->node, point, &range, 3);
+#ifdef  TEST_BBOX
+  for ( unsigned j = 0; j < 3; ++j )
+    if ( query_pt[j] < gs->min[j] || query_pt[j] > gs->max[j] ) return index;
+#endif
+
+  kdNode *node = kd_nearest(kdt->node, query_pt, &range, 3);
 
   float frange = KDATA_INVSCALE(range);
   if ( !(frange < range0) ) node = NULL;
@@ -612,11 +646,11 @@ size_t gs_nearest_kdsph(kdTree_t *kdt, double lon, double lat, double *prange)
   float range0 = gs_set_range(prange);
   kdata_t range = KDATA_SCALE(range0);
 
-  kdata_t point[2];
-  point[0] = lon;
-  point[1] = lat;
+  kdata_t query_pt[2];
+  query_pt[0] = lon;
+  query_pt[1] = lat;
 
-  kdNode *node = kd_nearest(kdt->node, point, &range, 3);
+  kdNode *node = kd_nearest(kdt->node, query_pt, &range, 3);
 
   float frange = KDATA_INVSCALE(range);
   if ( !(frange < range0) ) node = NULL;
@@ -636,22 +670,22 @@ size_t gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double *p
 #if defined(ENABLE_NEARPT3)
   float range0 = gs_set_range(prange);
 
-  float point[3];
-  LLtoXYZ_f(lon, lat, point);
+  float query_pt[3];
+  LLtoXYZ_f(lon, lat, query_pt);
 
   Coord_T q[3];
-  q[0] = NPT3SCALE(point[0]);
-  q[1] = NPT3SCALE(point[1]);
-  q[2] = NPT3SCALE(point[2]);
+  q[0] = NPT3SCALE(query_pt[0]);
+  q[1] = NPT3SCALE(query_pt[1]);
+  q[2] = NPT3SCALE(query_pt[2]);
 
   int closestpt = nearpt3_query(near->nearpt3, q);
 
   if ( closestpt >= 0 )
     {
-      float point0[3];
-      LLtoXYZ_f(near->plons[closestpt], near->plats[closestpt], point0);
+      float query_pt0[3];
+      LLtoXYZ_f(near->plons[closestpt], near->plats[closestpt], query_pt0);
       
-      float range = distance(point, point0);
+      float range = distance(query_pt, query_pt0);
       if ( range < range0 )
         {
           index = (size_t) closestpt;
@@ -675,8 +709,8 @@ size_t gs_nearest_full(struct  gsFull *full, double lon, double lat, double *pra
   
   float range0 = gs_set_range(prange);
 
-  float point[3];
-  LLtoXYZ_f(lon, lat, point);
+  float query_pt[3];
+  LLtoXYZ_f(lon, lat, query_pt);
 
   size_t n = full->n;
   float **pts = full->pts;
@@ -684,7 +718,7 @@ size_t gs_nearest_full(struct  gsFull *full, double lon, double lat, double *pra
   float dist = FLT_MAX;
   for ( size_t i = 0; i < n; i++ )
     {
-      float d = distance(point, pts[i]);
+      float d = distance(query_pt, pts[i]);
       if ( closestpt >=n || d < dist || (d<=dist && i < closestpt) )
         {
           dist = d;
@@ -712,7 +746,7 @@ size_t gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double
   if ( gs )
     {
       // clang-format off
-      if      ( gs->method_nn == GS_KDTREE )    index = gs_nearest_kdtree(gs->kdt, lon, lat, prange);
+      if      ( gs->method_nn == GS_KDTREE )    index = gs_nearest_kdtree(gs->kdt, lon, lat, prange, gs);
       else if ( gs->method_nn == GS_NANOFLANN ) index = gs_nearest_nanoflann(gs->nft, lon, lat, prange);
       else if ( gs->method_nn == GS_KDSPH )     index = gs_nearest_kdsph(gs->kdt, lon, lat, prange);
       else if ( gs->method_nn == GS_NEARPT3 )   index = gs_nearest_nearpt3(gs->near, lon, lat, prange);
@@ -729,16 +763,16 @@ struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat
 {
   if ( gs->kdt == NULL ) return NULL;
   
-  kdata_t point[3];
+  kdata_t query_pt[3];
   float range0 = gs_set_range(prange);
   kdata_t range = KDATA_SCALE(range0);
   struct pqueue *result = NULL;
 
-  LLtoXYZ_kd(lon, lat, point);
+  LLtoXYZ_kd(lon, lat, query_pt);
 
   if ( gs )
     {
-      result = kd_qnearest(gs->kdt->node, point, &range, nnn, 3);
+      result = kd_qnearest(gs->kdt->node, query_pt, &range, nnn, 3);
       // printf("range %g %g %g %p\n", lon, lat, range, node);
 
       float frange = KDATA_INVSCALE(range);
diff --git a/src/grid_search.h b/src/grid_search.h
index a426b1e..b3f7754 100644
--- a/src/grid_search.h
+++ b/src/grid_search.h
@@ -6,18 +6,15 @@
 #include "nearpt3c.h"
 #include "nanoflann.hpp"
 
-#define GS_NOT_FOUND  SIZE_MAX
+//#define  TEST_BBOX  1
+#define  GS_NOT_FOUND  SIZE_MAX
 
 enum T_GRIDSEARCH_METHOD_NN  {GS_FULL=1, GS_NANOFLANN, GS_KDTREE, GS_KDSPH, GS_NEARPT3};
 
 template <typename T>
 struct PointCloud
 {
-  struct Point
-  {
-    T  x,y,z;
-  };
-
+  struct Point { T  x,y,z; };
   std::vector<Point>  pts;
 
   // Must return the number of data points
@@ -82,6 +79,9 @@ struct gridsearch {
   double *coslon, *sinlon;   // cosine, sine of grid lons (for distance)
 
   double lonmin, lonmax, latmin, latmax;
+#ifdef  TEST_BBOX
+  float min[3], max[3];
+#endif
 };
 
 struct gsknn {
diff --git a/src/modules.cc b/src/modules.cc
index ac79b86..cfaa75e 100644
--- a/src/modules.cc
+++ b/src/modules.cc
@@ -1349,14 +1349,67 @@ void close_library_handles() {
 #endif
 	
 // helper function for setting the spacing in operatorPrintList
-std::string get_spacing_for(std::string str) {
-    int max = 16;
+std::string get_spacing_for(int p_space, std::string str) {
     std::string spacing = "";
-    for (int i = str.size(); i <= max; i++) {
+    for (int i = str.size(); i <= p_space; i++) {
         spacing += " ";
     }
     return spacing;
 }
+std::string get_operator_description(std::string p_current_op_name, std::vector<std::string> help)
+{
+    std::string description = "";
+    unsigned long cur_help_idx;
+    bool help_contains_name;
+    std::string line;
+    unsigned long operator_section = 0;
+
+    cur_help_idx = 0;
+    //search for operator section
+    while (operator_section == 0 && cur_help_idx < help.size() - 1) {
+        line = help[++cur_help_idx];
+        if (line.find("OPERATORS") != std::string::npos) {
+            operator_section = cur_help_idx;
+        }
+    }
+    //if no operator section is found
+    if (operator_section == 0) {
+        cur_help_idx = 0;
+        line = help[0];
+        std::string name_section = help[0];
+        help_contains_name = false;
+        //search for the operator name in the description
+        while (!line.empty()) {
+            line = help[++cur_help_idx];
+            if (line.find(p_current_op_name) != std::string::npos) {
+                help_contains_name = true;
+            }
+            name_section += line;
+        }
+        //if the name was found save description for later use
+        if (help_contains_name) {
+            description = name_section.substr(name_section.find_first_of('-') + 2,
+                                              name_section.size());
+        }
+    } else {
+
+        line = help.at(++operator_section);
+        //search the operator section for current operator line
+        while (line.find(p_current_op_name + " ") == std::string::npos && !line.empty() &&
+               operator_section < help.size() - 1) {
+            line = help.at(++operator_section);
+        }
+        //if operator line found save description for later use
+        if (!line.empty() && operator_section < help.size()) {
+            auto op_name_start = line.find_first_not_of(" \t");
+
+            description = line.substr(
+                line.find_first_not_of(" \t", op_name_start + p_current_op_name.size()),
+                line.size());
+        }
+    }
+    return description;
+}
 /***
  * Prints all operator names and their short descriptions
  * Aliases are listed and point to their original operator name.
@@ -1374,73 +1427,29 @@ void operatorPrintList(bool print_no_output) {
     {
         output_list = get_sorted_operator_name_list();
     }
-    std::vector<std::string> help;
+
     unsigned long list_length = output_list.size();
-    unsigned long cur_help_idx;
-    std::string line;
-    std::string description;
-    bool help_contains_name;
+    modules_t *current_module;
+
+    //help variables
 
     for (unsigned long out_list_idx = 0; out_list_idx < list_length; out_list_idx++) {
         std::string current_op_name = output_list[out_list_idx];
-        help = modules[get_module_name_to(current_op_name)].help;
+        current_module = &modules[get_module_name_to(current_op_name)];
         if (aliases.find(current_op_name) != aliases.end()) {
 
             output_list[out_list_idx] +=
-                std::string(get_spacing_for(current_op_name) + "--> " + aliases[current_op_name]);
+                std::string(get_spacing_for(16, current_op_name) + "--> " + aliases[current_op_name]);
         }
-        else if (!help.empty()) {
-            description = "";
-
-            unsigned long operator_section = 0;
-            cur_help_idx = 0;
-            //search for operator section
-            while (operator_section == 0 && cur_help_idx < help.size() - 1) {
-                line = help[++cur_help_idx];
-                if (line.find("OPERATORS") != std::string::npos) {
-                    operator_section = cur_help_idx;
-                }
-            }
-            //if no operator section is found
-            if (operator_section == 0) {
-                cur_help_idx = 0;
-                line = help[0];
-                std::string name_section = help[0];
-                help_contains_name = false;
-                //search for the operator name in the description
-                while (!line.empty()) {
-                    line = help[++cur_help_idx];
-                    if (line.find(current_op_name) != std::string::npos) {
-                        help_contains_name = true;
-                    }
-                    name_section += line;
-                }
-                //if the name was found save description for later use
-                if (help_contains_name) {
-                    description = name_section.substr(name_section.find_first_of('-') + 2,
-                                                      name_section.size());
-                }
-            } else {
-
-                line = help[++operator_section];
-                //search the operator section for current operator line
-                while (line.find(current_op_name + " ") == std::string::npos && !line.empty() &&
-                       operator_section < help.size()) {
-                    line = help[++operator_section];
-                    ;
-                }
-                //if operator line found save description for later use
-                if (!line.empty() && operator_section < help.size()) {
-                    auto op_name_start = line.find_first_not_of(" \t");
-
-                    description = line.substr(
-                        line.find_first_not_of(" \t", op_name_start + current_op_name.size()),
-                        line.size());
-                }
-            }
+        else if (!current_module->help.empty()) {
             //add spaceing and saving output line to the output list
-            output_list[out_list_idx] += get_spacing_for(current_op_name) + description;
+            std::string description = get_operator_description(current_op_name, current_module->help);
+            output_list[out_list_idx] += get_spacing_for(16, current_op_name) + description;
         }
+        std::string in_out_info = "(" + std::to_string(current_module->streamInCnt) 
+                                      + "|" + std::to_string(current_module->streamOutCnt) 
+                                      + ")";
+        output_list[out_list_idx] += get_spacing_for(90, output_list[out_list_idx]) + in_out_info;
     }
     //print generated output list
     for (std::string str : output_list) {
diff --git a/src/nanoflann.hpp b/src/nanoflann.hpp
index 0d3a2d0..dc1cb2e 100644
--- a/src/nanoflann.hpp
+++ b/src/nanoflann.hpp
@@ -46,7 +46,7 @@
 #ifndef  NANOFLANN_HPP_
 #define  NANOFLANN_HPP_
 
-#define  NANOFLANN_FIRST_MATCH 1
+#define  NANOFLANN_FIRST_MATCH  1
 
 #include <vector>
 #include <cassert>
@@ -54,7 +54,7 @@
 #include <stdexcept>
 #include <cstdio>  // for fwrite()
 #define _USE_MATH_DEFINES // Required by MSVC to define M_PI,etc. in <cmath>
-#include <cmath>   // for abs()
+#include <math.h>   // for abs()
 #include <cstdlib> // for abs()
 #include <limits>
 
diff --git a/src/process.cc b/src/process.cc
index 582bd3f..dec9a51 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -1331,9 +1331,10 @@ void cdoFinish(void)
       size_t memmax = getPeakRSS();
       if (memmax)
         {
-          int muindex = 0;
-          while (memmax > 9999) { memmax /= 1024; muindex++; }
-          const char *mu[] = { "B", "KB", "MB", "GB", "TB" };
+          size_t muindex = 0;
+          const char *mu[] = { "B", "KB", "MB", "GB", "TB", "PB" };
+          const size_t nmu = sizeof(mu)/sizeof(char*);
+          while (memmax > 9999 && muindex < nmu-1) { memmax /= 1024; muindex++; }
           snprintf(memstring, sizeof(memstring), " %zu%s", memmax, mu[muindex]);
         }
 
diff --git a/src/remap_conserv.cc b/src/remap_conserv.cc
index f6822d9..5e33bbe 100644
--- a/src/remap_conserv.cc
+++ b/src/remap_conserv.cc
@@ -4,15 +4,11 @@
 #include "remap.h"
 #include "remap_store_link.h"
 
-#ifdef __cplusplus
 extern "C" {
-#endif
 #include "clipping/clipping.h"
 #include "clipping/area.h"
 #include "clipping/geometry.h"
-#ifdef __cplusplus
 }
-#endif
 
 //#define STIMER
 
diff --git a/src/remaplib.cc b/src/remaplib.cc
index 6e0d3b2..5742a17 100644
--- a/src/remaplib.cc
+++ b/src/remaplib.cc
@@ -447,13 +447,6 @@ int expand_lonlat_grid(int gridID)
   Free(xvals);
   Free(yvals);
 
-  if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL )
-    {
-      double xpole, ypole, angle;
-      gridInqParamRLL(gridID, &xpole, &ypole, &angle);
-      gridDefParamRLL(gridIDnew, xpole, ypole, angle);
-    }
-
   return gridIDnew;
 }
 
@@ -813,8 +806,7 @@ void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t
 
   if ( !src_grid->lextrapolate && gridInqSize(src_grid->gridID) > 1 &&
        map_type == MAP_TYPE_DISTWGT &&
-       ((gridInqType(gridID1) == GRID_PROJECTION && gridInqProjType(gridID1) == CDI_PROJ_RLL) ||
-	(gridInqType(gridID1) == GRID_LONLAT && src_grid->non_global)) )
+       (gridInqType(gridID1) == GRID_LONLAT && src_grid->non_global) )
     {
       src_grid->gridID = gridID1 = expand_lonlat_grid(gridID1);
       reg2d_src_gridID = gridID1;
@@ -847,6 +839,7 @@ void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t
   int sgridID = src_grid->gridID;
   if ( gridInqSize(sgridID) > 1 && 
        ((gridInqType(sgridID) == GRID_PROJECTION && gridInqProjType(sgridID) == CDI_PROJ_LCC) || 
+	(gridInqType(sgridID) == GRID_PROJECTION && gridInqProjType(sgridID) == CDI_PROJ_RLL) || 
 	(gridInqType(sgridID) == GRID_PROJECTION && gridInqProjType(sgridID) == CDI_PROJ_LAEA) || 
 	(gridInqType(sgridID) == GRID_PROJECTION && gridInqProjType(sgridID) == CDI_PROJ_SINU)) )
     {
diff --git a/test/data/tsurf_spain_dis_off_ref b/test/data/tsurf_spain_dis_off_ref
index b2f38b8..fa6c596 100644
Binary files a/test/data/tsurf_spain_dis_off_ref and b/test/data/tsurf_spain_dis_off_ref differ

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



More information about the debian-science-commits mailing list