File fix_Ydrunstat_crash.patch of Package cdo

diff --git a/src/Ydrunstat.cc b/src/Ydrunstat.cc
index 8d5144a..4ab8927 100644
--- a/src/Ydrunstat.cc
+++ b/src/Ydrunstat.cc
@@ -41,46 +41,34 @@
 
 #define NDAY 373
 
-struct YDAY_STATS
+class YDAY_STATS
 {
+public:
   int64_t vdate[NDAY];
   int vtime[NDAY];
   FieldVector2D vars1[NDAY];
   FieldVector2D vars2[NDAY];
   int nsets[NDAY];
   int vlist;
-};
-
-static YDAY_STATS *
-ydstatCreate(int vlistID)
-{
-  YDAY_STATS *stats = (YDAY_STATS *) Malloc(sizeof(YDAY_STATS));
-
-  for (int dayoy = 0; dayoy < NDAY; dayoy++)
-    {
-      stats->vdate[dayoy] = 0;
-      stats->vtime[dayoy] = 0;
-      stats->nsets[dayoy] = 0;
-    }
-
-  stats->vlist = vlistID;
-
-  return stats;
-}
 
-static void
-ydstatDestroy(YDAY_STATS *stats)
-{
-  if (stats != nullptr) Free(stats);
-}
+  YDAY_STATS(int vlistID) : vlist(vlistID)
+  {
+    for (int dayoy = 0; dayoy < NDAY; dayoy++)
+      {
+        vdate[dayoy] = 0;
+        vtime[dayoy] = 0;
+        nsets[dayoy] = 0;
+      }
+  }
+};
 
 static void
