Commit 33e0a053 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Merge declaration and definition.

parent fb724ccd
......@@ -31,59 +31,52 @@
/* Same code as Trend ! */
void *Regres(void *argument)
{
int gridsize;
int vdate = 0, vtime = 0;
int nrecs, nrecords;
int gridID, varID, levelID, recID;
int tsID;
int i, w;
int streamID1,/* streamID2, */streamID3;
int vlistID1, vlistID2, taxisID1, taxisID2;
int nrecs;
int varID, levelID;
int nmiss;
int *recVarID, *recLevelID;
int nwork = 5;
double temp1, temp2;
double missval, missval1, missval2;
field_t **work[5];
field_t field1, field2;
enum {nwork = 5};
field_t **work[nwork];
cdoInitialize(argument);
streamID1 = streamOpenRead(cdoStreamName(0));
int streamID1 = streamOpenRead(cdoStreamName(0));
vlistID1 = streamInqVlist(streamID1);
vlistID2 = vlistDuplicate(vlistID1);
int vlistID1 = streamInqVlist(streamID1);
int vlistID2 = vlistDuplicate(vlistID1);
vlistDefNtsteps(vlistID2, 1);
taxisID1 = vlistInqTaxis(vlistID1);
taxisID2 = taxisDuplicate(taxisID1);
int taxisID1 = vlistInqTaxis(vlistID1);
int taxisID2 = taxisDuplicate(taxisID1);
vlistDefTaxis(vlistID2, taxisID2);
/*
streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
streamDefVlist(streamID2, vlistID2);
*/
streamID3 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
int streamID3 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
streamDefVlist(streamID3, vlistID2);
nrecords = vlistNrecs(vlistID1);
int nrecords = vlistNrecs(vlistID1);
recVarID = (int*) Malloc(nrecords*sizeof(int));
recLevelID = (int*) Malloc(nrecords*sizeof(int));
int *recVarID = (int*) Malloc(nrecords*sizeof(int));
int *recLevelID = (int*) Malloc(nrecords*sizeof(int));
gridsize = vlistGridsizeMax(vlistID1);
int gridsize = vlistGridsizeMax(vlistID1);
field_t field1, field2;
field_init(&field1);
field_init(&field2);
field1.ptr = (double*) Malloc(gridsize*sizeof(double));
field2.ptr = (double*) Malloc(gridsize*sizeof(double));
for ( w = 0; w < nwork; w++ )
for ( int w = 0; w < nwork; w++ )
work[w] = field_calloc(vlistID1, FIELD_PTR);
tsID = 0;
int vdate = 0, vtime = 0;
int tsID = 0;
while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
{
vdate = taxisInqVdate(taxisID1);
......@@ -91,7 +84,7 @@ void *Regres(void *argument)
tsID++; /* don't move this line !!! */
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
......@@ -103,11 +96,11 @@ void *Regres(void *argument)
streamReadRecord(streamID1, field1.ptr, &nmiss);
missval = vlistInqVarMissval(vlistID1, varID);
gridID = vlistInqVarGrid(vlistID1, varID);
gridsize = gridInqSize(gridID);
double missval = vlistInqVarMissval(vlistID1, varID);
int gridID = vlistInqVarGrid(vlistID1, varID);
int gridsize = gridInqSize(gridID);
for ( i = 0; i < gridsize; i++ )
for ( int i = 0; i < gridsize; i++ )
if ( !DBL_IS_EQUAL(field1.ptr[i], missval) )
{
work[0][varID][levelID].ptr[i] += tsID;
......@@ -125,19 +118,19 @@ void *Regres(void *argument)
/* streamDefTimestep(streamID2, 0); */
streamDefTimestep(streamID3, 0);
for ( recID = 0; recID < nrecords; recID++ )
for ( int recID = 0; recID < nrecords; recID++ )
{
varID = recVarID[recID];
levelID = recLevelID[recID];
missval = vlistInqVarMissval(vlistID1, varID);
gridID = vlistInqVarGrid(vlistID1, varID);
gridsize = gridInqSize(gridID);
double missval = vlistInqVarMissval(vlistID1, varID);
int gridID = vlistInqVarGrid(vlistID1, varID);
int gridsize = gridInqSize(gridID);
missval1 = missval;
missval2 = missval;
double missval1 = missval;
double missval2 = missval;
for ( i = 0; i < gridsize; i++ )
for ( int i = 0; i < gridsize; i++ )
{
temp1 = SUBMN(work[2][varID][levelID].ptr[i],
DIVMN( MULMN(work[0][varID][levelID].ptr[i], work[3][varID][levelID].ptr[i]), work[4][varID][levelID].ptr[i]));
......@@ -158,7 +151,7 @@ void *Regres(void *argument)
streamWriteRecord(streamID2, field1.ptr, nmiss);
*/
nmiss = 0;
for ( i = 0; i < gridsize; i++ )
for ( int i = 0; i < gridsize; i++ )
if ( DBL_IS_EQUAL(field2.ptr[i], missval) ) nmiss++;
streamDefRecord(streamID3, varID, levelID);
......@@ -166,7 +159,7 @@ void *Regres(void *argument)
}
for ( w = 0; w < nwork; w++ ) field_free(work[w], vlistID1);
for ( int w = 0; w < nwork; w++ ) field_free(work[w], vlistID1);
if ( field1.ptr ) Free(field1.ptr);
if ( field2.ptr ) Free(field2.ptr);
......
......@@ -220,27 +220,24 @@ double *vlist_hybrid_vct(int vlistID, int *rzaxisIDh, int *rnvct, int *rnhlevf)
void *Remapeta(void *argument)
{
int nfis2gp = 0;
int recID, nrecs;
int i, offset, iv;
int nrecs;
int i, iv;
int varID, levelID;
int nvars3D = 0;
int zaxisID;
int nlevel;
int sgeopotID = -1, tempID = -1, sqID = -1, psID = -1, lnpsID = -1, presID = -1;
int code;
int sgeopotID = -1, tempID = -1, sqID = -1, psID = -1, lnpsID = -1;
char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
double *single2;
double *fis1 = NULL, *ps1 = NULL, *t1 = NULL, *q1 = NULL;
double *fis2 = NULL, *ps2 = NULL, *t2 = NULL, *q2 = NULL;
double *fis2 = NULL;
double *t1 = NULL, *q1 = NULL;
double *t2 = NULL, *q2 = NULL;
double *tscor = NULL, *pscor = NULL, *secor = NULL;
int nmiss, nmissout = 0;
int ltq = FALSE;
int lfis2 = FALSE;
bool ltq = false;
bool lfis2 = false;
int varids[MAX_VARS3D];
int *imiss = NULL;
int timer_hetaeta = 0;
long nctop = 0;
double *array = NULL;
double *deltap1 = NULL, *deltap2 = NULL;
double *half_press1 = NULL, *half_press2 = NULL;
double *sum1 = NULL, *sum2 = NULL;
......@@ -248,7 +245,6 @@ void *Remapeta(void *argument)
double minval, maxval;
double missval = 0;
double cconst = 1.E-6;
const char *fname;
double cptop = 0; /* min. pressure level for cond. */
if ( cdoTimer ) timer_hetaeta = timer_new("Remapeta_hetaeta");
......@@ -290,13 +286,11 @@ void *Remapeta(void *argument)
if ( operatorArgc() == 2 )
{
int streamID;
lfis2 = true;
lfis2 = TRUE;
fname = operatorArgv()[1];
const char *fname = operatorArgv()[1];
argument_t *fileargument = file_argument_new(fname);
streamID = streamOpenRead(fileargument);
int streamID = streamOpenRead(fileargument);
file_argument_free(fileargument);
int vlistID1 = streamInqVlist(streamID);
......@@ -394,11 +388,11 @@ void *Remapeta(void *argument)
for ( varID = 0; varID < nvars; varID++ )
{
gridID = vlistInqVarGrid(vlistID1, varID);
zaxisID = vlistInqVarZaxis(vlistID1, varID);
nlevel = zaxisInqSize(zaxisID);
int gridID = vlistInqVarGrid(vlistID1, varID);
int zaxisID = vlistInqVarZaxis(vlistID1, varID);
int nlevel = zaxisInqSize(zaxisID);
code = vlistInqVarCode(vlistID1, varID);
int code = vlistInqVarCode(vlistID1, varID);
/* code = -1; */
if ( code <= 0 || code == 255 )
{
......@@ -457,7 +451,7 @@ void *Remapeta(void *argument)
if ( tempID != -1 && sqID != -1 )
{
ltq = TRUE;
ltq = true;
}
else
{
......@@ -465,14 +459,14 @@ void *Remapeta(void *argument)
if ( sqID != -1 ) cdoAbort("Humidity without temperature unsupported!");
}
/*
if ( ltq == FALSE )
if ( ltq == false )
{
cdoWarning("Temperature and Humidity not found!");
}
*/
if ( operatorID == REMAPETA ) {}
if ( operatorID == REMAPETAS || operatorID == REMAPETAZ)
if ( operatorID == REMAPETAS || operatorID == REMAPETAZ )
{
sum1 = (double*) Malloc(gridsize*sizeof(double));
sum2 = (double*) Malloc(gridsize*sizeof(double));
......@@ -486,15 +480,15 @@ void *Remapeta(void *argument)
half_press2 = (double*) Malloc(gridsize*(nhlevf2+1)*sizeof(double));
}
array = (double*) Malloc(gridsize*sizeof(double));
double *array = (double*) Malloc(gridsize*sizeof(double));
fis1 = (double*) Malloc(gridsize*sizeof(double));
ps1 = (double*) Malloc(gridsize*sizeof(double));
double *fis1 = (double*) Malloc(gridsize*sizeof(double));
double *ps1 = (double*) Malloc(gridsize*sizeof(double));
if ( lfis2 == FALSE ) fis2 = (double*) Malloc(gridsize*sizeof(double));
if ( lfis2 == TRUE && gridsize != nfis2gp ) cdoAbort("Orographies have different grid size!");
if ( lfis2 == false ) fis2 = (double*) Malloc(gridsize*sizeof(double));
if ( lfis2 == true && gridsize != nfis2gp ) cdoAbort("Orographies have different grid size!");
ps2 = (double*) Malloc(gridsize*sizeof(double));
double *ps2 = (double*) Malloc(gridsize*sizeof(double));
if ( ltq )
{
......@@ -529,7 +523,7 @@ void *Remapeta(void *argument)
memset(fis1, 0, gridsize*sizeof(double));
}
presID = lnpsID;
int presID = lnpsID;
if ( zaxisIDh != -1 && lnpsID == -1 )
{
if ( psID == -1 )
......@@ -546,21 +540,20 @@ void *Remapeta(void *argument)
cdoPrint("using %s", var_stdname(surface_air_pressure));
}
if ( cdoVerbose ) cdoPrint("nvars3D = %d ltq = %d", nvars3D, ltq);
if ( cdoVerbose ) cdoPrint("nvars3D = %d ltq = %d", nvars3D, (int)ltq);
int tsID = 0;
while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
{
taxisCopyTimestep(taxisID2, taxisID1);
streamDefTimestep(streamID2, tsID);
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
zaxisID = vlistInqVarZaxis(vlistID1, varID);
nlevel = zaxisInqSize(zaxisID);
offset = gridsize*levelID;
int zaxisID = vlistInqVarZaxis(vlistID1, varID);
int nlevel = zaxisInqSize(zaxisID);
int offset = gridsize*levelID;
streamReadRecord(streamID1, array, &nmiss);
if ( zaxisIDh != -1 )
......@@ -614,16 +607,16 @@ void *Remapeta(void *argument)
cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval);
}
if ( lfis2 == FALSE )
for ( i = 0; i < gridsize; i++ ) fis2[i] = fis1[i];
if ( lfis2 == false )
for ( int i = 0; i < gridsize; i++ ) fis2[i] = fis1[i];
if ( ltq )
{
varID = tempID;
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
for ( levelID = 0; levelID < nlevel; levelID++ )
{
offset = gridsize*levelID;
int offset = gridsize*levelID;
single2 = t1 + offset;
minmaxval(gridsize, single2, imiss, &minval, &maxval);
......@@ -636,7 +629,7 @@ void *Remapeta(void *argument)
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
for ( levelID = 0; levelID < nlevel; levelID++ )
{
offset = gridsize*levelID;
int offset = gridsize*levelID;
single2 = q1 + offset;
corr_hum(gridsize, single2, MIN_Q);
......@@ -690,10 +683,10 @@ void *Remapeta(void *argument)
if ( ltq )
{
varID = tempID;
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
for ( levelID = 0; levelID < nlevel; levelID++ )
{
offset = gridsize*levelID;
int offset = gridsize*levelID;
single2 = t2 + offset;
minmaxval(gridsize, single2, imiss, &minval, &maxval);
......@@ -710,7 +703,7 @@ void *Remapeta(void *argument)
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
for ( levelID = 0; levelID < nlevel; levelID++ )
{
offset = gridsize*levelID;
int offset = gridsize*levelID;
single2 = q2 + offset;
corr_hum(gridsize, single2, MIN_Q);
......@@ -733,7 +726,7 @@ void *Remapeta(void *argument)
{
varID = varids[iv];
nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
if ( operatorID == REMAPETAS )
{
......@@ -765,7 +758,7 @@ void *Remapeta(void *argument)
for ( levelID = 0; levelID < nlevel; levelID++ )
{
offset = gridsize*levelID;
int offset = gridsize*levelID;
single2 = vars2[iv] + offset;
if ( operatorID == REMAPETAS || operatorID == REMAPETAZ )
......
......@@ -33,15 +33,12 @@ void *Replace(void *argument)
{
int varID, varID1, varID2;
int nrecs = 0;
int recID, levelID, levelID2;
int levelID, levelID2;
int nrecs2;
int nchvars = 0;
int idx;
int nlevel1, nlevel2;
char varname1[CDI_MAX_NAME], varname2[CDI_MAX_NAME];
int nmiss;
int gridsize;
int offset;
int varlist1[MAX_VARS], varlist2[MAX_VARS];
int **varlevel = NULL;
int **varnmiss2 = NULL;
......@@ -77,13 +74,11 @@ void *Replace(void *argument)
if ( varID1 < nvars1 )
{
int gridsize1, gridsize2, nlevel1, nlevel2;
int gridsize1 = gridInqSize(vlistInqVarGrid(vlistID1, varID1));
int nlevel1 = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
gridsize1 = gridInqSize(vlistInqVarGrid(vlistID1, varID1));
nlevel1 = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
gridsize2 = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
nlevel2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
int gridsize2 = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
int nlevel2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
if ( gridsize1 != gridsize2 )
cdoAbort("Variables have different gridsize!");
......@@ -113,9 +108,9 @@ void *Replace(void *argument)
{
varID1 = varlist1[idx];
varID2 = varlist2[idx];
nlevel1 = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
nlevel2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
int nlevel1 = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
int nlevel2 = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
int gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
vardata2[idx] = (double*) Malloc(nlevel2*gridsize*sizeof(double));
varnmiss2[idx] = (int*) Malloc(nlevel2*sizeof(int));
varlevel[idx] = (int*) Malloc(nlevel1*sizeof(int));
......@@ -159,7 +154,7 @@ void *Replace(void *argument)
vlistDefTaxis(vlistID3, taxisID3);
streamDefVlist(streamID3, vlistID3);
gridsize = vlistGridsizeMax(vlistID1);
int gridsize = vlistGridsizeMax(vlistID1);
double *array = (double*) Malloc(gridsize*sizeof(double));
int nts2 = vlistNtsteps(vlistID2);
......@@ -175,15 +170,15 @@ void *Replace(void *argument)
if ( nrecs2 == 0 )
cdoAbort("Input streams have different number of timesteps!");
for ( recID = 0; recID < nrecs2; recID++ )
for ( int recID = 0; recID < nrecs2; recID++ )
{
streamInqRecord(streamID2, &varID, &levelID);
for ( idx = 0; idx < nchvars; idx++ )
if ( varlist2[idx] == varID )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
offset = gridsize*levelID;
int gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
int offset = gridsize*levelID;
parray = vardata2[idx]+offset;
streamReadRecord(streamID2, parray, &nmiss);
varnmiss2[idx][levelID] = nmiss;
......@@ -194,7 +189,7 @@ void *Replace(void *argument)
streamDefTimestep(streamID3, tsID);
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
......@@ -206,8 +201,8 @@ void *Replace(void *argument)
levelID2 = varlevel[idx][levelID];
if ( levelID2 != -1 )
{
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
offset = gridsize*levelID2;
int gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
int offset = gridsize*levelID2;
parray = vardata2[idx]+offset;
nmiss = varnmiss2[idx][levelID2];
break;
......
......@@ -31,19 +31,9 @@
void *Runpctl(void *argument)
{
int timestat_date = TIMESTAT_MEAN;
int gridsize;
int varID;
int recID;
int nrecs;
int levelID;
int tsID;
int otsID;
int i, j, inp, its;
int nmiss;
int nlevels;
double missval, val;
double *array;
field_t ***vars1 = NULL;
cdoInitialize(argument);
......@@ -78,22 +68,21 @@ void *Runpctl(void *argument)
dtlist_set_stat(dtlist, timestat_date);
dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
vars1 = (field_t ***) Malloc((ndates+1)*sizeof(field_t **));
array = (double*) Malloc(ndates*sizeof(double));
field_t ***vars1 = (field_t ***) Malloc((ndates+1)*sizeof(field_t **));
double *array = (double*) Malloc(ndates*sizeof(double));
for ( its = 0; its < ndates; its++ )
{
vars1[its] = field_malloc(vlistID1, FIELD_PTR);
}
for ( int its = 0; its < ndates; its++ )
vars1[its] = field_malloc(vlistID1, FIELD_PTR);
int tsID;
for ( tsID = 0; tsID < ndates; tsID++ )
{
nrecs = streamInqTimestep(streamID1, tsID);
int nrecs = streamInqTimestep(streamID1, tsID);
if ( nrecs == 0 ) cdoAbort("File has less than %d timesteps!", ndates);
dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
......@@ -108,27 +97,27 @@ void *Runpctl(void *argument)
}
}
otsID = 0;
int otsID = 0;
while ( TRUE )
{
for ( varID = 0; varID < nvars; varID++ )
{
if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
missval = vlistInqVarMissval(vlistID1, varID);
nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
int gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
double missval = vlistInqVarMissval(vlistID1, varID);
int nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
for ( levelID = 0; levelID < nlevels; levelID++ )
{
nmiss = 0;
for ( i = 0; i < gridsize; i++ )
for ( int i = 0; i < gridsize; i++ )
{
for ( inp = 0, j = 0; inp < ndates; inp++ )
int j = 0;
for ( int inp = 0, j = 0; inp < ndates; inp++ )
{
val = vars1[inp][varID][levelID].ptr[i];
if ( !DBL_IS_EQUAL(val, missval) )
array[j++] = val;
double val = vars1[inp][varID][levelID].ptr[i];
if ( !DBL_IS_EQUAL(val, missval) ) array[j++] = val;
}
if ( j > 0 )
......@@ -148,7 +137,7 @@ void *Runpctl(void *argument)
dtlist_stat_taxisDefTimestep(dtlist, taxisID2, ndates);
streamDefTimestep(streamID2, otsID);
for ( recID = 0; recID < nrecords; recID++ )
for ( int recID = 0; recID < nrecords; recID++ )
{
varID = recVarID[recID];
levelID = recLevelID[recID];
......@@ -164,17 +153,14 @@ void *Runpctl(void *argument)
dtlist_shift(dtlist);
vars1[ndates] = vars1[0];
for ( inp = 0; inp < ndates; inp++ )
{
vars1[inp] = vars1[inp+1];
}
for ( int inp = 0; inp < ndates; inp++ ) vars1[inp] = vars1[inp+1];
nrecs = streamInqTimestep(streamID1, tsID);
int nrecs = streamInqTimestep(streamID1, tsID);
if ( nrecs == 0 ) break;
dtlist_taxisInqTimestep(dtlist, taxisID1, ndates-1);
for ( recID = 0; recID < nrecs; recID++ )
for ( int recID = 0; recID < nrecs; recID++ )
{
streamInqRecord(streamID1, &varID, &levelID);
......@@ -185,10 +171,8 @@ void *Runpctl(void *argument)
tsID++;
}
for ( its = 0; its < ndates; its++ )
{
field_free(vars1[its], vlistID1);
}
for ( int its = 0; its < ndates; its++ )
field_free(vars1[its], vlistID1);
Free(vars1);
Free(array);
......
......@@ -38,20 +38,10 @@
void *Runstat(void *argument)
{
int timestat_date = TIMESTAT_MEAN;
int gridsize;
int i;
int varID;
int recID;
int nrecs;
int levelID;
int tsID;
int otsID;
int its;
int nmiss;
int nlevel;
int runstat_nomiss = 0;
double missval;
field_t ***vars1 = NULL, ***vars2 = NULL, ***samp1 = NULL;
cdoInitialize(argument);
......@@ -107,13 +97,14 @@ void *Runstat(void *argument)
dtlist_set_stat(dtlist, timestat_date);
dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
vars1 = (field_t ***) Malloc((ndates+1)*sizeof(field_t **));