#include "config.h"
#include <stdlib.h>
#include <assert.h>
#include "libgfortran.h"
extern void count_4_l4 (gfc_array_i4 *, gfc_array_l4 *, index_type *);
export_proto(count_4_l4);
void
count_4_l4 (gfc_array_i4 *retarray, gfc_array_l4 *array, index_type *pdim)
{
index_type count[GFC_MAX_DIMENSIONS];
index_type extent[GFC_MAX_DIMENSIONS];
index_type sstride[GFC_MAX_DIMENSIONS];
index_type dstride[GFC_MAX_DIMENSIONS];
GFC_LOGICAL_4 *base;
GFC_INTEGER_4 *dest;
index_type rank;
index_type n;
index_type len;
index_type delta;
index_type dim;
dim = (*pdim) - 1;
rank = GFC_DESCRIPTOR_RANK (array) - 1;
if (array->dim[0].stride == 0)
array->dim[0].stride = 1;
len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
delta = array->dim[dim].stride;
for (n = 0; n < dim; n++)
{
sstride[n] = array->dim[n].stride;
extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
}
for (n = dim; n < rank; n++)
{
sstride[n] = array->dim[n + 1].stride;
extent[n] =
array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
}
if (retarray->data == NULL)
{
for (n = 0; n < rank; n++)
{
retarray->dim[n].lbound = 0;
retarray->dim[n].ubound = extent[n]-1;
if (n == 0)
retarray->dim[n].stride = 1;
else
retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1];
}
retarray->data
= internal_malloc_size (sizeof (GFC_INTEGER_4)
* retarray->dim[rank-1].stride
* extent[rank-1]);
retarray->base = 0;
retarray->dtype = (array->dtype & ~GFC_DTYPE_RANK_MASK) | rank;
}
else
{
if (retarray->dim[0].stride == 0)
retarray->dim[0].stride = 1;
if (rank != GFC_DESCRIPTOR_RANK (retarray))
runtime_error ("rank of return array incorrect");
}
for (n = 0; n < rank; n++)
{
count[n] = 0;
dstride[n] = retarray->dim[n].stride;
if (extent[n] <= 0)
len = 0;
}
base = array->data;
dest = retarray->data;
while (base)
{
GFC_LOGICAL_4 *src;
GFC_INTEGER_4 result;
src = base;
{
result = 0;
if (len <= 0)
*dest = 0;
else
{
for (n = 0; n < len; n++, src += delta)
{
if (*src)
result++;
}
*dest = result;
}
}
count[0]++;
base += sstride[0];
dest += dstride[0];
n = 0;
while (count[n] == extent[n])
{
count[n] = 0;
base -= sstride[n] * extent[n];
dest -= dstride[n] * extent[n];
n++;
if (n == rank)
{
base = NULL;
break;
}
else
{
count[n]++;
base += sstride[n];
dest += dstride[n];
}
}
}
}