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