1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 #ifndef __COMPOPER_H_
12 #define __COMPOPER_H_
13 
14 #define MAX_INTYPES 4		/* the addition of any operator that requires
15 				 * more than MAX_INTYPES inputs types will
16 				 * require that this number be bumped.
17 				 */
18 typedef struct OperBinding OperBinding;
19 typedef int (*TypeCheckFunc)(PTreeNode *, ObjStruct *, OperBinding *);
20 struct OperBinding {
21     int numArgs;	/* -1 -> arbitrary, match with first arg. */
22     CompFuncV impl;
23     TypeCheckFunc typeCheck;
24     MetaType outType;
25     MetaType inTypes[MAX_INTYPES];
26 };
27 
28 typedef struct {
29     int op;
30     char *name;
31     int numBindings;
32     OperBinding *bindings;
33 } OperDesc;
34 
35 
36 /* Function calls recognised by this file */
37 #define FUNC_sqrt	(LAST_OPER+  1)
38 #define FUNC_pow	(LAST_OPER+  2)
39 #define FUNC_sin	(LAST_OPER+  3)
40 #define FUNC_cos	(LAST_OPER+  4)
41 #define FUNC_tan	(LAST_OPER+  5)
42 #define FUNC_ln		(LAST_OPER+  6)
43 #define FUNC_log10	(LAST_OPER+  7)
44 #define FUNC_min	(LAST_OPER+  8)
45 #define FUNC_max	(LAST_OPER+  9)
46 #define FUNC_floor	(LAST_OPER+ 10)
47 #define FUNC_ceil	(LAST_OPER+ 11)
48 #define FUNC_trunc	(LAST_OPER+ 12)
49 #define FUNC_rint	(LAST_OPER+ 13)
50 #define FUNC_exp	(LAST_OPER+ 14)
51 #define FUNC_tanh	(LAST_OPER+ 15)
52 #define FUNC_sinh	(LAST_OPER+ 16)
53 #define FUNC_cosh	(LAST_OPER+ 17)
54 #define FUNC_acos	(LAST_OPER+ 18)
55 #define FUNC_asin	(LAST_OPER+ 19)
56 #define FUNC_atan	(LAST_OPER+ 20)
57 #define FUNC_atan2	(LAST_OPER+ 21)
58 #define FUNC_mag	(LAST_OPER+ 22)
59 #define FUNC_norm	(LAST_OPER+ 23)
60 #define FUNC_abs	(LAST_OPER+ 24)
61 #define FUNC_int	(LAST_OPER+ 25)
62 #define FUNC_float	(LAST_OPER+ 26)
63 #define FUNC_real	(LAST_OPER+ 27)
64 #define FUNC_imag	(LAST_OPER+ 28)
65 #define FUNC_complex	(LAST_OPER+ 29)
66 #define FUNC_imagi	(LAST_OPER+ 30)
67 #define FUNC_imagj	(LAST_OPER+ 31)
68 #define FUNC_imagk	(LAST_OPER+ 32)
69 #define FUNC_quaternion	(LAST_OPER+ 33)
70 #define FUNC_sign	(LAST_OPER+ 34)
71 #define FUNC_qsin	(LAST_OPER+ 35)
72 #define FUNC_qcos	(LAST_OPER+ 36)
73 #define FUNC_char	(LAST_OPER+ 37)
74 #define FUNC_short	(LAST_OPER+ 38)
75 #define FUNC_double	(LAST_OPER+ 39)
76 #define FUNC_signed_int	(LAST_OPER+ 40)
77 #define FUNC_rank	(LAST_OPER+ 41)
78 #define FUNC_shape	(LAST_OPER+ 42)
79 #define FUNC_and	(LAST_OPER+ 43)
80 #define FUNC_or		(LAST_OPER+ 44)
81 #define FUNC_xor	(LAST_OPER+ 45)
82 #define FUNC_not	(LAST_OPER+ 46)
83 #define FUNC_random	(LAST_OPER+ 47)
84 #define FUNC_arg	(LAST_OPER+ 48)
85 #define FUNC_invalid	(LAST_OPER+ 49)
86 #define FUNC_sbyte	(LAST_OPER+ 50)
87 #define FUNC_uint	(LAST_OPER+ 51)
88 #define FUNC_ushort	(LAST_OPER+ 52)
89 #define FUNC_strcmp	(LAST_OPER+ 53)
90 #define FUNC_stricmp	(LAST_OPER+ 54)
91 #define FUNC_strlen	(LAST_OPER+ 57)
92 #define FUNC_strstr	(LAST_OPER+ 58)
93 #define FUNC_stristr	(LAST_OPER+ 59)
94 #define FUNC_finite	(LAST_OPER+ 60)
95 #define FUNC_isnan	(LAST_OPER+ 61)
96 
97 
98 typedef struct {
99     float realPart;
100     float iPart;
101     float jPart;
102     float kPart;
103 } quaternionFloat;
104 typedef struct {
105     int realPart;
106     int iPart;
107     int jPart;
108     int kPart;
109 } quaternionInt;
110 
111 typedef struct {
112     char realPart;
113     char imagPart;
114 } complexChar;
115 typedef struct {
116     short realPart;
117     short imagPart;
118 } complexShort;
119 typedef struct {
120     int realPart;
121     int imagPart;
122 } complexInt;
123 typedef struct {
124     float realPart;
125     float imagPart;
126 } complexFloat;
127 typedef struct {
128     double realPart;
129     double imagPart;
130 } complexDouble;
131 
132 #define REAL(x) ((x).realPart)
133 #define IMAG(x) ((x).imagPart)
134 #define IMAGI(x) ((x).iPart)
135 #define IMAGJ(x) ((x).jPart)
136 #define IMAGK(x) ((x).kPart)
137 
138 int
139 _dxfComputeCopy(
140     PTreeNode *pt,
141     ObjStruct *os,
142     int numInputs,
143     Pointer *inputs,
144     Pointer result,
145     InvalidComponentHandle *invalids,
146     InvalidComponentHandle outInvalid);
147 
148 /* A set of macros to build generic routines.  BINOP builds
149  * a routine called `name', that takes inputs of type `t0', and `t1', and
150  * returns an output of type `t1' after performing `op' on the inputs.
151  * Similarly is UNOP (unary operator).  Also, VBINOP (and the others)
152  * are define which * work on similarly shaped, non-scalar, inputs and
153  * output on an element by element basis.  These macros can be used for
154  * many of the given operators.
155  *
156  * Note that in each case, the size of an input array will be either
157  * 1 or the size of the output array.  If all input arrays are of size 1,
158  * then the size of the output array will also be 1.
159  */
160 #define BINOP(name, tr, t0, t1, op)		\
161 static int					\
162 name(						\
163     PTreeNode *pt, 				\
164     ObjStruct *os, 				\
165     int numInputs,				\
166     Pointer *inputs,				\
167     Pointer result,				\
168     InvalidComponentHandle *invalids,		\
169     InvalidComponentHandle outInvalid)		\
170 {						\
171     register tr *out = (tr *) result;		\
172     register t0 *in0 = (t0 *) inputs[0];	\
173     register t1 *in1 = (t1 *) inputs[1];	\
174     int nelts = pt->metaType.items;		\
175     int size0 = pt->args->metaType.items;	\
176     int size1 = pt->args->next->metaType.items;	\
177     int i;					\
178     int allValid = 				\
179 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
180 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
181 						\
182     if (size0 > 1 && size1 > 1)	{		\
183 	for (i = 0; i < nelts; ++i) {		\
184 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
185 		out[i] = in0[i] op in1[i];	\
186 	}					\
187     }						\
188     else if (size0 > 1) {			\
189 	for (i = 0; i < nelts; ++i) {		\
190 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
191 		out[i] = in0[i] op in1[0];	\
192 	}					\
193     }						\
194     else if (size1 > 1) {			\
195 	for (i = 0; i < nelts; ++i) {		\
196 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
197 		out[i] = in0[0] op in1[i];	\
198 	}					\
199     }						\
200     else {					\
201 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
202 	    out[0] = in0[0] op in1[0];		\
203     }						\
204     return (OK);				\
205 }
206 
207 #define UNOP(name, tr, t0, op)			\
208 static int					\
209 name(						\
210     PTreeNode *pt, 				\
211     ObjStruct *os, 				\
212     int numInputs,				\
213     Pointer *inputs,				\
214     Pointer result,				\
215     InvalidComponentHandle *invalids,		\
216     InvalidComponentHandle outInvalid)		\
217 {						\
218     register tr *out = (tr *) result;		\
219     register t0 *in0 = (t0 *) inputs[0];	\
220     int nelts = pt->metaType.items;		\
221     int i;					\
222     int allValid = 				\
223 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); \
224 						\
225     for (i = 0; i < nelts; ++i) {		\
226 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
227 	    out[i] = op in0[i];			\
228     }						\
229     return (OK);				\
230 }
231 
232 #define VBINOP(name, tr, t0, t1, op)		\
233 static int					\
234 name(						\
235     PTreeNode *pt, 				\
236     ObjStruct *os, 				\
237     int numInputs,				\
238     Pointer *inputs,				\
239     Pointer result,				\
240     InvalidComponentHandle *invalids,		\
241     InvalidComponentHandle outInvalid)		\
242 {						\
243     register tr *out = (tr *) result;		\
244     register t0 *in0 = (t0 *) inputs[0];	\
245     register t1 *in1 = (t1 *) inputs[1];	\
246     int nelts = pt->metaType.items;		\
247     int size0 = pt->args->metaType.items;	\
248     int size1 = pt->args->next->metaType.items;	\
249     int i, j;					\
250     int numBasic;				\
251     int allValid = 				\
252 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
253 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
254 						\
255     for (numBasic = 1, i = 0; 			\
256 	    i < pt->metaType.rank;		\
257 	    ++i)				\
258 	numBasic *= pt->metaType.shape[i];	\
259 						\
260     if (size0 > 1 && size1 > 1) {		\
261 	for (i = 0; i < nelts; ++i)		\
262 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
263 		for (j = 0; j < numBasic; ++j)	\
264 		    out[i*numBasic+j] = in0[i*numBasic+j] op in1[i*numBasic+j];\
265     }						\
266     else if (size0 > 1) {			\
267 	for (i = 0; i < nelts; ++i)		\
268 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
269 		for (j = 0; j < numBasic; ++j)	\
270 		    out[j + i * numBasic] = in0[j + i * numBasic] op in1[j]; \
271     }						\
272     else if (size1 > 1) {			\
273 	for (i = 0; i < nelts; ++i)		\
274 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
275 		for (j = 0; j < numBasic; ++j)	\
276 		    out[j + i * numBasic] = in0[j] op in1[j + i * numBasic]; \
277     }						\
278     else {					\
279 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
280 	    for (j = 0; j < numBasic; ++j)	\
281 		out[j] = in0[j] op in1[j];	\
282     }						\
283     return (OK);				\
284 }
285 
286 #define VSBINOP(name, tr, t0, t1, op)		\
287 static int					\
288 name(						\
289     PTreeNode *pt, 				\
290     ObjStruct *os, 				\
291     int numInputs,				\
292     Pointer *inputs,				\
293     Pointer result,				\
294     InvalidComponentHandle *invalids,		\
295     InvalidComponentHandle outInvalid)		\
296 {						\
297     register tr *out = (tr *) result;		\
298     register t0 *in0 = (t0 *) inputs[0];	\
299     register t1 *in1 = (t1 *) inputs[1];	\
300     int nelts = pt->metaType.items;		\
301     int size0 = pt->args->metaType.items;	\
302     int size1 = pt->args->next->metaType.items;	\
303     int i, j;					\
304     int numBasic;				\
305     int allValid = 				\
306 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
307 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
308 						\
309     for (numBasic = 1, i = 0; 			\
310 	    i < pt->metaType.rank;		\
311 	    ++i)				\
312 	numBasic *= pt->metaType.shape[i];	\
313 						\
314     if (size0 > 1 && size1 > 1) {	\
315 	for (i = 0; i < nelts; ++i)		\
316 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
317 		for (j = 0; j < numBasic; ++j)	\
318 		    out[i * numBasic + j] = in0[i * numBasic + j] op in1[i]; \
319     }						\
320     else if (size0 > 1) {		\
321 	for (i = 0; i < nelts; ++i)		\
322 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
323 		for (j = 0; j < numBasic; ++j)	\
324 		    out[i * numBasic + j] = in0[i * numBasic + j] op in1[0]; \
325     }						\
326     else if (size1 > 1) {		\
327 	for (i = 0; i < nelts; ++i)		\
328 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
329 		for (j = 0; j < numBasic; ++j)	\
330 		    out[i * numBasic + j] = in0[j] op in1[i]; \
331     }						\
332     else {					\
333 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
334 	    for (j = 0; j < numBasic; ++j)	\
335 		out[j] = in0[j] op in1[0];	\
336     }						\
337     return (OK);				\
338 }
339 
340 #define SVBINOP(name, tr, t0, t1, op)		\
341 static int					\
342 name(						\
343     PTreeNode *pt, 				\
344     ObjStruct *os, 				\
345     int numInputs,				\
346     Pointer *inputs,				\
347     Pointer result,				\
348     InvalidComponentHandle *invalids,		\
349     InvalidComponentHandle outInvalid)		\
350 {						\
351     register tr *out = (tr *) result;		\
352     register t0 *in0 = (t0 *) inputs[0];	\
353     register t1 *in1 = (t1 *) inputs[1];	\
354     int nelts = pt->metaType.items;		\
355     int size0 = pt->args->metaType.items;	\
356     int size1 = pt->args->next->metaType.items;	\
357     int i, j;					\
358     int numBasic;				\
359     int allValid = 				\
360 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
361 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
362 						\
363     for (numBasic = 1, i = 0; 			\
364 	    i < pt->metaType.rank;		\
365 	    ++i)				\
366 	numBasic *= pt->metaType.shape[i];	\
367 						\
368     if (size0 > 1 && size1 > 1) {		\
369 	for (i = 0; i < nelts; ++i)		\
370 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
371 		for (j = 0; j < numBasic; ++j)	\
372 		    out[i * numBasic + j] = in0[i] op in1[i * numBasic + j]; \
373     }						\
374     else if (size0 > 1) {			\
375 	for (i = 0; i < nelts; ++i)		\
376 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
377 		for (j = 0; j < numBasic; ++j)	\
378 		    out[i * numBasic + j] = in0[i] op in1[j]; \
379     }						\
380     else if (size1 > 1) {			\
381 	for (i = 0; i < nelts; ++i)		\
382 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
383 		for (j = 0; j < numBasic; ++j)	\
384 		    out[i * numBasic + j] = in0[0] op in1[i * numBasic + j]; \
385     }						\
386     else {					\
387 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
388 	    for (j = 0; j < numBasic; ++j)	\
389 		out[j] = in0[0] op in1[j];	\
390     }						\
391     return (OK);				\
392 }
393 
394 #define VBINOPRC(name, tr, t0, t1, op, range, msg)		\
395 static int					\
396 name(						\
397     PTreeNode *pt, 				\
398     ObjStruct *os, 				\
399     int numInputs,				\
400     Pointer *inputs,				\
401     Pointer result,				\
402     InvalidComponentHandle *invalids,		\
403     InvalidComponentHandle outInvalid)		\
404 {						\
405     register tr *out = (tr *) result;		\
406     register t0 *in0 = (t0 *) inputs[0];	\
407     register t1 *in1 = (t1 *) inputs[1];	\
408     int nelts = pt->metaType.items;		\
409     int size0 = pt->args->metaType.items;	\
410     int size1 = pt->args->next->metaType.items;	\
411     int i, j;					\
412     int numBasic;				\
413     int allValid = 				\
414 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
415 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
416 						\
417     for (numBasic = 1, i = 0; 			\
418 	    i < pt->metaType.rank;		\
419 	    ++i)				\
420 	numBasic *= pt->metaType.shape[i];	\
421 						\
422     if (size0 > 1 && size1 > 1) {		\
423 	for (i = 0; i < nelts; ++i)	\
424 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
425 		for (j = 0; j < numBasic; ++j)	\
426 		    if (!range(in0[i*numBasic+j], in1[i*numBasic+j]))	\
427 		    {				\
428 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i*numBasic+j], in1[i*numBasic+j]); \
429 			return ERROR;		\
430 		    }				\
431     }						\
432     else if (size0 > 1) {			\
433 	for (i = 0; i < nelts; ++i)		\
434 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
435 		for (j = 0; j < numBasic; ++j)	\
436 		    if (!range(in0[j + i * numBasic], in1[j])) \
437 		    {				\
438 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[j + i * numBasic], in1[j]); \
439 			return ERROR;		\
440 		    }				\
441     }						\
442     else if (size1 > 1) {			\
443 	for (i = 0; i < nelts; ++i)		\
444 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
445 		for (j = 0; j < numBasic; ++j)	\
446 		    if (!range(in0[j], in1[j + i * numBasic])) \
447 		    {				\
448 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[j], in1[j + i * numBasic]); \
449 			return ERROR;		\
450 		    }				\
451     }						\
452     else {					\
453 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
454 	    for (j = 0; j < numBasic; ++j)	\
455 		if (!range(in0[j], in1[j]))	\
456 		{				\
457 		    DXSetError(ERROR_BAD_PARAMETER, msg, 0, in0[j], in1[j]); \
458 		    return ERROR;		\
459 		}				\
460     }						\
461 						\
462     if (size0 > 1 && size1 > 1) {		\
463 	for (i = 0; i < nelts; ++i)	\
464 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
465 		for (j = 0; j < numBasic; ++j)	\
466 		    out[i*numBasic+j] = in0[i*numBasic+j] op in1[i*numBasic+j];\
467     }						\
468     else if (size0 > 1) {			\
469 	for (i = 0; i < nelts; ++i)		\
470 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
471 		for (j = 0; j < numBasic; ++j)	\
472 		    out[j + i * numBasic] = in0[j + i * numBasic] op in1[j]; \
473     }						\
474     else if (size1 > 1) {			\
475 	for (i = 0; i < nelts; ++i)		\
476 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
477 		for (j = 0; j < numBasic; ++j)	\
478 		    out[j + i * numBasic] = in0[j] op in1[j + i * numBasic]; \
479     }						\
480     else {					\
481 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
482 	    for (j = 0; j < numBasic; ++j)		\
483 		out[j] = in0[j] op in1[j];		\
484     }						\
485     return (OK);				\
486 }
487 
488 #define VSBINOPRC(name, tr, t0, t1, op, range, msg)		\
489 static int					\
490 name(						\
491     PTreeNode *pt, 				\
492     ObjStruct *os, 				\
493     int numInputs,				\
494     Pointer *inputs,				\
495     Pointer result,				\
496     InvalidComponentHandle *invalids,		\
497     InvalidComponentHandle outInvalid)		\
498 {						\
499     register tr *out = (tr *) result;		\
500     register t0 *in0 = (t0 *) inputs[0];	\
501     register t1 *in1 = (t1 *) inputs[1];	\
502     int nelts = pt->metaType.items;		\
503     int size0 = pt->args->metaType.items;	\
504     int size1 = pt->args->next->metaType.items;	\
505     int i, j;					\
506     int numBasic;				\
507     int allValid = 				\
508 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
509 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
510 						\
511     for (numBasic = 1, i = 0; 			\
512 	    i < pt->metaType.rank;		\
513 	    ++i)				\
514 	numBasic *= pt->metaType.shape[i];	\
515 						\
516     if (size0 > 1 && size1 > 1) {	\
517 	for (i = 0; i < nelts; ++i)		\
518 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
519 		for (j = 0; j < numBasic; ++j)	\
520 		    if (!range(in0[i * numBasic + j], in1[i]))	\
521 		    {					\
522 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i * numBasic + j], in1[i]); \
523 			return ERROR;			\
524 		    }					\
525     }						\
526     else if (size0 > 1) {		\
527 	for (i = 0; i < nelts; ++i)		\
528 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
529 		for (j = 0; j < numBasic; ++j)	\
530 		    if (!range(in0[i * numBasic + j], in1[0]))	\
531 		    {					\
532 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i * numBasic + j], in1[0]); \
533 			return ERROR;			\
534 		    }					\
535     }						\
536     else if (size1 > 1) {		\
537 	for (i = 0; i < nelts; ++i)		\
538 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
539 		for (j = 0; j < numBasic; ++j)	\
540 		    if (!range(in0[j], in1[i]))	\
541 		    {					\
542 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[j], in1[i]); \
543 			return ERROR;			\
544 		    }					\
545     }						\
546     else {					\
547 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
548 	    for (j = 0; j < numBasic; ++j)		\
549 		if (!range(in0[j], in1[0]))		\
550 		{					\
551 		    DXSetError(ERROR_BAD_PARAMETER, msg, 0, in0[j], in1[0]); \
552 		    return ERROR;			\
553 		}					\
554     }						\
555 						\
556     if (size0 > 1 && size1 > 1) {	\
557 	for (i = 0; i < nelts; ++i)		\
558 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
559 		for (j = 0; j < numBasic; ++j)	\
560 		    out[i * numBasic + j] = in0[i * numBasic + j] op in1[i]; \
561     }						\
562     else if (size0 > 1) {		\
563 	for (i = 0; i < nelts; ++i)		\
564 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
565 		for (j = 0; j < numBasic; ++j)	\
566 		    out[i * numBasic + j] = in0[i * numBasic + j] op in1[0]; \
567     }						\
568     else if (size1 > 1) {		\
569 	for (i = 0; i < nelts; ++i)		\
570 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
571 		for (j = 0; j < numBasic; ++j)	\
572 		    out[i * numBasic + j] = in0[j] op in1[i]; \
573     }						\
574     else {					\
575 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
576 	    for (j = 0; j < numBasic; ++j)		\
577 		out[j] = in0[j] op in1[0];		\
578     }						\
579     return (OK);				\
580 }
581 
582 #define SVBINOPRC(name, tr, t0, t1, op, range, msg)		\
583 static int					\
584 name(						\
585     PTreeNode *pt, 				\
586     ObjStruct *os, 				\
587     int numInputs,				\
588     Pointer *inputs,				\
589     Pointer result,				\
590     InvalidComponentHandle *invalids,		\
591     InvalidComponentHandle outInvalid)		\
592 {						\
593     register tr *out = (tr *) result;		\
594     register t0 *in0 = (t0 *) inputs[0];	\
595     register t1 *in1 = (t1 *) inputs[1];	\
596     int nelts = pt->metaType.items;		\
597     int size0 = pt->args->metaType.items;	\
598     int size1 = pt->args->next->metaType.items;	\
599     int i, j;					\
600     int numBasic;				\
601     int allValid = 				\
602 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
603 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
604 						\
605     for (numBasic = 1, i = 0; 			\
606 	    i < pt->metaType.rank;		\
607 	    ++i)				\
608 	numBasic *= pt->metaType.shape[i];	\
609 						\
610     if (size0 > 1 && size1 > 1) {		\
611 	for (i = 0; i < nelts; ++i)		\
612 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
613 		for (j = 0; j < numBasic; ++j)	\
614 		    if (!range(in0[i], in1[i * numBasic + j]))	\
615 		    {					\
616 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i], in1[i * numBasic + j]); \
617 			return ERROR;			\
618 		    }					\
619     }						\
620     else if (size0 > 1) {			\
621 	for (i = 0; i < nelts; ++i)		\
622 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
623 		for (j = 0; j < numBasic; ++j)	\
624 		    if (!range(in0[i], in1[j]))	\
625 		    {					\
626 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i], in1[j]); \
627 			return ERROR;			\
628 		    }					\
629     }						\
630     else if (size1 > 1) {			\
631 	for (i = 0; i < nelts; ++i)		\
632 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
633 		for (j = 0; j < numBasic; ++j)	\
634 		    if (!range(in0[0], in1[i * numBasic + j]))	\
635 		    {					\
636 			DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[0], in1[i * numBasic + j]); \
637 			return ERROR;			\
638 		    }					\
639     }						\
640     else {					\
641 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
642 	    for (j = 0; j < numBasic; ++j)		\
643 		if (!range(in0[0], in1[j]))		\
644 		{					\
645 		    DXSetError(ERROR_BAD_PARAMETER, msg, 0, in0[0], in1[j]); \
646 		    return ERROR;			\
647 		}					\
648     }						\
649 						\
650     if (size0 > 1 && size1 > 1) {		\
651 	for (i = 0; i < nelts; ++i)		\
652 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
653 		for (j = 0; j < numBasic; ++j)	\
654 		    out[i * numBasic + j] = in0[i] op in1[i * numBasic + j]; \
655     }						\
656     else if (size0 > 1) {			\
657 	for (i = 0; i < nelts; ++i)		\
658 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
659 		for (j = 0; j < numBasic; ++j)	\
660 		    out[i * numBasic + j] = in0[i] op in1[j]; \
661     }						\
662     else if (size1 > 1) {			\
663 	for (i = 0; i < nelts; ++i)		\
664 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
665 		for (j = 0; j < numBasic; ++j)	\
666 		    out[i * numBasic + j] = in0[0] op in1[i * numBasic + j]; \
667     }						\
668     else {					\
669 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
670 	    for (j = 0; j < numBasic; ++j)		\
671 		out[j] = in0[0] op in1[j];		\
672     }						\
673     return (OK);				\
674 }
675 
676 #define VUNOP(name, tr, t0, op)			\
677 static int					\
678 name(						\
679     PTreeNode *pt, 				\
680     ObjStruct *os, 				\
681     int numInputs,				\
682     Pointer *inputs,				\
683     Pointer result,				\
684     InvalidComponentHandle *invalids,		\
685     InvalidComponentHandle outInvalid)		\
686 {						\
687     register tr *out = (tr *) result;		\
688     register t0 *in0 = (t0 *) inputs[0];	\
689     int i,j;					\
690     int numBasic;				\
691     int items;					\
692     int allValid = 				\
693 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); \
694 						\
695     for (numBasic = 1, i = 0; 			\
696 	    i < pt->metaType.rank;		\
697 	    ++i)				\
698 	numBasic *= pt->metaType.shape[i];	\
699 						\
700     items = pt->metaType.items;			\
701     for (i = 0; i < items; ++i) {		\
702 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
703 	for (j = 0; j < numBasic; ++j) {	\
704 	    out[i*numBasic+j] = op in0[i*numBasic+j];	\
705 	}					\
706     }						\
707     return (OK);				\
708 }
709 
710 #define VFUNC2(name, tr, t0, t1, op)		\
711 static int					\
712 name(						\
713     PTreeNode *pt, 				\
714     ObjStruct *os, 				\
715     int numInputs,				\
716     Pointer *inputs,				\
717     Pointer result,				\
718     InvalidComponentHandle *invalids,		\
719     InvalidComponentHandle outInvalid)		\
720 {						\
721     register tr *out = (tr *) result;		\
722     register t0 *in0 = (t0 *) inputs[0];	\
723     register t1 *in1 = (t1 *) inputs[1];	\
724     int nelts = pt->metaType.items;		\
725     int size0 = pt->args->metaType.items;	\
726     int size1 = pt->args->next->metaType.items;	\
727     int i, j;					\
728     int numBasic;				\
729     int allValid = 				\
730 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
731 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
732 						\
733     for (numBasic = 1, i = 0; 			\
734 	    i < pt->metaType.rank;		\
735 	    ++i)				\
736 	numBasic *= pt->metaType.shape[i];	\
737 						\
738     if (size0 > 1 && size1 > 1) {	\
739 	for (i = 0; i < nelts; ++i)		\
740 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
741 		for (j = 0; j < numBasic; ++j)	\
742 		    out[i*numBasic+j] = op(in0[i*numBasic+j], in1[i*numBasic+j]);\
743     }						\
744     else if (size0 > 1) {		\
745 	for (i = 0; i < nelts; ++i)		\
746 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
747 		for (j = 0; j < numBasic; ++j)	\
748 		    out[j + i * numBasic] = op(in0[j + i * numBasic], in1[j]); \
749     }						\
750     else if (size1 > 1) {		\
751 	for (i = 0; i < nelts; ++i)		\
752 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
753 		for (j = 0; j < numBasic; ++j)	\
754 		    out[j + i * numBasic] = op(in0[j], in1[j + i * numBasic]); \
755     }						\
756     else {					\
757 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
758 	    for (j = 0; j < numBasic; ++j)		\
759 		out[j] = op(in0[j], in1[j]);	\
760     }						\
761     return (OK);				\
762 }
763 
764 #define VSFUNC2(name, tr, t0, t1, op)		\
765 static int					\
766 name(						\
767     PTreeNode *pt, 				\
768     ObjStruct *os, 				\
769     int numInputs,				\
770     Pointer *inputs,				\
771     Pointer result,				\
772     InvalidComponentHandle *invalids,		\
773     InvalidComponentHandle outInvalid)		\
774 {						\
775     register tr *out = (tr *) result;		\
776     register t0 *in0 = (t0 *) inputs[0];	\
777     register t1 *in1 = (t1 *) inputs[1];	\
778     int nelts = pt->metaType.items;		\
779     int size0 = pt->args->metaType.items;	\
780     int size1 = pt->args->next->metaType.items;	\
781     int i, j;					\
782     int numBasic;				\
783     int allValid = 				\
784 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
785 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
786 						\
787     for (numBasic = 1, i = 0; 			\
788 	    i < pt->metaType.rank;		\
789 	    ++i)				\
790 	numBasic *= pt->metaType.shape[i];	\
791 						\
792     if (size0 > 1 && size1 > 1) {		\
793 	for (i = 0; i < nelts; ++i)		\
794 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
795 		for (j = 0; j < numBasic; ++j)	\
796 		    out[i * numBasic + j] = op(in0[i * numBasic + j], in1[i]); \
797     }						\
798     else if (size0 > 1) {			\
799 	for (i = 0; i < nelts; ++i)		\
800 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
801 		for (j = 0; j < numBasic; ++j)	\
802 		    out[i * numBasic + j] = op(in0[i * numBasic + j], in1[0]); \
803     }						\
804     else if (size1 > 1) {			\
805 	for (j = 0; j < numBasic; ++j)		\
806 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
807 		for (i = 0; i < nelts; ++i)		\
808 		    out[i * numBasic + j] = op(in0[j], in1[i]); \
809     }						\
810     else {					\
811 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
812 	    for (j = 0; j < numBasic; ++j)		\
813 		out[j] = op(in0[j], in1[0]);	\
814     }						\
815     return (OK);				\
816 }
817 
818 #define SVFUNC2(name, tr, t0, t1, op)		\
819 static int					\
820 name(						\
821     PTreeNode *pt, 				\
822     ObjStruct *os, 				\
823     int numInputs,				\
824     Pointer *inputs,				\
825     Pointer result,				\
826     InvalidComponentHandle *invalids,		\
827     InvalidComponentHandle outInvalid)		\
828 {						\
829     register tr *out = (tr *) result;		\
830     register t0 *in0 = (t0 *) inputs[0];	\
831     register t1 *in1 = (t1 *) inputs[1];	\
832     int nelts = pt->metaType.items;		\
833     int size0 = pt->args->metaType.items;	\
834     int size1 = pt->args->next->metaType.items;	\
835     int i, j;					\
836     int numBasic;				\
837     int allValid = 				\
838 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
839 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
840 						\
841     for (numBasic = 1, i = 0; 			\
842 	    i < pt->metaType.rank;		\
843 	    ++i)				\
844 	numBasic *= pt->metaType.shape[i];	\
845 						\
846     if (size0 > 1 && size1 > 1) {		\
847 	for (i = 0; i < nelts; ++i)		\
848 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
849 		for (j = 0; j < numBasic; ++j)	\
850 		    out[i * numBasic + j] = op(in0[i], in1[i * numBasic + j]); \
851     }						\
852     else if (size0 > 1) {			\
853 	for (i = 0; i < nelts; ++i)		\
854 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
855 		for (j = 0; j < numBasic; ++j)	\
856 		    out[i * numBasic + j] = op(in0[i], in1[j]); \
857     }						\
858     else if (size1 > 1) {			\
859 	for (j = 0; j < numBasic; ++j)		\
860 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
861 		for (i = 0; i < nelts; ++i)		\
862 		    out[i * numBasic + j] = op(in0[0], in1[i * numBasic + j]); \
863     }						\
864     else {					\
865 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
866 	    for (j = 0; j < numBasic; ++j)		\
867 		out[j] = op(in0[0], in1[j]);	\
868     }						\
869 						\
870     return (OK);				\
871 }
872 
873 
874 #define VFUNC2RC(name, tr, t0, t1, op, range, msg)	\
875 static int					\
876 name(						\
877     PTreeNode *pt, 				\
878     ObjStruct *os, 				\
879     int numInputs,				\
880     Pointer *inputs,				\
881     Pointer result,				\
882     InvalidComponentHandle *invalids,		\
883     InvalidComponentHandle outInvalid)		\
884 {						\
885     register tr *out = (tr *) result;		\
886     register t0 *in0 = (t0 *) inputs[0];	\
887     register t1 *in1 = (t1 *) inputs[1];	\
888     int nelts = pt->metaType.items;		\
889     int size0 = pt->args->metaType.items;	\
890     int size1 = pt->args->next->metaType.items;	\
891     int i, j;					\
892     int numBasic;				\
893     int allValid = 				\
894 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
895 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
896 						\
897     for (numBasic = 1, i = 0; 			\
898 	    i < pt->metaType.rank;		\
899 	    ++i)				\
900 	numBasic *= pt->metaType.shape[i];	\
901 						\
902     if (size0 > 1 && size1 > 1) {	\
903 	for (i = 0; i < nelts; ++i)	\
904 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
905 		for (j = 0; j < numBasic; ++j)	\
906 		    if (!range(in0[i*numBasic+j], in1[i*numBasic+j])) \
907 		    {					\
908 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[i*numBasic+j], in1[i*numBasic+j]);\
909 			return (ERROR);			\
910 		    }					\
911     }						\
912     else if (size0 > 1) {		\
913 	for (i = 0; i < nelts; ++i)		\
914 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
915 		for (j = 0; j < numBasic; ++j)	\
916 		    if (!range(in0[j+i*numBasic], in1[j]))		\
917 		    {					\
918 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[j+i*numBasic], in1[j]);\
919 			return (ERROR);			\
920 		    }					\
921     }						\
922     else if (size1 > 1) {		\
923 	for (i = 0; i < nelts; ++i)		\
924 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
925 		for (j = 0; j < numBasic; ++j)	\
926 		    if (!range(in0[j], in1[j+i*numBasic]))		\
927 		    {					\
928 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[j], in1[j+i*numBasic]);\
929 			return (ERROR);			\
930 		    }					\
931     }						\
932     else {					\
933 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
934 	    for (j = 0; j < numBasic; ++j)		\
935 		if (!range(in0[j], in1[j]))		\
936 		{					\
937 		    DXSetError(ERROR_BAD_PARAMETER,msg,0, in0[j], in1[j]);\
938 		    return (ERROR);			\
939 		}					\
940     }						\
941 						\
942     if (size0 > 1 && size1 > 1) {	\
943 	for (i = 0; i < nelts; ++i)	\
944 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
945 		for (j = 0; j < numBasic; ++j)	\
946 		    out[i*numBasic+j] = op(in0[i*numBasic+j], in1[i*numBasic+j]);\
947     }						\
948     else if (size0 > 1) {		\
949 	for (i = 0; i < nelts; ++i)		\
950 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
951 		for (j = 0; j < numBasic; ++j)	\
952 		    out[j + i * numBasic] = op(in0[j + i * numBasic], in1[j]); \
953     }						\
954     else if (size1 > 1) {		\
955 	for (i = 0; i < nelts; ++i)		\
956 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
957 		for (j = 0; j < numBasic; ++j)	\
958 		    out[j + i * numBasic] = op(in0[j], in1[j + i * numBasic]); \
959     }						\
960     else {					\
961 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
962 	    for (j = 0; j < numBasic; ++j)		\
963 		out[j] = op(in0[j], in1[j]);	\
964     }						\
965     return (OK);				\
966 }
967 
968 #define VSFUNC2RC(name, tr, t0, t1, op, range,msg)	\
969 static int					\
970 name(						\
971     PTreeNode *pt, 				\
972     ObjStruct *os, 				\
973     int numInputs,				\
974     Pointer *inputs,				\
975     Pointer result,				\
976     InvalidComponentHandle *invalids,		\
977     InvalidComponentHandle outInvalid)		\
978 {						\
979     register tr *out = (tr *) result;		\
980     register t0 *in0 = (t0 *) inputs[0];	\
981     register t1 *in1 = (t1 *) inputs[1];	\
982     int nelts = pt->metaType.items;		\
983     int size0 = pt->args->metaType.items;	\
984     int size1 = pt->args->next->metaType.items;	\
985     int i, j;					\
986     int numBasic;				\
987     int allValid = 				\
988 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
989 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
990 						\
991     for (numBasic = 1, i = 0; 			\
992 	    i < pt->metaType.rank;		\
993 	    ++i)				\
994 	numBasic *= pt->metaType.shape[i];	\
995 						\
996     if (size0 > 1 && size1 > 1) {		\
997 	for (i = 0; i < nelts; ++i)		\
998 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
999 		for (j = 0; j < numBasic; ++j)	\
1000 		    if (!range(in0[i*numBasic+j], in1[i]))		\
1001 		    {					\
1002 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[i*numBasic+j], in1[i]);\
1003 			return (ERROR);			\
1004 		    }					\
1005     }						\
1006     else if (size0 > 1) {			\
1007 	for (i = 0; i < nelts; ++i)		\
1008 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
1009 		for (j = 0; j < numBasic; ++j)	\
1010 		    if (!range(in0[i * numBasic + j], in1[0]))		\
1011 		    {					\
1012 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[i * numBasic + j], in1[0]);\
1013 			return (ERROR);			\
1014 		    }					\
1015     }						\
1016     else if (size1 > 1) {			\
1017 	for (i = 0; i < nelts; ++i)		\
1018 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
1019 		for (j = 0; j < numBasic; ++j)		\
1020 		    if (!range(in0[j], in1[i]))		\
1021 		    {					\
1022 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[j], in1[i]);\
1023 			return (ERROR);			\
1024 		    }					\
1025     }						\
1026     else {					\
1027 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
1028 	    for (j = 0; j < numBasic; ++j)		\
1029 		if (!range(in0[j], in1[0]))		\
1030 		{					\
1031 		    DXSetError(ERROR_BAD_PARAMETER,msg,0, in0[j], in1[0]);\
1032 		    return (ERROR);			\
1033 		}					\
1034     }						\
1035 						\
1036     if (size0 > 1 && size1 > 1) {		\
1037 	for (i = 0; i < nelts; ++i)		\
1038 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
1039 		for (j = 0; j < numBasic; ++j)	\
1040 		    out[i * numBasic + j] = op(in0[i * numBasic + j], in1[i]); \
1041     }						\
1042     else if (size0 > 1) {			\
1043 	for (i = 0; i < nelts; ++i)		\
1044 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
1045 		for (j = 0; j < numBasic; ++j)	\
1046 		    out[i * numBasic + j] = op(in0[i * numBasic + j], in1[0]); \
1047     }						\
1048     else if (size1 > 1) {			\
1049 	for (i = 0; i < nelts; ++i)		\
1050 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
1051 		for (j = 0; j < numBasic; ++j)		\
1052 		    out[i * numBasic + j] = op(in0[j], in1[i]); \
1053     }						\
1054     else {					\
1055 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
1056 	    for (j = 0; j < numBasic; ++j)		\
1057 		out[j] = op(in0[j], in1[0]);	\
1058     }						\
1059     return (OK);				\
1060 }
1061 
1062 #define SVFUNC2RC(name, tr, t0, t1, op, range, msg)	\
1063 static int					\
1064 name(						\
1065     PTreeNode *pt, 				\
1066     ObjStruct *os, 				\
1067     int numInputs,				\
1068     Pointer *inputs,				\
1069     Pointer result,				\
1070     InvalidComponentHandle *invalids,		\
1071     InvalidComponentHandle outInvalid)		\
1072 {						\
1073     register tr *out = (tr *) result;		\
1074     register t0 *in0 = (t0 *) inputs[0];	\
1075     register t1 *in1 = (t1 *) inputs[1];	\
1076     int nelts = pt->metaType.items;		\
1077     int size0 = pt->args->metaType.items;	\
1078     int size1 = pt->args->next->metaType.items;	\
1079     int i, j;					\
1080     int numBasic;				\
1081     int allValid = 				\
1082 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
1083 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
1084 						\
1085     for (numBasic = 1, i = 0; 			\
1086 	    i < pt->metaType.rank;		\
1087 	    ++i)				\
1088 	numBasic *= pt->metaType.shape[i];	\
1089 						\
1090     if (size0 > 1 && size1 > 1) {		\
1091 	for (i = 0; i < nelts; ++i)		\
1092 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
1093 		for (j = 0; j < numBasic; ++j)	\
1094 		    if (!range(in0[i], in1[i * numBasic + j]))		\
1095 		    {					\
1096 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[i], in1[i * numBasic + j]);\
1097 			return (ERROR);			\
1098 		    }					\
1099     }						\
1100     else if (size0 > 1) {			\
1101 	for (i = 0; i < nelts; ++i)		\
1102 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
1103 		for (j = 0; j < numBasic; ++j)	\
1104 		    if (!range(in0[i], in1[j]))		\
1105 		    {					\
1106 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[i], in1[j]);\
1107 			return (ERROR);			\
1108 		    }					\
1109     }						\
1110     else if (size1 > 1) {			\
1111 	for (i = 0; i < nelts; ++i)		\
1112 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
1113 		for (j = 0; j < numBasic; ++j)		\
1114 		    if (!range(in0[0], in1[i * numBasic + j]))		\
1115 		    {					\
1116 			DXSetError(ERROR_BAD_PARAMETER,msg,i, in0[0], in1[i * numBasic + j]);\
1117 			return (ERROR);			\
1118 		    }					\
1119     }						\
1120     else {					\
1121 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], i)) \
1122 	    for (j = 0; j < numBasic; ++j)		\
1123 		if (!range(in0[0], in1[j]))		\
1124 		{					\
1125 		    DXSetError(ERROR_BAD_PARAMETER,msg,0, in0[0], in1[j]);\
1126 		    return (ERROR);			\
1127 		}					\
1128     }						\
1129 						\
1130     if (size0 > 1 && size1 > 1) {		\
1131 	for (i = 0; i < nelts; ++i)		\
1132 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], i)) \
1133 		for (j = 0; j < numBasic; ++j)	\
1134 		    out[i * numBasic + j] = op(in0[i], in1[i * numBasic + j]); \
1135     }						\
1136     else if (size0 > 1) {			\
1137 	for (i = 0; i < nelts; ++i)		\
1138 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], i, invalids[1], 0)) \
1139 		for (j = 0; j < numBasic; ++j)	\
1140 		    out[i * numBasic + j] = op(in0[i], in1[j]); \
1141     }						\
1142     else if (size1 > 1) {			\
1143 	for (i = 0; i < nelts; ++i)		\
1144 	    if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], 0, invalids[1], i)) \
1145 		for (j = 0; j < numBasic; ++j)		\
1146 		    out[i * numBasic + j] = op(in0[0], in1[i * numBasic + j]); \
1147     }						\
1148     else {					\
1149 	if (allValid || _dxfComputeInvalidOr(outInvalid, 0, invalids[0], 0, invalids[1], 0)) \
1150 	    for (j = 0; j < numBasic; ++j)		\
1151 		out[j] = op(in0[0], in1[j]);	\
1152     }						\
1153 						\
1154     return (OK);				\
1155 }
1156 
1157 #define VFUNC1(name, tr, t0, op)		\
1158 static int					\
1159 name(						\
1160     PTreeNode *pt, 				\
1161     ObjStruct *os, 				\
1162     int numInputs,				\
1163     Pointer *inputs,				\
1164     Pointer result,				\
1165     InvalidComponentHandle *invalids,		\
1166     InvalidComponentHandle outInvalid)		\
1167 {						\
1168     register tr *out = (tr *) result;		\
1169     register t0 *in0 = (t0 *) inputs[0];	\
1170     int i,j;					\
1171     int numBasic, items;			\
1172     int allValid = 				\
1173 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); \
1174 						\
1175     for (numBasic = 1, i = 0; 			\
1176 	    i < pt->metaType.rank;		\
1177 	    ++i)				\
1178 	numBasic *= pt->metaType.shape[i];	\
1179     numBasic *= DXCategorySize(pt->metaType.category); \
1180     items = pt->metaType.items;			\
1181     for (i = 0; i < items; ++i)			\
1182 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
1183 	    for (j = 0; j < numBasic; ++j)	\
1184 		out[i*numBasic+j] = op (in0[i*numBasic+j]);		\
1185     return (OK);				\
1186 }
1187 
1188 #define VFUNC1RC(name, tr, t0, op, range, msg)	\
1189 static int					\
1190 name(						\
1191     PTreeNode *pt, 				\
1192     ObjStruct *os, 				\
1193     int numInputs,				\
1194     Pointer *inputs,				\
1195     Pointer result,				\
1196     InvalidComponentHandle *invalids,		\
1197     InvalidComponentHandle outInvalid)		\
1198 {						\
1199     register tr *out = (tr *) result;		\
1200     register t0 *in0 = (t0 *) inputs[0];	\
1201     int i, j;					\
1202     int numBasic, items;			\
1203     int allValid = 				\
1204 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); \
1205 						\
1206     for (numBasic = 1, i = 0; 			\
1207 	    i < pt->metaType.rank;		\
1208 	    ++i)				\
1209 	numBasic *= pt->metaType.shape[i];	\
1210     numBasic *= DXCategorySize(pt->metaType.category); \
1211     items = pt->metaType.items;			\
1212     for (i = 0; i < items; ++i) {		\
1213 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
1214 	    for (j = 0; j < numBasic; ++j) {	\
1215 		if (!range(in0[i*numBasic+j]))	\
1216 		{				\
1217 		    DXSetError(ERROR_BAD_PARAMETER, msg, i, in0[i*numBasic+j]);\
1218 		    return(ERROR);		\
1219 		}				\
1220 	    }					\
1221     }						\
1222     for (i = 0; i < items; ++i)			\
1223 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
1224 	    for (j = 0; j < numBasic; ++j)	\
1225 		out[i*numBasic+j] = op (in0[i*numBasic+j]);		\
1226     return (OK);				\
1227 }
1228 
1229 
1230 #define VCATFUNC1(name, tr, t0, op)		\
1231 static int					\
1232 name(						\
1233     PTreeNode *pt, 				\
1234     ObjStruct *os, 				\
1235     int numInputs,				\
1236     Pointer *inputs,				\
1237     Pointer result,				\
1238     InvalidComponentHandle *invalids,		\
1239     InvalidComponentHandle outInvalid)		\
1240 {						\
1241     register tr *out = (tr *) result;		\
1242     register t0 *in0 = (t0 *) inputs[0];	\
1243     int i, j;					\
1244     int numBasic, items;			\
1245     int allValid = 				\
1246 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0); \
1247 						\
1248     for (numBasic = 1, i = 0; 			\
1249 	    i < pt->metaType.rank;		\
1250 	    ++i)				\
1251 	numBasic *= pt->metaType.shape[i];	\
1252 						\
1253     numBasic *= DXCategorySize(pt->metaType.category); \
1254     items = pt->metaType.items;			\
1255     for (i = 0; i < items; ++i)			\
1256 	if (allValid || _dxfComputeInvalidOne(outInvalid, i, invalids[0], i)) \
1257 	    for (j = 0; j < numBasic; ++j)		\
1258 		out[i*numBasic+j] = op (in0[i*numBasic+j]);		\
1259     return (OK);				\
1260 }
1261 
1262 #define VCMP(name, tr, t0, t1, op, conjunction)		\
1263 static int						\
1264 name(							\
1265     PTreeNode *pt, 					\
1266     ObjStruct *os, 					\
1267     int numInputs,					\
1268     Pointer *inputs,					\
1269     Pointer result,					\
1270     InvalidComponentHandle *invalids,			\
1271     InvalidComponentHandle outInvalid)			\
1272 {							\
1273     register int *out = (tr *) result;			\
1274 							\
1275     int size0 = pt->args->metaType.items;		\
1276     int size1 = pt->args->next->metaType.items;		\
1277     int i, j, k, l;					\
1278     int numBasic;					\
1279     int size;						\
1280     int items;						\
1281     int allValid = 				\
1282 	(invalids[0] == NULL || DXGetInvalidCount(invalids[0]) == 0) && \
1283 	(invalids[1] == NULL || DXGetInvalidCount(invalids[1]) == 0);	\
1284 							\
1285     for (numBasic = 1, i = 0; i < pt->args->metaType.rank; ++i) {	\
1286 	numBasic *= pt->args->metaType.shape[i];		\
1287     }							\
1288     size = DXCategorySize (pt->args->metaType.category) *	\
1289 	   numBasic;					\
1290 							\
1291     items = pt->metaType.items;				\
1292     for (i = j = k = 0;					\
1293 	    i < items;					\
1294 	    ++i) {					\
1295 	if (allValid || _dxfComputeInvalidOr(outInvalid, i, invalids[0], j, invalids[1], k)) {	\
1296 	    out[i] = (*(((t0 *)inputs[0]) + j * size) op \
1297 		 *(((t1 *)inputs[1]) + k * size));  \
1298 	    for (l = 1; l < size; ++l)					\
1299 		out[i] = out[i] conjunction		\
1300 		    (*(((t0 *)inputs[0]) + j * size + l) op \
1301 		     *(((t1 *)inputs[1]) + k * size + l));  \
1302 	}						\
1303 	++j, ++k;					\
1304 	if (j >= size0) j = 0;				\
1305 	if (k >= size1) k = 0;				\
1306     }							\
1307     return (OK);					\
1308 }
1309 
1310 #define VMULTIOP(name,tr,t,op,init)			\
1311 static int						\
1312 name(							\
1313     PTreeNode *pt, 					\
1314     ObjStruct *os, 					\
1315     int numInputs,					\
1316     Pointer *inputs,					\
1317     Pointer result,					\
1318     InvalidComponentHandle *invalids,			\
1319     InvalidComponentHandle outInvalid)			\
1320 {							\
1321     register tr *out = (tr *) result;			\
1322     register t *in;					\
1323     PTreeNode *subTree;					\
1324     int size0;						\
1325     int i, j, arg;					\
1326     int anyValid;					\
1327     int items = pt->metaType.items;			\
1328     int *allValid;					\
1329 							\
1330     allValid = (int*)DXAllocateLocal(sizeof(int) * numInputs); \
1331     if (allValid == NULL)				\
1332 	return ERROR;					\
1333     for (arg = 0; arg < numInputs; ++arg) {		\
1334 	allValid[arg] = invalids[arg] == NULL || 	\
1335 	    DXGetInvalidCount(invalids[arg]) == 0;	\
1336     }							\
1337     /* for each element */				\
1338     for (i = j = 0; i < items; ++i) {			\
1339 	subTree = pt->args;				\
1340 	out[i] = init;					\
1341 	anyValid = 0;					\
1342 	for (arg = 0; arg < numInputs; ++arg) {		\
1343 	    in = (t *) inputs[arg];			\
1344 	    size0 = subTree->metaType.items;		\
1345 	    if (size0 != 1)				\
1346 		j = i;					\
1347 	    else					\
1348 		j = 0;					\
1349 	    if (allValid[arg] || !DXIsElementInvalidSequential(invalids[arg], j)) { \
1350 		anyValid = 1;				\
1351 		out[i] = op (out[i], in[j]);		\
1352 	    }						\
1353 	    subTree = subTree->next;			\
1354 	}						\
1355 	if (!anyValid)					\
1356 	    DXSetElementInvalid(outInvalid, i);		\
1357     }							\
1358     DXFree((Pointer)allValid);				\
1359     return (OK);					\
1360 }
1361 
1362 
1363 /*
1364  * Routines to manipulate invalid data.
1365  */
1366 Error _dxfComputeComputeInvalidCopy(
1367     InvalidComponentHandle out,
1368     InvalidComponentHandle in0);
1369 int _dxfComputeInvalidOne(
1370     InvalidComponentHandle out,
1371     int indexout,
1372     InvalidComponentHandle in0,
1373     int index0);
1374 int _dxfComputeInvalidOr(
1375     InvalidComponentHandle out,
1376     int indexout,
1377     InvalidComponentHandle in0,
1378     int index0,
1379     InvalidComponentHandle in1,
1380     int index1);
1381 
1382 int
1383 _dxfComputeCompareType(MetaType *left, MetaType *right);
1384 
1385 
1386 /* Checks a arguments to be sure all are vectors of same type and Category
1387  * as binding says arg0 should be, and same length.  It defines the result
1388  * to be of speced rank (scalar or vector) from the binding structure,
1389  * and if vector, the same length as the inputs.
1390  */
1391 int
1392 _dxfComputeCheckVects (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1393 
1394 /* Checks a arguments to be sure all are objects of same type and Category
1395  * as binding says they should be, and rank and shape.  It defines the result
1396  * to be of input cat, type, rank and shape.
1397  */
1398 int
1399 _dxfComputeCheckSameShape (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1400 
1401 /* Checks a arguments to be sure all are objects of same type, Category, and
1402  * rank (if scalar) as binding says they should be, and any shape allowed.
1403  * If bindings says rank == 1, no scalars are allowed.
1404  * Output is that rank and shape of first non-scalar in binding.
1405  */
1406 int
1407 _dxfComputeCheckDimAnyShape (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1408 
1409 /*
1410  * Check that the inputs match the types specified in the binding structure.
1411  * Return the type specified in the binding structure.
1412  */
1413 int
1414 _dxfComputeCheckMatch (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1415 
1416 /*
1417  * Check that the inputs (any number > 1) match the type
1418  * of input[0], which is also used as the output type.
1419  */
1420 int
1421 _dxfComputeCheckSame (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1422 
1423 /*
1424  * Check that the inputs (any number) match the type specified in the binding
1425  * structure for input[0], which is also used as the output type.
1426  */
1427 int
1428 _dxfComputeCheckSameAs (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1429 
1430 /*
1431  * Check that the inputs (any number) match the type of input[0], like
1432  * CheckSame, but use the outputType specified in the binding structure.
1433  */
1434 int
1435 _dxfComputeCheckSameSpecReturn (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1436 /*
1437  * Check that the inputs (any number) match the type of input[0], like
1438  * CheckSame, have the same Type specified in the binding, but use
1439  * the outputType specified in the binding structure.
1440  */
1441 int
1442 _dxfComputeCheckSameTypeSpecReturn (PTreeNode *pt, ObjStruct *os, OperBinding *binding);
1443 
1444 int     _dxfComputeLookupFunction (char *);
1445 int     _dxfComputeFinishExecution();
1446 int     _dxfComputeTypeCheck (PTreeNode *, ObjStruct *);
1447 void    _dxfComputeInitExecution (void);
1448 int     _dxfComputeExecuteNode (PTreeNode *, ObjStruct *,
1449                                 Pointer, InvalidComponentHandle *);
1450 
1451 #define MAXTOKEN        200
1452 
1453 
1454 /* Routines to work on complex numbers. */
1455 void         _dxfccinput(char *);
1456 complexFloat _dxfComputeAddComplexFloat(complexFloat x, complexFloat y);
1457 complexFloat _dxfComputeSubComplexFloat(complexFloat x, complexFloat y);
1458 complexFloat _dxfComputeNegComplexFloat(complexFloat x);
1459 complexFloat _dxfComputeMulComplexFloat(complexFloat x, complexFloat y);
1460 complexFloat _dxfComputeDivComplexFloat(complexFloat x, complexFloat y);
1461 float _dxfComputeAbsComplexFloat(complexFloat x);
1462 float _dxfComputeArgComplexFloat(complexFloat x);
1463 complexFloat _dxfComputeSqrtComplexFloat(complexFloat x);
1464 complexFloat _dxfComputeLnComplexFloat(complexFloat x);
1465 complexFloat _dxfComputePowComplexFloatFloat(complexFloat x, float y);
1466 complexFloat _dxfComputeExpComplexFloat(complexFloat x);
1467 complexFloat _dxfComputePowComplexFloat(complexFloat x, complexFloat y);
1468 complexFloat _dxfComputeSinComplexFloat(complexFloat x);
1469 complexFloat _dxfComputeCosComplexFloat(complexFloat x);
1470 complexFloat _dxfComputeSinhComplexFloat(complexFloat x);
1471 complexFloat _dxfComputeCoshComplexFloat(complexFloat x);
1472 complexFloat _dxfComputeTanComplexFloat(complexFloat x);
1473 complexFloat _dxfComputeTanhComplexFloat(complexFloat x);
1474 int _dxfComputeFiniteComplexFloat(complexFloat x);
1475 int _dxfComputeIsnanComplexFloat(complexFloat x);
1476 complexFloat _dxfComputeAsinComplexFloat(complexFloat x);
1477 complexFloat _dxfComputeAcosComplexFloat(complexFloat x);
1478 complexFloat _dxfComputeAtanComplexFloat(complexFloat x);
1479 
1480 
1481 #endif /* __COMPOPER_H_ */
1482