/***********************************************************************/ /* 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 /* This file contains the description of each operator from a type and * execution pint of view. For each operator (such as COND (?:), *, * min, [...], etc.) there is a structure containing the operator * code, name, and a list of valid operator bindings. Each binding contains * the routine to implement the operation, a routine to check the type * of the operator, and type descriptors that the typeCheck routine may or * may not use. For an operator, the bindings are searched sequentially * until one is found to match the given arguments. If the search fails, * all arguments which are ints are promoted to floats, and the search is * repeated. The typecheck routine that finds a match must load the parse * tree\'s type field. * * All of the operators defined herein function on vectors, and (if the * compiler supports it) should be easily vectorisable and utilize the * processor\'s floating point pipeline. * * Note that the routines defining the operation are followed by the * OperBinding structure, and that this structure is referenced by the * OperDesc structure defined just before the Externally Callable Routines. * * Note also that the OperBinding structures are ordered such that if * the inputs match a vector routine, that routine is called first. If * the inputs miss the vector binding, one vectors are treated as scalars, * later on. * * The file exists in several sections: * Macros and utility routines. * Structure operators (such as const, input, construct, select, and cond). * Binary and unary operators (such as *, -, dot) * Builtin functions (such as min, float, sin). * Externally callable routines _dxfComputeTypeCheck, * _dxfComputeExecuteNode, and _dxfComputeLookupFunction * * To add a new operator: * The Parser must be changed to recognize it, and it must be added to * the set of operator codes in _compute.h * The OperBinding structure must be defined that * contains pointers to routines to implement and check the type must be * defined. * This structure must be inserted into the OperDesc structure. * * Adding new built-ins is a little easier, because to make the parse * recognize it, it must be added to the list in _ComputeLookupFunction and * the set of builtin codes shown below. * * Several generic routines are provided to do typechecking, but new ones may * be needed for special case typechecking. The extant routines are: * CheckVects -- Check input for vectors of same length * CheckSameShape -- Check input for same shaped objects * CheckMatch -- Check that the inputs match the types specified in * the binding structure. * CheckSame -- Check that the inputs (any number) match the type * of input[0], which is also the output type. * CheckSameAs -- Check that the inputs (any number) match the type * specified for input[0] in the binding structure. * CheckSameSpecReturn -- Same as CheckSame, but use the output type * given in the binding structure. * CheckDimAnyShape -- matches scalars in the binding exactly, but * if the binding shape == 1, it allows any dimension and shape. */ #include #include #include #include #include #include "_compute.h" #include "_compputils.h" #include "_compoper.h" #if !defined(DXD_STANDARD_IEEE) #include #endif /* A macro to ease the definition of the OperDesc field */ #define OP_RECORD(c, s, b) {(c), (s), (sizeof (b) / sizeof ((b)[0])), (b)} #define OP_RECORD_SIZE(c, s, b, size) {(c), (s), 0, (b)} static int TypeCheckLeaf(PTreeNode *tree, ObjStruct *input); /* * Routines to manipulate invalid data. */ Error _dxfComputeInvalidCopy( InvalidComponentHandle out, InvalidComponentHandle in0) { int i; if (in0 == NULL) return OK; if (DXInitGetNextInvalidElementIndex(in0) == ERROR) return ERROR; while ((i = DXGetNextInvalidElementIndex(in0)) >= 0) DXSetElementInvalid(out, i); return OK; } int _dxfComputeInvalidOne( InvalidComponentHandle out, int indexout, InvalidComponentHandle in0, int index0) { int result; if (in0 == NULL) return 1; if ((result = DXIsElementInvalidSequential(in0, index0))) DXSetElementInvalid(out, indexout); return !result; } int _dxfComputeInvalidOr( InvalidComponentHandle out, int indexout, InvalidComponentHandle in0, int index0, InvalidComponentHandle in1, int index1) { int result; if (in0 == NULL || in1 == NULL) return 1; if ((result = (DXIsElementInvalidSequential(in0, index0) || DXIsElementInvalidSequential(in1, index1)))) DXSetElementInvalid(out, indexout); return !result; } int _dxfComputeCompareType(MetaType *left, MetaType *right) { int i; if (left->type == right->type && left->category == right->category && left->rank == right->rank) { for (i = 0; i < left->rank; ++i) { if (left->shape[i] != right->shape[i]) { return (ERROR); } } return (OK); } else { return (ERROR); } } /* Checks a arguments to be sure all are same type * as binding says arg0 should be. It defines the result * to be of speced rank (scalar or vector) from the binding structure. */ int _dxfComputeCheckStrings (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int searchFailed; PTreeNode *arg; int j; int items = pt->metaType.items; searchFailed = 0; arg = pt->args; if (pt->args != NULL) { pt->metaType.shape[0] = pt->args->metaType.shape[0]; } /* Search through argument list to ensure match */ for (j = 0; !searchFailed && j < binding->numArgs && arg != NULL; ++j) { if (arg->metaType.rank != 1 || arg->metaType.type != binding->inTypes[j].type || arg->metaType.category != binding->inTypes[j].category) { searchFailed = 1; } arg = arg->next; } if (!searchFailed) { if (arg != NULL || j != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->impl = binding->impl; pt->metaType.type = binding->outType.type; pt->metaType.category = binding->outType.category; pt->metaType.rank = binding->outType.rank; pt->metaType.items = items; return (OK); } else { return (ERROR); } } /* This is the start of the Structure Operator Section */ static int ExecConstant ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { int size; #ifdef COMP_DEBUG DXDebug ("C", "ExecConst, %d: pt = 0x%08x, os = 0x%08x, os items = %d, pt items = %d", __LINE__, pt, os, os->metaType.items, pt->metaType.items); #endif /* Note that pt->metaType.items should always be 1 in this case. */ if (pt->metaType.type == TYPE_STRING) size = pt->metaType.shape[0]; else size = DXTypeSize (pt->metaType.type) * DXCategorySize (pt->metaType.category); bcopy (&pt->u, ((char*)result), size); return (OK); } static int CheckConstant (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { /* pt already contains out type, return Success */ pt->impl = binding->impl; return (OK); } static Pointer ComputeProductArray_GetArrayData(ProductArray a, Pointer *p) { int i, j, k, l, nterms, ndim, nl, nr, rank; Array *terms = NULL; float *result = (float*)p, *res, *right, *rt, *left, *lt; int freelocal = 0; int shape[100]; int totalItems; DXGetProductArrayInfo(a, &nterms, NULL); terms = DXAllocateLocal(nterms * sizeof (Array)); if (!terms) goto error; DXGetProductArrayInfo(a, NULL, terms); DXGetArrayInfo((Array)a, &totalItems, NULL, NULL, &rank, shape); for (i=0, ndim=1; ishape[0]==ndim);*/ /* copy first term data if nterms is 1 */ /* XXX - is there any way to avoid this? */ if (nterms==1) { int size = nl * ndim * sizeof(float); if (!result) goto error; memcpy(result, left, size); /* accumulate product left to right */ } else for (i=1; ishape[0]==ndim);*/ /* allocate result */ if (i < nterms - 1) res = result = (float *) DXAllocate(nl*nr*ndim*sizeof(float)); else res = result = (float*)p; if (!result) goto error; /* left operand plus right operand */ switch (ndim) { case 1: for (j=0, lt=left; j1) DXFree((Pointer)left); left = result; nl *= nr; if (freelocal) DXFreeArrayDataLocal(terms[i], (Pointer)right); } /* ASSERT(nl==totalItems); */ DXFree((Pointer)terms); /* DXunlock and return */ return (Pointer) result; error: if (freelocal) DXFreeArrayDataLocal(terms[i], (Pointer)right); /* and fall thru */ DXFree((Pointer)terms); return NULL; } static int ExecInput ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { Object o; int i; int numBasic; int size; Pointer data; Pointer scratch; InvalidComponentHandle fieldInvalid = NULL; int status = OK; ArrayHandle arrayHandle = NULL; int items; int dims; #ifdef COMP_DEBUG DXDebug ("C", "ExecInput, %d: pt = 0x%08x, os = 0x%08x, os items = %d, pt items = %d", __LINE__, pt, os, os->metaType.items, pt->metaType.items); #endif /* Quit if this is some kind of empty field. */ if (pt->metaType.items == 0) return OK; /* Ojbect is either an array or a field, make it an array, and * copy the array data into the result. */ o = os->inputs[pt->u.i]; if (DXGetObjectClass(o) == CLASS_FIELD) { Object a; char *dep; a = DXGetComponentAttribute((Field)o, "data", "dep"); if (a && DXExtractString(a, &dep)) { fieldInvalid = DXCreateInvalidComponentHandle(o, NULL, dep); if (!fieldInvalid) { status = ERROR; goto error; } } o = DXGetComponentValue ((Field)o, "data"); } /* Copy input data into result array */ for (numBasic = 1, i = 0; i < pt->metaType.rank; ++i) { numBasic *= pt->metaType.shape[i]; } size = DXTypeSize (pt->metaType.type) * DXCategorySize (pt->metaType.category) * numBasic; switch (DXGetArrayClass((Array)o)) { case CLASS_STRING: strcpy(result, DXGetString((String)o)); break; case CLASS_ARRAY: data = DXGetArrayData((Array)o); bcopy (data, result, pt->metaType.items * size); break; case CLASS_PRODUCTARRAY: if (ComputeProductArray_GetArrayData((ProductArray)o, result) == NULL) { status = ERROR; goto error; } break; case CLASS_REGULARARRAY: if (pt->metaType.items == 1) { if (DXGetRegularArrayInfo((RegularArray)o, NULL, result, NULL) == NULL) { DXSetError (ERROR_INTERNAL, "CheckInput, %d: Unable to get regular data", __LINE__); status = ERROR; goto error; } } else goto defaultCase; break; case CLASS_CONSTANTARRAY: data = DXGetConstantArrayData((Array)o); if (data == NULL) { DXSetError (ERROR_INTERNAL, "CheckInput, %d: Unable to get constant data", __LINE__); status = ERROR; goto error; } if (pt->metaType.items == 1) bcopy (data, result, size); else for (i = 0; i < pt->metaType.items; ++i) bcopy (data, ((char*)result) + i * size, size); break; /* ELSE Continue on for CLASS_PATHARRAY, * CLASS_PRODUCTARRAY, CLASS_MESHARRAY, or any one * we don't yet understand. */ default: defaultCase: arrayHandle = DXCreateArrayHandle((Array)o); if (!arrayHandle) { status = ERROR; goto error; } scratch = DXAllocateLocal(size); if (!scratch) { status = ERROR; goto error; } items = pt->metaType.items; for (i = 0; i < items; ++i) { data = DXGetArrayEntry(arrayHandle, i, scratch); bcopy (data, ((char*)result) + i * size, size); } DXFree(scratch); break; } error: if (arrayHandle) { DXFreeArrayHandle(arrayHandle); } if (fieldInvalid) { status = _dxfComputeInvalidCopy(outInvalid, fieldInvalid) && status; DXFreeInvalidComponentHandle(fieldInvalid); } return status; } static int CheckInput (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { Array a; Object attr; char *dep; int invalidSize = 0; if (DXGetObjectClass (os->inputs[pt->u.i]) == CLASS_STRING) { pt->metaType.items = 1; pt->metaType.type = TYPE_STRING; pt->metaType.category = CATEGORY_REAL; pt->metaType.rank = 1; pt->metaType.shape[0] = strlen(DXGetString((String)os->inputs[pt->u.i]))+1; pt->impl = binding->impl; return (OK); } if (DXGetObjectClass (os->inputs[pt->u.i]) == CLASS_FIELD) { a = (Array)DXGetComponentValue ((Field)os->inputs[pt->u.i], "data"); } else { a = (Array)os->inputs[pt->u.i]; } if (a != NULL) { if (DXGetArrayInfo ( a, &pt->metaType.items, &pt->metaType.type, &pt->metaType.category, &pt->metaType.rank, pt->metaType.shape) == NULL) { DXSetError (ERROR_INTERNAL, "CheckInput, %d: Unable to get input type info", __LINE__); return (ERROR); } if (DXGetObjectClass (os->inputs[pt->u.i]) == CLASS_FIELD) { attr = DXGetComponentAttribute((Field)os->inputs[pt->u.i], "data", "dep"); if (attr && DXExtractString(attr, &dep)) { char invalidName[1000]; Array invalidArray; sprintf(invalidName, "invalid %s", dep); invalidArray = (Array)DXGetComponentValue( (Field)os->inputs[pt->u.i], invalidName); if (invalidArray != NULL) { if (DXGetArrayInfo (invalidArray, &invalidSize, NULL, NULL, NULL, NULL) == NULL) { DXSetError (ERROR_INTERNAL, "CheckInput, %d: Unable to get input type info", __LINE__); return (ERROR); } } } } if (DXQueryConstantArray (a, NULL, NULL) && invalidSize == 0) pt->metaType.items = 1; } else { pt->metaType.items = 0; pt->metaType.type = TYPE_FLOAT; pt->metaType.category = CATEGORY_REAL; pt->metaType.rank = 1; pt->metaType.shape[0] = 1; } pt->impl = binding->impl; return (OK); } static int ExecConstruct ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { int i, j; int numBasic; int size; int subSize; PTreeNode *arg; int items; int allValid; #ifdef COMP_DEBUG DXDebug ("C", "ExecConstruct, %d: pt = 0x%08x, os = 0x%08x", __LINE__, pt, os); #endif /* Get type of arguments, and allocate nargs of pointers. * For each arg, allocate a result array, and execute it */ arg = pt->args; for (numBasic = 1, i = 0; i < arg->metaType.rank; ++i) { numBasic *= arg->metaType.shape[i]; } subSize = DXTypeSize (arg->metaType.type) * DXCategorySize (arg->metaType.category) * numBasic; /* Put the results together into a list */ size = subSize * numInputs; items = pt->metaType.items; for (i = 0; i < items; ++i) { arg = pt->args; for (j = 0; j < numInputs; ++j) { allValid = (invalids[j] == NULL || DXGetInvalidCount(invalids[j]) == 0); if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[j], i)) { if (arg->metaType.items == 1) bcopy ((Pointer)((char *)inputs[j]), (Pointer)(((char *)result) + (i * size) + j*subSize), subSize); else bcopy ((Pointer)(((char *)inputs[j]) + (i * subSize)), (Pointer)(((char *)result) + (i * size) + j*subSize), subSize); } else break; arg = arg->next; } } return (OK); } static int CheckConstruct (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *subTree; int listElement; int i; int seenScalar = 0; int seenOneVect = 0; #ifdef COMP_DEBUG DXDebug ("C", "Check type of CA_CONSTRUCT node"); #endif /* Ensure that all elements of a vector are the same type. * Result is same type with rank and shape adjusted. * Number of elements is same as largest (if any != 0). */ pt->metaType.type = pt->args->metaType.type; pt->metaType.category = pt->args->metaType.category; pt->metaType.rank = pt->args->metaType.rank; for (i = 0; i < pt->args->metaType.rank; ++i) { pt->metaType.shape[i] = pt->args->metaType.shape[i]; } listElement = 0; subTree = pt->args; /* Resolve types of subtree */ while (subTree != NULL) { if (subTree->metaType.rank == 0) seenScalar = 1; else if (subTree->metaType.rank == 1 && subTree->metaType.shape[0] == 1) seenOneVect = 1; if (_dxfComputeCompareType (&pt->metaType, &subTree->metaType) == ERROR) { if (!((subTree->metaType.rank == 0 && seenOneVect) || (subTree->metaType.rank == 1 && subTree->metaType.shape[0] == 1) && seenScalar)) return (ERROR); } subTree = subTree->next; ++listElement; } /* Adjust rank and shape */ if (seenScalar && seenOneVect) { pt->metaType.shape[0] = listElement; pt->metaType.rank = 1; } else { for (i = pt->args->metaType.rank; i > 0 ; --i) { pt->metaType.shape[i] = pt->metaType.shape[i-1]; } pt->metaType.shape[0] = listElement; pt->metaType.rank++; } pt->impl = binding->impl; return (OK); } static int ExecSelect ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k; int numBasic; int size; int subSize; PTreeNode *vect; int vectLen; int selector; int items; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); #ifdef COMP_DEBUG DXDebug ("C", "ExecSelect, %d: pt = 0x%08x, os = 0x%08x", __LINE__, pt, os); #endif /* Get type of arguments, and allocate nargs of pointers. * For each arg, allocate a result array, and execute it */ vect = pt->args; if (vect->metaType.rank == 0) { subSize = DXTypeSize (vect->metaType.type) * DXCategorySize (vect->metaType.category); size = subSize; vectLen = 1; } else { for (numBasic = 1, i = 1; i < vect->metaType.rank; ++i) { numBasic *= vect->metaType.shape[i]; } subSize = DXTypeSize (vect->metaType.type) * DXCategorySize (vect->metaType.category) * numBasic; /* Put the results together into a list */ vectLen = vect->metaType.shape[0]; size = subSize * vectLen; } /* For each item in list, select out the value */ items = pt->metaType.items; for (i = j = k = 0; i < items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { selector = *(int *)(((char *)inputs[1]) + k * sizeof (int)); if (selector < vectLen && selector >= 0) { bcopy ((Pointer)(((char *)inputs[0]) + (j * size) + selector * subSize), (Pointer)(((char *)result) + (i * subSize)), subSize); } else { DXSetError (ERROR_BAD_TYPE, "#12010", selector, vectLen); return (ERROR); } } if (size0 != 1) ++j; if (size1 != 1) ++k; } return (OK); } static int CheckSelect (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *vect; PTreeNode *select; int i; #ifdef COMP_DEBUG DXDebug ("C", "Check type of Selection node"); #endif /* Ensure that vect is at least a vector, and select is an int */ vect = pt->args; if (vect == NULL) { DXSetError (ERROR_INTERNAL, "CheckSelect, %d: no vector expression", __LINE__); return (ERROR); } select = vect->next; if (select == NULL) { DXSetError (ERROR_INTERNAL, "CheckSelect, %d: no select expression", __LINE__); return (ERROR); } if (_dxfComputeCompareType (&intExpr, &select->metaType) == ERROR) { return (ERROR); } pt->metaType.type = vect->metaType.type; pt->metaType.category = vect->metaType.category; if (vect->metaType.rank != 0) { pt->metaType.rank = vect->metaType.rank - 1; for (i = 0; i < pt->metaType.rank; ++i) { pt->metaType.shape[i] = vect->metaType.shape[i + 1]; } } pt->impl = binding->impl; return (OK); } static int ExecStrcmp( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register int *out = (int *) result; register char *in0 = (char *) inputs[0]; register char *in1 = (char *) inputs[1]; int vectorLen0 = pt->args->metaType.shape[0]; int vectorLen1 = pt->args->next->metaType.shape[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k, l; int ncmp; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); ncmp = MAX(vectorLen0, vectorLen1); for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { out[i] = strncmp(&in0[j*vectorLen0], &in1[k*vectorLen1], ncmp); } if (size0 != 1) ++j; if (size1 != 1) ++k; } return (OK); } static int ExecStricmp( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register int *out = (int *) result; register char *in0 = (char *) inputs[0]; register char *in1 = (char *) inputs[1]; int vectorLen0 = pt->args->metaType.shape[0]; int vectorLen1 = pt->args->next->metaType.shape[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k, l; int ncmp; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); ncmp = MAX(vectorLen0, vectorLen1); for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { int cc = 0; char *s1 = &in0[j*vectorLen0]; char *s2 = &in1[k*vectorLen1]; for ( ; ccargs->metaType.shape[0]; int vectorLen1 = pt->args->next->metaType.shape[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k; int ncmp; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); ncmp = MAX(vectorLen0, vectorLen1); for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { char *s = strstr(&in0[j*vectorLen0], &in1[k*vectorLen1]); out[i] = (s == NULL) ? 0 : (int) (s - &in0[i*vectorLen0] + 1); } if (size0 != 1) ++j; if (size1 != 1) ++k; } return (OK); } static int ExecStristr( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register int *out = (int *) result; register char *in0 = (char *) inputs[0]; register char *in1 = (char *) inputs[1]; int vectorLen0 = pt->args->metaType.shape[0]; int vectorLen1 = pt->args->next->metaType.shape[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k; int ncmp; char *bigbuff; char *buff1, *buff2; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); ncmp = MAX(vectorLen0, vectorLen1); bigbuff = DXAllocate(2*ncmp*sizeof(char)); if (!bigbuff) return (ERROR); buff1 = &bigbuff[0]; buff2 = &bigbuff[ncmp]; for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { char *s, *s1, *s2; int cc, sz1, sz2; s1 = &in0[j*vectorLen0]; sz1 = strlen(s1); s2 = &in1[k*vectorLen1]; sz2 = strlen(s2); strcpy(buff1, s1); strcpy(buff2, s2); for (cc = 0, s = buff1; cc < sz1; s++, cc++) *s = toupper(*s); for (cc = 0, s = buff2; cc < sz2; s++, cc++) *s = toupper(*s); s = strstr(buff1, buff2); out[i] = (s == NULL) ? 0 : (int) (s - buff1 + 1); } if (size0 != 1) ++j; if (size1 != 1) ++k; } DXFree(bigbuff); return (OK); } static int ExecStrlen( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register int *out = (int *) result; register char *in0 = (char *) inputs[0]; int vectorLen0 = pt->args->metaType.shape[0]; int size0 = pt->args->metaType.items; int i, j; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); for (i = j = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], j)) { out[i] = strlen(&in0[j*vectorLen0]); } if (size0 != 1) ++j; } return (OK); } static int ExecCond ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register int *cond = (int *) inputs[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int size2 = pt->args->next->next->metaType.items; int i, j, k, l; PTreeNode *arg; int numBasic; int size; int items; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); #ifdef COMP_DEBUG DXDebug ("C", "ExecCond, %d: pt = 0x%08x, os = 0x%08x", __LINE__, pt, os); #endif arg = pt->args->next; for (numBasic = 1, i = 0; i < arg->metaType.rank; ++i) { numBasic *= arg->metaType.shape[i]; } size = DXTypeSize (arg->metaType.type) * DXCategorySize (arg->metaType.category) * numBasic; items = pt->metaType.items; for (i = j = k = l = 0; i < items; ++i) { if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], j)) { if (cond[j]) { if (_dxfComputeInvalidOne(outInvalid, i, invalids[1], k)) bcopy ((Pointer)(((char *)inputs[1]) + k * size), (Pointer)(((char *)result) + i * size), size); } else { if (_dxfComputeInvalidOne(outInvalid, i, invalids[2], l)) bcopy ((Pointer)(((char *)inputs[2]) + l * size), (Pointer)(((char *)result) + i * size), size); } } ++j, ++k, ++l; if (j >= size0) j = 0; if (k >= size1) k = 0; if (l >= size2) l = 0; } return (OK); } static int CheckCond (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *condExpr; PTreeNode *thenExpr; PTreeNode *elseExpr; int result; int items; InvalidComponentHandle invalid = NULL; #ifdef COMP_DEBUG DXDebug ("C", "Check type of Conditional node"); #endif pt->metaType.items = 0; /* Ensure that first arg is an int, and others are the same * Result is type of both arguments */ condExpr = pt->args; if (condExpr == NULL) { DXSetError (ERROR_INTERNAL, "CheckCond, %d: no conditional expression", __LINE__); goto error; } thenExpr = condExpr->next; if (thenExpr == NULL) { DXSetError (ERROR_INTERNAL, "CheckCond, %d: no then expression", __LINE__); goto error; } elseExpr = thenExpr->next; if (elseExpr == NULL) { DXSetError (ERROR_INTERNAL, "CheckCond, %d: no else expression", __LINE__); goto error; } if (TypeCheckLeaf(condExpr, os) != OK) goto error; if (pt->metaType.items < condExpr->metaType.items) pt->metaType.items = condExpr->metaType.items; if (_dxfComputeCompareType (&intExpr, &condExpr->metaType) == ERROR) { DXSetError (ERROR_BAD_TYPE, "#11985"); goto error; } if (condExpr->metaType.items == 1) { if (_dxfComputeExecuteNode (condExpr, os, (Pointer) &result, &invalid) == ERROR) goto error; if (invalid == NULL || DXGetInvalidCount(invalid) == 0) { if (result) { if (TypeCheckLeaf(thenExpr, os) != OK) { goto error; } pt->metaType = thenExpr->metaType; if (pt->metaType.items < condExpr->metaType.items) pt->metaType.items = condExpr->metaType.items; } else { if (TypeCheckLeaf(elseExpr, os) != OK) { goto error; } pt->metaType = elseExpr->metaType; if (pt->metaType.items < condExpr->metaType.items) pt->metaType.items = condExpr->metaType.items; } } else { if (TypeCheckLeaf(thenExpr, os) != OK) goto error; if (pt->metaType.items < thenExpr->metaType.items) pt->metaType.items = thenExpr->metaType.items; if (TypeCheckLeaf(elseExpr, os) != OK) goto error; if (pt->metaType.items < elseExpr->metaType.items) pt->metaType.items = elseExpr->metaType.items; if (thenExpr->metaType.rank == 1 && thenExpr->metaType.shape[0] == 1) thenExpr->metaType.rank = 0; if (elseExpr->metaType.rank == 1 && elseExpr->metaType.shape[0] == 1) elseExpr->metaType.rank = 0; if (_dxfComputeCompareType (&thenExpr->metaType, &elseExpr->metaType) == ERROR) goto error; items = pt->metaType.items; pt->metaType = thenExpr->metaType; pt->metaType.items = items;; } } else { if (TypeCheckLeaf(thenExpr, os) != OK) goto error; if (pt->metaType.items < thenExpr->metaType.items) pt->metaType.items = thenExpr->metaType.items; if (TypeCheckLeaf(elseExpr, os) != OK) goto error; if (pt->metaType.items < elseExpr->metaType.items) pt->metaType.items = elseExpr->metaType.items; if (thenExpr->metaType.rank == 1 && thenExpr->metaType.shape[0] == 1) thenExpr->metaType.rank = 0; if (elseExpr->metaType.rank == 1 && elseExpr->metaType.shape[0] == 1) elseExpr->metaType.rank = 0; if (_dxfComputeCompareType (&thenExpr->metaType, &elseExpr->metaType) == ERROR) { DXSetError(ERROR_BAD_TYPE, "#11986"); goto error; } items = pt->metaType.items; pt->metaType = thenExpr->metaType; pt->metaType.items = items; } pt->impl = binding->impl; if (invalid) { DXFreeInvalidComponentHandle(invalid); } return (OK); error: if (invalid) { DXFreeInvalidComponentHandle(invalid); } return (ERROR); } typedef struct SymTab { char *name; Pointer value; InvalidComponentHandle invalid; MetaType metaType; } SymTab; static int symbolTableSize = 0; static int symbolTableUsed = 0; static SymTab *symbolTable = NULL; static int AddSymbol(char *name, MetaType *type) { int i; for (i = 0; i < symbolTableUsed; ++i) if (strcmp(name, symbolTable[i].name) == 0) { symbolTable[i].metaType = *type; return OK; } /* We have to extend the symbol table */ if (symbolTableSize == 0) symbolTable = (SymTab*)DXAllocateLocal(5 * sizeof (SymTab)); else symbolTable = (SymTab*)DXReAllocate((Pointer)symbolTable, (symbolTableSize + 5) * sizeof (SymTab)); symbolTableSize += 5; symbolTable[symbolTableUsed].name = (char*)DXAllocateLocal(strlen(name)+1); if (symbolTable[symbolTableUsed].name == NULL) return ERROR; strcpy(symbolTable[symbolTableUsed].name, name); symbolTable[symbolTableUsed].metaType = *type; symbolTable[symbolTableUsed].value = NULL; symbolTable[symbolTableUsed].invalid = NULL; symbolTableUsed++; return OK; } static int DefineSymbol(char *name, ObjStruct *os, Pointer value, InvalidComponentHandle invalid) { int i, j; int size; Object o; for (i = 0; i < symbolTableUsed; ++i) if (strcmp(name, symbolTable[i].name) == 0) { if (symbolTable[i].value) DXFree((Pointer)symbolTable[i].value); if (symbolTable[i].invalid) DXFreeInvalidComponentHandle(symbolTable[i].invalid); symbolTable[i].value = NULL; symbolTable[i].invalid = NULL; size = DXTypeSize(symbolTable[i].metaType.type) * DXCategorySize(symbolTable[i].metaType.category) * symbolTable[i].metaType.items; for (j = 0; j < symbolTable[i].metaType.rank; ++j) size *= symbolTable[i].metaType.shape[j]; symbolTable[i].value = DXAllocateLocal(size); if (symbolTable[i].value == NULL) { DXResetError(); symbolTable[i].value = DXAllocate(size); } if (symbolTable[i].value == NULL) { return ERROR; } bcopy((char*)value, (char*)symbolTable[i].value, size); o = os->output; if (invalid && DXGetObjectClass(o) == CLASS_FIELD) { Object a; char *dep; a = DXGetComponentAttribute((Field)o, "data", "dep"); if (a && DXExtractString(a, &dep)) { symbolTable[i].invalid = DXCreateInvalidComponentHandle(o, NULL, dep); if (!symbolTable[i].invalid) { return ERROR; } } return _dxfComputeInvalidCopy(symbolTable[i].invalid, invalid); } else return OK; } DXSetError(ERROR_INTERNAL, "Defining an unadded symbol `%s'", name); return ERROR; } static void ClearSymbolTable() { int i; for (i = 0; i < symbolTableUsed; ++i) { DXFree((Pointer)symbolTable[i].name); DXFree((Pointer)symbolTable[i].value); DXFreeInvalidComponentHandle(symbolTable[i].invalid); } DXFree((Pointer)symbolTable); symbolTable = NULL; symbolTableUsed = symbolTableSize = 0; } static int GetSymbol(char *name, Pointer *p, InvalidComponentHandle *invalid) { int i; for (i = 0; i < symbolTableUsed; ++i) { if (strcmp(name, symbolTable[i].name) == 0) { *p = symbolTable[i].value; *invalid = symbolTable[i].invalid; return OK; } } return ERROR; } static int GetSymbolType(char *name, MetaType **metaType) { int i; for (i = 0; i < symbolTableUsed; ++i) { if (strcmp(name, symbolTable[i].name) == 0) { *metaType = &symbolTable[i].metaType; return OK; } } return ERROR; } static int ExecAssignment ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { if (DefineSymbol(pt->u.s, os, inputs[0], invalids[0]) == ERROR) return ERROR; return _dxfComputeCopy(pt, os, numInputs, inputs, result, invalids, outInvalid); } static int CheckAssignment (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { if (AddSymbol(pt->u.s, &pt->args->metaType) == ERROR) return ERROR; pt->metaType = pt->args->metaType; pt->impl = binding->impl; return OK; } static int ExecVariable ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { Pointer p; InvalidComponentHandle definedInvalid; if (GetSymbol(pt->u.s, &p, &definedInvalid) == ERROR) { DXSetError(ERROR_INTERNAL, "Refering to an unadded symbol `%s'", pt->u.s); return ERROR; } return _dxfComputeCopy(pt, os, 1, &p, result, &definedInvalid, outInvalid); } static int CheckVariable (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { MetaType *t; if (GetSymbolType(pt->u.s, &t) == ERROR) { DXSetError(ERROR_BAD_PARAMETER, "#12091", pt->u.s); return ERROR; } pt->metaType = *t; pt->impl = binding->impl; return OK; } static OperBinding inputs[] = { {0, (CompFuncV)ExecInput, CheckInput} }; static OperBinding consts[] = { {0, (CompFuncV)ExecConstant, CheckConstant} }; static OperBinding construct[] = { {-1, (CompFuncV)ExecConstruct, CheckConstruct} }; static OperBinding cond[] = { {3, (CompFuncV)ExecCond, CheckCond} }; static OperBinding selects[] = { {2, (CompFuncV)ExecSelect, CheckSelect} }; static OperBinding strcmps[] = { {2, (CompFuncV)ExecStrcmp, _dxfComputeCheckStrings, {0, TYPE_INT, CATEGORY_REAL, 0 }, { {0, TYPE_STRING, CATEGORY_REAL}, {0, TYPE_STRING, CATEGORY_REAL}}}, }; static OperBinding stricmps[] = { {2, (CompFuncV)ExecStricmp, _dxfComputeCheckStrings, {0, TYPE_INT, CATEGORY_REAL, 0 }, { {0, TYPE_STRING, CATEGORY_REAL}, {0, TYPE_STRING, CATEGORY_REAL}}}, }; static OperBinding strstrs[] = { {2, (CompFuncV)ExecStrstr, _dxfComputeCheckStrings, {0, TYPE_INT, CATEGORY_REAL, 0 }, { {0, TYPE_STRING, CATEGORY_REAL}, {0, TYPE_STRING, CATEGORY_REAL}}}, }; static OperBinding stristrs[] = { {2, (CompFuncV)ExecStristr, _dxfComputeCheckStrings, {0, TYPE_INT, CATEGORY_REAL, 0 }, { {0, TYPE_STRING, CATEGORY_REAL}, {0, TYPE_STRING, CATEGORY_REAL}}}, }; static OperBinding strlens[] = { {1, (CompFuncV)ExecStrlen, _dxfComputeCheckStrings, {0, TYPE_INT, CATEGORY_REAL, 0 }, { {0, TYPE_STRING, CATEGORY_REAL}}}, }; static OperBinding assignments[] = { {1, (CompFuncV)ExecAssignment, CheckAssignment} }; static OperBinding variables[] = { {0, (CompFuncV)ExecVariable, CheckVariable} }; /* Checks a arguments to be sure all are vectors of same type and Category * as binding says arg0 should be, and same length. It defines the result * to be of speced rank (scalar or vector) from the binding structure, * and if vector, the same length as the inputs. */ int _dxfComputeCheckVects (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int searchFailed; PTreeNode *arg; int j; int items = pt->metaType.items; searchFailed = 0; arg = pt->args; if (pt->args != NULL) { pt->metaType.shape[0] = pt->args->metaType.shape[0]; } /* Search through argument list to ensure match */ for (j = 0; !searchFailed && j < binding->numArgs && arg != NULL; ++j) { if (arg->metaType.rank != 1 || arg->metaType.shape[0] != pt->metaType.shape[0] || arg->metaType.type != binding->inTypes[j].type || arg->metaType.category != binding->inTypes[j].category) { searchFailed = 1; } arg = arg->next; } if (!searchFailed) { if (arg != NULL || j != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->impl = binding->impl; pt->metaType.type = binding->outType.type; pt->metaType.category = binding->outType.category; pt->metaType.rank = binding->outType.rank; pt->metaType.items = items; return (OK); } else { return (ERROR); } } /* Checks a arguments to be sure all are objects of same type and Category * as binding says they should be, and rank and shape. It defines the result * to be of input cat, type, rank and shape. */ int _dxfComputeCheckSameShape (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int searchFailed; PTreeNode *arg; int j; int i; int items = pt->metaType.items; searchFailed = 0; arg = pt->args; if (pt->args != NULL) { pt->metaType = pt->args->metaType; pt->metaType.items = items; } /* Search through argument list to ensure match */ for (j = 0; !searchFailed && j < binding->numArgs && arg != NULL; ++j) { if (arg->metaType.rank != pt->metaType.rank || arg->metaType.type != binding->inTypes[j].type || ! (binding->inTypes[j].category != (Category) -1? arg->metaType.category == binding->inTypes[j].category: arg->metaType.category == pt->metaType.category)) { searchFailed = 1; } else { for (i = 0; i < arg->metaType.rank; ++i) { if (arg->metaType.shape[i] != pt->metaType.shape[i]) { searchFailed = 1; } } } arg = arg->next; } if (!searchFailed) { if (arg != NULL || j != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->impl = binding->impl; pt->metaType.type = binding->outType.type; if (binding->outType.category != (Category)-1) pt->metaType.category = binding->outType.category; return (OK); } else { return (ERROR); } } /* Checks a arguments to be sure all are objects of same type, Category, and * rank (if scalar) as binding says they should be, and any shape allowed. * If bindings says rank == 1, no scalars are allowed. * Output is that rank and shape of first non-scalar in binding. */ int _dxfComputeCheckDimAnyShape (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int searchFailed; PTreeNode *arg; int j; int first = 1; int items = pt->metaType.items; searchFailed = 0; arg = pt->args; if (pt->args != NULL) { pt->metaType = pt->args->metaType; pt->metaType.items = items; } /* Search through argument list to ensure match */ for (j = 0; !searchFailed && j < binding->numArgs && arg != NULL; ++j) { /* if binding says scalar, compare */ if (binding->inTypes[j].rank == 0) { searchFailed = !_dxfComputeCompareType (&binding->inTypes[j], &arg->metaType); } else if (arg->metaType.type != binding->inTypes[j].type || arg->metaType.category != binding->inTypes[j].category) { searchFailed = 1; } else if (arg->metaType.rank == 0) { return (ERROR); } else { if (first) { pt->metaType = arg->metaType; pt->metaType.items = items; first = 0; } } arg = arg->next; } if (!searchFailed) { if (arg != NULL || j != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->impl = binding->impl; return (OK); } else { return (ERROR); } } /* * Check that the inputs match the types specified in the binding structure. * Return the type specified in the binding structure. */ int _dxfComputeCheckMatch (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int searchFailed; PTreeNode *arg; int j; int items = pt->metaType.items; searchFailed = 0; arg = pt->args; /* Search through argument list to ensure match */ for (j = 0; !searchFailed && j < binding->numArgs && arg != NULL; ++j) { if (!_dxfComputeCompareType ( &binding->inTypes[j], &arg->metaType)) { searchFailed = 1; } arg = arg->next; } if (!searchFailed) { if (arg != NULL || j != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->impl = binding->impl; pt->metaType = binding->outType; pt->metaType.items = items; return (OK); } else { return (ERROR); } } /* * Check that the inputs (any number > 1) match the type * of input[0], which is also used as the output type. */ int _dxfComputeCheckSame (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *subTree; int listElement; int items = pt->metaType.items; int count; /* Count number of arguments (ensure match) */ if (binding->numArgs != -1) { for (count = 0, subTree = pt->args; subTree != NULL; ++count, subTree = subTree->next) ; if (count != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } } else if (pt->args == NULL) { return (ERROR); } /* Ensure that all elements of a vector are the same type. * Result is same type with rank and shape adjusted. * Number of elements is same as largest (if any != 0). */ pt->metaType = pt->args->metaType; pt->metaType.items = items; listElement = 0; subTree = pt->args; /* Resolve types of subtree */ while (subTree != NULL) { if (_dxfComputeCompareType (&pt->metaType, &subTree->metaType) == ERROR) { return (ERROR); } subTree = subTree->next; ++listElement; } if (listElement != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } else { pt->impl = binding->impl; return (OK); } } /* * Check that the inputs (any number) match the type specified in the binding * structure for input[0], which is also used as the output type. */ int _dxfComputeCheckSameAs (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *subTree; int listElement; int items = pt->metaType.items; int count; /* Count number of arguments (ensure match) */ if (binding->numArgs != -1) { for (count = 0, subTree = pt->args; subTree != NULL; ++count, subTree = subTree->next) ; if (count != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } } else if (pt->args == NULL) { return (ERROR); } /* Ensure that all elements of a vector are the same type. * Result is same type with rank and shape adjusted. * Number of elements is same as largest (if any != 0). */ pt->metaType = binding->outType; pt->metaType.items = items; listElement = 0; subTree = pt->args; /* Resolve types of subtree */ while (subTree != NULL) { if (_dxfComputeCompareType (&binding->inTypes[0], &subTree->metaType) == ERROR) { return (ERROR); } subTree = subTree->next; ++listElement; } pt->impl = binding->impl; return (OK); } /* * Check that the inputs (any number) match the type of input[0], like * CheckSame, but use the outputType specified in the binding structure. */ int _dxfComputeCheckSameSpecReturn (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *subTree; int listElement; int items = pt->metaType.items; int count; /* Count number of arguments (ensure match) */ if (binding->numArgs != -1) { for (count = 0, subTree = pt->args; subTree != NULL; ++count, subTree = subTree->next) ; if (count != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } } else if (pt->args == NULL) { return (ERROR); } /* Ensure that all elements of a vector are the same type. * Result is same type with rank and shape adjusted. * Number of elements is same as largest (if any != 0). */ pt->metaType = pt->args->metaType; pt->metaType.items = items; listElement = 0; subTree = pt->args; /* Resolve types of subtree */ while (subTree != NULL) { if (_dxfComputeCompareType (&pt->metaType, &subTree->metaType) == ERROR) { return (ERROR); } subTree = subTree->next; ++listElement; } pt->metaType = binding->outType; pt->metaType.items = items; pt->impl = binding->impl; return (OK); } /* * Check that the inputs (any number) match the type of input[0], like * CheckSame, have the same Type specified in the binding, but use * the outputType specified in the binding structure. */ int _dxfComputeCheckSameTypeSpecReturn (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *subTree; int listElement; int items = pt->metaType.items; int count; /* Count number of arguments (ensure match) */ if (binding->numArgs != -1) { for (count = 0, subTree = pt->args; subTree != NULL; ++count, subTree = subTree->next) ; if (count != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } } else if (pt->args == NULL) { return (ERROR); } /* Ensure that all elements of a vector are the same type. * Result is same type with rank and shape adjusted. * Number of elements is same as largest (if any != 0). */ pt->metaType = pt->args->metaType; pt->metaType.items = items; listElement = 0; subTree = pt->args; /* Resolve types of subtree */ while (subTree != NULL) { if (subTree->metaType.type != binding->inTypes[0].type || _dxfComputeCompareType (&pt->metaType, &subTree->metaType) == ERROR) { return (ERROR); } subTree = subTree->next; ++listElement; } pt->metaType = binding->outType; pt->metaType.items = items; pt->impl = binding->impl; return (OK); } /* * Now follows the set of binary and unary operators */ int _dxfComputeCopy( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { int numBasic; int i; int size; for (numBasic = 1, i = 0; i < pt->metaType.rank; ++i) { numBasic *= pt->metaType.shape[i]; } size = DXTypeSize (pt->metaType.type) * DXCategorySize (pt->metaType.category) * numBasic; if (pt->args != NULL && pt->args->metaType.items == 1) for (i = 0; i < pt->metaType.items; ++i) bcopy (inputs[0], ((char*)result) + i * size, size); else bcopy (inputs[0], result, size * pt->metaType.items); return _dxfComputeInvalidCopy(outInvalid, invalids[0]); } VBINOP (mulVUBUB, unsigned char, unsigned char, unsigned char, *) VSBINOP (mulVSUBUB, unsigned char, unsigned char, unsigned char, *) SVBINOP (mulSVUBUB, unsigned char, unsigned char, unsigned char, *) VBINOP (mulVBB, signed char, signed char, signed char, *) VSBINOP (mulVSBB, signed char, signed char, signed char, *) SVBINOP (mulSVBB, signed char, signed char, signed char, *) VBINOP (mulVUSUS, unsigned short, unsigned short, unsigned short, *) VSBINOP (mulVSUSUS, unsigned short, unsigned short, unsigned short, *) SVBINOP (mulSVUSUS, unsigned short, unsigned short, unsigned short, *) VBINOP (mulVSS, signed short, signed short, signed short, *) VSBINOP (mulVSSS, signed short, signed short, signed short, *) SVBINOP (mulSVSS, signed short, signed short, signed short, *) VBINOP (mulVUIUI, unsigned int, unsigned int, unsigned int, *) VSBINOP (mulVSUIUI, unsigned int, unsigned int, unsigned int, *) SVBINOP (mulSVUIUI, unsigned int, unsigned int, unsigned int, *) VBINOP (mulVII, signed int, signed int, signed int, *) VSBINOP (mulVSII, signed int, signed int, signed int, *) SVBINOP (mulSVII, signed int, signed int, signed int, *) VSBINOP (mulVSFF, float, float, float, *) SVBINOP (mulSVFF, float, float, float, *) VBINOP (mulVFF, float, float, float, *) VSBINOP (mulVSDD, double, double, double, *) SVBINOP (mulSVDD, double, double, double, *) VBINOP (mulVDD, double, double, double, *) VFUNC2 (mulVFFC, complexFloat, complexFloat, complexFloat, _dxfComputeMulComplexFloat) VSFUNC2 (mulVSFFC, complexFloat, complexFloat, complexFloat, _dxfComputeMulComplexFloat) SVFUNC2 (mulSVFFC, complexFloat, complexFloat, complexFloat, _dxfComputeMulComplexFloat) static OperBinding muls[] = { {2, (CompFuncV)mulVSUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 1}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 1}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 1}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 1}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 1}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 1}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSFFC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {2, (CompFuncV)mulSVUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)mulSVFFC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}}}, {2, (CompFuncV)mulVUBUB, _dxfComputeCheckSameShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVBB, _dxfComputeCheckSameShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVUSUS, _dxfComputeCheckSameShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVSS, _dxfComputeCheckSameShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVUIUI, _dxfComputeCheckSameShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVII, _dxfComputeCheckSameShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVFF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVDD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVFFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, }; #define NONZ(x,y) ((y) != 0) #define FCNONZ(x,y) (REAL(y) != 0 || IMAG(y) != 0) VBINOPRC (divVUBUB, unsigned char, unsigned char, unsigned char, /, NONZ, "#12020") VBINOPRC (divVBB, signed char, signed char, signed char, /, NONZ, "#12020") VBINOPRC (divVUSUS, unsigned short, unsigned short, unsigned short, /, NONZ, "#12020") VBINOPRC (divVSS, signed short, signed short, signed short, /, NONZ, "#12020") VBINOPRC (divVUIUI, unsigned int, unsigned int, unsigned int, /, NONZ, "#12020") VBINOPRC (divVII, signed int, signed int, signed int, /, NONZ, "#12020") VBINOPRC (divVFF, float, float, float, /, NONZ, "#12020") VBINOPRC (divVDD, double, double, double, /, NONZ, "#12020") VFUNC2RC (divVFFC, complexFloat, complexFloat, complexFloat, _dxfComputeDivComplexFloat, FCNONZ, "#12020") VSBINOPRC (divVSUBUB, unsigned char, unsigned char, unsigned char, /, NONZ, "#12020") VSBINOPRC (divVSBB, signed char, signed char, signed char, /, NONZ, "#12020") VSBINOPRC (divVSUSUS, unsigned short, unsigned short, unsigned short, /, NONZ, "#12020") VSBINOPRC (divVSSS, signed short, signed short, signed short, /, NONZ, "#12020") VSBINOPRC (divVSUIUI, unsigned int, unsigned int, unsigned int, /, NONZ, "#12020") VSBINOPRC (divVSII, signed int, signed int, signed int, /, NONZ, "#12020") VSBINOPRC (divVSFF, float, float, float, /, NONZ, "#12020") VSBINOPRC (divVSDD, double, double, double, /, NONZ, "#12020") VSFUNC2RC (divVSFFC, complexFloat, complexFloat, complexFloat, _dxfComputeDivComplexFloat, FCNONZ, "#12020") SVBINOPRC (divSVUBUB, unsigned char, unsigned char, unsigned char, /, NONZ, "#12020") SVBINOPRC (divSVBB, signed char, signed char, signed char, /, NONZ, "#12020") SVBINOPRC (divSVUSUS, unsigned short, unsigned short, unsigned short, /, NONZ, "#12020") SVBINOPRC (divSVSS, signed short, signed short, signed short, /, NONZ, "#12020") SVBINOPRC (divSVUIUI, unsigned int, unsigned int, unsigned int, /, NONZ, "#12020") SVBINOPRC (divSVII, signed int, signed int, signed int, /, NONZ, "#12020") SVBINOPRC (divSVFF, float, float, float, /, NONZ, "#12020") SVBINOPRC (divSVDD, double, double, double, /, NONZ, "#12020") SVFUNC2RC (divSVFFC, complexFloat, complexFloat, complexFloat, _dxfComputeDivComplexFloat, FCNONZ, "#12020") VBINOPRC (modVUBUB, unsigned char, unsigned char, unsigned char, %, NONZ, "#12020") VBINOPRC (modVBB, signed char, signed char, signed char, %, NONZ, "#12020") VBINOPRC (modVUSUS, unsigned short, unsigned short, unsigned short, %, NONZ, "#12020") VBINOPRC (modVSS, signed short, signed short, signed short, %, NONZ, "#12020") VBINOPRC (modVUIUI, unsigned int, unsigned int, unsigned int, %, NONZ, "#12020") VBINOPRC (modVII, signed int, signed int, signed int, %, NONZ, "#12020") VFUNC2RC (modVFF, float, float, float, fmod, NONZ, "#12020") VFUNC2RC (modVDD, double, double, double, fmod, NONZ, "#12020") VSBINOPRC (modVSUBUB, unsigned char, unsigned char, unsigned char, %, NONZ, "#12020") VSBINOPRC (modVSBB, signed char, signed char, signed char, %, NONZ, "#12020") VSBINOPRC (modVSUSUS, unsigned short, unsigned short, unsigned short, %, NONZ, "#12020") VSBINOPRC (modVSSS, signed short, signed short, signed short, %, NONZ, "#12020") VSBINOPRC (modVSUIUI, unsigned int, unsigned int, unsigned int, %, NONZ, "#12020") VSBINOPRC (modVSII, signed int, signed int, signed int, %, NONZ, "#12020") VSFUNC2RC (modVSFF, float, float, float, fmod, NONZ, "#12020") VSFUNC2RC (modVSDD, double, double, double, fmod, NONZ, "#12020") SVBINOPRC (modSVUBUB, unsigned char, unsigned char, unsigned char, %, NONZ, "#12020") SVBINOPRC (modSVBB, signed char, signed char, signed char, %, NONZ, "#12020") SVBINOPRC (modSVUSUS, unsigned short, unsigned short, unsigned short, %, NONZ, "#12020") SVBINOPRC (modSVSS, signed short, signed short, signed short, %, NONZ, "#12020") SVBINOPRC (modSVUIUI, unsigned int, unsigned int, unsigned int, %, NONZ, "#12020") SVBINOPRC (modSVII, signed int, signed int, signed int, %, NONZ, "#12020") SVFUNC2RC (modSVFF, float, float, float, fmod, NONZ, "#12020") SVFUNC2RC (modSVDD, double, double, double, fmod, NONZ, "#12020") static OperBinding divs[] = { {2, (CompFuncV)divVSUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 1}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 1}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 1}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 1}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 1}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 1}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSFFC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {2, (CompFuncV)divSVUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)divSVFFC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}}}, {2, (CompFuncV)divVUBUB, _dxfComputeCheckSameShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVBB, _dxfComputeCheckSameShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVUSUS, _dxfComputeCheckSameShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVSS, _dxfComputeCheckSameShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVUIUI, _dxfComputeCheckSameShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVII, _dxfComputeCheckSameShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVFF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVDD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)divVFFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, }; static OperBinding mods[] = { {2, (CompFuncV)modVSUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 1}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 1}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 1}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 1}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 1}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 1}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modSVUBUB, _dxfComputeCheckDimAnyShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVBB, _dxfComputeCheckDimAnyShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVUSUS, _dxfComputeCheckDimAnyShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVSS, _dxfComputeCheckDimAnyShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVUIUI, _dxfComputeCheckDimAnyShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVII, _dxfComputeCheckDimAnyShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modSVDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)modVUBUB, _dxfComputeCheckSameShape, {0, TYPE_UBYTE, CATEGORY_REAL, 1}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}, {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVBB, _dxfComputeCheckSameShape, {0, TYPE_BYTE, CATEGORY_REAL, 1}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}, {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVUSUS, _dxfComputeCheckSameShape, {0, TYPE_USHORT, CATEGORY_REAL, 1}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}, {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVSS, _dxfComputeCheckSameShape, {0, TYPE_SHORT, CATEGORY_REAL, 1}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}, {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVUIUI, _dxfComputeCheckSameShape, {0, TYPE_UINT, CATEGORY_REAL, 1}, { {0, TYPE_UINT, CATEGORY_REAL, 0}, {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVII, _dxfComputeCheckSameShape, {0, TYPE_INT, CATEGORY_REAL, 1}, { {0, TYPE_INT, CATEGORY_REAL, 0}, {0, TYPE_INT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVFF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 1}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)modVDD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, }; /* Now follows the set of builtin functions for type conversion and * truncation */ #ifndef sgi # define ffloor floor # define fceil ceil # define ftrunc trunc # define flog log # define flog10 log10 # define fexp exp # define fsin sin # define fcos cos # define ftan tan # define fsinh sinh # define fcosh cosh # define ftanh tanh # define fasin asin # define facos acos # define fatan atan # define fatan2 atan2 # define fsqrt sqrt #endif #ifdef aviion # define trunc(x) ((float)((int)(x))) #endif #ifdef sun4 # define trunc(x) ((float)((int)(x))) #endif #ifdef solaris # define trunc(x) ((float)((int)(x))) #endif #ifdef ibmpvs # define rint(x) ((float)((int)((x) + 0.5))) # define trunc(x) ((float)((int)(x))) #endif #ifdef hp700 # define rint(x) ((float)((int)((x) + 0.5))) # define trunc(x) ((float)((int)(x))) #endif #define SIGN(x) ((x) >= 0? (1): (-1)) /* These are the math operators */ #define POWCK(x,y) ((x) >= 0.0 || ceil(y) == (y)) VSFUNC2RC (powVSFF, float, float, float, pow, POWCK, "#12030") SVFUNC2RC (powSVFF, float, float, float, pow, POWCK, "#12030") VFUNC2RC (powVFF, float, float, float, pow, POWCK, "#12030") VSFUNC2RC (powVSDD, double, double, double, pow, POWCK, "#12030") SVFUNC2RC (powSVDD, double, double, double, pow, POWCK, "#12030") VFUNC2RC (powVDD, double, double, double, pow, POWCK, "#12030") VSFUNC2 (powVSFFCC, complexFloat, complexFloat, complexFloat, _dxfComputePowComplexFloat) SVFUNC2 (powSVFFCC, complexFloat, complexFloat, complexFloat, _dxfComputePowComplexFloat) VFUNC2 (powVFFCC, complexFloat, complexFloat, complexFloat, _dxfComputePowComplexFloat) VSFUNC2 (powVSFFCR, complexFloat, complexFloat, float, _dxfComputePowComplexFloatFloat) SVFUNC2 (powSVFFCR, complexFloat, complexFloat, float, _dxfComputePowComplexFloatFloat) VFUNC2 (powVFFCR, complexFloat, complexFloat, float, _dxfComputePowComplexFloatFloat) #define NONNEG(x) ((x) >= 0.0) VFUNC1RC (sqrtF, float, float, fsqrt, NONNEG, "#12040") VFUNC1RC (sqrtD, double, double, sqrt, NONNEG, "#12040") VFUNC1(sqrtFC, complexFloat, complexFloat, _dxfComputeSqrtComplexFloat) #define POS(x) ((x) > 0.0) VFUNC1RC (lnF, float, float, flog, POS, "#12050") VFUNC1RC (lnD, double, double, log, POS, "#12050") VFUNC1(lnFC, complexFloat, complexFloat, _dxfComputeLnComplexFloat) VFUNC1RC (log10F, float, float, flog10, POS, "#12050") VFUNC1RC (log10D, double, double, log10, POS, "#12050") VFUNC1 (expF, float, float, fexp) VFUNC1 (expD, double, double, exp) VFUNC1 (expFC, complexFloat, complexFloat, _dxfComputeExpComplexFloat) #define ABS(x) ((x) < 0? -(x): (x)) VFUNC1 (absF, float, float, ABS ) VFUNC1 (absD, double, double, ABS ) VFUNC1 (absFC, float, complexFloat, _dxfComputeAbsComplexFloat) VFUNC1 (absI, int, int, ABS ) VFUNC1 (absS, short, short, ABS ) VFUNC1 (absB, signed char, signed char, ABS ) VFUNC1 (argFC, float, complexFloat, _dxfComputeArgComplexFloat) static OperBinding sqrts[] = { {1, (CompFuncV)sqrtFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {1, (CompFuncV)sqrtF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)sqrtD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}} }; static OperBinding pows[] = { {2, (CompFuncV)powVSFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)powSVFF, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)powVFF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)powVSDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 1}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)powSVDD, _dxfComputeCheckDimAnyShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 1}}}, {2, (CompFuncV)powVDD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {2, (CompFuncV)powVSFFCC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {2, (CompFuncV)powSVFFCC, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}}}, {2, (CompFuncV)powVFFCC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {2, (CompFuncV)powVSFFCR, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)powSVFFCR, _dxfComputeCheckDimAnyShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1}}}, {2, (CompFuncV)powVFFCR, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}} }; static OperBinding lns[] = { {1, (CompFuncV)lnF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)lnD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)lnFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding log10s[] = { {1, (CompFuncV)log10F, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)log10D, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}} }; static OperBinding exps[] = { {1, (CompFuncV)expF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)expD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)expFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding abss[] = { {1, (CompFuncV)_dxfComputeCopy, _dxfComputeCheckSameShape, {0, TYPE_UBYTE, CATEGORY_REAL, 0}, { {0, TYPE_UBYTE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)_dxfComputeCopy, _dxfComputeCheckSameShape, {0, TYPE_USHORT, CATEGORY_REAL, 0}, { {0, TYPE_USHORT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)_dxfComputeCopy, _dxfComputeCheckSameShape, {0, TYPE_UINT, CATEGORY_REAL, 0}, { {0, TYPE_UINT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absI, _dxfComputeCheckSameShape, {0, TYPE_INT, CATEGORY_REAL, 0}, { {0, TYPE_INT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absS, _dxfComputeCheckSameShape, {0, TYPE_SHORT, CATEGORY_REAL, 0}, { {0, TYPE_SHORT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absB, _dxfComputeCheckSameShape, {0, TYPE_BYTE, CATEGORY_REAL, 0}, { {0, TYPE_BYTE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding args[] = { {1, (CompFuncV)argFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; VFUNC1 (sinF, float, float, fsin) VFUNC1 (cosF, float, float, fcos) VFUNC1 (tanF, float, float, ftan) VFUNC1 (sinhF, float, float, fsinh) VFUNC1 (coshF, float, float, fcosh) VFUNC1 (tanhF, float, float, ftanh) VFUNC1 (sinD, double, double, sin) VFUNC1 (cosD, double, double, cos) VFUNC1 (tanD, double, double, tan) VFUNC1 (sinhD, double, double, sinh) VFUNC1 (coshD, double, double, cosh) VFUNC1 (tanhD, double, double, tanh) VFUNC1 (sinFC, complexFloat, complexFloat, _dxfComputeSinComplexFloat) VFUNC1 (cosFC, complexFloat, complexFloat, _dxfComputeCosComplexFloat) VFUNC1 (tanFC, complexFloat, complexFloat, _dxfComputeTanComplexFloat) VFUNC1 (sinhFC, complexFloat, complexFloat, _dxfComputeSinhComplexFloat) VFUNC1 (coshFC, complexFloat, complexFloat, _dxfComputeCoshComplexFloat) VFUNC1 (tanhFC, complexFloat, complexFloat, _dxfComputeTanhComplexFloat) #define FPM1(x) ((x) >= -1 && (x) <= 1) VFUNC1RC (asinF, float, float, fasin, FPM1, "#12060") VFUNC1RC (acosF, float, float, facos, FPM1, "#12061") VFUNC1 (atanF, float, float, fatan) VFUNC1RC (asinD, double, double, asin, FPM1, "#12060") VFUNC1RC (acosD, double, double, acos, FPM1, "#12061") VFUNC1 (atanD, double, double, atan) VFUNC1 (asinFC, complexFloat, complexFloat, _dxfComputeAsinComplexFloat) VFUNC1 (acosFC, complexFloat, complexFloat, _dxfComputeAcosComplexFloat) VFUNC1 (atanFC, complexFloat, complexFloat, _dxfComputeAtanComplexFloat) VFUNC2 (atan2F, float, float, float, fatan2) VFUNC2 (atan2D, double, double, double, atan2) static OperBinding sins[] = { {1, (CompFuncV)sinF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)sinD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)sinFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding coss[] = { {1, (CompFuncV)cosF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)cosD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)cosFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding tans[] = { {1, (CompFuncV)tanF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)tanD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)tanFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding sinhs[] = { {1, (CompFuncV)sinhF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)sinhD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)sinhFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding coshs[] = { {1, (CompFuncV)coshF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)coshD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)coshFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding tanhs[] = { {1, (CompFuncV)tanhF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)tanhD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)tanhFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding asins[] = { {1, (CompFuncV)asinF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)asinD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)asinFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding acoss[] = { {1, (CompFuncV)acosF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)acosD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)acosFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}} }; static OperBinding atans[] = { {1, (CompFuncV)atanF, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)atanD, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}}, {1, (CompFuncV)atanFC, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}, { {0, TYPE_FLOAT, CATEGORY_COMPLEX, 0}}}, {2, (CompFuncV)atan2F, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)atan2D, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}} }; static OperBinding atan2s[] = { {2, (CompFuncV)atan2F, _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)atan2D, _dxfComputeCheckSameShape, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}, {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}} }; #define PI 3.1415926535898 static int #if defined(sgi) && defined(_SYSTYPE_SVR4) qsinx( #else qsin( #endif PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; register float *in0 = (float *) inputs[0]; int i; int numBasic; for (numBasic = 1, i = 0; i < pt->metaType.rank; ++i) numBasic *= pt->metaType.shape[i]; numBasic *= pt->metaType.items; #ifdef COMMENT_FMOD vsdiv(in0, 1, 2 * PI, out, 1, numBasic); vfrac(out, 1, out, 1, numBasic); vsmul(out, 1, 2 * PI, out, 1, numBasic); for (i = 0; i < numBasic; ++i) if (out[i] < -PI) out[i] += 2 * PI; else if (out[i] > PI) out[i] -= 2 * PI; #endif /* COMMENT_FMOD */ qvsin (numBasic, in0, out); return (OK); } static int #if defined(sgi) && defined(_SYSTYPE_SVR4) qcosx( #else qcos( #endif PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; register float *in0 = (float *) inputs[0]; int i; int numBasic; for (numBasic = 1, i = 0; i < pt->metaType.rank; ++i) numBasic *= pt->metaType.shape[i]; numBasic *= pt->metaType.items; #ifdef COMMENT_FMOD vsdiv(in0, 1, 2 * PI, out, 1, numBasic); vfrac(out, 1, out, 1, numBasic); vsmul(out, 1, 2 * PI, out, 1, numBasic); for (i = 0; i < numBasic; ++i) if (out[i] < -PI) out[i] += 2 * PI; else if (out[i] > PI) out[i] -= 2 * PI; #endif /* COMMENT_FMOD */ qvcos(numBasic, in0, out); return (OK); } static OperBinding qsins[] = { {1, #if defined(sgi) && defined(_SYSTYPE_SVR4) (CompFuncV)qsinx, #else (CompFuncV)qsin, #endif _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}} }; static OperBinding qcoss[] = { {1, #if defined(sgi) && defined(_SYSTYPE_SVR4) (CompFuncV)qcosx, #else (CompFuncV)qcos, #endif _dxfComputeCheckSameShape, {0, TYPE_FLOAT, CATEGORY_REAL, 0}, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}} }; static int cross3( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { typedef float threevect[3]; register threevect *out = (threevect *) result; register threevect *in0 = (threevect *) inputs[0]; register threevect *in1 = (threevect *) inputs[1]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { out[i][0] = in0[j][1] * in1[k][2] - in0[j][2] * in1[k][1]; out[i][1] = in0[j][2] * in1[k][0] - in0[j][0] * in1[k][2]; out[i][2] = in0[j][0] * in1[k][1] - in0[j][1] * in1[k][0]; } if (size0 != 1) ++j; if (size1 != 1) ++k; } return (OK); } static OperBinding crosses[] = { {2, (CompFuncV)cross3, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 1, {3}}, { {0, TYPE_FLOAT, CATEGORY_REAL, 1, {3}}, {0, TYPE_FLOAT, CATEGORY_REAL, 1, {3}}}} }; /* dot */ static int dotFF( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; register float *in0 = (float *) inputs[0]; register float *in1 = (float *) inputs[1]; int vectorLen = pt->metaType.shape[0]; int size0 = pt->args->metaType.items; int size1 = pt->args->next->metaType.items; int i, j, k, l; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && (invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0); for (i = j = k = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) { out[i] = in0[j * vectorLen + 0] * in1[k * vectorLen + 0]; for (l = 1; l < vectorLen; ++l) { out[i] += in0[j * vectorLen + l] * in1[k * vectorLen + l]; } } if (size0 != 1) ++j; if (size1 != 1) ++k; } return (OK); } static OperBinding dots[] = { {2, (CompFuncV)dotFF, _dxfComputeCheckVects, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL}, {0, TYPE_FLOAT, CATEGORY_REAL}}}, {2, (CompFuncV)mulVFF, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVFF, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL, 1, 1}, {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {2, (CompFuncV)mulVFF, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}, {0, TYPE_FLOAT, CATEGORY_REAL, 1, 1}}} }; /* magv */ static int magvF( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; register float *in0 = (float *) inputs[0]; int vectorLen = pt->metaType.shape[0]; int i, j; double temp; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); for (i = 0; i < pt->metaType.items; ++i) { if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) { temp = (double)in0[i * vectorLen + 0] * (double)in0[i * vectorLen + 0]; for (j = 1; j < vectorLen; ++j) { temp += (double)in0[i * vectorLen + j] * (double)in0[i * vectorLen + j]; } out[i] = sqrt (temp); } } return (OK); } static OperBinding magvs[] = { {1, (CompFuncV)magvF, _dxfComputeCheckVects, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL}}}, {1, (CompFuncV)absF, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}}, {1, (CompFuncV)absD, _dxfComputeCheckMatch, {0, TYPE_DOUBLE, CATEGORY_REAL, 0 }, { {0, TYPE_DOUBLE, CATEGORY_REAL, 0}}} }; static int normF( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; register float *in0 = (float *) inputs[0]; register double mag; int vectorLen = pt->metaType.shape[0]; int i, j; int items; int allValid = (invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); items = pt->metaType.items; for (i = 0; i < items; ++i) { if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) { mag = (double)in0[i * vectorLen + 0] * (double)in0[i * vectorLen + 0]; for (j = 1; j < vectorLen; ++j) { mag += (double)in0[i * vectorLen + j] * (double)in0[i * vectorLen + j]; } if (mag != 0.0) mag = 1. / sqrt(mag); for (j = 0; j < vectorLen; ++j) { out[i * vectorLen + j] = mag * in0[i * vectorLen + j]; } } } return (OK); } #define SIGNF(x) ((float)SIGN(x)) VFUNC1 (normSF, float, float, SIGNF) static OperBinding norms[] = { {1, (CompFuncV)normF, _dxfComputeCheckVects, {0, TYPE_FLOAT, CATEGORY_REAL, 1 }, { {0, TYPE_FLOAT, CATEGORY_REAL}}}, {1, (CompFuncV)normSF, _dxfComputeCheckMatch, {0, TYPE_FLOAT, CATEGORY_REAL, 0 }, { {0, TYPE_FLOAT, CATEGORY_REAL, 0}}} }; static int CheckRank(PTreeNode *pt, ObjStruct *os, OperBinding *binding) { int numArgs; PTreeNode *arg; for (numArgs = 0, arg = pt->args; arg; ++numArgs, arg = arg->next) ; if (numArgs != binding->numArgs) { DXSetError(ERROR_BAD_TYPE, "#11945", binding->numArgs); return (ERROR); } pt->metaType.items = 1; pt->metaType.type = TYPE_INT; pt->metaType.category = CATEGORY_REAL; pt->metaType.rank = 0; pt->impl = binding->impl; if (numArgs == 2 && _dxfComputeCompareType (&intExpr, &pt->args->next->metaType) == ERROR) { DXSetError (ERROR_BAD_TYPE, "#11980"); return (ERROR); } return (OK); } static int ExecRank ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { *(int *)result = pt->args->metaType.rank; return (OK); } static int ExecShape ( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { if (*(int*)(inputs[1]) < pt->args->metaType.rank) { *(int *)result = pt->args->metaType.shape[*(int*)(inputs[1])]; return (OK); } else { DXSetError (ERROR_BAD_TYPE, "#11970"); return (ERROR); } } static OperBinding shapes[] = { {2, (CompFuncV)ExecShape, CheckRank} }; static OperBinding ranks[] = { {1, (CompFuncV)ExecRank, CheckRank} }; static int randNULL( PTreeNode *pt, ObjStruct *os, int numInputs, Pointer *inputs, Pointer result, InvalidComponentHandle *invalids, InvalidComponentHandle outInvalid) { register float *out = (float *) result; int i, j, items; int *seed0 = (int *)inputs[1]; int seed; int numBasic; #define RANDSORTBINS 1023 float rands[RANDSORTBINS]; int index; seed = *seed0 + os->metaType.id; #ifdef COMP_DEBUG DXDebug ("C", "randNULL, %d: pt = 0x%08x, os = 0x%08x, os items = %d, pt items = %d, seed0 = %d, seed = %d", __LINE__, pt, os, os->metaType.items, pt->metaType.items, *seed0, seed); #endif srandom(seed); for (i = 0; imetaType.rank; i++) numBasic *= pt->metaType.shape[i]; numBasic *= DXCategorySize(pt->metaType.category); items = pt->metaType.items; for (i = 0; i < items; ++i) for (j = 0; j < numBasic; j++) { index = ((float)random()/0x7fffffff)*RANDSORTBINS; out[i*numBasic + j] = rands[index]; rands[index] = ((float)random()/0x7fffffff); } return (OK); } static int CheckRAND (PTreeNode *pt, ObjStruct *os, OperBinding *binding) { PTreeNode *stuff; PTreeNode *seed; int i; /* Ensure that vect is at least a vector, and select is an int */ stuff = pt->args; if (stuff == NULL) { DXSetError (ERROR_INTERNAL, "CheckRand, %d: no input object", __LINE__); return (ERROR); } seed = stuff->next; if (seed == NULL) { DXSetError (ERROR_INTERNAL, "CheckRand, %d: no seed expression", __LINE__); return (ERROR); } if (_dxfComputeCompareType (&intExpr, &seed->metaType) == ERROR) { return (ERROR); } pt->metaType.type = binding->outType.type; pt->metaType.category = binding->outType.category; pt->metaType.rank = stuff->metaType.rank; for (i=0; imetaType.rank; i++) pt->metaType.shape[i] = stuff->metaType.shape[i]; pt->impl = binding->impl; return (OK); } static OperBinding randoms[] = { {2, (CompFuncV)randNULL, CheckRAND, {1, TYPE_FLOAT, CATEGORY_REAL, 0}, { {1, TYPE_FLOAT, CATEGORY_REAL, 0}, {1, TYPE_INT, CATEGORY_REAL, 0}} } }; extern OperBinding _dxdComputeAdds[]; extern OperBinding _dxdComputeSubs[]; extern OperBinding _dxdComputeLts[]; extern OperBinding _dxdComputeLes[]; extern OperBinding _dxdComputeGts[]; extern OperBinding _dxdComputeGes[]; extern OperBinding _dxdComputeEqs[]; extern OperBinding _dxdComputeNes[]; extern OperBinding _dxdComputeAnds[]; extern OperBinding _dxdComputeOrs[]; extern OperBinding _dxdComputeNots[]; extern OperBinding _dxdComputeMins[]; extern OperBinding _dxdComputeMaxs[]; extern OperBinding _dxdComputeInts[]; extern OperBinding _dxdComputeFloats[]; extern OperBinding _dxdComputeReals[]; extern OperBinding _dxdComputeImags[]; extern OperBinding _dxdComputeComplexes[]; extern OperBinding _dxdComputeImagis[]; extern OperBinding _dxdComputeImagjs[]; extern OperBinding _dxdComputeImagks[]; extern OperBinding _dxdComputeQuaternions[]; extern OperBinding _dxdComputeSigns[]; extern OperBinding _dxdComputeUbytes[]; extern OperBinding _dxdComputeShorts[]; extern OperBinding _dxdComputeDoubles[]; extern OperBinding _dxdComputeSigned_ints[]; extern OperBinding _dxdComputeBands[]; extern OperBinding _dxdComputeBors[]; extern OperBinding _dxdComputeBxors[]; extern OperBinding _dxdComputeBnots[]; extern OperBinding _dxdComputeSbytes[]; extern OperBinding _dxdComputeUints[]; extern OperBinding _dxdComputeUshorts[]; extern OperBinding _dxdComputeInvalids[]; extern OperBinding _dxdComputeFloors[]; extern OperBinding _dxdComputeCeils[]; extern OperBinding _dxdComputeTruncs[]; extern OperBinding _dxdComputeRints[]; extern int _dxdComputeAddsSize; extern int _dxdComputeSubsSize; extern int _dxdComputeLtsSize; extern int _dxdComputeLesSize; extern int _dxdComputeGtsSize; extern int _dxdComputeGesSize; extern int _dxdComputeEqsSize; extern int _dxdComputeNesSize; extern int _dxdComputeAndsSize; extern int _dxdComputeOrsSize; extern int _dxdComputeNotsSize; extern int _dxdComputeMinsSize; extern int _dxdComputeMaxsSize; extern int _dxdComputeIntsSize; extern int _dxdComputeFloatsSize; extern int _dxdComputeRealsSize; extern int _dxdComputeImagsSize; extern int _dxdComputeComplexesSize; extern int _dxdComputeImagisSize; extern int _dxdComputeImagjsSize; extern int _dxdComputeImagksSize; extern int _dxdComputeQuaternionsSize; extern int _dxdComputeSignsSize; extern int _dxdComputeUbytesSize; extern int _dxdComputeShortsSize; extern int _dxdComputeDoublesSize; extern int _dxdComputeSigned_intsSize; extern int _dxdComputeBandsSize; extern int _dxdComputeBorsSize; extern int _dxdComputeBxorsSize; extern int _dxdComputeBnotsSize; extern int _dxdComputeSbytesSize; extern int _dxdComputeUintsSize; extern int _dxdComputeUshortsSize; extern int _dxdComputeInvalidsSize; extern int _dxdComputeFloorsSize; extern int _dxdComputeCeilsSize; extern int _dxdComputeTruncsSize; extern int _dxdComputeRintsSize; /* Here is the operator table that ties it all together */ static OperDesc operators[] = { OP_RECORD (NT_INPUT, "input", inputs), OP_RECORD (NT_CONSTANT, "constant", consts), OP_RECORD (NT_CONSTRUCT, "vector constructor", construct), OP_RECORD (NT_COND, "conditional", cond), /* OP_RECORD (NT_TOP, "top", tops), */ OP_RECORD_SIZE (OPER_PLUS, "+", _dxdComputeAdds, _dxdComputeAddsSize), OP_RECORD_SIZE (OPER_MINUS, "-", _dxdComputeSubs, _dxdComputeSubsSize), OP_RECORD (OPER_MUL, "*", muls), OP_RECORD (OPER_DIV, "/", divs), OP_RECORD (OPER_MOD, "%", mods), OP_RECORD (OPER_CROSS, "cross", crosses), OP_RECORD (OPER_DOT, "dot", dots), OP_RECORD_SIZE (OPER_LT, "<", _dxdComputeLts, _dxdComputeLtsSize), OP_RECORD_SIZE (OPER_LE, "<=", _dxdComputeLes, _dxdComputeLesSize), OP_RECORD_SIZE (OPER_GT, ">", _dxdComputeGts, _dxdComputeGtsSize), OP_RECORD_SIZE (OPER_GE, ">=", _dxdComputeGes, _dxdComputeGesSize), OP_RECORD_SIZE (OPER_EQ, "==", _dxdComputeEqs, _dxdComputeEqsSize), OP_RECORD_SIZE (OPER_NE, "!=", _dxdComputeNes, _dxdComputeNesSize), OP_RECORD_SIZE (OPER_AND, "&&", _dxdComputeAnds, _dxdComputeAndsSize), OP_RECORD_SIZE (OPER_OR, "||", _dxdComputeOrs, _dxdComputeOrsSize), OP_RECORD (OPER_EXP, "^", pows), OP_RECORD (OPER_PERIOD, ".", selects), OP_RECORD_SIZE (OPER_NOT, "!", _dxdComputeNots, _dxdComputeNotsSize), OP_RECORD (FUNC_sqrt, "sqrt", sqrts), OP_RECORD (FUNC_pow, "pow", pows), OP_RECORD (FUNC_sin, "sin", sins), OP_RECORD (FUNC_cos, "cos", coss), OP_RECORD (FUNC_tan, "tan", tans), OP_RECORD (FUNC_ln, "ln", lns), OP_RECORD (FUNC_log10, "log10", log10s), OP_RECORD_SIZE (FUNC_min, "min", _dxdComputeMins, _dxdComputeMinsSize), OP_RECORD_SIZE (FUNC_max, "max", _dxdComputeMaxs, _dxdComputeMaxsSize), OP_RECORD_SIZE (FUNC_floor, "floor", _dxdComputeFloors, _dxdComputeFloorsSize), OP_RECORD_SIZE (FUNC_ceil, "ceil", _dxdComputeCeils, _dxdComputeFloorsSize), OP_RECORD_SIZE (FUNC_trunc, "trunc", _dxdComputeTruncs, _dxdComputeFloorsSize), OP_RECORD_SIZE (FUNC_rint, "rint", _dxdComputeRints, _dxdComputeFloorsSize), OP_RECORD (FUNC_exp, "exp", exps), OP_RECORD (FUNC_tanh, "tanh", tanhs), OP_RECORD (FUNC_sinh, "sinh", sinhs), OP_RECORD (FUNC_cosh, "cosh", coshs), OP_RECORD (FUNC_acos, "acos", acoss), OP_RECORD (FUNC_asin, "asin", asins), OP_RECORD (FUNC_atan, "atan", atans), OP_RECORD (FUNC_atan2, "atan2", atan2s), OP_RECORD (FUNC_strcmp, "strcmp", strcmps), OP_RECORD (FUNC_stricmp, "stricmp", stricmps), OP_RECORD (FUNC_strstr, "strstr", strstrs), OP_RECORD (FUNC_stristr, "stristr", stristrs), OP_RECORD (FUNC_strlen, "strlen", strlens), OP_RECORD (FUNC_mag, "mag", magvs), OP_RECORD (FUNC_norm, "norm", norms), OP_RECORD (FUNC_abs, "abs", abss), OP_RECORD_SIZE (FUNC_int, "int", _dxdComputeInts, _dxdComputeIntsSize), OP_RECORD_SIZE (FUNC_float, "float", _dxdComputeFloats, _dxdComputeFloatsSize), OP_RECORD_SIZE (FUNC_real, "real", _dxdComputeReals, _dxdComputeRealsSize), OP_RECORD_SIZE (FUNC_imag, "imag", _dxdComputeImags, _dxdComputeImagsSize), OP_RECORD_SIZE (FUNC_complex,"complex", _dxdComputeComplexes, _dxdComputeComplexesSize), OP_RECORD_SIZE (FUNC_imagi, "imagi", _dxdComputeImagis, _dxdComputeImagisSize), OP_RECORD_SIZE (FUNC_imagj, "imagj", _dxdComputeImagjs, _dxdComputeImagjsSize), OP_RECORD_SIZE (FUNC_imagk, "imagk", _dxdComputeImagks, _dxdComputeImagksSize), OP_RECORD_SIZE (FUNC_quaternion, "quaternion", _dxdComputeQuaternions, _dxdComputeQuaternionsSize), /* Not available on the i860 version * OP_RECORD (FUNC_acosh, "acosh", acoshs), * OP_RECORD (FUNC_asinh, "asinh", asinhs), * OP_RECORD (FUNC_atanh, "atanh", atanhs), */ OP_RECORD_SIZE (FUNC_sign, "sign", _dxdComputeSigns, _dxdComputeSignsSize), OP_RECORD (FUNC_qsin, "qsin", qsins), OP_RECORD (FUNC_qcos, "qcos", qcoss), OP_RECORD_SIZE (FUNC_char, "char", _dxdComputeUbytes, _dxdComputeUbytesSize), OP_RECORD_SIZE (FUNC_short, "short", _dxdComputeShorts, _dxdComputeShortsSize), OP_RECORD_SIZE (FUNC_double,"double", _dxdComputeDoubles, _dxdComputeDoublesSize), OP_RECORD_SIZE (FUNC_signed_int, "signed_int", _dxdComputeSigned_ints, _dxdComputeSigned_intsSize), OP_RECORD (FUNC_rank, "rank", ranks), OP_RECORD (FUNC_shape, "shape", shapes), OP_RECORD_SIZE (FUNC_and, "and", _dxdComputeBands, _dxdComputeBandsSize), OP_RECORD_SIZE (FUNC_or, "or", _dxdComputeBors, _dxdComputeBorsSize), OP_RECORD_SIZE (FUNC_xor, "xor", _dxdComputeBxors, _dxdComputeBxorsSize), OP_RECORD_SIZE (FUNC_not, "not", _dxdComputeBnots, _dxdComputeBnotsSize), OP_RECORD (FUNC_random, "random", randoms), OP_RECORD (FUNC_arg, "arg", args), OP_RECORD_SIZE (FUNC_invalid,"invalid", _dxdComputeInvalids, _dxdComputeInvalidsSize), OP_RECORD_SIZE (FUNC_sbyte, "sbyte", _dxdComputeSbytes, _dxdComputeSbytesSize), OP_RECORD_SIZE (FUNC_uint, "uint", _dxdComputeUints, _dxdComputeUintsSize), OP_RECORD_SIZE (FUNC_ushort, "ushort", _dxdComputeUshorts, _dxdComputeUshortsSize), OP_RECORD (OPER_ASSIGNMENT, "assignment", assignments), OP_RECORD (OPER_VARIABLE, "variable", variables) }; static int TypeCheckLeaf(PTreeNode *tree, ObjStruct *input) { PTreeNode *subTree; int i; int knownOpers = sizeof (operators) / sizeof (operators[0]); int b; int op = tree->oper; OperBinding *bindings; int numBindings; PTreeNode *newTree; PTreeNode **nextPtr; #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf for parse node 0x%08x and leaf 0x%08x", tree, input); #endif /* Conditional ShortCut to avoid checking and doing one side or the * other if the conditional is a constant */ if (tree->oper == NT_COND) { for (i = 0; i < knownOpers && op != operators[i].op; ++i) ; bindings = operators[i].bindings; if (CheckCond(tree, input, &bindings[0]) == ERROR) { /* We failed, skip to the regular promotion stuff */ } else { DXResetError(); tree->operName = operators[i].name; return (OK); } } /* MAIN PATH: * Resolve types of subtrees */ subTree = tree->args; while (subTree != NULL) { if (TypeCheckLeaf(subTree, input) != OK) { return (ERROR); } if (tree->metaType.items < subTree->metaType.items) tree->metaType.items = subTree->metaType.items; subTree = subTree->next; } /* Find the appropriate operator */ for (i = 0; i < knownOpers; ++i) { if (op == operators[i].op) { bindings = operators[i].bindings; numBindings = operators[i].numBindings; /* Search For the Correct Binding */ for (b = 0; b < numBindings; ++b) { if ((*bindings[b].typeCheck)(tree, input, bindings + b) == OK) { #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf: items in tree 0x%08x after checking = %d", tree, tree->metaType.items); #endif tree->operName = operators[i].name; DXResetError(); return (OK); } } /* We failed, Promote all small ints to ints and try again */ if (tree->oper != FUNC_int) { subTree = tree->args; nextPtr = &tree->args; while (subTree != NULL) { if ((subTree->metaType.type == TYPE_UBYTE || subTree->metaType.type == TYPE_BYTE || subTree->metaType.type == TYPE_USHORT || subTree->metaType.type == TYPE_SHORT || subTree->metaType.type == TYPE_UINT) && (subTree->metaType.category == CATEGORY_REAL || subTree->metaType.category == CATEGORY_COMPLEX)) { newTree = _dxfMakeFunCall ("int", subTree); newTree->next = subTree->next; subTree->next = NULL; *nextPtr = newTree; /* Type check the new node */ if (TypeCheckLeaf(newTree, input) != OK) { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } nextPtr = &newTree->next; subTree = newTree->next; } else { nextPtr = &subTree->next; subTree = subTree->next; } } } else { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } for (b = 0; b < numBindings; ++b) { if ((*bindings[b].typeCheck)(tree, input, bindings + b) == OK) { #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf: items in tree 0x%08x after checking = %d", tree, tree->metaType.items); #endif tree->operName = operators[i].name; DXResetError(); return (OK); } } /* We failed, Promote all non-floats to floats and try again */ if (tree->oper != FUNC_float) { subTree = tree->args; nextPtr = &tree->args; for (i = 0; subTree != NULL; ++i) { if ((tree->oper != NT_COND || i != 0) && subTree->metaType.type != TYPE_FLOAT && (subTree->metaType.category == CATEGORY_REAL || subTree->metaType.category == CATEGORY_COMPLEX)) { if (subTree->metaType.type == TYPE_DOUBLE) DXWarning("#11960", operators[i].name); newTree = _dxfMakeFunCall ("float", subTree); newTree->next = subTree->next; subTree->next = NULL; *nextPtr = newTree; /* Type check the new node */ if (TypeCheckLeaf(newTree, input) != OK) { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } nextPtr = &newTree->next; subTree = newTree->next; } else { nextPtr = &subTree->next; subTree = subTree->next; } } } else { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } for (b = 0; b < numBindings; ++b) { if ((*bindings[b].typeCheck)(tree, input, bindings + b) == OK) { #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf: items in tree 0x%08x after checking = %d", tree, tree->metaType.items); #endif tree->operName = operators[i].name; DXResetError(); return (OK); } } /* We failed, Demote all 1 vectors to scalars and try again */ if (tree->oper != FUNC_float) { subTree = tree->args; nextPtr = &tree->args; while (subTree != NULL) { if (subTree->metaType.rank == 1 && subTree->metaType.shape[0] == 1) { newTree = _dxfMakeFunCall ("select", subTree); newTree->next = subTree->next; subTree->next = _dxfMakeArg(NT_CONSTANT); subTree->next->metaType.items = 1; subTree->next->metaType.type = TYPE_INT; subTree->next->metaType.category = CATEGORY_REAL; subTree->next->u.i = 0; subTree->next->next = NULL; *nextPtr = newTree; /* Type check the new node */ if (TypeCheckLeaf(newTree, input) != OK) { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } nextPtr = &newTree->next; subTree = newTree->next; } else { nextPtr = &subTree->next; subTree = subTree->next; } } } else { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } for (b = 0; b < numBindings; ++b) { if ((*bindings[b].typeCheck)(tree, input, bindings + b) == OK) { #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf: items in tree 0x%08x after checking = %d", tree, tree->metaType.items); #endif tree->operName = operators[i].name; DXResetError(); return (OK); } } /* We failed, Promote all floats to complex and try again */ if (tree->oper != FUNC_complex) { subTree = tree->args; nextPtr = &tree->args; for (i = 0; subTree != NULL; ++i) { if ((tree->oper != NT_COND || i != 0) && (subTree->metaType.category == CATEGORY_REAL)) { if (subTree->metaType.type == TYPE_DOUBLE) DXWarning("#11960", operators[i].name); newTree = _dxfMakeFunCall ("complex", subTree); newTree->next = subTree->next; subTree->next = NULL; *nextPtr = newTree; /* Type check the new node */ if (TypeCheckLeaf(newTree, input) != OK) { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } nextPtr = &newTree->next; subTree = newTree->next; } else { nextPtr = &subTree->next; subTree = subTree->next; } } } else { DXSetError (ERROR_NOT_IMPLEMENTED, "#11950"); return (ERROR); } for (b = 0; b < numBindings; ++b) { if ((*bindings[b].typeCheck)(tree, input, bindings + b) == OK) { #ifdef COMP_DEBUG DXDebug ("C", "TypeCheckLeaf: items in tree 0x%08x after checking = %d", tree, tree->metaType.items); #endif tree->operName = operators[i].name; DXResetError(); return (OK); } } /* We failed again, error out */ if (DXGetError() == ERROR_NONE) DXSetError(ERROR_BAD_TYPE, "#11940", operators[i].name); else DXAddMessage("#11940", operators[i].name); return (ERROR); } } DXSetError (ERROR_INTERNAL, "#11930", op); return (ERROR); } int _dxfComputeTypeCheck(PTreeNode *tree, ObjStruct *input) { #ifdef COMP_DEBUG DXDebug ("C", "_dxfComputeTypeCheck (tree = 0x%08x, input = 0x%08x)", tree, input); #endif if (input->class != CLASS_ARRAY && input->class != CLASS_FIELD && input->class != CLASS_STRING) { DXSetError(ERROR_BAD_CLASS, "#10370", "leaves", "field or numeric list"); return ERROR; } input->parseTree = _dxfComputeCopyTree (tree); if (input->parseTree == NULL) return ERROR; else return TypeCheckLeaf(input->parseTree, input); } /* * _dxfComputeInitExecution() * This initializes lots of execution stuff, and should be called once per * processor per object computed upon. */ void _dxfComputeInitExecution(void) { int i; int knownOpers = sizeof (operators) / sizeof (operators[0]); for (i = 0; i < knownOpers; ++i) { switch (operators[i].op) { case OPER_PLUS: operators[i].numBindings = _dxdComputeAddsSize; break; case OPER_MINUS: operators[i].numBindings = _dxdComputeSubsSize; break; case OPER_LT: operators[i].numBindings = _dxdComputeLtsSize; break; case OPER_LE: operators[i].numBindings = _dxdComputeLesSize; break; case OPER_GT: operators[i].numBindings = _dxdComputeGtsSize; break; case OPER_GE: operators[i].numBindings = _dxdComputeGesSize; break; case OPER_EQ: operators[i].numBindings = _dxdComputeEqsSize; break; case OPER_NE: operators[i].numBindings = _dxdComputeNesSize; break; case OPER_AND: operators[i].numBindings = _dxdComputeAndsSize; break; case OPER_OR: operators[i].numBindings = _dxdComputeOrsSize; break; case OPER_NOT: operators[i].numBindings = _dxdComputeNotsSize; break; case FUNC_min: operators[i].numBindings = _dxdComputeMinsSize; break; case FUNC_max: operators[i].numBindings = _dxdComputeMaxsSize; break; case FUNC_int: operators[i].numBindings = _dxdComputeIntsSize; break; case FUNC_float: operators[i].numBindings = _dxdComputeFloatsSize; break; case FUNC_real: operators[i].numBindings = _dxdComputeRealsSize; break; case FUNC_imag: operators[i].numBindings = _dxdComputeImagsSize; break; case FUNC_complex: operators[i].numBindings = _dxdComputeComplexesSize; break; case FUNC_imagi: operators[i].numBindings = _dxdComputeImagisSize; break; case FUNC_imagj: operators[i].numBindings = _dxdComputeImagjsSize; break; case FUNC_imagk: operators[i].numBindings = _dxdComputeImagksSize; break; case FUNC_quaternion: operators[i].numBindings = _dxdComputeQuaternionsSize; break; case FUNC_sign: operators[i].numBindings = _dxdComputeSignsSize; break; case FUNC_char: operators[i].numBindings = _dxdComputeUbytesSize; break; case FUNC_short: operators[i].numBindings = _dxdComputeShortsSize; break; case FUNC_double: operators[i].numBindings = _dxdComputeDoublesSize; break; case FUNC_signed_int: operators[i].numBindings = _dxdComputeSigned_intsSize; break; case FUNC_and: operators[i].numBindings = _dxdComputeBandsSize; break; case FUNC_or: operators[i].numBindings = _dxdComputeBorsSize; break; case FUNC_xor: operators[i].numBindings = _dxdComputeBxorsSize; break; case FUNC_not: operators[i].numBindings = _dxdComputeBnotsSize; break; case FUNC_invalid: operators[i].numBindings = _dxdComputeInvalidsSize; break; case FUNC_sbyte: operators[i].numBindings = _dxdComputeSbytesSize; break; case FUNC_uint: operators[i].numBindings = _dxdComputeUintsSize; break; case FUNC_ushort: operators[i].numBindings = _dxdComputeUshortsSize; break; case FUNC_floor: operators[i].numBindings = _dxdComputeFloorsSize; break; case FUNC_ceil: operators[i].numBindings = _dxdComputeCeilsSize; break; case FUNC_trunc: operators[i].numBindings = _dxdComputeTruncsSize; break; case FUNC_rint: operators[i].numBindings = _dxdComputeRintsSize; break; } } } int _dxfComputeFinishExecution() { ClearSymbolTable(); return OK; } #if !defined(DXD_STANDARD_IEEE) static jmp_buf broken; static void handlefp(void) { longjmp(broken, 1); } #endif /* * _dxfComputeExecuteNode allocates memory for each sub-argument, and then * passes the results off to the function which performs this node. */ int _dxfComputeExecuteNode( PTreeNode *pt, ObjStruct *os, Pointer result, InvalidComponentHandle *invalid) { int numArgs, i, argIndex; int numBasic; int subSize; Pointer *subData = NULL; InvalidComponentHandle *subInvalids = NULL; PTreeNode *args; int status = ERROR; *invalid = NULL; #ifdef COMP_DEBUG DXDebug ("C", "_dxfComputeExecuteNode, %d: pt = 0x%08x, os = 0x%08x", __LINE__, pt, os); #endif /* Conditional ShortCut */ while (pt->oper == NT_COND && pt->args->metaType.items == 1) { _dxfComputeExecuteNode (pt->args, os, (Pointer)&status, invalid); if (*invalid == NULL || DXGetInvalidCount(*invalid) == 0) { if (status) pt = pt->args->next; else pt = pt->args->next->next; } else break; } if (*invalid) { DXFreeInvalidComponentHandle(*invalid); } /* Get type of arguments, and allocate nargs of pointers. * For each arg, allocate a result array, and execute it */ args = pt->args; numArgs = 0; if (args) { /* Count Args and alloc an array of pointers and an array of * invalid component handles for the called routine to fill. */ for (numArgs = 0; args != NULL; ++numArgs) args = args->next; args = pt->args; subData = (Pointer *) DXAllocateLocalZero (numArgs * sizeof (Pointer)); if (subData == NULL) { DXResetError(); subData = (Pointer *) DXAllocateZero (numArgs * sizeof (Pointer)); if (subData == NULL) goto error; } subInvalids = (InvalidComponentHandle *) DXAllocateLocalZero (numArgs * sizeof (InvalidComponentHandle)); if (subInvalids == NULL) { DXResetError(); subInvalids = (InvalidComponentHandle *) DXAllocateZero (numArgs * sizeof (InvalidComponentHandle)); if (subInvalids == NULL) goto error; } for (argIndex = 0, args = pt->args; args != NULL; args = args->next, ++argIndex) { for (numBasic = 1, i = 0; i < args->metaType.rank; ++i) { numBasic *= args->metaType.shape[i]; } subSize = DXTypeSize (args->metaType.type) * DXCategorySize (args->metaType.category) * numBasic; subData[argIndex] = DXAllocateLocal(pt->metaType.items*subSize); if (subData[argIndex] == NULL) { DXResetError(); subData[argIndex] = DXAllocate(pt->metaType.items*subSize); if (subData[argIndex] == NULL) { goto error; } } if (_dxfComputeExecuteNode (args, os, subData[argIndex], &subInvalids[argIndex]) == ERROR) goto error; } } else { subData = NULL; } /* * Allocate an invalidcomponenthandle for the work routine to fill */ if (os->class == CLASS_FIELD) { Object a; char *dep; a = DXGetComponentAttribute((Field)os->output, "data", "dep"); if (a && DXExtractString(a, &dep) != ERROR) { *invalid = DXCreateInvalidComponentHandle(os->output, NULL, dep); if (!*invalid || DXSetAllValid(*invalid) == ERROR) goto error; } } #if !defined(DXD_STANDARD_IEEE) if (setjmp(broken)) { DXSetError (ERROR_INVALID_DATA, "#11790"); /* fpe */ goto error; } signal (SIGFPE, handlefp); #endif status = (*pt->impl) (pt, os, numArgs, subData, result, subInvalids, *invalid); #if !defined(DXD_STANDARD_IEEE) signal (SIGFPE, SIG_DFL); #endif error: /* Free locally allocated memory */ if (subData != NULL) { for (i = 0; i < numArgs; ++i) { DXFree (subData[i]); } DXFree ((Pointer) subData); } if (subInvalids != NULL) { for (i = 0; i < numArgs; ++i) { if (subInvalids[i]) { DXFreeInvalidComponentHandle(subInvalids[i]); } } DXFree ((Pointer) subInvalids); } return (status); } int _dxfComputeLookupFunction (char *name) { static struct { char *name; int code; } functs[] = { "select", OPER_PERIOD, "mod", OPER_MOD, "dot", OPER_DOT, "cross", OPER_CROSS, "sqrt", FUNC_sqrt, "pow", FUNC_pow, "sin", FUNC_sin, "cos", FUNC_cos, "tan", FUNC_tan, "ln", FUNC_ln, "log10", FUNC_log10, "min", FUNC_min, "max", FUNC_max, "floor", FUNC_floor, "ceil", FUNC_ceil, "trunc", FUNC_trunc, "rint", FUNC_rint, "exp", FUNC_exp, "tanh", FUNC_tanh, "sinh", FUNC_sinh, "cosh", FUNC_cosh, "acos", FUNC_acos, "asin", FUNC_asin, "atan", FUNC_atan, "atan2", FUNC_atan2, "mag", FUNC_mag, "norm", FUNC_norm, "abs", FUNC_abs, "int", FUNC_int, "float", FUNC_float, "real", FUNC_real, "imag", FUNC_imag, "complex", FUNC_complex, "imagi", FUNC_imagi, "imagj", FUNC_imagj, "imagk", FUNC_imagk, "quaternion", FUNC_quaternion, "sign", FUNC_sign, "qsin", FUNC_qsin, "qcos", FUNC_qcos, "char", FUNC_char, "byte", FUNC_char, "short", FUNC_short, "double", FUNC_double, "signed_int", FUNC_signed_int, "rank", FUNC_rank, "shape", FUNC_shape, "log", FUNC_ln, "and", FUNC_and, "or", FUNC_or, "xor", FUNC_xor, "not", FUNC_not, "random", FUNC_random, "arg", FUNC_arg, "invalid", FUNC_invalid, "ubyte", FUNC_char, "sbyte", FUNC_sbyte, "uint", FUNC_uint, "sint", FUNC_int, "ushort", FUNC_ushort, "sshort", FUNC_short, "strcmp", FUNC_strcmp, "stricmp", FUNC_stricmp, "strstr", FUNC_strstr, "stristr", FUNC_stristr, "strlen", FUNC_strlen }; int i; for (i = 0; i < sizeof (functs) / sizeof (functs[0]); ++i) if (strcmp (functs[i].name, name) == 0) return (functs[i].code); return (NT_ERROR); }