/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ /* * $Header: /home/gda/dxcvs/dx/src/exec/dxmods/list.c,v 1.3 1999/05/10 15:45:27 gda Exp $ */ #include #include #define MAXALLOC 100 #define MAXOBJECTS 21 #define MAXRANK 16 /* make this externally accessible (used to be static) */ Array _dxfBuildList(Object *in); #define CHECK_LIMIT() \ if (strcnt >= maxalloc) { \ maxalloc *= 1.5; \ strlist = (char **)DXReAllocate((Pointer)strlist, \ sizeof(char *) * maxalloc); \ if (!strlist) \ goto error; \ } /* if you want to also operate on the data array from a field, set this to 1 */ #define DO_FIELDS 0 int m_List(Object *in, Object *out) { out[0] = (Object)_dxfBuildList(in); return out[0] ? OK : ERROR; } /* * internal entry point; take a list of arrays and coalesce into one array. */ Array _dxfBuildList(Object *in) { int i, onum; int first = 1; int seen_null = 0, warn_null = 0; float f; Array new = NULL; Object next = NULL; Type type, nexttype; Category cat, nextcat; int rank, nextrank, shape[MAXRANK], nextshape[MAXRANK]; int items = 0, nextitems; int num = 0; int isstring = 0; int strcnt = 0; int maxalloc = MAXALLOC; char **strlist = NULL; char *src, *dst; int ncount = 0; Array alist[MAXOBJECTS]; Array na; /* make room for list of strings to collect (this isn't used if the * input is a list of regular arrays) */ strlist = (char **)DXAllocate(sizeof(char *) * maxalloc); if (!strlist) return NULL; /* for each input, if it is null, skip it and continue; * otherwise, make sure the type matches the first parm, and add * the data to the list. */ for (onum = 0, next = in[onum]; onum < MAXOBJECTS; next = in[++onum]) { /* skip nulls */ if (!next) { seen_null = 1; continue; } if (seen_null) { warn_null = 1; seen_null = 0; } /* input. if field, get data. if array, use bare. */ switch(DXGetObjectClass(next)) { case CLASS_STRING: /* must be a string */ if (!isstring) isstring = 1; else if (isstring < 0) { DXSetError(ERROR_BAD_PARAMETER, "#10680", "inputs", 0, onum); goto error; } /* accumulate strings into list - _dxfNewStringListV() will be * called later. */ strlist[strcnt] = DXGetString((String)next); if (!strlist[strcnt]) goto error; strcnt++; CHECK_LIMIT(); continue; #if DO_FIELDS case CLASS_FIELD: next = (Object)DXGetComponentValue((Field)next, "data"); if (!next) { DXSetError(ERROR_INVALID_DATA, "no data component found in field to add to list"); goto error; } /* FALL THRU */ #endif case CLASS_ARRAY: if (!DXExtractNthString(next, 0, &src)) { /* can't be a string */ if (!isstring) isstring = -1; else if (isstring > 0) { DXSetError(ERROR_BAD_PARAMETER, "#10680", "inputs", 0, onum); goto error; } alist[ncount++] = (Array)next; } else { /* must be a string or stringlist */ for (i=0; DXExtractNthString(next, i, &src); i++) { if (!isstring) isstring = 1; else if (isstring < 1) { DXSetError(ERROR_BAD_PARAMETER, "#10680", "inputs", 0, onum); goto error; } strlist[strcnt] = src; if (!strlist[strcnt]) goto error; strcnt++; CHECK_LIMIT(); } } break; default: DXSetError(ERROR_BAD_PARAMETER, "input %d must be %s", onum, #if FIELD_SUPPORT "field or array" #else "an array" #endif ); goto error; } } /* if input was string instead of data array, delete any byte data * arrays which might have been accumulated and make a stringlist instead. */ if (isstring > 0) { new = DXMakeStringListV(strcnt, strlist); if (!new) goto error; } else { /* find a common format and convert the arrays to it */ if (DXQueryArrayCommonV(&type, &cat, &rank, shape, ncount, alist) != OK) goto error; new = DXNewArrayV(type, cat, rank, shape); if (!new) goto error; items = 0; for (i=0; i