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 
12 
13 #include "defines.h"
14 #include <stdio.h>
15 #include <string.h>
16 #if defined(HAVE_UNISTD_H)
17 #include <unistd.h>
18 #endif
19 #if defined(HAVE_MALLOC_H)
20 #include <malloc.h>
21 #endif
22 #include "ErrorDialogManager.h"
23 #include "WarningDialogManager.h"
24 #include "MBGenerate.h"
25 #include "MBApplication.h"
26 
27 #if defined(__cplusplus) || defined(c_plusplus)
28 extern "C" {
29 #endif
30 
31 static int process_input(char *, Module *, Parameter **, Parameter **);
32 static int do_mdf(char *, Module *, Parameter **, Parameter **);
33 static int do_makefile(char *, Module *);
34 static int do_builder(char *, Module *, Parameter **, Parameter **);
35 static int cleanup(Module *m, Parameter **in, Parameter **out);
36 
37 static int GetDXDataType(enum datatype, char **);
38 static int GetCDataType(enum datatype, char **);
39 static int GetDXDataShape(enum datashape, char **, char **);
40 static int GetElementTypeString(enum elementtype, char **);
41 static int copy_comments(char *, FILE *, char *, char *, char *);
42 
43 #define MAX_IN	128
44 #define MAX_OUT 128
45 
46 #define DO_MDF	0x1
47 #define DO_C    0x2
48 #define DO_MAKE 0x4
49 
50 // Added COMMA_AND_NEWLINE to replace the use of a comma-separated list
51 // of statements in a cond?expr1:expr2 clause.  (The expr1 was the list
52 // and its contents were passed to a sprintf function, the outcome of
53 // which was unpredictable.) MST
54 #if defined(intelnt) || defined (WIN32)
55 #define NEWLINE "\r\n"
56 #define COMMA_AND_NEWLINE ",\r\n"
57 #else
58 #define NEWLINE "\n"
59 #define COMMA_AND_NEWLINE ",\n"
60 #endif
61 
Generate(int which,char * filename)62 int Generate(int which, char *filename)
63 {
64     Module module;
65     Parameter *inputs[MAX_IN], *outputs[MAX_OUT];
66     int i;
67     char *c, *fnamecopy = (char *)malloc(strlen(filename) + 1);
68 
69     inputs[0] = outputs[0] = NULL;
70     memset(&module, 0, sizeof(module));
71     strcpy(fnamecopy, filename);
72 
73     for (i = 0; i < strlen(fnamecopy); i++)
74 	if (fnamecopy[i] == '.')
75 	{
76 	    fnamecopy[i] = '\0';
77 	    break;
78 	}
79 
80     if (! process_input(fnamecopy, &module, inputs, outputs))
81 	return 0;
82 
83     if (which & DO_MDF)
84 	if (! do_mdf(fnamecopy, &module, inputs, outputs))
85 	    return 0;
86 
87     if (which & DO_C)
88 	if (! do_builder(fnamecopy, &module, inputs, outputs))
89 	    return 0;
90 
91     if (which & DO_MAKE)
92 	if (! do_makefile(fnamecopy, &module))
93 	    return 0;
94 
95     if (! cleanup(&module, inputs, outputs))
96 	return 0;
97 
98     free(fnamecopy);
99     return 1;
100 }
101 
102 static int
cleanup(Module * m,Parameter ** in,Parameter ** out)103 cleanup(Module *m, Parameter **in, Parameter **out)
104 {
105     Parameter **p;
106 
107     if (m->name)                free(m->name);
108     if (m->category)            free(m->category);
109     if (m->description)         free(m->description);
110     if (m->outboard_host)       free(m->description);
111     if (m->outboard_executable) free(m->outboard_executable);
112     if (m->loadable_executable) free(m->loadable_executable);
113     if (m->include_file)        free(m->include_file);
114 
115     for (p = in; *p != NULL; p++)
116     {
117 	if ((*p)->name)          free((*p)->name);
118 	if ((*p)->description)   free((*p)->description);
119 	if ((*p)->default_value) free((*p)->default_value);
120 	if ((*p)->types)         free((*p)->types);
121 	free((char *)*p);
122     }
123 
124     for (p = out; *p != NULL; p++)
125     {
126 	if ((*p)->name)          free((*p)->name);
127 	if ((*p)->description)   free((*p)->description);
128 	if ((*p)->default_value) free((*p)->default_value);
129 	if ((*p)->types)         free((*p)->types);
130 	free((char *)*p);
131     }
132 
133     return 1;
134 }
135 
136 static int
do_makefile(char * basename,Module * mod)137 do_makefile(char *basename, Module *mod)
138 {
139     FILE      *fd = NULL;
140     char      *buf = (char *)malloc(strlen(basename) + 7);
141     char      *makefilename;
142     char      *c;
143     const char *uiroot = NULL;
144     #define OBJ_EXT "$(OBJEXT)"
145 
146     if (! buf)
147     {
148 	WarningMessage("allocation error");
149 	goto error;
150     }
151 
152     sprintf(buf, "%s.make", basename);
153 
154     fd = fopen(buf, "w");
155     if (! fd)
156     {
157 	ErrorMessage("error opening output file");
158 	goto error;
159     }
160 
161     if (! copy_comments(basename, fd, NULL, "# ", NULL))
162 	goto error;
163 
164     for (c = basename; *c; c++)
165 	if (*c == '/')
166 	    basename = c+1;
167 
168     uiroot = theMBApplication->getUIRoot();
169     // This should not be necessary, but we'll be very
170     // careful just before the 3.1 release
171     if (!uiroot)
172         uiroot = "/usr/local/dx";
173 
174     fprintf(fd, "SHELL = /bin/sh%s", NEWLINE);
175     fprintf(fd, "BASE = %s%s%s",uiroot, NEWLINE, NEWLINE);
176 
177     fprintf(fd, "# need arch set, e.g. by%s", NEWLINE);
178     fprintf(fd, "# setenv DXARCH `dx -whicharch`%s", NEWLINE);
179     fprintf(fd, "include $(BASE)/lib_$(DXARCH)/arch.mak%s%s", NEWLINE, NEWLINE);
180 
181     if(mod->outboard_executable != NULL)
182 	fprintf(fd, "FILES_%s = %s.%s%s%s", basename, basename, OBJ_EXT, NEWLINE, NEWLINE);
183     else if(mod->loadable_executable != NULL)
184 	fprintf(fd, "FILES_%s = user%s.%s %s.%s%s%s",
185                 basename, basename, OBJ_EXT, basename, OBJ_EXT, NEWLINE, NEWLINE);
186     else
187 	fprintf(fd, "FILES_%s = user%s.%s %s.%s%s%s",
188 	    basename, basename, OBJ_EXT, basename, OBJ_EXT, NEWLINE, NEWLINE);
189 
190     fprintf(fd, "BIN = $(BASE)/bin%s%s", NEWLINE, NEWLINE);
191     fprintf(fd, "#windows BIN = $(BASE)\\bin%s%s", NEWLINE, NEWLINE);
192     fprintf(fd, "CFLAGS = -I./ -I$(BASE)/include $(DX_CFLAGS)%s%s", NEWLINE, NEWLINE);
193     fprintf(fd, "LDFLAGS = -L$(BASE)/lib_$(DXARCH)%s%s", NEWLINE, NEWLINE);
194     fprintf(fd, "LIBS = -lDX $(DX_GL_LINK_LIBS) $(DXEXECLINKLIBS)%s%s", NEWLINE, NEWLINE);
195     fprintf(fd, "OLIBS = -lDXlite -lm%s%s", NEWLINE, NEWLINE);
196     fprintf(fd, "BIN = $(BASE)/bin%s%s", NEWLINE, NEWLINE);
197 
198 
199     fprintf(fd, "# create the necessary executable%s", NEWLINE);
200     if(mod->outboard_executable != NULL)
201     {
202 	fprintf(fd, "%s: $(FILES_%s) outboard.$(OBJEXT)%s",
203 		mod->outboard_executable,
204 		basename, NEWLINE);
205 	fprintf(fd,
206 		"\t$(CC) $(DXABI) $(LDFLAGS) $(FILES_%s) outboard.$(OBJEXT) $(OLIBS) -o %s$(DOT_EXE_EXT)%s%s",
207 		basename,
208 		mod->outboard_executable, NEWLINE, NEWLINE);
209 
210 	  fprintf(fd, "# how to make the outboard main routine%s", NEWLINE);
211 	  fprintf(fd, "outboard.$(OBJEXT): $(BASE)/lib/outboard.c%s", NEWLINE);
212 	  fprintf(fd, "\t%s%s%s%s",
213 	     "$(CC) $(DXABI) $(CFLAGS) -DUSERMODULE=m_",
214 	    mod->name,
215 	     " -c $(BASE)/lib/outboard.c", NEWLINE);
216 	  fprintf(fd, "%s%s", NEWLINE, NEWLINE);
217     }
218     else if(mod->loadable_executable != NULL)
219     {
220        fprintf(fd, "%s: $(FILES_%s) %s",
221                mod->loadable_executable, basename, NEWLINE);
222 
223        fprintf(fd, "\t$(SHARED_LINK) $(DXABI) $(DX_RTL_CFLAGS) $(LDFLAGS) -o %s user%s.$(OBJEXT) %s.$(OBJEXT) $(DX_RTL_LDFLAGS) $(SYSLIBS) $(DX_RTL_IMPORTS) $(DX_RTL_DXENTRY)%s%s",
224                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
225 #if 0
226 #ifdef alphax
227        fprintf(fd, "\tld $(LDFLAGS) -o %s user%s.$(OBJEXT) %s.$(OBJEXT) $(SYSLIBS)%s%s",
228                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
229 #endif
230 #ifdef hp700
231        fprintf(fd, "\tld $(LDFLAGS) -o %s user%s.$(OBJEXT) %s.$(OBJEXT) $(SYSLIBS)%s%s",
232                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
233 #endif
234 #ifdef ibm6000
235        fprintf(fd, "\tcc -o %s user%s.$(OBJEXT) %s.$(OBJEXT) -qmkshrobj -G  -bI:$(IMP)%s%s",
236                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
237 #endif
238 #ifdef DXD_WIN
239        fprintf(fd, "\t$(CC) $(CFLAGS) -o %s  user%s.$(OBJEXT) %s.$(OBJEXT)  $(SYSLIBS) $(OLIBS) %s%s",
240                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
241 #endif
242 #ifdef sgi
243        fprintf(fd, "\tcc $(LDFLAGS) -o %s user%s.$(OBJEXT) %s.$(OBJEXT) $(SYSLIBS)%s%s",
244                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
245 #endif
246 #ifdef solaris
247        fprintf(fd, "\tcc $(LDFLAGS) -o %s user%s.$(OBJEXT) %s.$(OBJEXT)%s%s",
248                mod->loadable_executable, basename, basename, NEWLINE, NEWLINE);
249 #endif
250 #endif /* zero */
251     }
252     else
253     {
254 	fprintf(fd, "dxexec: $(FILES_%s) %s",
255 		basename, NEWLINE);
256 	fprintf(fd, "\t$(CC) $(LDFLAGS) $(FILES_%s) $(LIBS) -o dxexec%s%s",
257 		basename, NEWLINE, NEWLINE);
258 #if 0
259 #if defined(DXD_WIN)  || defined(OS2)
260 	fprintf(fd, "dxexec.exe: $(FILES_%s) %s",
261 		basename, NEWLINE);
262 #else
263 	fprintf(fd, "dxexec: $(FILES_%s) %s",
264 		basename, NEWLINE);
265 #endif
266 #endif /* zero */
267 
268 #if 0
269 #if   defined(DXD_WIN)
270 	fprintf(fd, "\t$(CC) (DXABI) $(LDFLAGS) $(FILES_%s) $(LIBS) -o dxexec.exe%s%s",
271 		basename, NEWLINE, NEWLINE);
272 #else
273 	fprintf(fd, "\t$(CC) $(DXABI) $(LDFLAGS) $(FILES_%s) $(LIBS) -o dxexec%s%s",
274 		basename, NEWLINE, NEWLINE);
275 #endif
276 #endif /* zero */
277     }
278 
279       fprintf(fd, ".c.o: ; cc -c $(DXABI) $(DX_RTL_CFLAGS) $(CFLAGS) $*.c %s%s", NEWLINE, NEWLINE);
280       fprintf(fd, ".C.o: ; cc -c $(DXABI) $(DX_RTL_CFLAGS) $(CFLAGS) $*.C %s%s", NEWLINE, NEWLINE);
281 
282 
283     /* a target to run dx using the user module */
284 
285     fprintf(fd, "# a command to run the user module%s", NEWLINE);
286     /* outboard module */
287     if(mod->outboard_executable != NULL) {
288       fprintf(fd, "run: %s %s", mod->outboard_executable, NEWLINE);
289       fprintf(fd, "\tdx -edit -mdf %s.mdf &%s", basename, NEWLINE);
290       fprintf(fd, "%s", NEWLINE);
291     }
292     else if(mod->loadable_executable != NULL) {
293     /* runtime loadable module */
294       fprintf(fd, "run: %s %s", mod->loadable_executable, NEWLINE);
295       fprintf(fd, "\tdx -edit -mdf %s.mdf &%s", basename, NEWLINE);
296       fprintf(fd, "%s", NEWLINE);
297     }
298     else {
299     /* inboard module */
300       fprintf(fd, "run: dxexec %s", NEWLINE);
301       fprintf(fd, "\tdx -edit -exec ./dxexec -mdf %s.mdf &%s", basename, NEWLINE);
302       fprintf(fd, "%s", NEWLINE);
303     }
304 
305     fprintf(fd, "# make the user files%s", NEWLINE);
306     fprintf(fd, "user%s.c: %s.mdf%s", basename, basename, NEWLINE);
307 
308 #ifdef DXD_WIN    /* just to change forward and back slashes    */
309     if(mod->loadable_executable != NULL)
310        fprintf(fd, "\t$(BIN)\\mdf2c -m %s.mdf > user%s.c%s", basename, basename, NEWLINE);
311     else
312        fprintf(fd, "\t$(BIN)\\mdf2c %s.mdf > user%s.c%s", basename, basename, NEWLINE);
313 
314 #else
315     if(mod->loadable_executable != NULL)
316        fprintf(fd, "\t$(BIN)/mdf2c -m %s.mdf > user%s.c%s", basename, basename, NEWLINE);
317     else
318        fprintf(fd, "\t$(BIN)/mdf2c %s.mdf > user%s.c%s", basename, basename, NEWLINE);
319 #endif
320 
321     fprintf(fd, "# kluge for when DXARCH isn't set%s", NEWLINE);
322     fprintf(fd, "$(BASE)/lib_/arch.mak:%s", NEWLINE);
323     makefilename=strrchr(buf,'/');
324     if(!makefilename) makefilename = buf;
325 	else makefilename++;
326     fprintf(fd, "\t(export DXARCH=`dx -whicharch` ; $(MAKE) -f %s )%s",makefilename, NEWLINE);
327     fprintf(fd, "\techo YOU NEED TO SET DXARCH via dx -whicharch%s", NEWLINE);
328     fclose(fd);
329     free(buf);
330     return 1;
331 
332 error:
333     if (fd)
334     {
335 	fclose(fd);
336 	unlink(buf);
337     }
338     free(buf);
339     return 0;
340 }
341 
342 static int
do_mdf(char * basename,Module * mod,Parameter ** in,Parameter ** out)343 do_mdf(char *basename, Module *mod, Parameter **in, Parameter **out)
344 {
345     FILE      *fd = NULL;
346     char      *buf = (char *)malloc(strlen(basename) + 5);
347 
348     if (! buf)
349     {
350 	ErrorMessage("allocation error");
351 	goto error;
352     }
353 
354     sprintf(buf, "%s.mdf", basename);
355 
356     fd = fopen(buf, "w");
357     if (! fd)
358     {
359 	ErrorMessage("error opening output file");
360 	goto error;
361     }
362 
363     if (! copy_comments(basename, fd, NULL, "# ", NULL))
364 	goto error;
365 
366     fprintf(fd, "MODULE %s%s", mod->name, NEWLINE);
367     fprintf(fd, "CATEGORY %s%s", mod->category, NEWLINE);
368     fprintf(fd, "DESCRIPTION %s%s", mod->description, NEWLINE);
369 
370     if (mod->outboard_persistent == TRUE ||
371 	mod->asynchronous  == TRUE       ||
372 	mod->pinned  == TRUE             ||
373 	mod->side_effect == TRUE)
374     {
375 	int first = 1;
376 	fprintf(fd, "FLAGS");
377 	if (mod->outboard_persistent == TRUE)
378 	    fprintf(fd, "%sPERSISTENT", first++ ? " " : ", ");
379 	if (mod->asynchronous == TRUE)
380 	    fprintf(fd, "%sASYNC", first++ ? " " : ", ");
381 	if (mod->pinned == TRUE)
382 	    fprintf(fd, "%sPIN", first++ ? " " : ", ");
383 	if (mod->side_effect == TRUE)
384 	    fprintf(fd, "%sSIDE_EFFECT", first++ ? " " : ", ");
385 	fprintf(fd, "%s", NEWLINE);
386     }
387 
388     if (mod->outboard_executable)
389     {
390 	fprintf(fd, "OUTBOARD %s;", mod->outboard_executable);
391 	if (mod->outboard_host)
392 	    fprintf(fd, "%s", mod->outboard_host);
393 	fprintf(fd, "%s", NEWLINE);
394     }
395 
396     if (mod->loadable_executable)
397     {
398 	fprintf(fd, "LOADABLE %s;", mod->loadable_executable);
399 	fprintf(fd, "%s", NEWLINE);
400     }
401 
402     while (*in)
403     {
404 	char *c;
405 	fprintf(fd, "INPUT %s; ", (*in)->name);
406 
407 	if ((*in)->types)
408 	{
409 	    char *buf, *b, *c;
410 	    int i, nc;
411 
412 	    for (c = (*in)->types, nc = 0; *c; c++)
413 		if (*c == ',') nc++;
414 
415             /* integer vector and integer vector list are not understood by
416                the ui */
417             if (!strcmp((*in)->types,"integer vector")) {
418 	        buf = b = (char *)malloc(strlen("vector") + 4*nc + 1);
419 	        for (c = "vector", nc = 0; *c; c++)
420 	           *b++ = *c;
421             }
422             else if (!strcmp((*in)->types,"integer vector list")) {
423 	        buf = b = (char *)malloc(strlen("vector list") + 4*nc + 1);
424 	        for (c = "vector list", nc = 0; *c; c++)
425 	           *b++ = *c;
426             }
427             else {
428 	        buf = b = (char *)malloc(strlen((*in)->types) + 4*nc + 1);
429 	        for (c = (*in)->types, nc = 0; *c; c++)
430 		    *b++ = *c;
431             }
432 
433 
434 	    *b = '\0';
435 
436 	    fprintf(fd, "%s; ", buf);
437 
438 	    free(buf);
439 	}
440 	else if ((*in)->structure == VALUE)
441 	    fprintf(fd, "value; ");
442 	else if ((*in)->structure == GROUP_FIELD)
443 	    fprintf(fd, "group; ");
444 	else
445 	{
446 	    ErrorMessage("input %s has no STRUCTURE parameter\n", (*in)->name);
447 	    goto error;
448 	}
449 	if ((*in)->required == TRUE)
450 	    fprintf(fd, " (none);");
451 	else if ((*in)->descriptive == TRUE)
452 	    fprintf(fd, " (%s);", (*in)->default_value);
453 	else
454 	    fprintf(fd, " %s;", (*in)->default_value);
455 	fprintf(fd, " %s%s", (*in)->description, NEWLINE);
456 	in++;
457     }
458 
459     while (*out)
460     {
461 	char *c;
462 	fprintf(fd, "OUTPUT %s; ", (*out)->name);
463 
464 	if ((*out)->types)
465 	{
466 	    char *buf, *b, *c;
467 	    int i, nc;
468 
469 	    for (c = (*out)->types, nc = 0; *c; c++)
470 		if (*c == ',') nc++;
471 
472 	    buf = b = (char *)malloc(strlen((*out)->types) + 4*nc + 1);
473 
474 	    for (c = (*out)->types, nc = 0; *c; c++)
475 		if (*c == ',')
476 		{
477 		    *b++ = ' ';
478 		    *b++ = 'o';
479 		    *b++ = 'r';
480 		    *b++ = ' ';
481 		}
482 		else
483 		    *b++ = *c;
484 
485 	    *b = '\0';
486 
487 	    fprintf(fd, "%s; ", buf);
488 
489 	    free(buf);
490 	}
491 	else if ((*out)->structure == VALUE)
492 	    fprintf(fd, "value; ");
493 	else if ((*out)->structure == GROUP_FIELD)
494 	    fprintf(fd, "group; ");
495 	else
496 	{
497 	    ErrorMessage("output %s has no STRUCTURE parameter\n", (*out)->name);
498 	    goto error;
499 	}
500 	fprintf(fd, " %s%s", (*out)->description, NEWLINE);
501 	out++;
502     }
503 
504     fclose(fd);
505     free(buf);
506     return 1;
507 
508 error:
509     if (fd)
510     {
511 	fclose(fd);
512 	unlink(buf);
513     }
514     free(buf);
515     return 0;
516 }
517 
518 static int
do_builder(char * basename,Module * mod,Parameter ** in,Parameter ** out)519 do_builder(char *basename, Module *mod, Parameter **in, Parameter **out)
520 {
521     FILE       *fd = NULL;
522     int        i, nin, nout, n_GF_in, n_GF_out, open;
523     char       *buf = (char *)malloc(strlen(basename) + 4);
524 
525     if (! buf)
526     {
527 	ErrorMessage("allocation error");
528 	goto error;
529     }
530 
531     sprintf(buf, "%s.c", basename);
532 
533     fd = fopen(buf, "w");
534     if (! fd)
535     {
536 	ErrorMessage("error opening output file");
537 	goto error;
538     }
539 
540     if (! copy_comments(basename, fd, "/*\n", " * ", " */\n"))
541 	goto error;
542 
543     for (nin  = 0; in[nin] != NULL; nin++);
544     for (nout = 0; out[nout] != NULL; nout++);
545 
546 fprintf(fd, "/*%s", NEWLINE);
547 fprintf(fd, " * Automatically generated on \"%s.mb\" by DX Module Builder%s",
548 				basename, NEWLINE);
549 fprintf(fd, " */%s%s", NEWLINE, NEWLINE);
550 
551 fprintf(fd, "/* define your pre-dx.h include file for inclusion here*/ %s", NEWLINE);
552 fprintf(fd, "#ifdef PRE_DX_H%s", NEWLINE);
553 fprintf(fd, "#include \"%s_predx.h\"%s",mod->name, NEWLINE);
554 fprintf(fd, "#endif%s", NEWLINE);
555 fprintf(fd, "#include \"dx/dx.h\"%s", NEWLINE);
556 fprintf(fd, "/* define your post-dx.h include file for inclusion here*/ %s", NEWLINE);
557 fprintf(fd, "#ifdef POST_DX_H%s", NEWLINE);
558 fprintf(fd, "#include \"%s_postdx.h\"%s",mod->name, NEWLINE);
559 fprintf(fd, "#endif%s", NEWLINE);
560 fprintf(fd, "%s", NEWLINE);
561 fprintf(fd, "static Error traverse(Object *, Object *);%s", NEWLINE);
562 fprintf(fd, "static Error doLeaf(Object *, Object *);%s", NEWLINE);
563 fprintf(fd, "%s", NEWLINE);
564 fprintf(fd, "/*%s", NEWLINE);
565 fprintf(fd, " * Declare the interface routine.%s", NEWLINE);
566 fprintf(fd, " */%s", NEWLINE);
567 fprintf(fd, "int%s%s_worker(%s", NEWLINE, mod->name, NEWLINE);
568 
569     open = 0;
570 
571     if (in[0]->positions == GRID_REGULAR)
572     {
573 	open = 1;
574 fprintf(fd, "    int, int, int *, float *, float *");
575     }
576     else if (in[0]->positions == GRID_IRREGULAR)
577     {
578 	open = 1;
579 fprintf(fd, "    int, int, float *");
580     }
581 
582     if (in[0]->connections == GRID_REGULAR)
583     {
584 fprintf(fd, "%s   int, int, int *", (open)?COMMA_AND_NEWLINE:"");
585 	open = 1;
586     }
587     else if (in[0]->connections == GRID_IRREGULAR)
588     {
589 fprintf(fd, "%s    int, int, int *", (open)?COMMA_AND_NEWLINE:"");
590 	open = 1;
591     }
592 
593     for (i = 0; i < nin; i++)
594     {
595 	char *type;
596 	GetCDataType(in[i]->datatype, &type);
597 fprintf(fd, "%s    int, %s *", (open)?COMMA_AND_NEWLINE:"", type);
598 	open = 1;
599     }
600 
601     for (i = 0; i < nout; i++)
602     {
603 	char *type;
604 	GetCDataType(out[i]->datatype, &type);
605 fprintf(fd, "%s    int, %s *", (open)?COMMA_AND_NEWLINE:"", type);
606 	open = 1;
607     }
608 
609 fprintf(fd, ");%s%s", NEWLINE, NEWLINE);
610 
611 fprintf(fd, "#if defined (__cplusplus) || defined (c_plusplus)%s", NEWLINE);
612 fprintf(fd, "extern \"C\"%s", NEWLINE);
613 fprintf(fd, "#endif%s", NEWLINE);
614 fprintf(fd, "Error%sm_%s(Object *in, Object *out)%s", NEWLINE, mod->name, NEWLINE);
615 fprintf(fd, "{%s", NEWLINE);
616 fprintf(fd, "  int i;%s", NEWLINE);
617 fprintf(fd, "%s", NEWLINE);
618 fprintf(fd, "  /*%s", NEWLINE);
619 fprintf(fd, "   * Initialize all outputs to NULL%s", NEWLINE);
620 fprintf(fd, "   */%s", NEWLINE);
621     if (nout == 1)
622 fprintf(fd, "  out[0] = NULL;%s", NEWLINE);
623     else if (nout > 1)
624     {
625 fprintf(fd, "  for (i = 0; i < %d; i++)%s", nout, NEWLINE);
626 fprintf(fd, "    out[i] = NULL;%s", NEWLINE);
627     }
628 
629 fprintf(fd, "%s", NEWLINE);
630 
631 fprintf(fd, "  /*%s", NEWLINE);
632 fprintf(fd, "   * Error checks: required inputs are verified.%s", NEWLINE);
633 fprintf(fd, "   */%s%s", NEWLINE, NEWLINE);
634 
635     n_GF_in = 0;
636     for (i = 0; i < nin; i++)
637     {
638 	if (in[i]->structure == GROUP_FIELD)
639 	    n_GF_in ++;
640 
641 	if (in[i]->required == TRUE || i == 0)
642 	{
643 fprintf(fd, "  /* Parameter \"%s\" is required. */%s", in[i]->name, NEWLINE);
644 fprintf(fd, "  if (in[%d] == NULL)%s", i, NEWLINE);
645 fprintf(fd, "  {%s", NEWLINE);
646 fprintf(fd, "    DXSetError(ERROR_MISSING_DATA, ");
647 fprintf(fd, "\"\\\"%s\\\" must be specified\");%s", in[i]->name, NEWLINE);
648 fprintf(fd, "    return ERROR;%s", NEWLINE);
649 fprintf(fd, "  }%s%s", NEWLINE, NEWLINE);
650 	}
651     }
652 
653     n_GF_out = 0;
654     for (i = 0; i < nout; i++)
655     {
656 fprintf(fd, "%s", NEWLINE);
657 
658 	if (out[i]->structure == GROUP_FIELD)
659 	{
660 	    n_GF_out ++;
661 
662 fprintf(fd, "  /*%s", NEWLINE);
663 fprintf(fd, "   * Since output \"%s\" is structure Field/Group, it initially%s", out[i]->name, NEWLINE);
664 fprintf(fd, "   * is a copy of input \"%s\".%s", in[0]->name, NEWLINE);
665 fprintf(fd, "   */%s", NEWLINE);
666 fprintf(fd, "  out[%d] = DXCopy(in[0], COPY_STRUCTURE);%s", i, NEWLINE);
667 fprintf(fd, "  if (! out[%d])%s", i, NEWLINE);
668 fprintf(fd, "    goto error;%s%s", NEWLINE, NEWLINE);
669 fprintf(fd, "  /*%s", NEWLINE);
670 fprintf(fd, "   * If in[0] was an array, then no copy is actually made - Copy %s", NEWLINE);
671 fprintf(fd, "   * returns a pointer to the input object.  Since this can't be written to%s", NEWLINE);
672 fprintf(fd, "   * we postpone explicitly copying it until the leaf level, when we'll need%s", NEWLINE);
673 fprintf(fd, "   * to be creating writable arrays anyway.%s", NEWLINE);
674 fprintf(fd, "   */%s", NEWLINE);
675 fprintf(fd, "  if (out[%d] == in[0])%s", i, NEWLINE);
676 fprintf(fd, "    out[%d] = NULL;%s", i, NEWLINE);
677 	}
678 	else if (out[i]->structure == VALUE)
679 	{
680 	    char *t;
681 	    char *r, *s;
682 	    char *l;
683 
684 	    if (! GetDXDataType(out[i]->datatype, &t))
685 	    {
686 		ErrorMessage("cannot create array without DATATYPE");
687 		goto error;
688 	    }
689 
690 	    if (! GetDXDataShape(out[i]->datashape, &r, &s))
691 	    {
692 		ErrorMessage("cannot create array without DATASHAPE");
693 		goto error;
694 	    }
695 
696 #if 0
697 	    switch(out[i]->counts)
698 	    {
699 		case COUNTS_1: l = "1"; break;
700 		default:
701 		    ErrorMessage("cannot create array without COUNTS");
702 		    goto error;
703 	    }
704 #endif
705 	    l = "1";
706 
707 fprintf(fd, "  /*%s", NEWLINE);
708 fprintf(fd, "   * Output \"%s\" is a value; set up an appropriate array%s", out[i]->name, NEWLINE);
709 fprintf(fd, "   */%s", NEWLINE);
710 fprintf(fd, "  out[%d] = (Object)DXNewArray(%s, CATEGORY_REAL, %s, %s);%s", i, t, r, s, NEWLINE);
711 fprintf(fd, "  if (! out[%d])%s", i, NEWLINE);
712 fprintf(fd, "    goto error;%s", NEWLINE);
713 fprintf(fd, "  if (! DXAddArrayData((Array)out[%d], 0, %s, NULL))%s", i, l, NEWLINE);
714 fprintf(fd, "    goto error;%s", NEWLINE);
715 fprintf(fd, "  memset(DXGetArrayData((Array)out[%d]), 0, %s*DXGetItemSize((Array)out[%d]));%s", i, l, i, NEWLINE);
716 fprintf(fd, "%s", NEWLINE);
717 	}
718     }
719 
720 fprintf(fd, "%s", NEWLINE);
721 
722 fprintf(fd, "  /*%s", NEWLINE);
723 fprintf(fd, "   * Call the hierarchical object traversal routine%s", NEWLINE);
724 fprintf(fd, "   */%s", NEWLINE);
725 fprintf(fd, "  if (!traverse(in, out))%s", NEWLINE);
726 fprintf(fd, "    goto error;%s", NEWLINE);
727 
728 fprintf(fd, "%s", NEWLINE);
729 
730 fprintf(fd, "  return OK;%s", NEWLINE);
731 fprintf(fd, "%s", NEWLINE);
732 fprintf(fd, "error:%s", NEWLINE);
733 fprintf(fd, "  /*%s", NEWLINE);
734 fprintf(fd, "   * On error, any successfully-created outputs are deleted.%s", NEWLINE);
735 fprintf(fd, "   */%s", NEWLINE);
736 fprintf(fd, "  for (i = 0; i < %d; i++)%s", nout, NEWLINE);
737 fprintf(fd, "  {%s", NEWLINE);
738 fprintf(fd, "    if (in[i] != out[i])%s", NEWLINE);
739 fprintf(fd, "      DXDelete(out[i]);%s", NEWLINE);
740 fprintf(fd, "    out[i] = NULL;%s", NEWLINE);
741 fprintf(fd, "  }%s", NEWLINE);
742 fprintf(fd, "  return ERROR;%s", NEWLINE);
743 fprintf(fd, "}%s", NEWLINE);
744 
745 fprintf(fd, "%s%s", NEWLINE, NEWLINE);
746 fprintf(fd, "static Error%s", NEWLINE);
747 fprintf(fd, "traverse(Object *in, Object *out)%s", NEWLINE);
748 fprintf(fd, "{%s", NEWLINE);
749 fprintf(fd, "  switch(DXGetObjectClass(in[0]))%s", NEWLINE);
750 fprintf(fd, "  {%s", NEWLINE);
751 fprintf(fd, "    case CLASS_FIELD:%s", NEWLINE);
752 fprintf(fd, "    case CLASS_ARRAY:%s", NEWLINE);
753 fprintf(fd, "    case CLASS_STRING:%s", NEWLINE);
754 fprintf(fd, "      /*%s", NEWLINE);
755 fprintf(fd, "       * If we have made it to the leaf level, call the leaf handler.%s", NEWLINE);
756 fprintf(fd, "       */%s", NEWLINE);
757 fprintf(fd, "      if (! doLeaf(in, out))%s", NEWLINE);
758 fprintf(fd, "  	     return ERROR;%s", NEWLINE);
759 fprintf(fd, "%s", NEWLINE);
760 fprintf(fd, "      return OK;%s", NEWLINE);
761 fprintf(fd, "%s", NEWLINE);
762 fprintf(fd, "    case CLASS_GROUP:%s", NEWLINE);
763 fprintf(fd, "    {%s", NEWLINE);
764 fprintf(fd, "      int   i, j;%s", NEWLINE);
765 fprintf(fd, "      int   memknt;%s", NEWLINE);
766 fprintf(fd, "      Class groupClass  = DXGetGroupClass((Group)in[0]);%s", NEWLINE);
767 fprintf(fd, "%s", NEWLINE);
768 fprintf(fd, "      DXGetMemberCount((Group)in[0], &memknt);%s", NEWLINE);
769 fprintf(fd, "%s", NEWLINE);
770 if (n_GF_in > 1)
771 {
772 fprintf(fd, "      /*%s", NEWLINE);
773 fprintf(fd, "       * All inputs that are not NULL and are type Field/Group must%s", NEWLINE);
774 fprintf(fd, "       * match the structure of input[0].  Verify that this is so.%s", NEWLINE);
775 fprintf(fd, "       */%s", NEWLINE);
776     for (i = 1; i < nin; i++)
777 	if (in[i]->structure == GROUP_FIELD)
778 	{
779 fprintf(fd, "       if (in[%d] &&%s", i, NEWLINE);
780 fprintf(fd, "            (DXGetObjectClass(in[%d]) != CLASS_GROUP ||%s", i, NEWLINE);
781 fprintf(fd, "             DXGetGroupClass((Group)in[%d])  != groupClass  ||%s", i, NEWLINE);
782 fprintf(fd, "             !DXGetMemberCount((Group)in[%d], &i) || i != memknt))%s", i, NEWLINE);
783 fprintf(fd, "	      {%s", NEWLINE);
784 fprintf(fd, "  		DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
785 fprintf(fd, "	            \"structure of \\\"%s\\\" doesn't match that of \\\"%s\\\"\");%s",
786 			    in[i]->name, in[0]->name, NEWLINE);
787 fprintf(fd, "  	         return ERROR;%s", NEWLINE);
788 fprintf(fd, "         }%s%s", NEWLINE, NEWLINE);
789 	}
790 }
791 else
792 fprintf(fd, "%s", NEWLINE);
793 
794 fprintf(fd, "       /*%s", NEWLINE);
795 fprintf(fd, "        * Create new in and out lists for each child%s", NEWLINE);
796 fprintf(fd, "        * of the first input. %s", NEWLINE);
797 fprintf(fd, "        */%s", NEWLINE);
798 fprintf(fd, "        for (i = 0; i < memknt; i++)%s", NEWLINE);
799 fprintf(fd, "        {%s", NEWLINE);
800 fprintf(fd, "          Object new_in[%d], new_out[%d];%s", nin, nout, NEWLINE);
801 fprintf(fd, "%s", NEWLINE);
802 
803 fprintf(fd, "         /*%s", NEWLINE);
804 fprintf(fd, "          * For all inputs that are Values, pass them to %s", NEWLINE);
805 fprintf(fd, "          * child object list.  For all that are Field/Group, get %s", NEWLINE);
806 fprintf(fd, "          * the appropriate decendent and place it into the%s", NEWLINE);
807 fprintf(fd, "          * child input object list.%s", NEWLINE);
808 fprintf(fd, "          */%s%s", NEWLINE, NEWLINE);
809 for (i = 0; i < nin; i++)
810     if (in[i]->structure == VALUE)
811     {
812 fprintf(fd, "          /* input \"%s\" is Value */%s", in[i]->name, NEWLINE);
813 fprintf(fd, "          new_in[%d] = in[%d];%s%s", i, i, NEWLINE, NEWLINE);
814     }
815     else if (in[i]->structure == GROUP_FIELD)
816     {
817 fprintf(fd, "          /* input \"%s\" is Field/Group */%s", in[i]->name, NEWLINE);
818 fprintf(fd, "          if (in[%d])%s", i, NEWLINE);
819 fprintf(fd, "            new_in[%d] = DXGetEnumeratedMember((Group)in[%d], i, NULL);%s", i, i, NEWLINE);
820 fprintf(fd, "          else%s", NEWLINE);
821 fprintf(fd, "            new_in[%d] = NULL;%s", i, NEWLINE);
822 fprintf(fd, "%s", NEWLINE);
823     }
824 
825 fprintf(fd, "         /*%s", NEWLINE);
826 fprintf(fd, "          * For all outputs that are Values, pass them to %s", NEWLINE);
827 fprintf(fd, "          * child object list.  For all that are Field/Group,  get%s", NEWLINE);
828 fprintf(fd, "          * the appropriate decendent and place it into the%s", NEWLINE);
829 fprintf(fd, "          * child output object list.  Note that none should%s", NEWLINE);
830 fprintf(fd, "          * be NULL (unlike inputs, which can default).%s", NEWLINE);
831 fprintf(fd, "          */%s%s", NEWLINE, NEWLINE);
832 for (i = 0; i < nout; i++)
833     if (out[i]->structure == VALUE)
834     {
835 fprintf(fd, "          /* output \"%s\" is Value */%s", out[i]->name, NEWLINE);
836 fprintf(fd, "          new_out[%d] = out[%d];%s%s", i, i, NEWLINE, NEWLINE);
837     }
838     else
839     {
840 fprintf(fd, "          /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
841 fprintf(fd, "          new_out[%d] = DXGetEnumeratedMember((Group)out[%d], i, NULL);%s%s", i, i, NEWLINE, NEWLINE);
842     }
843 
844 fprintf(fd, "          if (! traverse(new_in, new_out))%s", NEWLINE);
845 fprintf(fd, "            return ERROR;%s", NEWLINE);
846 fprintf(fd, "%s", NEWLINE);
847 
848 if (n_GF_out)
849 {
850 fprintf(fd, "         /*%s", NEWLINE);
851 fprintf(fd, "          * Now for each output that is not a Value, replace%s", NEWLINE);
852 fprintf(fd, "          * the updated child into the object in the parent.%s", NEWLINE);
853 fprintf(fd, "          */%s%s", NEWLINE, NEWLINE);
854     for (i = 0; i < nout; i++)
855 	if (out[i]->structure == GROUP_FIELD)
856 	{
857 fprintf(fd, "          /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
858 fprintf(fd, "          DXSetEnumeratedMember((Group)out[%d], i, new_out[%d]);%s%s", i, i, NEWLINE, NEWLINE);
859 	}
860 }
861 
862 fprintf(fd, "        }%s", NEWLINE);
863 fprintf(fd, "      return OK;%s", NEWLINE);
864 fprintf(fd, "    }%s", NEWLINE);
865 fprintf(fd, "%s", NEWLINE);
866 fprintf(fd, "    case CLASS_XFORM:%s", NEWLINE);
867 fprintf(fd, "    {%s", NEWLINE);
868 fprintf(fd, "      int    i, j;%s", NEWLINE);
869 fprintf(fd, "      Object new_in[%d], new_out[%d];%s", nin, nout, NEWLINE);
870 fprintf(fd, "%s", NEWLINE);
871 
872 if (n_GF_in > 1)
873 {
874 fprintf(fd, "      /*%s", NEWLINE);
875 fprintf(fd, "       * All inputs that are not NULL and are type Field/Group must%s", NEWLINE);
876 fprintf(fd, "       * match the structure of input[0].  Verify that this is so.%s", NEWLINE);
877 fprintf(fd, "       */%s", NEWLINE);
878     for (i = 1; i < nin; i++)
879 	if (in[i]->structure == GROUP_FIELD)
880 	{
881 fprintf(fd, "      if (in[%d] && DXGetObjectClass(in[%d]) != CLASS_XFORM)%s", i, i, NEWLINE);
882 fprintf(fd, "      {%s", NEWLINE);
883 fprintf(fd, "        DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
884 fprintf(fd, "	            \"structure of \\\"%s\\\" doesn't match that of \\\"%s\\\"\");%s",
885 			    in[i]->name, in[0]->name, NEWLINE);
886 fprintf(fd, "        return ERROR;%s", NEWLINE);
887 fprintf(fd, "      }%s%s", NEWLINE, NEWLINE);
888 	}
889 }
890 else
891 fprintf(fd, "%s", NEWLINE);
892 
893 fprintf(fd, "      /*%s", NEWLINE);
894 fprintf(fd, "       * Create new in and out lists for the decendent of the%s", NEWLINE);
895 fprintf(fd, "       * first input.  For inputs and outputs that are Values%s", NEWLINE);
896 fprintf(fd, "       * copy them into the new in and out lists.  Otherwise%s", NEWLINE);
897 fprintf(fd, "       * get the corresponding decendents.%s", NEWLINE);
898 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
899 for (i = 0; i < nin; i++)
900     if (in[i]->structure == VALUE)
901     {
902 fprintf(fd, "      /* input \"%s\" is Value */%s", in[i]->name, NEWLINE);
903 fprintf(fd, "      new_in[%d] = in[%d];%s%s", i, i, NEWLINE, NEWLINE);
904     }
905     else
906     {
907 fprintf(fd, "      /* input \"%s\" is Field/Group */%s", in[i]->name, NEWLINE);
908 fprintf(fd, "      if (in[%d])%s", i, NEWLINE);
909 fprintf(fd, "        DXGetXformInfo((Xform)in[%d], &new_in[%d], NULL);%s", i, i, NEWLINE);
910 fprintf(fd, "      else%s", NEWLINE);
911 fprintf(fd, "        new_in[%d] = NULL;%s", i, NEWLINE);
912 fprintf(fd, "%s", NEWLINE);
913     }
914 fprintf(fd, "      /*%s", NEWLINE);
915 fprintf(fd, "       * For all outputs that are Values, copy them to %s", NEWLINE);
916 fprintf(fd, "       * child object list.  For all that are Field/Group,  get%s", NEWLINE);
917 fprintf(fd, "       * the appropriate decendent and place it into the%s", NEWLINE);
918 fprintf(fd, "       * child output object list.  Note that none should%s", NEWLINE);
919 fprintf(fd, "       * be NULL (unlike inputs, which can default).%s", NEWLINE);
920 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
921 for (i = 0; i < nout; i++)
922     if (out[i]->structure == VALUE)
923     {
924 fprintf(fd, "      /* output \"%s\" is Value */%s", out[i]->name, NEWLINE);
925 fprintf(fd, "      new_out[%d] = out[%d];%s%s", i, i, NEWLINE, NEWLINE);
926     }
927     else
928     {
929 fprintf(fd, "      /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
930 fprintf(fd, "      DXGetXformInfo((Xform)out[%d], &new_out[%d], NULL);%s%s", i,i, NEWLINE, NEWLINE);
931     }
932 fprintf(fd, "      if (! traverse(new_in, new_out))%s", NEWLINE);
933 fprintf(fd, "        return ERROR;%s", NEWLINE);
934 fprintf(fd, "%s", NEWLINE);
935 
936 if (n_GF_out)
937 {
938 fprintf(fd, "      /*%s", NEWLINE);
939 fprintf(fd, "       * Now for each output that is not a Value replace%s", NEWLINE);
940 fprintf(fd, "       * the updated child into the object in the parent.%s", NEWLINE);
941 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
942     for (i = 0; i < nout; i++)
943 	if (out[i]->structure == GROUP_FIELD)
944 	{
945 fprintf(fd, "      /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
946 fprintf(fd, "      DXSetXformObject((Xform)out[%d], new_out[%d]);%s%s", i, i, NEWLINE, NEWLINE);
947 	}
948 }
949 
950 fprintf(fd, "      return OK;%s", NEWLINE);
951 fprintf(fd, "    }%s", NEWLINE);
952 fprintf(fd, "%s", NEWLINE);
953 fprintf(fd, "    case CLASS_SCREEN:%s", NEWLINE);
954 fprintf(fd, "    {%s", NEWLINE);
955 fprintf(fd, "      int    i, j;%s", NEWLINE);
956 fprintf(fd, "      Object new_in[%d], new_out[%d];%s", nin, nout, NEWLINE);
957 fprintf(fd, "%s", NEWLINE);
958 if (n_GF_in > 1)
959 {
960 fprintf(fd, "      /*%s", NEWLINE);
961 fprintf(fd, "       * All inputs that are not NULL and are type Field/Group must%s", NEWLINE);
962 fprintf(fd, "       * match the structure of input[0].  Verify that this is so.%s", NEWLINE);
963 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
964     for (i = 1; i < nin; i++)
965 	if (in[i]->structure == GROUP_FIELD)
966 	{
967 fprintf(fd, "       if (in[%d] && DXGetObjectClass(in[%d]) != CLASS_SCREEN)%s", i, i, NEWLINE);
968 fprintf(fd, "       {%s", NEWLINE);
969 fprintf(fd, "           DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
970 fprintf(fd, "	            \"structure of \\\"%s\\\" doesn't match that of \\\"%s\\\"\");%s",
971 			    in[i]->name, in[0]->name, NEWLINE);
972 fprintf(fd, "           return ERROR;%s", NEWLINE);
973 fprintf(fd, "       }%s%s", NEWLINE, NEWLINE);
974 	}
975 }
976 else
977 fprintf(fd, "%s", NEWLINE);
978 
979 fprintf(fd, "      /*%s", NEWLINE);
980 fprintf(fd, "       * Create new in and out lists for the decendent of the%s", NEWLINE);
981 fprintf(fd, "       * first input.  For inputs and outputs that are Values%s", NEWLINE);
982 fprintf(fd, "       * copy them into the new in and out lists.  Otherwise%s", NEWLINE);
983 fprintf(fd, "       * get the corresponding decendents.%s", NEWLINE);
984 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
985 for (i = 0; i < nin; i++)
986     if (in[i]->structure == VALUE)
987     {
988 fprintf(fd, "      /* input \"%s\" is Value */%s", in[i]->name, NEWLINE);
989 fprintf(fd, "      new_in[%d] = in[%d];%s%s", i, i, NEWLINE, NEWLINE);
990     }
991     else
992     {
993 fprintf(fd, "      /* input \"%s\" is Field/Group */%s", in[i]->name, NEWLINE);
994 fprintf(fd, "      if (in[%d])%s", i, NEWLINE);
995 fprintf(fd, "        DXGetScreenInfo((Screen)in[%d], &new_in[%d], NULL, NULL);%s",i,i, NEWLINE);
996 fprintf(fd, "      else%s", NEWLINE);
997 fprintf(fd, "        new_in[%d] = NULL;%s%s", i, NEWLINE,NEWLINE);
998     }
999 fprintf(fd, "%s", NEWLINE);
1000 fprintf(fd, "      /*%s", NEWLINE);
1001 fprintf(fd, "       * For all outputs that are Values, copy them to %s", NEWLINE);
1002 fprintf(fd, "       * child object list.  For all that are Field/Group,  get%s", NEWLINE);
1003 fprintf(fd, "       * the appropriate decendent and place it into the%s", NEWLINE);
1004 fprintf(fd, "       * child output object list.  Note that none should%s", NEWLINE);
1005 fprintf(fd, "       * be NULL (unlike inputs, which can default).%s", NEWLINE);
1006 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
1007 for (i = 0; i < nout; i++)
1008     if (out[i]->structure == VALUE)
1009     {
1010 fprintf(fd, "       /* output \"%s\" is Value */%s", out[i]->name, NEWLINE);
1011 fprintf(fd, "       new_out[%d] = out[%d];%s%s", i, i, NEWLINE, NEWLINE);
1012     }
1013     else
1014     {
1015 fprintf(fd, "       /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
1016 fprintf(fd, "       DXGetScreenInfo((Screen)out[%d], &new_out[%d], NULL, NULL);%s%s", i,i, NEWLINE, NEWLINE);
1017     }
1018 
1019 fprintf(fd, "       if (! traverse(new_in, new_out))%s", NEWLINE);
1020 fprintf(fd, "         return ERROR;%s", NEWLINE);
1021 fprintf(fd, "%s", NEWLINE);
1022 
1023 if (n_GF_out)
1024 {
1025 fprintf(fd, "      /*%s", NEWLINE);
1026 fprintf(fd, "       * Now for each output that is not a Value, replace%s", NEWLINE);
1027 fprintf(fd, "       * the updated child into the object in the parent.%s", NEWLINE);
1028 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
1029 for (i = 0; i < nout; i++)
1030     if (out[i]->structure == GROUP_FIELD)
1031     {
1032 fprintf(fd, "      /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
1033 fprintf(fd, "       DXSetScreenObject((Screen)out[%d], new_out[%d]);%s%s", i,i, NEWLINE, NEWLINE);
1034     }
1035 }
1036 
1037 fprintf(fd, "       return OK;%s", NEWLINE);
1038 fprintf(fd, "     }%s", NEWLINE);
1039 fprintf(fd, "%s", NEWLINE);
1040 fprintf(fd, "     case CLASS_CLIPPED:%s", NEWLINE);
1041 fprintf(fd, "     {%s", NEWLINE);
1042 fprintf(fd, "       int    i, j;%s", NEWLINE);
1043 fprintf(fd, "       Object new_in[%d], new_out[%d];%s", nin, nout, NEWLINE);
1044 fprintf(fd, "%s", NEWLINE);
1045 if (n_GF_in > 1)
1046 {
1047 fprintf(fd, "      /*%s", NEWLINE);
1048 fprintf(fd, "       * All inputs that are not NULL and are type Field/Group must%s", NEWLINE);
1049 fprintf(fd, "       * match the structure of input[0].  Verify that this is so.%s", NEWLINE);
1050 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
1051     for (i = 1; i < nin; i++)
1052 	if (in[i]->structure == GROUP_FIELD)
1053 	{
1054 fprintf(fd, "       if (in[%d] && DXGetObjectClass(in[%d]) != CLASS_CLIPPED)%s", i, i, NEWLINE);
1055 fprintf(fd, "       {%s", NEWLINE);
1056 fprintf(fd, "           DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1057 fprintf(fd, "               \"mismatching Field/Group objects\");%s", NEWLINE);
1058 fprintf(fd, "           return ERROR;%s", NEWLINE);
1059 fprintf(fd, "       }%s%s", NEWLINE, NEWLINE);
1060 	}
1061 }
1062 else
1063 fprintf(fd, "%s", NEWLINE);
1064 
1065 for (i = 0; i < nin; i++)
1066     if (in[i]->structure == VALUE)
1067     {
1068 fprintf(fd, "       /* input \"%s\" is Value */%s", in[i]->name, NEWLINE);
1069 fprintf(fd, "       new_in[%d] = in[%d];%s%s", i, i, NEWLINE, NEWLINE);
1070     }
1071     else
1072     {
1073 fprintf(fd, "       /* input \"%s\" is Field/Group */%s", in[i]->name, NEWLINE);
1074 fprintf(fd, "       if (in[%d])%s", i, NEWLINE);
1075 fprintf(fd, "         DXGetClippedInfo((Clipped)in[%d], &new_in[%d], NULL);%s",i,i, NEWLINE);
1076 fprintf(fd, "       else%s", NEWLINE);
1077 fprintf(fd, "         new_in[%d] = NULL;%s%s", i, NEWLINE, NEWLINE);
1078     }
1079 fprintf(fd, "%s", NEWLINE);
1080 fprintf(fd, "      /*%s", NEWLINE);
1081 fprintf(fd, "       * For all outputs that are Values, copy them to %s", NEWLINE);
1082 fprintf(fd, "       * child object list.  For all that are Field/Group,  get%s", NEWLINE);
1083 fprintf(fd, "       * the appropriate decendent and place it into the%s", NEWLINE);
1084 fprintf(fd, "       * child output object list.  Note that none should%s", NEWLINE);
1085 fprintf(fd, "       * be NULL (unlike inputs, which can default).%s", NEWLINE);
1086 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
1087 for (i = 0; i < nout; i++)
1088     if (out[i]->structure == VALUE)
1089     {
1090 fprintf(fd, "       /* output \"%s\" is Value */%s", out[i]->name, NEWLINE);
1091 fprintf(fd, "       new_out[%d] = out[%d];%s%s", i, i, NEWLINE, NEWLINE);
1092     }
1093     else
1094     {
1095 fprintf(fd, "       /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
1096 fprintf(fd, "       DXGetClippedInfo((Clipped)out[%d], &new_out[%d], NULL);%s%s", i,i, NEWLINE, NEWLINE);
1097     }
1098 
1099 fprintf(fd, "       if (! traverse(new_in, new_out))%s", NEWLINE);
1100 fprintf(fd, "         return ERROR;%s", NEWLINE);
1101 fprintf(fd, "%s", NEWLINE);
1102 
1103 if (n_GF_out)
1104 {
1105 fprintf(fd, "      /*%s", NEWLINE);
1106 fprintf(fd, "       * Now for each output that is not a Value, replace%s", NEWLINE);
1107 fprintf(fd, "       * the updated child into the object in the parent.%s", NEWLINE);
1108 fprintf(fd, "       */%s%s", NEWLINE, NEWLINE);
1109 for (i = 0; i < nout; i++)
1110     if (out[i]->structure == GROUP_FIELD)
1111     {
1112 fprintf(fd, "       /* output \"%s\" is Field/Group */%s", out[i]->name, NEWLINE);
1113 fprintf(fd, "       DXSetClippedObjects((Clipped)out[%d], new_out[%d], NULL);%s%s", i, i, NEWLINE, NEWLINE);
1114     }
1115 }
1116 
1117 fprintf(fd, "       return OK;%s", NEWLINE);
1118 fprintf(fd, "     }%s", NEWLINE);
1119 fprintf(fd, "%s", NEWLINE);
1120 fprintf(fd, "     default:%s", NEWLINE);
1121 fprintf(fd, "     {%s", NEWLINE);
1122 fprintf(fd, "       DXSetError(ERROR_BAD_CLASS, ");
1123 fprintf(fd, "\"encountered in object traversal\");%s", NEWLINE);
1124 fprintf(fd, "       return ERROR;%s", NEWLINE);
1125 fprintf(fd, "     }%s", NEWLINE);
1126 fprintf(fd, "  }%s", NEWLINE);
1127 fprintf(fd, "}%s", NEWLINE);
1128 fprintf(fd, "%s", NEWLINE);
1129 
1130 
1131 fprintf(fd, "static int%s", NEWLINE);
1132 fprintf(fd, "doLeaf(Object *in, Object *out)%s", NEWLINE);
1133 fprintf(fd, "{%s", NEWLINE);
1134 fprintf(fd, "  int i, result=0;%s", NEWLINE);
1135 fprintf(fd, "  Array array;%s", NEWLINE);
1136 fprintf(fd, "  Field field;%s", NEWLINE);
1137 fprintf(fd, "  Pointer *in_data[%d], *out_data[%d];%s", nin, nout, NEWLINE);
1138 fprintf(fd, "  int in_knt[%d], out_knt[%d];%s", nin, nout, NEWLINE);
1139 fprintf(fd, "  Type type;%s", NEWLINE);
1140 fprintf(fd, "  Category category;%s", NEWLINE);
1141 fprintf(fd, "  int rank, shape;%s", NEWLINE);
1142 fprintf(fd, "  Object attr, src_dependency_attr = NULL;%s", NEWLINE);
1143 fprintf(fd, "  char *src_dependency = NULL;%s", NEWLINE);
1144   if (in[0]->elementtype != ELT_NOT_REQUIRED)
1145   {
1146 fprintf(fd, "  Object element_type_attr;%s", NEWLINE);
1147 fprintf(fd, "  char *element_type;%s", NEWLINE);
1148   }
1149 
1150   if (in[0]->positions == GRID_REGULAR)
1151   {
1152 fprintf(fd, "  /*%s", NEWLINE);
1153 fprintf(fd, "   * Regular positions info%s", NEWLINE);
1154 fprintf(fd, "   */%s", NEWLINE);
1155 fprintf(fd, "  int p_knt = -1, p_dim, *p_counts = NULL;%s", NEWLINE);
1156 fprintf(fd, "  float *p_origin = NULL, *p_deltas = NULL;%s", NEWLINE);
1157   }
1158   else if (in[0]->positions == GRID_IRREGULAR)
1159   {
1160 fprintf(fd, "  /*%s", NEWLINE);
1161 fprintf(fd, "   * Irregular positions info%s", NEWLINE);
1162 fprintf(fd, "   */%s", NEWLINE);
1163 fprintf(fd, "  int p_knt, p_dim;%s", NEWLINE);
1164 fprintf(fd, "  float *p_positions;%s", NEWLINE);
1165   }
1166   else
1167 fprintf(fd, "  int p_knt = -1;%s", NEWLINE);
1168 
1169   if (in[0]->connections == GRID_REGULAR)
1170   {
1171 fprintf(fd, "  /*%s", NEWLINE);
1172 fprintf(fd, "   * Regular connections info%s", NEWLINE);
1173 fprintf(fd, "   */%s", NEWLINE);
1174 fprintf(fd, "  int c_knt, c_nv, c_dim, *c_counts = NULL;%s", NEWLINE);
1175   }
1176   else if (in[0]->connections == GRID_IRREGULAR)
1177   {
1178 fprintf(fd, "  /*%s", NEWLINE);
1179 fprintf(fd, "   * Irregular connections info%s", NEWLINE);
1180 fprintf(fd, "   */%s", NEWLINE);
1181 fprintf(fd, "  int c_knt, c_dim, c_nv;%s", NEWLINE);
1182 fprintf(fd, "  float *c_connections;%s", NEWLINE);
1183   }
1184   else
1185 fprintf(fd, "  int c_knt = -1;%s", NEWLINE);
1186 
1187 fprintf(fd, "%s", NEWLINE);
1188 
1189 if (in[0]->connections != GRID_NOT_REQUIRED ||
1190     in[0]->positions   != GRID_NOT_REQUIRED)
1191 {
1192 fprintf(fd, "  /*%s", NEWLINE);
1193 fprintf(fd, "   * positions and/or connections are required, so the first must%s", NEWLINE);
1194 fprintf(fd, "   * be a field.%s", NEWLINE);
1195 fprintf(fd, "   */%s", NEWLINE);
1196 fprintf(fd, "  if (DXGetObjectClass(in[0]) != CLASS_FIELD)%s", NEWLINE);
1197 fprintf(fd, "  {%s", NEWLINE);
1198 fprintf(fd, "      DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1199 fprintf(fd, "           \"positions and/or connections unavailable in array object\");%s", NEWLINE);
1200 fprintf(fd, "      goto error;%s", NEWLINE);
1201 fprintf(fd, "  }%s", NEWLINE);
1202 fprintf(fd, "  else%s", NEWLINE);
1203 }
1204 else
1205 fprintf(fd, "  if (DXGetObjectClass(in[0]) == CLASS_FIELD)%s", NEWLINE);
1206 
1207 fprintf(fd, "  {%s", NEWLINE);
1208 fprintf(fd, "%s", NEWLINE);
1209 fprintf(fd, "    field = (Field)in[0];%s", NEWLINE);
1210 fprintf(fd, "%s", NEWLINE);
1211 fprintf(fd, "    if (DXEmptyField(field))%s", NEWLINE);
1212 fprintf(fd, "      return OK;%s", NEWLINE);
1213 fprintf(fd, "%s", NEWLINE);
1214 fprintf(fd, "    /* %s", NEWLINE);
1215 fprintf(fd, "     * Determine the dependency of the source object's data%s", NEWLINE);
1216 fprintf(fd, "     * component.%s", NEWLINE);
1217 fprintf(fd, "     */%s", NEWLINE);
1218 fprintf(fd, "    src_dependency_attr = DXGetComponentAttribute(field, \"data\", \"dep\");%s", NEWLINE);
1219 fprintf(fd, "    if (! src_dependency_attr)%s", NEWLINE);
1220 fprintf(fd, "    {%s", NEWLINE);
1221 fprintf(fd, "      DXSetError(ERROR_MISSING_DATA, \"\\\"%s\\\" data component is missing a dependency attribute\");%s", in[0]->name, NEWLINE);
1222 fprintf(fd, "      goto error;%s", NEWLINE);
1223 fprintf(fd, "    }%s", NEWLINE);
1224 fprintf(fd, "%s", NEWLINE);
1225 fprintf(fd, "    if (DXGetObjectClass(src_dependency_attr) != CLASS_STRING)%s", NEWLINE);
1226 fprintf(fd, "    {%s", NEWLINE);
1227 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" dependency attribute\");%s", in[0]->name, NEWLINE);
1228 fprintf(fd, "      goto error;%s", NEWLINE);
1229 fprintf(fd, "    }%s", NEWLINE);
1230 fprintf(fd, "%s", NEWLINE);
1231 fprintf(fd, "    src_dependency = DXGetString((String)src_dependency_attr);%s", NEWLINE);
1232 fprintf(fd, "%s", NEWLINE);
1233 fprintf(fd, "    array = (Array)DXGetComponentValue(field, \"positions\");%s", NEWLINE);
1234 fprintf(fd, "    if (! array)%s", NEWLINE);
1235 fprintf(fd, "    {%s", NEWLINE);
1236 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" contains no positions component\");%s", in[0]->name, NEWLINE);
1237 fprintf(fd, "      goto error;%s", NEWLINE);
1238 fprintf(fd, "    }%s", NEWLINE);
1239 fprintf(fd, "%s", NEWLINE);
1240     if (in[0]->positions == GRID_REGULAR)
1241     {
1242 fprintf(fd, "    /* %s", NEWLINE);
1243 fprintf(fd, "     * Input[0] should have regular positions.  First check%s", NEWLINE);
1244 fprintf(fd, "     * that they are, and while you're at it, get the%s", NEWLINE);
1245 fprintf(fd, "     * dimensionality so we can size arrays later.%s", NEWLINE);
1246 fprintf(fd, "     */%s", NEWLINE);
1247 fprintf(fd, "    if (! DXQueryGridPositions(array, &p_dim, NULL, NULL, NULL))%s", NEWLINE);
1248 fprintf(fd, "    {%s", NEWLINE);
1249 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" positions component is not regular\");%s", in[0]->name, NEWLINE);
1250 fprintf(fd, "      goto error;%s", NEWLINE);
1251 fprintf(fd, "    }%s", NEWLINE);
1252 fprintf(fd, "%s", NEWLINE);
1253 fprintf(fd, "    /* %s", NEWLINE);
1254 fprintf(fd, "     * Allocate arrays for position counts, origin and deltas.%s", NEWLINE);
1255 fprintf(fd, "     * Check that the allocations worked, then get the info.%s", NEWLINE);
1256 fprintf(fd, "     */%s", NEWLINE);
1257 fprintf(fd, "    p_counts = (int   *)DXAllocate(p_dim*sizeof(int));%s", NEWLINE);
1258 fprintf(fd, "    p_origin = (float *)DXAllocate(p_dim*sizeof(float));%s", NEWLINE);
1259 fprintf(fd, "    p_deltas = (float *)DXAllocate(p_dim*p_dim*sizeof(float));%s", NEWLINE);
1260 fprintf(fd, "    if (! p_counts || ! p_origin || ! p_deltas)%s", NEWLINE);
1261 fprintf(fd, "      goto error;%s", NEWLINE);
1262 fprintf(fd, "%s", NEWLINE);
1263 fprintf(fd, "    DXQueryGridPositions(array, NULL, p_counts, p_origin, p_deltas);%s", NEWLINE);
1264 fprintf(fd, "    DXGetArrayInfo(array, &p_knt, NULL, NULL, NULL, NULL);%s", NEWLINE);
1265 fprintf(fd, "%s", NEWLINE);
1266     }
1267     else if (in[0]->positions == GRID_IRREGULAR)
1268     {
1269 fprintf(fd, "    /* %s", NEWLINE);
1270 fprintf(fd, "     * The user requested irregular positions.  So we%s", NEWLINE);
1271 fprintf(fd, "     * get the count, the dimensionality and a pointer to the%s", NEWLINE);
1272 fprintf(fd, "     * explicitly enumerated positions.  If the positions%s", NEWLINE);
1273 fprintf(fd, "     * are in fact regular, this will expand them.%s", NEWLINE);
1274 fprintf(fd, "     */%s", NEWLINE);
1275 fprintf(fd, "    DXGetArrayInfo(array, &p_knt, NULL, NULL, NULL, &p_dim);%s", NEWLINE);
1276 fprintf(fd, "%s", NEWLINE);
1277 fprintf(fd, "    p_positions = (float *)DXGetArrayData(array);%s", NEWLINE);
1278 fprintf(fd, "    if (! p_positions)%s", NEWLINE);
1279 fprintf(fd, "      goto error;%s", NEWLINE);
1280 fprintf(fd, "%s", NEWLINE);
1281     }
1282     else
1283 fprintf(fd, "    DXGetArrayInfo(array, &p_knt, NULL, NULL, NULL, NULL);%s", NEWLINE);
1284 
1285     if (in[0]->connections == GRID_REGULAR ||
1286         in[0]->connections == GRID_IRREGULAR ||
1287 	in[0]->elementtype != ELT_NOT_REQUIRED)
1288     {
1289 fprintf(fd, "    array = (Array)DXGetComponentValue(field, \"connections\");%s", NEWLINE);
1290 fprintf(fd, "    if (! array)%s", NEWLINE);
1291 fprintf(fd, "    {%s", NEWLINE);
1292 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" contains no connections component\");%s", in[0]->name, NEWLINE);
1293 fprintf(fd, "      goto error;%s", NEWLINE);
1294 fprintf(fd, "    }%s", NEWLINE);
1295 fprintf(fd, "%s", NEWLINE);
1296 
1297 	if (in[0]->elementtype != ELT_NOT_REQUIRED)
1298 	{
1299 	    char *str;
1300 
1301 	    if (! GetElementTypeString(in[0]->elementtype, &str))
1302 		goto error;
1303 
1304 fprintf(fd, "    /*%s", NEWLINE);
1305 fprintf(fd, "     * Check that the field's element type matches that requested%s", NEWLINE);
1306 fprintf(fd, "     */%s", NEWLINE);
1307 fprintf(fd, "    element_type_attr = DXGetAttribute((Object)array, \"element type\");%s", NEWLINE);
1308 fprintf(fd, "    if (! element_type_attr)%s", NEWLINE);
1309 fprintf(fd, "    {%s", NEWLINE);
1310 fprintf(fd, "        DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1311 fprintf(fd, "            \"input \\\"%s\\\" has no element type attribute\");%s", in[0]->name, NEWLINE);
1312 fprintf(fd, "        goto error;%s", NEWLINE);
1313 fprintf(fd, "    }%s%s", NEWLINE, NEWLINE);
1314 fprintf(fd, "    if (DXGetObjectClass(element_type_attr) != CLASS_STRING)%s", NEWLINE);
1315 fprintf(fd, "    {%s", NEWLINE);
1316 fprintf(fd, "        DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1317 fprintf(fd, "            \"input \\\"%s\\\" element type attribute is not a string\");%s", in[0]->name, NEWLINE);
1318 fprintf(fd, "        goto error;%s", NEWLINE);
1319 fprintf(fd, "    }%s%s", NEWLINE, NEWLINE);
1320 fprintf(fd, "    if (strcmp(DXGetString((String)element_type_attr), \"%s\"))%s", str, NEWLINE);
1321 fprintf(fd, "    {%s", NEWLINE);
1322 fprintf(fd, "        DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1323 fprintf(fd, "            \"input \\\"%s\\\" invalid element type\");%s", in[0]->name, NEWLINE);
1324 fprintf(fd, "        goto error;%s", NEWLINE);
1325 fprintf(fd, "    }%s%s", NEWLINE, NEWLINE);
1326 	}
1327 
1328 	if (in[0]->connections == GRID_REGULAR)
1329 	{
1330 fprintf(fd, "    /* %s", NEWLINE);
1331 fprintf(fd, "     * Input[0] should have regular connections.  First check%s", NEWLINE);
1332 fprintf(fd, "     * that they are, and while you're at it, get the%s", NEWLINE);
1333 fprintf(fd, "     * dimensionality so we can size an array later.%s", NEWLINE);
1334 fprintf(fd, "     */%s", NEWLINE);
1335 fprintf(fd, "    if (! DXQueryGridConnections(array, &c_dim, NULL))%s", NEWLINE);
1336 fprintf(fd, "    {%s", NEWLINE);
1337 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" connections component is not regular\");%s", in[0]->name, NEWLINE);
1338 fprintf(fd, "      goto error;%s", NEWLINE);
1339 fprintf(fd, "    }%s", NEWLINE);
1340 fprintf(fd, "%s", NEWLINE);
1341 fprintf(fd, "    /* %s", NEWLINE);
1342 fprintf(fd, "     * Allocate arrays for connections counts.%s", NEWLINE);
1343 fprintf(fd, "     * Check that the allocation worked, then get the info.%s", NEWLINE);
1344 fprintf(fd, "     */%s", NEWLINE);
1345 fprintf(fd, "    c_counts = (int   *)DXAllocate(c_dim*sizeof(int));%s", NEWLINE);
1346 fprintf(fd, "    if (! c_counts)%s", NEWLINE);
1347 fprintf(fd, "      goto error;%s", NEWLINE);
1348 fprintf(fd, "%s", NEWLINE);
1349 fprintf(fd, "    DXQueryGridConnections(array, NULL, c_counts);%s", NEWLINE);
1350 fprintf(fd, "    DXGetArrayInfo(array, &c_knt, NULL, NULL, NULL, &c_nv);%s", NEWLINE);
1351 fprintf(fd, "%s", NEWLINE);
1352 	}
1353 	else if (in[0]->connections == GRID_IRREGULAR)
1354 	{
1355 fprintf(fd, "    /* %s", NEWLINE);
1356 fprintf(fd, "     * The user requested irregular connections.  So we%s", NEWLINE);
1357 fprintf(fd, "     * get the count, the dimensionality and a pointer to the%s", NEWLINE);
1358 fprintf(fd, "     * explicitly enumerated elements.  If the positions%s", NEWLINE);
1359 fprintf(fd, "     * are in fact regular, this will expand them.%s", NEWLINE);
1360 fprintf(fd, "     */%s", NEWLINE);
1361 fprintf(fd, "    DXGetArrayInfo(array, &c_knt, NULL, NULL, NULL, &c_nv);%s", NEWLINE);
1362 fprintf(fd, "%s", NEWLINE);
1363 fprintf(fd, "    c_connections = (float *)DXGetArrayData(array);%s", NEWLINE);
1364 fprintf(fd, "    if (! c_connections)%s", NEWLINE);
1365 fprintf(fd, "      goto error;%s", NEWLINE);
1366 fprintf(fd, "%s", NEWLINE);
1367 	}
1368 	else
1369 fprintf(fd, "    DXGetArrayInfo(array, &c_knt, NULL, NULL, NULL, NULL);%s", NEWLINE);
1370     }
1371     else
1372     {
1373 fprintf(fd, "    /* %s", NEWLINE);
1374 fprintf(fd, "     * If there are connections, get their count so that%s", NEWLINE);
1375 fprintf(fd, "     * connections-dependent result arrays can be sized.%s", NEWLINE);
1376 fprintf(fd, "     */%s", NEWLINE);
1377 fprintf(fd, "    array = (Array)DXGetComponentValue(field, \"connections\");%s", NEWLINE);
1378 fprintf(fd, "    if (array)%s", NEWLINE);
1379 fprintf(fd, "        DXGetArrayInfo(array, &c_knt, NULL, NULL, NULL, NULL);%s", NEWLINE);
1380     }
1381 
1382 fprintf(fd, "  }%s", NEWLINE);
1383 
1384   for (i = 0; i < nin; i++)
1385   {
1386     char *type, *rank, *shape;
1387 
1388     if (! GetDXDataType(in[i]->datatype, &type) ||
1389           ! GetDXDataShape(in[i]->datashape, &rank, &shape))
1390           goto error;
1391 
1392 
1393 fprintf(fd, "  /*%s", NEWLINE);
1394 fprintf(fd, "   * If the input argument is not NULL then we get the %s", NEWLINE);
1395 fprintf(fd, "   * data array: either the object itself, if its an %s", NEWLINE);
1396 fprintf(fd, "   * array, or the data component if the argument is a field%s", NEWLINE);
1397 fprintf(fd, "   */%s", NEWLINE);
1398 fprintf(fd, "  if (! in[%d])%s", i, NEWLINE);
1399 fprintf(fd, "  {%s", NEWLINE);
1400 fprintf(fd, "    array = NULL;%s", NEWLINE);
1401 fprintf(fd, "    in_data[%d] = NULL;%s", i, NEWLINE);
1402 fprintf(fd, "    in_knt[%d] = NULL;%s", i, NEWLINE);
1403 fprintf(fd, "  }%s", NEWLINE);
1404 fprintf(fd, "  else%s", NEWLINE);
1405 fprintf(fd, "  {%s", NEWLINE);
1406 fprintf(fd, "    if (DXGetObjectClass(in[%d]) == CLASS_ARRAY)%s", i, NEWLINE);
1407 fprintf(fd, "    {%s", NEWLINE);
1408 fprintf(fd, "      array = (Array)in[%d];%s", i, NEWLINE);
1409 fprintf(fd, "    }%s", NEWLINE);
1410 fprintf(fd, "    else if (DXGetObjectClass(in[%d]) == CLASS_STRING)%s", i, NEWLINE);
1411 fprintf(fd, "    {%s", NEWLINE);
1412 fprintf(fd, "      in_data[%d] = (Pointer *)DXGetString((String)in[%d]);%s",i,i, NEWLINE);
1413 fprintf(fd, "      in_knt[%d] = 1;%s",i, NEWLINE);
1414 fprintf(fd, "    }%s", NEWLINE);
1415 fprintf(fd, "    else%s", NEWLINE);
1416 fprintf(fd, "    {%s", NEWLINE);
1417 fprintf(fd, "      if (DXGetObjectClass(in[%d]) != CLASS_FIELD)%s", i, NEWLINE);
1418 fprintf(fd, "      {%s", NEWLINE);
1419 fprintf(fd, "        DXSetError(ERROR_BAD_CLASS, \"\\\"%s\\\" should be a field\");%s", in[i]->name, NEWLINE);
1420 fprintf(fd, "        goto error;%s", NEWLINE);
1421 fprintf(fd, "      }%s", NEWLINE);
1422 fprintf(fd, "%s", NEWLINE);
1423 fprintf(fd, "      array = (Array)DXGetComponentValue((Field)in[%d], \"data\");%s", i, NEWLINE);
1424 fprintf(fd, "      if (! array)%s", NEWLINE);
1425 fprintf(fd, "      {%s", NEWLINE);
1426 fprintf(fd, "        DXSetError(ERROR_MISSING_DATA, \"\\\"%s\\\" has no data component\");%s", in[i]->name, NEWLINE);
1427 fprintf(fd, "        goto error;%s", NEWLINE);
1428 fprintf(fd, "      }%s", NEWLINE);
1429 fprintf(fd, "%s", NEWLINE);
1430 fprintf(fd, "      if (DXGetObjectClass((Object)array) != CLASS_ARRAY)%s", NEWLINE);
1431 fprintf(fd, "      {%s", NEWLINE);
1432 fprintf(fd, "        DXSetError(ERROR_BAD_CLASS, \"data component of \\\"%s\\\" should be an array\");%s", in[i]->name, NEWLINE);
1433 fprintf(fd, "        goto error;%s", NEWLINE);
1434 fprintf(fd, "      }%s", NEWLINE);
1435 fprintf(fd, "    }%s", NEWLINE);
1436 fprintf(fd, "%s", NEWLINE);
1437 
1438       if (in[i]->dependency != NO_DEPENDENCY)
1439       {
1440 fprintf(fd, "    /* %s", NEWLINE);
1441 fprintf(fd, "     * get the dependency of the data component%s", NEWLINE);
1442 fprintf(fd, "     */%s", NEWLINE);
1443 fprintf(fd, "    attr = DXGetAttribute((Object)array, \"dep\");%s", NEWLINE);
1444 fprintf(fd, "    if (! attr)%s", NEWLINE);
1445 fprintf(fd, "    {%s", NEWLINE);
1446 fprintf(fd, "      DXSetError(ERROR_MISSING_DATA, \"data component of \\\"%s\\\" has no dependency\");%s", in[i]->name, NEWLINE);
1447 fprintf(fd, "      goto error;%s", NEWLINE);
1448 fprintf(fd, "    }%s", NEWLINE);
1449 fprintf(fd, "%s", NEWLINE);
1450 fprintf(fd, "    if (DXGetObjectClass(attr) != CLASS_STRING)%s", NEWLINE);
1451 fprintf(fd, "    {%s", NEWLINE);
1452 fprintf(fd, "      DXSetError(ERROR_BAD_CLASS, \"dependency attribute of data component of \\\"%s\\\"\");%s", in[i]->name, NEWLINE);
1453 fprintf(fd, "      goto error;%s", NEWLINE);
1454 fprintf(fd, "    }%s", NEWLINE);
1455 fprintf(fd, "%s", NEWLINE);
1456 	if (in[i]->dependency == DEP_INPUT && i != 0)
1457 	{
1458 fprintf(fd, "  /*%s", NEWLINE);
1459 fprintf(fd, "   * The dependency of this arg should match input[0].%s", NEWLINE);
1460 fprintf(fd, "   */%s", NEWLINE);
1461 fprintf(fd, "    if (strcmp(src_dependency, DXGetString((String)attr)))%s", NEWLINE);
1462 fprintf(fd, "    {%s", NEWLINE);
1463 fprintf(fd, "      DXSetError(ERROR_DATA_INVALID, \"data dependency of \\\"%s\\\" must match \\\"%s\\\"\");%s",
1464 						in[i]->name, in[0]->name, NEWLINE);
1465 fprintf(fd, "      goto error;%s", NEWLINE);
1466 fprintf(fd, "    }%s", NEWLINE);
1467 	}
1468 	else if (in[i]->dependency == DEP_POSITIONS)
1469 	{
1470 fprintf(fd, "  /*%s", NEWLINE);
1471 fprintf(fd, "   * The dependency of this arg should be positions%s", NEWLINE);
1472 fprintf(fd, "   */%s", NEWLINE);
1473 fprintf(fd, "    if (strcmp(\"positions\", DXGetString((String)attr)))%s", NEWLINE);
1474 fprintf(fd, "    {%s", NEWLINE);
1475 fprintf(fd, "      DXSetError(ERROR_DATA_INVALID, \"data dependency of \\\"%s\\\" must be positions\");%s",
1476 						in[i]->name, NEWLINE);
1477 fprintf(fd, "      goto error;%s", NEWLINE);
1478 fprintf(fd, "    }%s", NEWLINE);
1479 	}
1480 	else if (in[i]->dependency == DEP_CONNECTIONS)
1481 	{
1482 fprintf(fd, "  /*%s", NEWLINE);
1483 fprintf(fd, "   * The dependency of this arg should be connections%s", NEWLINE);
1484 fprintf(fd, "   */%s", NEWLINE);
1485 fprintf(fd, "    if (strcmp(\"connections\", DXGetString((String)attr)))%s", NEWLINE);
1486 fprintf(fd, "    {%s", NEWLINE);
1487 fprintf(fd, "      DXSetError(ERROR_DATA_INVALID, \"data dependency of \\\"%s\\\" must be connections\");%s",
1488 						in[i]->name, NEWLINE);
1489 fprintf(fd, "      goto error;%s", NEWLINE);
1490 fprintf(fd, "    }%s", NEWLINE);
1491 	}
1492       }
1493 fprintf(fd, "%s", NEWLINE);
1494 fprintf(fd, "    if (DXGetObjectClass(in[%d]) != CLASS_STRING)", i);
1495 fprintf(fd, "    {%s", NEWLINE);
1496 fprintf(fd, "       DXGetArrayInfo(array, &in_knt[%d], &type, &category, &rank, &shape);%s", i, NEWLINE);
1497 fprintf(fd, "       if (type != %s || category != CATEGORY_REAL ||%s", type, NEWLINE);
1498 
1499   if (! strcmp(rank, "0"))
1500 fprintf(fd, "             !((rank == 0) || ((rank == 1)&&(shape == 1))))%s", NEWLINE);
1501   else
1502 fprintf(fd, "           rank != %s || shape != %s)%s", rank, shape, NEWLINE);
1503 
1504 fprintf(fd, "       {%s", NEWLINE);
1505 fprintf(fd, "         DXSetError(ERROR_DATA_INVALID, \"input \\\"%s\\\"\");%s", in[i]->name, NEWLINE);
1506 fprintf(fd, "         goto error;%s", NEWLINE);
1507 fprintf(fd, "       }%s", NEWLINE);
1508 fprintf(fd, "%s", NEWLINE);
1509 fprintf(fd, "       in_data[%d] = DXGetArrayData(array);%s", i, NEWLINE);
1510 fprintf(fd, "       if (! in_data[%d])%s", i, NEWLINE);
1511 fprintf(fd, "          goto error;%s", NEWLINE);
1512 fprintf(fd, "%s", NEWLINE);
1513 fprintf(fd, "    }%s", NEWLINE);
1514 fprintf(fd, "  }%s", NEWLINE);
1515     }
1516 
1517   for (i = 0; i < nout; i++)
1518   {
1519     char *type, *rank, *shape;
1520 
1521     if (! GetDXDataType(out[i]->datatype, &type) ||
1522 	! GetDXDataShape(out[i]->datashape, &rank, &shape))
1523 	goto error;
1524 
1525     if (out[i]->structure == VALUE)
1526     {
1527 fprintf(fd, "  if (! out[%d])%s", i, NEWLINE);
1528 fprintf(fd, "  {%s", NEWLINE);
1529 fprintf(fd, "    DXSetError(ERROR_INTERNAL, \"Value output %d (\\\"%s\\\") is NULL\");%s", i, out[i]->name, NEWLINE);
1530 fprintf(fd, "    goto error;%s", NEWLINE);
1531 fprintf(fd, "  }%s", NEWLINE);
1532 fprintf(fd, "  if (DXGetObjectClass(out[%d]) != CLASS_ARRAY)%s", i, NEWLINE);
1533 fprintf(fd, "  {%s", NEWLINE);
1534 fprintf(fd, "    DXSetError(ERROR_INTERNAL, \"Value output %d (\\\"%s\\\") is not an array\");%s", i, out[i]->name, NEWLINE);
1535 fprintf(fd, "    goto error;%s", NEWLINE);
1536 fprintf(fd, "  }%s", NEWLINE);
1537 fprintf(fd, "%s", NEWLINE);
1538 fprintf(fd, "  array = (Array)out[%d];%s", i, NEWLINE);
1539 fprintf(fd, "%s", NEWLINE);
1540 fprintf(fd, "  DXGetArrayInfo(array, &out_knt[%d], &type, &category, &rank, &shape);%s", i, NEWLINE);
1541 fprintf(fd, "  if (type != %s || category != CATEGORY_REAL ||%s", type, NEWLINE);
1542 	if (out[i]->datashape == SCALAR)
1543 fprintf(fd, "      !((rank == 0) || ((rank == 1)&&(shape == 1))))%s", NEWLINE);
1544 	else
1545 fprintf(fd, "      rank != %s || shape != %s)%s", rank, shape, NEWLINE);
1546 fprintf(fd, "  {%s", NEWLINE);
1547 fprintf(fd, "    DXSetError(ERROR_DATA_INVALID, \"Value output \\\"%s\\\" has bad type\");%s", out[i]->name, NEWLINE);
1548 fprintf(fd, "    goto error;%s", NEWLINE);
1549 fprintf(fd, "  }%s", NEWLINE);
1550 fprintf(fd, "%s", NEWLINE);
1551     }
1552     else
1553     {
1554 fprintf(fd, "  /*%s", NEWLINE);
1555 fprintf(fd, "   * Create an output data array typed according to the%s", NEWLINE);
1556 fprintf(fd, "   * specification given%s", NEWLINE);
1557 fprintf(fd, "   */%s", NEWLINE);
1558 fprintf(fd, "  array = DXNewArray(%s, CATEGORY_REAL, %s, %s);%s", type, rank, shape, NEWLINE);
1559 fprintf(fd, "  if (! array)%s", NEWLINE);
1560 fprintf(fd, "    goto error;%s", NEWLINE);
1561 fprintf(fd, "%s", NEWLINE);
1562       if (out[i]->dependency == DEP_INPUT)
1563       {
1564 fprintf(fd, "  /*%s", NEWLINE);
1565 fprintf(fd, "   * Set the dependency of the array to the same as the first input%s", NEWLINE);
1566 fprintf(fd, "   */%s", NEWLINE);
1567 fprintf(fd, "  if (src_dependency_attr != NULL)%s", NEWLINE);
1568 fprintf(fd, "    if (! DXSetAttribute((Object)array, \"dep\", src_dependency_attr))%s", NEWLINE);
1569 fprintf(fd, "      goto error;%s%s", NEWLINE, NEWLINE);
1570 fprintf(fd, "  /*%s", NEWLINE);
1571 fprintf(fd, "   * The size and dependency of this output data array will %s", NEWLINE);
1572 fprintf(fd, "   * match that of input[0]%s", NEWLINE);
1573 fprintf(fd, "   */%s", NEWLINE);
1574 fprintf(fd, "  out_knt[%d] = in_knt[0];%s", i, NEWLINE);
1575       }
1576       else if (out[i]->dependency == DEP_POSITIONS)
1577       {
1578 fprintf(fd, "  /*%s", NEWLINE);
1579 fprintf(fd, "   * This output data array will be dep positions - and sized%s", NEWLINE);
1580 fprintf(fd, "   * appropriately - if the appropriate size is known%s", NEWLINE);
1581 fprintf(fd, "   */%s", NEWLINE);
1582 fprintf(fd, "  if (p_knt == -1)%s", NEWLINE);
1583 fprintf(fd, "  {%s", NEWLINE);
1584 fprintf(fd, "    DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1585 fprintf(fd, "      \"cannot make output \\\"%s\\\" dep on positions because no positions were found in input[0]\");%s", out[i]->name, NEWLINE);
1586 fprintf(fd, "    goto error;%s", NEWLINE);
1587 fprintf(fd, "  }%s%s", NEWLINE, NEWLINE);
1588 fprintf(fd, "  out_knt[%d] = p_knt;%s", i, NEWLINE);
1589 fprintf(fd, "%s", NEWLINE);
1590 fprintf(fd, "  if (! DXSetAttribute((Object)array, \"dep\", (Object)DXNewString(\"positions\")))%s", NEWLINE);
1591 fprintf(fd, "    goto error;%s", NEWLINE);
1592       }
1593       else if (out[i]->dependency == DEP_CONNECTIONS)
1594       {
1595 fprintf(fd, "  /*%s", NEWLINE);
1596 fprintf(fd, "   * This output data array will be dep connections - and sized%s", NEWLINE);
1597 fprintf(fd, "   * appropriately - if the appropriate size is known%s", NEWLINE);
1598 fprintf(fd, "   */%s", NEWLINE);
1599 fprintf(fd, "  if (c_knt == -1)%s", NEWLINE);
1600 fprintf(fd, "  {%s", NEWLINE);
1601 fprintf(fd, "    DXSetError(ERROR_DATA_INVALID,%s", NEWLINE);
1602 fprintf(fd, "      \"cannot make output \\\"%s\\\" dep on connections because no connections were found in input \\\"%s\\\"\");%s", out[i]->name, in[i]->name, NEWLINE);
1603 fprintf(fd, "    goto error;%s", NEWLINE);
1604 fprintf(fd, "  }%s%s", NEWLINE, NEWLINE);
1605 fprintf(fd, "  out_knt[%d] = c_knt;%s", i, NEWLINE);
1606 fprintf(fd, "%s", NEWLINE);
1607 fprintf(fd, "  if (! DXSetAttribute((Object)array, \"dep\", (Object)DXNewString(\"connections\")))%s", NEWLINE);
1608 fprintf(fd, "    goto error;%s", NEWLINE);
1609       }
1610       else
1611       {
1612 	ErrorMessage("field parameter must have a dependency set%s", NEWLINE);
1613 	goto error;
1614       }
1615 
1616 fprintf(fd, "  /*%s", NEWLINE);
1617 fprintf(fd, "   * Actually allocate the array data space%s", NEWLINE);
1618 fprintf(fd, "   */%s", NEWLINE);
1619 fprintf(fd, "  if (! DXAddArrayData(array, 0, out_knt[%d], NULL))%s", i, NEWLINE);
1620 fprintf(fd, "    goto error;%s", NEWLINE);
1621 fprintf(fd, "%s", NEWLINE);
1622 fprintf(fd, "  /*%s", NEWLINE);
1623 fprintf(fd, "   * If the output vector slot is not NULL, then it better be a field, and%s", NEWLINE);
1624 fprintf(fd, "   * we'll add the new array to it as its data component (delete any prior%s", NEWLINE);
1625 fprintf(fd, "   * data component so that its attributes won't overwrite the new component's)%s", NEWLINE);
1626 fprintf(fd, "   * Otherwise, place the new array into the out vector.%s", NEWLINE);
1627 fprintf(fd, "   */%s", NEWLINE);
1628 fprintf(fd, "  if (out[%d])%s", i, NEWLINE);
1629 fprintf(fd, "  {%s", NEWLINE);
1630 fprintf(fd, "    if (DXGetObjectClass(out[%d]) != CLASS_FIELD)%s", i, NEWLINE);
1631 fprintf(fd, "    {%s", NEWLINE);
1632 fprintf(fd, "      DXSetError(ERROR_INTERNAL, \"non-field object found in output vector\");%s", NEWLINE);
1633 fprintf(fd, "      goto error;%s", NEWLINE);
1634 fprintf(fd, "    }%s%s", NEWLINE, NEWLINE);
1635 fprintf(fd, "    if (DXGetComponentValue((Field)out[%d], \"data\"))%s", i, NEWLINE);
1636 fprintf(fd, "      DXDeleteComponent((Field)out[%d], \"data\");%s%s", i, NEWLINE, NEWLINE);
1637 fprintf(fd, "    if (! DXSetComponentValue((Field)out[%d], \"data\", (Object)array))%s", i, NEWLINE);
1638 fprintf(fd, "      goto error;%s", NEWLINE);
1639 fprintf(fd, "%s", NEWLINE);
1640 fprintf(fd, "  }%s", NEWLINE);
1641 fprintf(fd, "  else%s", NEWLINE);
1642 fprintf(fd, "    out[%d] = (Object)array;%s", i, NEWLINE);
1643     }
1644 
1645 fprintf(fd, "  /*%s", NEWLINE);
1646 fprintf(fd, "   * Now get the pointer to the contents of the array%s", NEWLINE);
1647 fprintf(fd, "   */%s", NEWLINE);
1648 fprintf(fd, "  out_data[%d] = DXGetArrayData(array);%s", i, NEWLINE);
1649 fprintf(fd, "  if (! out_data[%d])%s", i, NEWLINE);
1650 fprintf(fd, "    goto error;%s", NEWLINE);
1651 fprintf(fd, "%s", NEWLINE);
1652   }
1653 fprintf(fd, "  /*%s", NEWLINE);
1654 fprintf(fd, "   * Call the user's routine.  Check the return code.%s", NEWLINE);
1655 fprintf(fd, "   */%s", NEWLINE);
1656 fprintf(fd, "  result = %s_worker(%s", mod->name, NEWLINE);
1657 
1658     open = 0;
1659 
1660     if (in[0]->positions == GRID_REGULAR)
1661     {
1662 fprintf(fd, "    p_knt, p_dim, p_counts, p_origin, p_deltas");
1663 	open = 1;
1664     }
1665     else if (in[0]->positions == GRID_IRREGULAR)
1666     {
1667 fprintf(fd, "    p_knt, p_dim, (float *)p_positions");
1668 	open = 1;
1669     }
1670 
1671     if (in[0]->connections == GRID_REGULAR)
1672     {
1673 fprintf(fd, "%s    c_knt, c_nv, c_counts", (open)?COMMA_AND_NEWLINE:"");
1674 	open = 1;
1675     }
1676     else if (in[0]->connections == GRID_IRREGULAR)
1677     {
1678 fprintf(fd, "%s    c_knt, c_nv, (int *)c_connections", (open)?COMMA_AND_NEWLINE:"");
1679 	open = 1;
1680     }
1681 
1682     for (i = 0; i < nin; i++)
1683     {
1684 	char *type;
1685 	GetCDataType(in[i]->datatype, &type);
1686 fprintf(fd, "%s    in_knt[%d], (%s *)in_data[%d]", (open)?COMMA_AND_NEWLINE:"", i, type, i);
1687 	open = 1;
1688     }
1689 
1690     for (i = 0; i < nout; i++)
1691     {
1692 	char *type;
1693 	GetCDataType(out[i]->datatype, &type);
1694 fprintf(fd, "%s    out_knt[%d], (%s *)out_data[%d]", (open)?COMMA_AND_NEWLINE:"", i, type, i);
1695 	open = 1;
1696     }
1697 
1698 fprintf(fd, ");%s%s", NEWLINE, NEWLINE);
1699 fprintf(fd, "  if (! result)%s", NEWLINE);
1700 fprintf(fd, "     if (DXGetError()==ERROR_NONE)%s", NEWLINE);
1701 fprintf(fd, "        DXSetError(ERROR_INTERNAL, \"error return from user routine\");%s", NEWLINE);
1702 fprintf(fd, "%s", NEWLINE);
1703 fprintf(fd, "  /*%s", NEWLINE);
1704 fprintf(fd, "   * In either event, clean up allocated memory%s", NEWLINE);
1705 fprintf(fd, "   */%s", NEWLINE);
1706 fprintf(fd, "%s", NEWLINE);
1707 fprintf(fd, "error:%s", NEWLINE);
1708 if (in[0]->positions == GRID_REGULAR)
1709 {
1710 fprintf(fd, "  /*%s", NEWLINE);
1711 fprintf(fd, "   * Free the arrays allocated for the regular positions%s", NEWLINE);
1712 fprintf(fd, "   * counts, origin and deltas%s", NEWLINE);
1713 fprintf(fd, "   */%s", NEWLINE);
1714 fprintf(fd, "  DXFree((Pointer)p_counts);%s", NEWLINE);
1715 fprintf(fd, "  DXFree((Pointer)p_origin);%s", NEWLINE);
1716 fprintf(fd, "  DXFree((Pointer)p_deltas);%s", NEWLINE);
1717 }
1718 if (in[0]->connections == GRID_REGULAR)
1719 {
1720 fprintf(fd, "  /*%s", NEWLINE);
1721 fprintf(fd, "   * Free the arrays allocated for the regular connections%s", NEWLINE);
1722 fprintf(fd, "   * counts%s", NEWLINE);
1723 fprintf(fd, "   */%s", NEWLINE);
1724 fprintf(fd, "  DXFree((Pointer)c_counts);%s", NEWLINE);
1725 }
1726 fprintf(fd, "  return result;%s", NEWLINE);
1727 fprintf(fd, "}%s%s", NEWLINE, NEWLINE);
1728 
1729 fprintf(fd, "int%s%s_worker(\n", NEWLINE, mod->name);
1730 
1731     open = 0;
1732 
1733     if (in[0]->positions == GRID_REGULAR)
1734     {
1735 fprintf(fd, "    int p_knt, int p_dim, int *p_counts, float *p_origin, float *p_deltas");
1736 	open = 1;
1737     }
1738     else if (in[0]->positions == GRID_IRREGULAR)
1739     {
1740 fprintf(fd, "    int p_knt, int p_dim, float *p_positions");
1741 	open = 1;
1742     }
1743 
1744     if (in[0]->connections == GRID_REGULAR)
1745     {
1746 fprintf(fd, "%s    int c_knt, int c_nv, int *c_counts", (open)?COMMA_AND_NEWLINE:"");
1747 	open = 1;
1748     }
1749     else if (in[0]->connections == GRID_IRREGULAR)
1750     {
1751 fprintf(fd, "%s    int c_knt, int c_nv, int *c_connections", (open)?COMMA_AND_NEWLINE:"");
1752 	open = 1;
1753     }
1754 
1755     for (i = 0; i < nin; i++)
1756     {
1757 	char *type;
1758 	GetCDataType(in[i]->datatype, &type);
1759 fprintf(fd, "%s    int %s_knt, %s *%s_data", (open)?COMMA_AND_NEWLINE:"", in[i]->name, type, in[i]->name);
1760 	open = 1;
1761     }
1762 
1763     for (i = 0; i < nout; i++)
1764     {
1765 	char *type;
1766 	GetCDataType(out[i]->datatype, &type);
1767 fprintf(fd, "%s    int %s_knt, %s *%s_data", (open)?COMMA_AND_NEWLINE:"", out[i]->name, type, out[i]->name);
1768 	open = 1;
1769     }
1770 
1771 fprintf(fd, ")%s{%s", NEWLINE, NEWLINE);
1772 fprintf(fd, "  /*%s", NEWLINE);
1773 fprintf(fd, "   * The arguments to this routine are:%s", NEWLINE);
1774 fprintf(fd, "   *%s", NEWLINE);
1775 
1776     if (in[0]->positions == GRID_REGULAR)
1777     {
1778 fprintf(fd, "   *  p_knt:           total count of input positions%s", NEWLINE);
1779 fprintf(fd, "   *  p_dim:           dimensionality of input positions%s", NEWLINE);
1780 fprintf(fd, "   *  p_counts:        count along each axis of regular positions grid%s", NEWLINE);
1781 fprintf(fd, "   *  p_origin:        origin of regular positions grid%s", NEWLINE);
1782 fprintf(fd, "   *  p_deltas:        regular positions delta vectors%s", NEWLINE);
1783     }
1784     else if (in[0]->positions == GRID_IRREGULAR)
1785     {
1786 fprintf(fd, "   *  p_knt:           total count of input positions%s", NEWLINE);
1787 fprintf(fd, "   *  p_dim:           dimensionality of input positions%s", NEWLINE);
1788 fprintf(fd, "   *  p_positions:     pointer to positions list%s", NEWLINE);
1789     }
1790 
1791     if (in[0]->connections == GRID_REGULAR)
1792     {
1793 fprintf(fd, "   *  c_knt:           total count of input connections elements%s", NEWLINE);
1794 fprintf(fd, "   *  c_nv:            number of vertices per element%s", NEWLINE);
1795 fprintf(fd, "   *  c_counts:        vertex count along each axis of regular positions grid%s", NEWLINE);
1796     }
1797     else if (in[0]->connections == GRID_IRREGULAR)
1798     {
1799 fprintf(fd, "   *  c_knt:           total count of input connections elements%s", NEWLINE);
1800 fprintf(fd, "   *  c_nv:            number of vertices per element%s", NEWLINE);
1801 fprintf(fd, "   *  c_connections:   pointer to connections list%s", NEWLINE);
1802     }
1803 
1804 fprintf(fd, "   *%s", NEWLINE);
1805 fprintf(fd, "   * The following are inputs and therefore are read-only.  The default%s", NEWLINE);
1806 fprintf(fd, "   * values are given and should be used if the knt is 0.%s", NEWLINE);
1807 fprintf(fd, "   *%s", NEWLINE);
1808     for (i = 0; i < nin; i++)
1809     {
1810 fprintf(fd, "   * %s_knt, %s_data:  count and pointer for input \"%s\"%s", in[i]->name, in[i]->name, in[i]->name, NEWLINE);
1811 	if (in[i]->default_value)
1812 	    if (in[i]->descriptive == TRUE)
1813 fprintf(fd, "   *                   descriptive default value is \"%s\"%s", in[i]->default_value, NEWLINE);
1814 	    else
1815 fprintf(fd, "   *                   non-descriptive default value is \"%s\"%s", in[i]->default_value, NEWLINE);
1816         else
1817 fprintf(fd, "   *                   no default value given.%s", NEWLINE);
1818     }
1819 
1820 fprintf(fd, "   *%s", NEWLINE);
1821 fprintf(fd, "   *  The output data buffer(s) are writable.%s", NEWLINE);
1822 fprintf(fd, "   *  The output buffer(s) are preallocated based on%s", NEWLINE);
1823 fprintf(fd, "   *     the dependency (positions or connections),%s", NEWLINE);
1824 fprintf(fd, "   *     the size of the corresponding positions or%s", NEWLINE);
1825 fprintf(fd, "   *     connections component in the first input, and%s", NEWLINE);
1826 fprintf(fd, "   *     the data type.%s", NEWLINE);
1827 fprintf(fd, "   *%s", NEWLINE);
1828     for (i = 0; i < nout; i++)
1829     {
1830 fprintf(fd, "   * %s_knt, %s_data:  count and pointer for output \"%s\"%s",
1831 				out[i]->name, out[i]->name, out[i]->name, NEWLINE);
1832     }
1833 fprintf(fd, "   */%s%s", NEWLINE, NEWLINE);
1834 fprintf(fd, "  /*%s", NEWLINE);
1835 fprintf(fd, "   * User's code goes here%s", NEWLINE);
1836 fprintf(fd, "   */%s", NEWLINE);
1837 fprintf(fd, "     %s", NEWLINE);
1838 fprintf(fd, "     %s", NEWLINE);
1839 /* was an include file specified? */
1840 if(mod->include_file != NULL)
1841 	fprintf(fd, "#include \"%s\" %s%s", mod->include_file, NEWLINE, NEWLINE);
1842 fprintf(fd, "  /*%s", NEWLINE);
1843 fprintf(fd, "   * successful completion%s", NEWLINE);
1844 fprintf(fd, "   */%s", NEWLINE);
1845 fprintf(fd, "   return 1;%s", NEWLINE);
1846 fprintf(fd, "     %s", NEWLINE);
1847 fprintf(fd, "  /*%s", NEWLINE);
1848 fprintf(fd, "   * unsuccessful completion%s", NEWLINE);
1849 fprintf(fd, "   */%s", NEWLINE);
1850 fprintf(fd, "error:%s", NEWLINE);
1851 fprintf(fd, "   return 0;%s", NEWLINE);
1852 fprintf(fd, "  %s}%s", NEWLINE, NEWLINE);
1853 
1854     fclose(fd);
1855     free(buf);
1856 
1857     return 1;
1858 
1859 error:
1860     if (fd)
1861     {
1862 	fclose(fd);
1863 	unlink(buf);
1864     }
1865     free(buf);
1866 
1867     return 0;
1868 }
1869 
1870 
1871 #define COPYSTRING(dst, src)					\
1872 {								\
1873     (dst) = (char *)malloc(strlen((src))+1);			\
1874     if ((dst) == NULL) {					\
1875 	ErrorMessage("allocation error");			\
1876 	goto error;						\
1877     }								\
1878 								\
1879     strcpy((dst), (src));					\
1880 }
1881 
1882 #define TRUEFALSE(dst, src)					\
1883 {								\
1884     if (! strcmp((src), "TRUE"))				\
1885 	(dst) = TRUE;						\
1886     else if (! strcmp((src), "FALSE"))				\
1887 	(dst) = FALSE;						\
1888     else {							\
1889 	ErrorMessage("invalid true/false: %s\n", src);	\
1890 	goto error;						\
1891     }								\
1892 }
1893 
1894 static int
copy_comments(char * basename,FILE * out,char * hdr,char * ldr,char * trlr)1895 copy_comments(char *basename, FILE *out, char *hdr, char *ldr, char *trlr)
1896 {
1897     FILE *in = NULL;
1898     int  first_comment = 1, comment_found = 0;
1899     int  first_char = 1, is_comment;
1900     int  i, c;
1901     char *buf = (char *)malloc(strlen(basename) + 4);
1902 
1903     if (! buf)
1904     {
1905 	ErrorMessage("allocation error");
1906 	goto error;
1907     }
1908 
1909     sprintf(buf, "%s.mb", basename);
1910 
1911     in = fopen(buf, "r");
1912     free(buf);
1913     buf = 0;
1914     if (! in)
1915     {
1916 	ErrorMessage("error opening mb file");
1917 	return 0;
1918     }
1919 
1920     while (! feof(in))
1921     {
1922 	c = getc(in);
1923 
1924 	if (first_char)
1925 	    is_comment = (c == '#');
1926 
1927 	if (is_comment)
1928 	{
1929 	    comment_found = 1;
1930 
1931 	    if (first_comment && hdr)
1932 	    {
1933 		for(i = 0; hdr[i] != '\0'; i++)
1934 		    if (! putc(hdr[i], out))
1935 			return 0;
1936 		first_comment = 0;
1937 	    }
1938 
1939 	    if (first_char && ldr)
1940 	    {
1941 		for(i = 0; ldr[i] != '\0'; i++)
1942 		    if (! putc(ldr[i], out))
1943 			return 0;
1944 	    }
1945 	    else
1946 		if (! putc(c, out))
1947 		    return 0;
1948 	}
1949 
1950 	if (c == '\n')
1951 	    first_char = 1;
1952 	else
1953 	    first_char = 0;
1954     }
1955 
1956     if (comment_found && trlr)
1957     {
1958 	for(i = 0; trlr[i] != '\0'; i++)
1959 	    if (! putc(trlr[i], out))
1960 		return 0;
1961 	first_comment = 0;
1962     }
1963 
1964     fclose(in);
1965     return 1;
1966 
1967 error:
1968     if (in)
1969         fclose(in);
1970     return 0;
1971 }
1972 
1973 #define MAXLINE	    16384
1974 char linebuf[MAXLINE];
1975 
1976 #define WHITESPACE(l) ((l) == ' ' || (l) == '\t')
1977 
1978 char *
_dxf_getline(FILE * fd)1979 _dxf_getline(FILE *fd)
1980 {
1981     int i;
1982     int c;
1983 
1984     if (feof(fd))
1985 	return NULL;
1986 
1987     do
1988     {
1989 	c = getc(fd);
1990     } while (c != EOF && WHITESPACE(c));
1991 
1992     if (c == EOF)
1993 	return NULL;
1994 
1995     for (i = 0; i < MAXLINE; i++, c = getc(fd))
1996     {
1997 	linebuf[i] = c;
1998 
1999 	if (c == EOF || c == '\n')
2000 	{
2001 	    while (i > 0 && WHITESPACE(linebuf[i-1]))
2002 	      i--;
2003 
2004 	    linebuf[i] = '\0';
2005 	    break;
2006 	}
2007 
2008     }
2009 
2010     if (i == MAXLINE)
2011     {
2012 	ErrorMessage("line exceeds max length");
2013 	return NULL;
2014     }
2015 
2016     return linebuf;
2017 }
2018 
2019 static void
parseline(char * line,char ** name,char ** value)2020 parseline(char *line, char **name, char **value)
2021 {
2022     *name = line;
2023 
2024     while (!WHITESPACE(*line) && *line != '=')
2025 	line ++;
2026 
2027     *line = '\0';
2028     line++;
2029 
2030     while (WHITESPACE(*line) || *line == '=')
2031 	line ++;
2032 
2033     *value = line;
2034 }
2035 
2036 
2037 #define ISTOKEN(a,b) (!strcmp(a, b))
2038 
2039 static int
process_input(char * basename,Module * mod,Parameter ** in,Parameter ** out)2040 process_input(char *basename, Module *mod, Parameter **in, Parameter **out)
2041 {
2042     FILE      *fd = NULL;
2043     int       nin = 0, nout = 0;
2044     int       linenum;
2045     char      *line, *name, *value;
2046     Parameter *parameter = NULL;
2047     char      *buf = (char *)malloc(strlen(basename) + 4);
2048 
2049     if (! buf)
2050     {
2051 	ErrorMessage("allocation error");
2052 	goto error;
2053     }
2054 
2055     sprintf(buf, "%s.mb", basename);
2056 
2057     mod->name                = NULL;
2058     mod->category            = NULL;
2059     mod->description         = NULL;
2060     mod->outboard_executable = NULL;
2061     mod->include_file        = NULL;
2062     mod->outboard_persistent = UNKNOWN;
2063     mod->asynchronous        = UNKNOWN;
2064     mod->pinned              = UNKNOWN;
2065     mod->side_effect         = UNKNOWN;
2066 
2067     in[0] = NULL; out[0] = NULL;
2068 
2069     fd = fopen(buf, "r");
2070     free(buf);
2071     buf = 0;
2072     if (! fd)
2073     {
2074 	ErrorMessage("error opening file: %s\n", basename);
2075 	goto error;
2076     }
2077 
2078     linenum = -1;
2079     while (NULL != (line = _dxf_getline(fd)))
2080     {
2081 	linenum ++;
2082 
2083 	if (line[0] == '\0')
2084 	    continue;
2085 
2086 	if (line[0] == '#')
2087 	    continue;
2088 
2089 	/*  FIXME  */
2090 	/*if (line[-1] == -1)
2091 	  goto error;*/
2092 
2093 	parseline(line, &name, &value);
2094 
2095 	if (ISTOKEN(name, "MODULE_NAME")) {
2096 	    COPYSTRING(mod->name, value);
2097 	}
2098 	else if (ISTOKEN(name, "CATEGORY")) {
2099 	    COPYSTRING(mod->category, value);
2100 	}
2101 	else if (ISTOKEN(name, "MODULE_DESCRIPTION")) {
2102 	    COPYSTRING(mod->description, value);
2103 	}
2104 	else if (ISTOKEN(name, "OUTBOARD_HOST")) {
2105 	    COPYSTRING(mod->outboard_host, value);
2106 	}
2107 	else if (ISTOKEN(name, "OUTBOARD_EXECUTABLE")) {
2108 	    COPYSTRING(mod->outboard_executable, value);
2109 	}
2110 	else if (ISTOKEN(name, "LOADABLE_EXECUTABLE")) {
2111 	    COPYSTRING(mod->loadable_executable, value);
2112 	}
2113 	else if (ISTOKEN(name, "INCLUDE_FILE")) {
2114 	    COPYSTRING(mod->include_file, value);
2115 	}
2116 	else if (ISTOKEN(name, "OUTBOARD_PERSISTENT")) {
2117 	    TRUEFALSE(mod->outboard_persistent, value);
2118 	}
2119 	else if (ISTOKEN(name, "ASYNCHRONOUS")) {
2120 	    TRUEFALSE(mod->asynchronous, value);
2121 	}
2122 	else if (ISTOKEN(name, "PINNED")) {
2123 	    TRUEFALSE(mod->pinned, value);
2124 	}
2125 	else if (ISTOKEN(name, "SIDE_EFFECT")) {
2126 	    TRUEFALSE(mod->side_effect, value);
2127 	}
2128 	else if (ISTOKEN(name, "LANGUAGE")) {
2129 	    if (ISTOKEN(value, "C"))
2130 		mod->language = C;
2131 	    else if (ISTOKEN(value, "Fortran"))
2132 		mod->language = FORTRAN;
2133 	    else
2134 	    {
2135 		ErrorMessage("unrecognized LANGUAGE: %s\n", value);
2136 		return 0;
2137 	    }
2138 	}
2139 
2140 	else if (ISTOKEN(name, "INPUT"))
2141 	{
2142 	    in[nin] = (Parameter *)malloc(sizeof(Parameter));
2143 	    if (in[nin] == NULL)
2144 	    {
2145 		ErrorMessage("allocation error");
2146 		goto error;
2147 	    }
2148 
2149 	    parameter = in[nin];
2150 	    nin ++;
2151 
2152 	    COPYSTRING(parameter->name, value);
2153 
2154 	    parameter->description   = NULL;
2155 	    parameter->required      = UNKNOWN;
2156 	    parameter->default_value = NULL;
2157 	    parameter->types         = NULL;
2158 	    parameter->structure     = NO_STRUCTURE;
2159 	    parameter->datatype      = NO_DATATYPE;
2160 	    parameter->datashape     = NO_DATASHAPE;
2161 	    parameter->counts        = NO_COUNTS;
2162 	    parameter->positions     = GRID_NOT_REQUIRED;
2163 	    parameter->connections   = GRID_NOT_REQUIRED;
2164 	    parameter->elementtype   = ELT_NOT_REQUIRED;
2165 	    parameter->dependency    = NO_DEPENDENCY;
2166 	}
2167 	else if (ISTOKEN(name, "OUTPUT"))
2168 	{
2169 	    out[nout] = (Parameter *)malloc(sizeof(Parameter));
2170 	    if (out[nout] == NULL)
2171 	    {
2172 		ErrorMessage("allocation error");
2173 		goto error;
2174 	    }
2175 
2176 	    parameter = out[nout];
2177 	    nout ++;
2178 
2179 	    COPYSTRING(parameter->name, value);
2180 
2181 	    parameter->description   = NULL;
2182 	    parameter->required      = UNKNOWN;
2183 	    parameter->default_value = NULL;
2184 	    parameter->types         = NULL;
2185 	    parameter->structure     = NO_STRUCTURE;
2186 	    parameter->datatype      = NO_DATATYPE;
2187 	    parameter->datashape     = NO_DATASHAPE;
2188 	    parameter->counts        = NO_COUNTS;
2189 	    parameter->positions     = GRID_NOT_REQUIRED;
2190 	    parameter->connections   = GRID_NOT_REQUIRED;
2191 	    parameter->elementtype   = ELT_NOT_REQUIRED;
2192 	    parameter->dependency    = NO_DEPENDENCY;
2193 	}
2194 	else if (ISTOKEN(name, "DESCRIPTION"))
2195 	{
2196 	    if (! parameter)
2197 	    {
2198 		ErrorMessage("syntax error line %d\n DESCRIPTION encountered outside of parameter definition", linenum);
2199 		goto error;
2200 	    }
2201 	    COPYSTRING(parameter->description, value);
2202 	}
2203 	else if (ISTOKEN(name, "DESCRIPTIVE"))
2204 	{
2205 	    if (! parameter)
2206 	    {
2207 		ErrorMessage("syntax error line %d\n DESCRIPTIVE encountered outsideof parameter definition", linenum);
2208 		goto error;
2209 	    }
2210 	    TRUEFALSE(parameter->descriptive, value);
2211 	}
2212 	else if (ISTOKEN(name, "REQUIRED"))
2213 	{
2214 	    if (! parameter)
2215 	    {
2216 		ErrorMessage("syntax error line %d\n REQUIRED encountered outsideof parameter definition", linenum);
2217 		goto error;
2218 	    }
2219 	    TRUEFALSE(parameter->required, value);
2220 	}
2221 	else if (ISTOKEN(name, "DEFAULT_VALUE"))
2222 	{
2223 	    if (! parameter)
2224 	    {
2225 		ErrorMessage("syntax error line %d\nDEFAULT_VALUE encountered outside of parameter definition", linenum);
2226 		goto error;
2227 	    }
2228 	    COPYSTRING(parameter->default_value, value);
2229 	}
2230 	else if (ISTOKEN(name, "TYPES"))
2231 	{
2232 	    if (! parameter)
2233 	    {
2234 		ErrorMessage("syntax error line %d\nTYPES encountered outsideof parameter definition", linenum);
2235 		goto error;
2236 	    }
2237 	    COPYSTRING(parameter->types, value);
2238 	}
2239 	else if (ISTOKEN(name, "STRUCTURE"))
2240 	{
2241 	    if (! parameter)
2242 	    {
2243 		ErrorMessage("syntax error line %d\nSTRUCTURE encountered outside of parameter definition", linenum);
2244 		goto error;
2245 	    }
2246 
2247 	    if (ISTOKEN(value, "Value"))
2248 		parameter->structure = VALUE;
2249 	    else if (ISTOKEN(value, "Field/Group"))
2250 		parameter->structure = GROUP_FIELD;
2251 	    else
2252 	    {
2253 		ErrorMessage("unknown STRUCTURE: %s\n", value);
2254 		goto error;
2255 	    }
2256 	}
2257 	else if (ISTOKEN(name, "DATA_TYPE"))
2258 	{
2259 	    if (! parameter)
2260 	    {
2261 		ErrorMessage("syntax error line %d\nDATA_TYPE encountered outside of parameter definition", linenum);
2262 		goto error;
2263 	    }
2264 
2265 	    if (ISTOKEN(value, "float"))
2266 		parameter->datatype = FLOAT;
2267 	    else if (ISTOKEN(value, "double"))
2268 		parameter->datatype = DOUBLE;
2269 	    else if (ISTOKEN(value, "int"))
2270 		parameter->datatype = INT;
2271 	    else if (ISTOKEN(value, "uint"))
2272 		parameter->datatype = UINT;
2273 	    else if (ISTOKEN(value, "short"))
2274 		parameter->datatype = SHORT;
2275 	    else if (ISTOKEN(value, "ushort"))
2276 		parameter->datatype = USHORT;
2277 	    else if (ISTOKEN(value, "byte"))
2278 		parameter->datatype = BYTE;
2279 	    else if (ISTOKEN(value, "ubyte"))
2280 		parameter->datatype = UBYTE;
2281 	    else if (ISTOKEN(value, "string"))
2282 		parameter->datatype = STRING;
2283 	    else
2284 	    {
2285 		ErrorMessage("unknown DATATYPE: %s\n", value);
2286 		goto error;
2287 	    }
2288 	}
2289 	else if (ISTOKEN(name, "DATA_SHAPE"))
2290 	{
2291 	    if (! parameter)
2292 	    {
2293 		ErrorMessage("syntax error line %dDATA_SHAPE encountered outside of parameter definition\n", linenum);
2294 		goto error;
2295 	    }
2296 
2297 	    if (ISTOKEN(value, "Scalar"))
2298 		parameter->datashape = SCALAR;
2299 	    else if (ISTOKEN(value, "1-vector"))
2300 		parameter->datashape = VECTOR_1;
2301 	    else if (ISTOKEN(value, "2-vector"))
2302 		parameter->datashape = VECTOR_2;
2303 	    else if (ISTOKEN(value, "3-vector"))
2304 		parameter->datashape = VECTOR_3;
2305 	    else if (ISTOKEN(value, "4-vector"))
2306 		parameter->datashape = VECTOR_4;
2307 	    else if (ISTOKEN(value, "5-vector"))
2308 		parameter->datashape = VECTOR_5;
2309 	    else if (ISTOKEN(value, "6-vector"))
2310 		parameter->datashape = VECTOR_6;
2311 	    else if (ISTOKEN(value, "7-vector"))
2312 		parameter->datashape = VECTOR_7;
2313 	    else if (ISTOKEN(value, "8-vector"))
2314 		parameter->datashape = VECTOR_8;
2315 	    else if (ISTOKEN(value, "9-vector"))
2316 		parameter->datashape = VECTOR_9;
2317 	    else
2318 	    {
2319 		ErrorMessage("unknown DATASHAPE: %s\n", value);
2320 		goto error;
2321 	    }
2322 	}
2323 	else if (ISTOKEN(name, "ELEMENT_TYPE"))
2324 	{
2325 	    if (! parameter)
2326 	    {
2327 		ErrorMessage("syntax error line %d\nELEMENT_TYPE encountered outside of parameter definition", linenum);
2328 		goto error;
2329 	    }
2330 
2331 	    if (ISTOKEN(value, "Lines"))
2332 		parameter->elementtype = ELT_LINES;
2333 	    else if (ISTOKEN(value, "Triangles"))
2334 		parameter->elementtype = ELT_TRIANGLES;
2335 	    else if (ISTOKEN(value, "Quads"))
2336 		parameter->elementtype = ELT_QUADS;
2337 	    else if (ISTOKEN(value, "Tetrahedra"))
2338 		parameter->elementtype = ELT_TETRAHEDRA;
2339 	    else if (ISTOKEN(value, "Cubes"))
2340 		parameter->elementtype = ELT_CUBES;
2341 	    else if (ISTOKEN(value, "Not required"))
2342 		parameter->elementtype = ELT_NOT_REQUIRED;
2343 	    else
2344 	    {
2345 		ErrorMessage("unknown ELEMENT_TYPE: %s\n", value);
2346 		goto error;
2347 	    }
2348 	}
2349 	else if (ISTOKEN(name, "COUNTS"))
2350 	{
2351 	    if (! parameter)
2352 	    {
2353 		ErrorMessage("syntax error line %d\nCOUNTS encountered outside of parameter definition", linenum);
2354 		goto error;
2355 	    }
2356 
2357 	    if (ISTOKEN(value, "1"))
2358 		parameter->counts = COUNTS_1;
2359 	    else if (ISTOKEN(value, "same as input"))
2360 		parameter->counts = COUNTS_SAME_AS_INPUT;
2361 	    else
2362 	    {
2363 		ErrorMessage("unknown COUNTS: %s\n", value);
2364 		goto error;
2365 	    }
2366 	}
2367 	else if (ISTOKEN(name, "POSITIONS"))
2368 	{
2369 	    if (! parameter)
2370 	    {
2371 		ErrorMessage("syntax error line %d\nPOSITIONS encountered outside of parameter definition", linenum);
2372 		goto error;
2373 	    }
2374 
2375 	    if (ISTOKEN(value, "Regular"))
2376 		parameter->positions = GRID_REGULAR;
2377 	    else if (ISTOKEN(value, "Irregular"))
2378 		parameter->positions = GRID_IRREGULAR;
2379 	    else if (ISTOKEN(value, "Not required"))
2380 		parameter->positions = GRID_NOT_REQUIRED;
2381 	    else
2382 	    {
2383 		ErrorMessage("unknown POSITIONS: %s\n", value);
2384 		goto error;
2385 	    }
2386 	}
2387 	else if (ISTOKEN(name, "CONNECTIONS"))
2388 	{
2389 	    if (! parameter)
2390 	    {
2391 		ErrorMessage("syntax error line %d\nCONNECTIONS encountered outside of parameter definition", linenum);
2392 		goto error;
2393 	    }
2394 
2395 	    if (ISTOKEN(value, "Regular"))
2396 		parameter->connections = GRID_REGULAR;
2397 	    else if (ISTOKEN(value, "Irregular"))
2398 		parameter->connections = GRID_IRREGULAR;
2399 	    else if (ISTOKEN(value, "Not required"))
2400 		parameter->connections = GRID_NOT_REQUIRED;
2401 	    else
2402 	    {
2403 		ErrorMessage("unknown CONNECTIONS: %s\n", value);
2404 		goto error;
2405 	    }
2406 	}
2407 	else if (ISTOKEN(name, "DEPENDENCY"))
2408 	{
2409 	    if (! parameter)
2410 	    {
2411 		ErrorMessage("syntax error line %d\nDEPENDENCY encountered outside of parameter definition", linenum);
2412 		goto error;
2413 	    }
2414 
2415 	    if (ISTOKEN(value, "No dependency"))
2416 		parameter->dependency = NO_DEPENDENCY;
2417 	    else if (ISTOKEN(value, "Positions only"))
2418 		parameter->dependency = DEP_POSITIONS;
2419 	    else if (ISTOKEN(value, "Connections only"))
2420 		parameter->dependency = DEP_CONNECTIONS;
2421 	    else if (ISTOKEN(value, "Positions or connections"))
2422 		parameter->dependency = DEP_INPUT;
2423 	    else
2424 	    {
2425 		ErrorMessage("unknown DEPENDENCY: %s\n", value);
2426 		goto error;
2427 	    }
2428 	}
2429 	else
2430 	{
2431 	    ErrorMessage("unrecognized keyword on line %d: %s\n",
2432 			linenum, name);
2433 	    goto error;
2434 	}
2435     }
2436 
2437     in[nin]   = NULL;
2438     out[nout] = NULL;
2439 
2440     fclose(fd);
2441 
2442     return 1;
2443 
2444 error:
2445     if (fd)
2446 	fclose(fd);
2447     return 0;
2448 }
2449 
2450 
2451 static int
GetDXDataType(enum datatype t,char ** type)2452 GetDXDataType(enum datatype t, char **type)
2453 {
2454     switch(t)
2455     {
2456 	case DOUBLE: *type = "TYPE_DOUBLE"; break;
2457 	case FLOAT:  *type = "TYPE_FLOAT";  break;
2458 	case INT:    *type = "TYPE_INT";    break;
2459 	case UINT:   *type = "TYPE_UINT";   break;
2460 	case SHORT:  *type = "TYPE_SHORT";  break;
2461 	case USHORT: *type = "TYPE_USHORT"; break;
2462 	case BYTE:   *type = "TYPE_BYTE";   break;
2463 	case UBYTE:  *type = "TYPE_UBYTE";  break;
2464 	case STRING: *type = "TYPE_STRING";  break;
2465 	default:
2466 	    ErrorMessage("cannot create array without DATATYPE");
2467 	    return 0;
2468     }
2469 
2470     return 1;
2471 }
2472 
2473 
2474 static int
GetCDataType(enum datatype t,char ** type)2475 GetCDataType(enum datatype t, char **type)
2476 {
2477     switch(t)
2478     {
2479 	case DOUBLE: *type = "double"; 		break;
2480 	case FLOAT:  *type = "float";  		break;
2481 	case INT:    *type = "int";    		break;
2482 	case UINT:   *type = "unsigned int";    break;
2483 	case SHORT:  *type = "short"; 		break;
2484 	case USHORT: *type = "unsigned short";	break;
2485 	case BYTE:   *type = "byte";  		break;
2486 	case UBYTE:  *type = "ubyte";  		break;
2487 	case STRING: *type = "char"; 		break;
2488 	default:
2489 	    ErrorMessage("cannot create array without DATATYPE");
2490 	    return 0;
2491     }
2492 
2493     return 1;
2494 }
2495 
2496 static int
GetDXDataShape(enum datashape t,char ** r,char ** s)2497 GetDXDataShape(enum datashape t, char **r, char **s)
2498 {
2499     switch(t)
2500     {
2501 	case SCALAR:   *r = "0"; *s = "0"; break;
2502 	case VECTOR_1: *r = "1"; *s = "1"; break;
2503 	case VECTOR_2: *r = "1"; *s = "2"; break;
2504 	case VECTOR_3: *r = "1"; *s = "3"; break;
2505 	case VECTOR_4: *r = "1"; *s = "4"; break;
2506 	case VECTOR_5: *r = "1"; *s = "5"; break;
2507 	case VECTOR_6: *r = "1"; *s = "6"; break;
2508 	case VECTOR_7: *r = "1"; *s = "7"; break;
2509 	case VECTOR_8: *r = "1"; *s = "8"; break;
2510 	case VECTOR_9: *r = "1"; *s = "9"; break;
2511 	default:
2512 	    ErrorMessage("cannot create array without DATASHAPE");
2513 	    return 0;
2514     }
2515 
2516     return 1;
2517 }
2518 
2519 
2520 static int
GetElementTypeString(enum elementtype t,char ** r)2521 GetElementTypeString(enum elementtype t, char **r)
2522 {
2523     switch(t)
2524     {
2525 	case ELT_LINES:      *r = "lines";      break;
2526 	case ELT_TRIANGLES:  *r = "triangles";  break;
2527 	case ELT_QUADS:      *r = "quads";      break;
2528 	case ELT_TETRAHEDRA: *r = "tetrahedra"; break;
2529 	case ELT_CUBES:      *r = "cubes";      break;
2530 	default:
2531 	    ErrorMessage("no element type string available");
2532 	    return 0;
2533     }
2534 
2535     return 1;
2536 }
2537 
2538 #if defined(__cplusplus) || defined(c_plusplus)
2539 }
2540 #endif
2541 
2542