/***********************************************************************/ /* 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" */ /***********************************************************************/ #include /*** MODULE: Compute2 SHORTDESCRIPTION: computes a pointwise expression over a field CATEGORY: Transformation INPUTS: expression; string or stringlist; NULL; inpute expression name0; string; "a"; name of input0 input0; value or field; NULL; input value name1; string; "b"; name of input1 input1; value or field; NULL; input value name2; string; "c"; name of input2 input2; value or field; NULL; input value name3; string; "d"; name of input3 input3; value or field; NULL; input value : OUTPUTS: output; value or field; NULL; output values FLAGS: BUGS: Always expands constants into arrays AUTHOR: Frank Suits END: ***/ #include #include #include "_compute.h" /* These are global variables to allow communication with the parser */ /* They're declared in compute.m, so extern here. */ extern PTreeNode *_dxdcomputeTree; extern CompInput _dxdcomputeInput[MAX_INPUTS]; int _dxfccparse(); int m_Compute2(Object *in, Object *out) { #define NAME_SIZE 256 char *expression0; ObjStruct *inputStruct; Object in2[MAX_INPUTS+1]; int i,cnt,n; char s[NAME_SIZE]; char *expression; int exp_size; char *name; char default_name[4]; #define DEFAULT_NAMES "abcdefghijklmnopqrstuvwxyz" #define DELTA_SIZE 512 #define ADD_STRING(p, s, sz) \ if ((s) && strlen(s)) { \ if (!(p)) { \ p = DXAllocate(DELTA_SIZE); \ if (!(p)) \ goto error; \ sz = DELTA_SIZE; \ *p = '\0'; \ } \ while (strlen(p)+strlen(s)+1 > sz) { \ sz += DELTA_SIZE; \ p = DXReAllocate(p, sz); \ if (!(p)) \ goto error; \ } \ strcat(p,s); \ } _dxfComputeInitInputs(_dxdcomputeInput); out[0] = NULL; expression = NULL; exp_size = 0; if (in[0] == NULL) { DXSetError (ERROR_BAD_PARAMETER, "#10200", "expression"); return ERROR; } for (i=0;i NAME_SIZE) { DXSetError(ERROR_BAD_PARAMETER, "Compute2: Name length exceeds maximum"); goto error; } sprintf(s,"%s=$%d;", name, cnt); ADD_STRING(expression, s, exp_size); in2[cnt]=in[i+1]; cnt++; } } switch (DXGetObjectClass(in[0])) { case CLASS_STRING: if (!DXExtractString (in[0], &expression0)) { DXSetError (ERROR_BAD_TYPE, "#10200", "expression"); goto error; } if (!strlen(expression0)) { DXSetError (ERROR_BAD_PARAMETER, "#10210", expression0, "expression"); goto error; } ADD_STRING(expression, expression0, exp_size); break; default: n = 0; while (DXExtractNthString(in[0], n++, &expression0)) { ADD_STRING(expression, expression0, exp_size); } break; } if (!expression || !strlen(expression)) DXSetError(ERROR_BAD_PARAMETER, "#10210", expression, "expression"); /* Build parse tree into _dxdcomputeTree */ _dxfccinput (expression); if (_dxfccparse () == 1 || _dxdcomputeTree == NULL) { goto error; } #if COMP_DEBUG _dxfComputeDumpParseTree (_dxdcomputeTree, 0); #endif /* Get the inputs used in the expression */ if ((inputStruct = _dxfComputeGetInputs (in2, _dxdcomputeInput)) == NULL) { _dxfComputeFreeTree(_dxdcomputeTree); goto error; } #if COMP_DEBUG _dxfComputeDumpInputs (_dxdcomputeInput, inputStruct); #endif /* Type check the expression with the inputs, returning an output * description in the top tree element, and execute the tree with * respect to that parse tree. */ if (_dxfComputeExecute (_dxdcomputeTree, inputStruct) == ERROR) { if (inputStruct->class != CLASS_ARRAY) DXDelete(inputStruct->output); _dxfComputeFreeTree (_dxdcomputeTree); _dxfComputeFreeObjStruct (inputStruct); goto error; } out[0] = inputStruct->output; _dxfComputeFreeTree (_dxdcomputeTree); _dxfComputeFreeObjStruct (inputStruct); DXFree(expression); return (OK); error: DXFree(expression); return (ERROR); }