-ydstatUpdate(YDAY_STATS *stats, int64_t vdate, int vtime, const FieldVector2D &vars1, const FieldVector2D &vars2, int nsets,
+ydstatUpdate(YDAY_STATS &stats, int64_t vdate, int vtime, const FieldVector2D &vars1, const FieldVector2D &vars2, int nsets,
              int operfunc)
 {
   bool lvarstd = vars2.size();
 
-  int nvars = vlistNvars(stats->vlist);
+  auto nvars = vlistNvars(stats.vlist);
 
   int year, month, day;
   cdiDecodeDate(vdate, &year, &month, &day);
@@ -88,61 +76,61 @@ ydstatUpdate(YDAY_STATS *stats, int64_t vdate, int vtime, const FieldVector2D &v
   const int dayoy = (month >= 1 && month <= 12) ? (month - 1) * 31 + day : 0;
   if (dayoy < 0 || dayoy >= NDAY) cdoAbort("day %d out of range!", dayoy);
 
-  stats->vdate[dayoy] = vdate;
-  stats->vtime[dayoy] = vtime;
+  stats.vdate[dayoy] = vdate;
+  stats.vtime[dayoy] = vtime;
 
-  if (!stats->vars1[dayoy].size())
+  if (!stats.vars1[dayoy].size())
     {
-      fieldsFromVlist(stats->vlist, stats->vars1[dayoy], FIELD_VEC);
-      if (lvarstd) fieldsFromVlist(stats->vlist, stats->vars2[dayoy], FIELD_VEC);
+      fieldsFromVlist(stats.vlist, stats.vars1[dayoy], FIELD_VEC);
+      if (lvarstd) fieldsFromVlist(stats.vlist, stats.vars2[dayoy], FIELD_VEC);
     }
 
   for (int varID = 0; varID < nvars; varID++)
     {
-      if (vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT) continue;
+      if (vlistInqVarTimetype(stats.vlist, varID) == TIME_CONSTANT) continue;
 
-      const int nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
+      const auto nlevels = zaxisInqSize(vlistInqVarZaxis(stats.vlist, varID));
       for (int levelID = 0; levelID < nlevels; levelID++)
         {
-          if (stats->nsets[dayoy] == 0)
+          if (stats.nsets[dayoy] == 0)
             {
-              stats->vars1[dayoy][varID][levelID].vec = vars1[varID][levelID].vec;
-              stats->vars1[dayoy][varID][levelID].nmiss = vars1[varID][levelID].nmiss;
+              stats.vars1[dayoy][varID][levelID].vec = vars1[varID][levelID].vec;
+              stats.vars1[dayoy][varID][levelID].nmiss = vars1[varID][levelID].nmiss;
 
               if (lvarstd)
                 {
-                  stats->vars2[dayoy][varID][levelID].vec = vars2[varID][levelID].vec;
-                  stats->vars2[dayoy][varID][levelID].nmiss = vars2[varID][levelID].nmiss;
+                  stats.vars2[dayoy][varID][levelID].vec = vars2[varID][levelID].vec;
+                  stats.vars2[dayoy][varID][levelID].nmiss = vars2[varID][levelID].nmiss;
                 }
             }
           else
             {
               if (lvarstd)
                 {
-                  vfarsum(stats->vars1[dayoy][varID][levelID], vars1[varID][levelID]);
-                  vfarsum(stats->vars2[dayoy][varID][levelID], vars2[varID][levelID]);
+                  vfarsum(stats.vars1[dayoy][varID][levelID], vars1[varID][levelID]);
+                  vfarsum(stats.vars2[dayoy][varID][levelID], vars2[varID][levelID]);
                 }
               else
                 {
-                  vfarfun(stats->vars1[dayoy][varID][levelID], vars1[varID][levelID], operfunc);
+                  vfarfun(stats.vars1[dayoy][varID][levelID], vars1[varID][levelID], operfunc);
                 }
             }
         }
     }
 
-  stats->nsets[dayoy] += nsets;
+  stats.nsets[dayoy] += nsets;
 }
 
 static void
-ydstatFinalize(YDAY_STATS *stats, int operfunc)
+ydstatFinalize(YDAY_STATS &stats, int operfunc)
 {
   int varID, levelID, nlevels;
   const int divisor = operfunc == func_std1 || operfunc == func_var1;
 
-  const int nvars = vlistNvars(stats->vlist);
+  const auto nvars = vlistNvars(stats.vlist);
 
   for (int dayoy = 0; dayoy < NDAY; dayoy++)
-    if (stats->nsets[dayoy])
+    if (stats.nsets[dayoy])
       {
         switch (operfunc)
           {
@@ -150,10 +138,10 @@ ydstatFinalize(YDAY_STATS *stats, int operfunc)
           case func_mean:
             for (varID = 0; varID < nvars; varID++)
               {
-                if (vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT) continue;
-                nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
+                if (vlistInqVarTimetype(stats.vlist, varID) == TIME_CONSTANT) continue;
+                nlevels = zaxisInqSize(vlistInqVarZaxis(stats.vlist, varID));
                 for (levelID = 0; levelID < nlevels; levelID++)
-                  vfarcdiv(stats->vars1[dayoy][varID][levelID], (double) stats->nsets[dayoy]);
+                  vfarcdiv(stats.vars1[dayoy][varID][levelID], (double) stats.nsets[dayoy]);
               }
             break;
 
@@ -161,10 +149,10 @@ ydstatFinalize(YDAY_STATS *stats, int operfunc)
           case func_std1:
             for (varID = 0; varID < nvars; varID++)
               {
-                if (vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT) continue;
-                nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
+                if (vlistInqVarTimetype(stats.vlist, varID) == TIME_CONSTANT) continue;
+                nlevels = zaxisInqSize(vlistInqVarZaxis(stats.vlist, varID));
                 for (levelID = 0; levelID < nlevels; levelID++)
-                  vfarcstd(stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID], stats->nsets[dayoy], divisor);
+                  vfarcstd(stats.vars1[dayoy][varID][levelID], stats.vars2[dayoy][varID][levelID], stats.nsets[dayoy], divisor);
               }
             break;
 
@@ -172,10 +160,10 @@ ydstatFinalize(YDAY_STATS *stats, int operfunc)
           case func_var1:
             for (varID = 0; varID < nvars; varID++)
               {
-                if (vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT) continue;
-                nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
+                if (vlistInqVarTimetype(stats.vlist, varID) == TIME_CONSTANT) continue;
+                nlevels = zaxisInqSize(vlistInqVarZaxis(stats.vlist, varID));
                 for (levelID = 0; levelID < nlevels; levelID++)
-                  vfarcvar(stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID], stats->nsets[dayoy], divisor);
+                  vfarcvar(stats.vars1[dayoy][varID][levelID], stats.vars2[dayoy][varID][levelID], stats.nsets[dayoy], divisor);
               }
             break;
           }
@@ -205,36 +193,36 @@ Ydrunstat(void *process)
   cdoOperatorAdd("ydrunstd1",  func_std1,  0, nullptr);
   // clang-format on
 
-  const int operatorID = cdoOperatorID();
-  const int operfunc = cdoOperatorF1(operatorID);
+  const auto operatorID = cdoOperatorID();
+  const auto operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg("number of timesteps");
-  const int ndates = parameter2int(operatorArgv()[0]);
+  const auto ndates = parameter2int(operatorArgv()[0]);
 
   const bool lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
 
   CdoStreamID streamID1 = cdoOpenRead(0);
 
-  const int vlistID1 = cdoStreamInqVlist(streamID1);
-  const int vlistID2 = vlistDuplicate(vlistID1);
+  const auto vlistID1 = cdoStreamInqVlist(streamID1);
+  const auto vlistID2 = vlistDuplicate(vlistID1);
 
-  const int taxisID1 = vlistInqTaxis(vlistID1);
-  const int taxisID2 = taxisDuplicate(taxisID1);
+  const auto taxisID1 = vlistInqTaxis(vlistID1);
+  const auto taxisID2 = taxisDuplicate(taxisID1);
   if (taxisHasBounds(taxisID2)) taxisDeleteBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  const int calendar = taxisInqCalendar(taxisID1);
-  const int dpy = calendar_dpy(calendar);
+  const auto calendar = taxisInqCalendar(taxisID1);
+  const auto dpy = calendar_dpy(calendar);
 
   CdoStreamID streamID2 = cdoOpenWrite(1);
   cdoDefVlist(streamID2, vlistID2);
 
-  const int maxrecs = vlistNrecs(vlistID1);
+  const auto maxrecs = vlistNrecs(vlistID1);
   std::vector<RecordInfo> recList(maxrecs);
 
   std::vector<CdoDateTime> datetime(ndates + 1);
 
-  YDAY_STATS *stats = ydstatCreate(vlistID1);
+  YDAY_STATS stats(vlistID1);
   FieldVector3D vars1(ndates + 1), vars2(ndates + 1);
 
   for (its = 0; its < ndates; its++)
@@ -345,38 +333,39 @@ Ydrunstat(void *process)
   int outyear = 1e9;
   int year, month, day;
   for ( int dayoy = 0; dayoy < NDAY; dayoy++ )
-    if ( stats->nsets[dayoy] )
+    if ( stats.nsets[dayoy] )
       {
-        cdiDecodeDate(stats->vdate[dayoy], &year, &month, &day);
+        cdiDecodeDate(stats.vdate[dayoy], &year, &month, &day);
         if ( year < outyear ) outyear = year;
       }
   for ( int dayoy = 0; dayoy < NDAY; dayoy++ )
-    if ( stats->nsets[dayoy] )
+    if ( stats.nsets[dayoy] )
       {
-        cdiDecodeDate(stats->vdate[dayoy], &year, &month, &day);
-        // printf("vdates[%d] = %d  nsets = %d\n", dayoy, stats->vdate[dayoy],
-  stats->nsets[dayoy]); if ( year > outyear ) stats->vdate[dayoy] =
+        cdiDecodeDate(stats.vdate[dayoy], &year, &month, &day);
+        // printf("vdates[%d] = %d  nsets = %d\n", dayoy, stats.vdate[dayoy],
+  stats.nsets[dayoy]); if ( year > outyear ) stats.vdate[dayoy] =
   cdiEncodeDate(outyear, month, day);
       }
   */
