Skip to content

Commit

Permalink
A bit of refactoring in xstruct, add xReduceField()
Browse files Browse the repository at this point in the history
  • Loading branch information
attipaci committed Dec 18, 2024
1 parent 24f48c0 commit 45c14d3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 35 deletions.
3 changes: 2 additions & 1 deletion include/xchange.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ long xDeepCountFields(const XStructure *s);
XStructure *xGetSubstruct(const XStructure *s, const char *id);
XField *xSetSubstruct(XStructure *s, const char *name, XStructure *substruct);
int xReduceDims(int *ndim, int *sizes);
int xReduceAllDims(XStructure *s);
int xReduceStruct(XStructure *s);
int xReduceField(XField *f);

// Sorting, ordering
int xSortFields(XStructure *s, int (*cmp)(const XField **f1, const XField **f2), boolean recursive);
Expand Down
86 changes: 52 additions & 34 deletions src/xstruct.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ XField *xCreateLongField(const char *name, long long value) {
XField *xCreateBooleanField(const char *name, boolean value) {
XField *f = xCreateScalarField(name, X_BOOLEAN, &value);
if(!f) return x_trace_null("xCreateBooleanField", NULL);
return f;
return f;
}


Expand Down Expand Up @@ -970,7 +970,7 @@ static int xUnwrapField(XField *f) {
if(nested->type == X_STRUCT) {
XStructure *s = (XStructure *) nested->value;
int i = xGetFieldCount(nested);
while(--i >= 0) xReduceAllDims(&s[i]);
while(--i >= 0) xReduceStruct(&s[i]);
}
else if(nested->type == X_FIELD) return xUnwrapField(nested);

Expand All @@ -982,6 +982,47 @@ static int xUnwrapField(XField *f) {
return X_SUCCESS;
}

/**
* Reduces a field by eliminating extraneous dimensions, and/or wrapping recursively.
*
* @param f Pointer to a field
* @return X_SUCCESS (0) if successful, or else an xchange.h error code <0.
*/
int xReduceField(XField *f) {
static const char *fn = "xReduceField";

if(!f) return x_error(X_NULL, EINVAL, fn, "input field is NULL");

xReduceDims(&f->ndim, f->sizes);

if(f->type == X_STRUCT) {
XStructure *sub = (XStructure *) f->value;
int i = xGetFieldCount(f);

while(--i >= 0) {
int status = xReduceStruct(&sub[i]);
if(status < 0) {
char *id = (char *) malloc(strlen(f->name) + 20);

if(!id) {
status = x_error(X_FAILURE, errno, fn, "alloc error (%ld bytes)", (long) (strlen(f->name) + 20));

xDestroyField(f);
return status;
}

sprintf(id, "%s[%d]", f->name, i);
x_trace(fn, id, status);
free(id);
}
}
}

else if(f->type == X_FIELD) xUnwrapField(f);

return X_SUCCESS;
}

/**
* Recursively eliminates unneccessary embedding of singular structures inside a structure as well as reduces the
* dimension of all array fields with xReduceDims(). It will also eliminate the unnecessary wrapping of a singular
Expand All @@ -993,10 +1034,11 @@ static int xUnwrapField(XField *f) {
*
* @see xReduceDims()
*/
int xReduceAllDims(XStructure *s) {
static const char *fn;
int xReduceStruct(XStructure *s) {
static const char *fn = "xReduceStruct";

XField *f;
int status = X_SUCCESS;

if(!s) return x_error(X_STRUCT_INVALID, EINVAL, fn, "input structure is NULL");

Expand All @@ -1008,7 +1050,6 @@ int xReduceAllDims(XStructure *s) {
// We can eliminate the unnecessary nesting.

XStructure *sub = (XStructure *) f->value;
int status;
XField *sf;

s->firstField = sub->firstField;
Expand All @@ -1019,42 +1060,19 @@ int xReduceAllDims(XStructure *s) {
while(--i >= 0) ss[i].parent = s;
}

status = xReduceAllDims(s);
status = xReduceStruct(s);
if(status < 0) x_trace(fn, f->name, status);

free(f);
return status;
}

for(; f != NULL; f = f->next) {
xReduceDims(&f->ndim, f->sizes);

if(f->type == X_STRUCT) {
XStructure *sub = (XStructure *) f->value;
int i = xGetFieldCount(f);

while(--i >= 0) {
int status = xReduceAllDims(&sub[i]);
if(status < 0) {
char *id = (char *) malloc(strlen(f->name) + 20);

if(!id) {
status = x_error(X_FAILURE, errno, "xReduceAllDims", "alloc error (%ld bytes)", (long) (strlen(f->name) + 20));
xDestroyField(f);
return status;
}

sprintf(id, "%s[%d]", f->name, i);
x_trace(fn, id, status);
free(id);
}
}
}

else if(f->type == X_FIELD) xUnwrapField(f);
int st = xReduceField(f);
if(!status) status = st;
}

return 0;
return X_SUCCESS;
}


Expand Down Expand Up @@ -1334,8 +1352,8 @@ static int XFieldNameCmp(const XField **f1, const XField **f2) {
* @sa xReverseFieldOrder()
*/
int xSortFieldsByName(XStructure *s, boolean recursive) {
prop_error("xSortFieldsByName", xSortFields(s, XFieldNameCmp, recursive));
return X_SUCCESS;
prop_error("xSortFieldsByName", xSortFields(s, XFieldNameCmp, recursive));
return X_SUCCESS;
}

/**
Expand Down

0 comments on commit 45c14d3

Please sign in to comment.