+
   ydstatFinalize(stats, operfunc);
 
   int otsID = 0;
 
   for (int dayoy = 0; dayoy < NDAY; dayoy++)
-    if (stats->nsets[dayoy])
+    if (stats.nsets[dayoy])
       {
-        taxisDefVdate(taxisID2, stats->vdate[dayoy]);
-        taxisDefVtime(taxisID2, stats->vtime[dayoy]);
+        taxisDefVdate(taxisID2, stats.vdate[dayoy]);
+        taxisDefVtime(taxisID2, stats.vtime[dayoy]);
         cdoDefTimestep(streamID2, otsID);
 
         for (int recID = 0; recID < maxrecs; recID++)
           {
             if (otsID && recList[recID].lconst) continue;
 
-            int varID = recList[recID].varID;
-            int levelID = recList[recID].levelID;
-            Field &rvars1 = stats->vars1[dayoy][varID][levelID];
+            auto varID = recList[recID].varID;
+            auto levelID = recList[recID].levelID;
+            Field &rvars1 = stats.vars1[dayoy][varID][levelID];
 
             cdoDefRecord(streamID2, varID, levelID);
             cdoWriteRecord(streamID2, rvars1.vec.data(), rvars1.nmiss);
@@ -385,8 +374,6 @@ Ydrunstat(void *process)
         otsID++;
       }
 
-  ydstatDestroy(stats);
-
   cdoStreamClose(streamID2);
   cdoStreamClose(streamID1);
 
--- a/ChangeLog.orig	2019-12-03 17:24:15.006529669 +0100
+++ b/ChangeLog	2019-12-03 17:25:06.202160761 +0100
@@ -1,3 +1,7 @@
+2019-09-13  Uwe Schulzweida
+
+	* Ydrunstat: fix seg. fault
+
 2019-06-13  Uwe Schulzweida
 
 	* Using CDI library version 1.9.7.1
openSUSE Build Service is sponsored by