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 #include "../base/defines.h"
11
12
13 #include <stdio.h>
14 #include <ctype.h>
15 #include <stdarg.h>
16 #include <string.h>
17
18 #include "lex.h"
19 #include "DXStrings.h"
20
21 #include "ParseMDF.h"
22
23 #include "DXType.h"
24 #include "NodeDefinition.h"
25 #include "ParameterDefinition.h"
26 #include "Dictionary.h"
27 #include "NDAllocatorDictionary.h"
28 #include "ErrorDialogManager.h"
29
30
31 /***
32 *** State constants:
33 ***/
34
35 #define ST_NONE 0
36 #define ST_MODULE 1
37 #define ST_CATEGORY 2
38 #define ST_DESCRIPTION 4
39 #define ST_INPUT 8
40 #define ST_REPEAT 16
41 #define ST_OUTPUT 32
42 #define ST_ERROR 64
43 #define ST_SAW_REPEAT 128
44 #define ST_FLAGS 256
45 #define ST_OUTBOARD 512
46 #define ST_LOADABLE 1024
47 #define ST_PACKAGE 2048
48 #define ST_OPTIONS 4096
49
50
51 #ifdef NOT_YET
52 /***
53 *** Static pointer to MDF (for sorting purposes)
54 ***/
55 static Dictionary* _mdf;
56 #endif
57
58 Dictionary *theDynamicPackageDictionary = new Dictionary;
59
60 /*****************************************************************************/
61 /* _ParsePackageLine - */
62 /* */
63 /* Parses and processes the PACKAGE line. */
64 /* */
65 /*****************************************************************************/
66
67 static
_ParsePackageLine(char * line,int lineNumber,int start)68 boolean _ParsePackageLine(char* line,
69 int lineNumber,
70 int start)
71 {
72 char *begin, *end;
73
74 ASSERT(line);
75 ASSERT(lineNumber > 0);
76 ASSERT(start >= 0);
77
78 begin = &line[start];
79
80 /*
81 * Skip space.
82 */
83 SkipWhiteSpace(begin);
84
85 /*
86 * Parse package name.
87 */
88 end = begin;
89 while (*end && !IsWhiteSpace(end) && (*end != '\n') && (*end != '\r'))
90 end++;
91 if (*end)
92 end--;
93
94 if (end == begin)
95 goto error;
96
97 *end = '\0';
98 theDynamicPackageDictionary->replaceDefinition(
99 (const char*)begin,
100 (const void*) NULL);
101
102 return TRUE;
103
104 error:
105 return FALSE;
106 }
107 /*****************************************************************************/
108 /* _ParseModuleLine - */
109 /* */
110 /* Parses and processes the MODULE line. */
111 /* */
112 /*****************************************************************************/
113
114 static
_ParseModuleLine(Dictionary * mdf,char * line,int lineNumber,int start)115 NodeDefinition *_ParseModuleLine(Dictionary *mdf,
116 char* line,
117 int lineNumber,
118 int start)
119 {
120 int current;
121 int temp;
122 char *function;
123 NodeDefinition *module = NUL(NodeDefinition*);
124
125 ASSERT(mdf != NUL(Dictionary*));
126 ASSERT(line);
127 ASSERT(lineNumber > 0);
128 ASSERT(start >= 0);
129
130 current = start;
131
132 /*
133 * Skip space.
134 */
135 SkipWhiteSpace(line,current);
136
137 /*
138 * Parse module name.
139 */
140 temp = current;
141 if (NOT IsRestrictedIdentifier(line, temp) ||
142 (temp != STRLEN(line) && !IsWhiteSpace(line, temp)))
143 {
144 ErrorMessage("Invalid %s: %s must start with a letter and contain "
145 "only letters and numbers (file %s line %d)",
146 "module name", line + current, "MDF", lineNumber);
147 goto error;
148 }
149
150 /*
151 * Extract the module name.
152 */
153 function = &line[current];
154
155 /*
156 * Look to see if the module has already been defined.
157 * remember the name index.
158 */
159 if (mdf->findDefinition(function))
160 {
161 ErrorMessage
162 ("Encountered another definition of module \"%s\" on line %d.",
163 function,
164 lineNumber);
165
166 goto error;
167 }
168
169 //
170 // Get a new NodeDefinition by name
171 //
172 module = theNDAllocatorDictionary->allocate(function);
173 if (!module) {
174 ErrorMessage("Can not find NodeDefinition allocator for module '%s'",
175 function);
176 goto error;
177 }
178 module->setName(function);
179
180 return module;
181
182 error:
183 if (module) delete module;
184 return NUL(NodeDefinition*);
185 }
186
187
188 #ifdef NOT_NEEDED
189 /*****************************************************************************/
190 /* _ParseCategoryLine - */
191 /* */
192 /* Parses and processes the CATEGORY line. */
193 /* */
194 /*****************************************************************************/
195
196 static
_ParseCategoryLine(Dictionary * mdf,NodeDefinition * module,char * line,int lineNumber,int start)197 boolean _ParseCategoryLine(Dictionary* mdf,
198 NodeDefinition* module,
199 char* line,
200 int lineNumber,
201 int start)
202 {
203 int current;
204 int temp;
205
206 ASSERT(mdf != NUL(Dictionary*));
207 ASSERT(module != NUL(NodeDefinition*));
208 ASSERT(line);
209 ASSERT(lineNumber > 0);
210 ASSERT(start >= 0);
211
212 current = start;
213
214 return TRUE;
215 }
216
217 #endif // NOT_NEEDED
218
ParseMDFTypes(ParameterDefinition * param,char * p,int lineNumber)219 boolean ParseMDFTypes(ParameterDefinition *param, char *p, int lineNumber)
220 {
221 char buffer[1000];
222 char *q;
223 int current;
224 char save;
225 DXType *input_type = NULL;
226 Type type;
227
228 /*
229 * Begin a new type.
230 */
231 current = 0;
232
233 SkipWhiteSpace(p);
234
235 while(*p != '\0')
236 {
237 /*
238 * Demarcate a token.
239 */
240 for (q = p; *q != ' ' AND *q != '\t' AND *q != '\0'; q++)
241 buffer[current++] = *q;
242 buffer[current++] = ' ';
243
244 save = *q;
245 *q = '\0';
246
247 if (EqualString(p, "or"))
248 {
249 /*
250 * Back up and erase " or " substring from end of buffer.
251 */
252 current -= 4;
253
254 /*
255 * Find a matching type.
256 */
257 buffer[current] = '\0';
258 if ((type = DXType::StringToType(buffer)) == DXType::UndefinedType)
259 {
260 ErrorMessage
261 ("Erroneous parameter type encountered in line %d.",
262 lineNumber);
263 if (input_type)
264 delete input_type;
265 return FALSE;
266 }
267
268 /*
269 * Begin a new type and the type to the param list of type.
270 */
271 input_type = new DXType(type);
272 boolean r = param->addType(input_type);
273 ASSERT(r);
274 input_type = NUL(DXType*);
275
276 current = 0;
277 }
278
279 /*
280 * Restore the saved character and skip space.
281 */
282 *q = save;
283 p = q;
284 SkipWhiteSpace(p);
285 }
286
287 /*
288 * Find a matching type.
289 */
290 buffer[--current] = '\0';
291 if ((type = DXType::StringToType(buffer)) == DXType::UndefinedType)
292 {
293 ErrorMessage ("Erroneous parameter type encountered in line %d.",
294 lineNumber);
295 if (input_type)
296 delete input_type;
297 return FALSE;
298 }
299 /*
300 * Begin a new type and add the type to the input list of type.
301 */
302 input_type = new DXType(type);
303 boolean r = param->addType(input_type);
304 ASSERT(r);
305
306 return TRUE;
307 }
308
309 /*****************************************************************************/
310
311 //
312 // Parse 'attribute:%d' from the given line.
313 // Return TRUE on success and set *val to %d.
314 //
GetIntegerAttribute(const char * line,const char * attr,int * val)315 static boolean GetIntegerAttribute(const char *line, const char *attr,
316 int *val)
317 {
318 const char *c = strstr(line,attr);
319 if (!c)
320 return FALSE;
321 c += STRLEN(attr);
322 while (*c && *c != ':') c++;
323 if (!*c)
324 return FALSE;
325 c++;
326 *val = atoi(c);
327 return TRUE;
328 }
329
_ParseParameterAttributes(ParameterDefinition * pd,const char * attr)330 boolean _ParseParameterAttributes(ParameterDefinition *pd , const char *attr)
331 {
332 int val;
333 boolean v;
334
335 if (GetIntegerAttribute(attr,"private",&val)) {
336 v = (val == 1 ? FALSE : TRUE);
337 pd->setViewability(v);
338 if (!v) pd->setDefaultVisibility(FALSE);
339 } else if (GetIntegerAttribute(attr,"hidden",&val)) {
340 v = (val == 1 ? FALSE : TRUE);
341 pd->setDefaultVisibility(v);
342 }
343
344 if (GetIntegerAttribute(attr,"visible",&val)) {
345 boolean visible=FALSE, viewable=FALSE;
346 if (val == 0) {
347 viewable = TRUE;
348 visible = FALSE;
349 } else if (val == 1) {
350 viewable = TRUE;
351 visible = TRUE;
352 } else if (val == 2) {
353 viewable = FALSE;
354 visible = FALSE;
355 }
356 pd->setViewability(viewable);
357 pd->setDefaultVisibility(visible);
358 }
359
360 if (GetIntegerAttribute(attr,"cache",&val))
361 pd->setDefaultCacheability((Cacheability)val);
362 if (pd->isInput() &&
363 GetIntegerAttribute(attr,"reroute",&val) &&
364 (val >= 0))
365 pd->setRerouteOutput(val+1); // MDF uses 0 based indices.
366
367 return TRUE;
368 }
369
370 /*****************************************************************************/
371 /* _ParseOUTBOARDLine - */
372 /* */
373 /* Parses and processes the ' OUTBOARD "command" [ ; host ]' line. */
374 /* */
375 /*****************************************************************************/
376
377 static
_ParseOutboardLine(NodeDefinition * module,char * line,int lineNumber,int start)378 boolean _ParseOutboardLine(NodeDefinition* module,
379 char* line,
380 int lineNumber,
381 int start)
382 {
383 int current;
384 int temp;
385 int i;
386 char* substring[2];
387
388 ASSERT(module != NUL(NodeDefinition*));
389 ASSERT(line);
390 ASSERT(lineNumber > 0);
391 ASSERT(start >= 0);
392
393 current = start;
394
395 /*
396 * Separate the two sections of the OUTBOARD string.
397 */
398 substring[0] = NULL;
399 substring[1] = NULL;
400 for (i = 0; i < 2; i++)
401 {
402 /*
403 * Skip space.
404 */
405 SkipWhiteSpace(line,current);
406
407 /*
408 * Tag the beginning of the substring.
409 */
410 substring[i] = &line[current];
411
412 /*
413 * Find the end of the substring.
414 */
415 while (line[current] != ';' AND line[current] != '\0')
416 current++;
417
418 /*
419 * Mark the end of the substring and remove trailing space.
420 */
421 temp = current - 1;
422 if (line[current] == ';')
423 line[current++] = '\0';
424 else
425 break;
426
427 while (line[temp] == ' ' OR line[temp] == '\t')
428 {
429 line[temp] = '\0';
430 temp--;
431 }
432 }
433
434 #ifdef DEBUG
435 char *s0 = substring[0];
436 char *s1 = substring[1];
437 #endif
438 if (!substring[0])
439 {
440 goto error;
441 }
442
443 /*
444 * Parse the first substring: COMMAND with optional "'s
445 */
446 if (substring[0][0] == '"') {
447 i = STRLEN(substring[0]);
448 if (substring[0][i-1] != '"')
449 goto error;
450 substring[0][i-1] = '\0';
451 i = 1;
452 } else
453 i = 0;
454
455 module->setOutboardCommand(&substring[0][i]);
456 if (substring[1])
457 module->setDefaultOutboardHost(substring[1]);
458
459 return TRUE;
460
461 error:
462 ErrorMessage("Encountered an erroneous OUTBOARD specification on line %d.",
463 lineNumber);
464 return FALSE;
465 }
466 /*****************************************************************************/
467 /* _ParseLOADABLELine - */
468 /* */
469 /* Parses and processes the ' Loadable file' */
470 /* */
471 /*****************************************************************************/
472
473 static
_ParseLoadableLine(NodeDefinition * module,char * line,int lineNumber,int start)474 boolean _ParseLoadableLine(NodeDefinition* module,
475 char* line,
476 int lineNumber,
477 int start)
478 {
479 int current;
480 int temp;
481 int i;
482 char* substring;
483
484 ASSERT(module != NUL(NodeDefinition*));
485 ASSERT(line);
486 ASSERT(lineNumber > 0);
487 ASSERT(start >= 0);
488
489 current = start;
490
491 /*
492 * Separate the two sections of the LOADABLE string.
493 */
494 substring = NULL;
495 for (i = 0; i < 1; i++)
496 {
497 /*
498 * Skip space.
499 */
500 SkipWhiteSpace(line,current);
501
502 /*
503 * Tag the beginning of the substring.
504 */
505 substring = &line[current];
506
507 /*
508 * Find the end of the substring.
509 */
510 while (line[current] != ';' AND line[current] != '\0')
511 current++;
512
513 /*
514 * Mark the end of the substring and remove trailing space.
515 */
516 temp = current - 1;
517 if (line[current] == ';')
518 line[current++] = '\0';
519 else
520 break;
521
522 while (line[temp] == ' ' OR line[temp] == '\t')
523 {
524 line[temp] = '\0';
525 temp--;
526 }
527 }
528
529 #ifdef DEBUG
530 char *s0 = substring;
531 #endif
532 if (!substring)
533 {
534 goto error;
535 }
536
537 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
538 for (i=0; i<strlen(substring); i++)
539 if(substring[i] == '\\') substring[i] = '/';
540 #endif
541
542 module->setDynamicLoadFile(substring);
543 return TRUE;
544
545 error:
546 ErrorMessage("Encountered an erroneous LOADABLE specification on line %d.",
547 lineNumber);
548 return FALSE;
549 }
550 /*****************************************************************************/
551 /* _ParseInputLine - */
552 /* */
553 /* Parses and processes the INPUT line. */
554 /* */
555 /*****************************************************************************/
556
557 static
_ParseInputLine(Dictionary * mdf,NodeDefinition * module,char * line,int lineNumber,int start)558 boolean _ParseInputLine(Dictionary* mdf,
559 NodeDefinition* module,
560 char* line,
561 int lineNumber,
562 int start)
563 {
564 ParameterDefinition *input = NUL(ParameterDefinition*);
565 Symbol symbol;
566 int current;
567 int temp;
568 int i;
569 char* p;
570 char* substring[4];
571 char *begin_attributes, *end_attributes;
572
573 ASSERT(mdf != NUL(Dictionary*));
574 ASSERT(module != NUL(NodeDefinition*));
575 ASSERT(line);
576 ASSERT(lineNumber > 0);
577 ASSERT(start >= 0);
578
579 current = start;
580
581 /*
582 * Separate the four sections of the INPUT string.
583 */
584 for (i = 0; i < 4; i++)
585 {
586 /*
587 * Skip space.
588 */
589 SkipWhiteSpace(line,current);
590
591 /*
592 * Tag the beginning of the substring.
593 */
594 substring[i] = &line[current];
595
596 /*
597 * Find the end of the substring.
598 */
599 while (line[current] != ';' AND line[current] != '\0')
600 current++;
601
602 /*
603 * Mark the end of the substring and remove trailing space.
604 */
605 if (line[current] == ';')
606 line[current++] = '\0';
607 else
608 break;
609
610 temp = current - 2;
611 while (line[temp] == ' ' OR line[temp] == '\t')
612 {
613 line[temp] = '\0';
614 temp--;
615 }
616 }
617
618 if (i < 3)
619 {
620 ErrorMessage
621 ("Encountered an erroneous INPUT specification on line %d.",
622 lineNumber);
623
624 goto error;
625 }
626
627 /*
628 * Parse the first substring: NAME and optional attributes.
629 */
630 begin_attributes = (char *) strchr(substring[0],'[');
631 if (begin_attributes) {
632 char *p = begin_attributes-1;
633 // strip trailing white space from name of parameter.
634 while (IsWhiteSpace(p)) {
635 *p = '\0';
636 p--;
637 }
638 *begin_attributes = '\0'; // Terminate identifier
639 begin_attributes++; // Point to beginning of attributes.
640
641 end_attributes = strrchr(begin_attributes,']');
642 if (end_attributes)
643 *end_attributes = '\0'; // Terminate attributes.
644 else
645 begin_attributes = NULL;
646 }
647 current = 0;
648 if (NOT IsIdentifier(substring[0], current) ||
649 (current != STRLEN(substring[0]) &&
650 !IsWhiteSpace(substring[0], current)))
651 {
652 ErrorMessage("Invalid %s: %s (file %s, line %d)",
653 "input name", substring[0], "MDF", lineNumber);
654 goto error;
655 }
656
657 /*
658 * Place the name into the symbol table, and create a parameter with
659 * the given name;
660 */
661 symbol = mdf->getSymbolManager()->registerSymbol(substring[0]);
662 input = new ParameterDefinition(symbol);
663 input->markAsInput(); // Set this as an input parameter
664 input->setDefaultVisibility(); // Default visibility is on.
665
666 //
667 // Now that we have a parameter, parse the attributes if there are any.
668 //
669 if (begin_attributes) {
670 if (!_ParseParameterAttributes(input,begin_attributes)) {
671 ErrorMessage("Unrecognized input attribute(s) (%s) in MDF line %d\n",
672 begin_attributes, lineNumber);
673 goto error;
674 }
675 }
676
677 /*
678 * Parse the second substring: TYPE.
679 */
680 p = substring[1];
681 if (!ParseMDFTypes(input, p, lineNumber))
682 goto error;
683
684 /*
685 * Parse the third substring: DEFAULT VALUE.
686 */
687
688 /*
689 * If the value is equal to "(none)", then mark this parameter
690 * as a required parameter.
691 */
692
693 if (substring[2][0] == '(') { // A descriptive value
694 if (EqualString(substring[2], "(none)"))
695 input->setRequired();
696 else
697 input->setNotRequired();
698 input->setDescriptiveValue(substring[2]);
699 } else if (!input->setDefaultValue(substring[2])) {
700 ErrorMessage(
701 "Default value given on line %d not one of given types.",
702 lineNumber);
703 goto error;
704 }
705
706
707
708
709 /*
710 * Parse the fourth substring: DESCRIPTION.
711 */
712 input->setDescription(substring[3]);
713
714
715 /*
716 * One more input parameter processed...
717 */
718 module->addInput(input);
719
720 return TRUE;
721
722 error:
723 if (input) delete input;
724 return FALSE;
725 }
726
727
728 /*****************************************************************************/
729 /* _ParseOutputLine - */
730 /* */
731 /* Parses and processes the OUTPUT line. */
732 /* */
733 /*****************************************************************************/
734
735 static
_ParseOutputLine(Dictionary * mdf,NodeDefinition * module,char * line,int lineNumber,int start)736 boolean _ParseOutputLine(Dictionary* mdf,
737 NodeDefinition* module,
738 char* line,
739 int lineNumber,
740 int start)
741 {
742 ParameterDefinition* output = NUL(ParameterDefinition*);
743 Symbol symbol;
744 int current;
745 int temp;
746 int i;
747 char* p;
748 char* substring[3];
749
750 ASSERT(mdf != NUL(Dictionary*));
751 ASSERT(module != NUL(NodeDefinition*));
752 ASSERT(line);
753 ASSERT(lineNumber > 0);
754 ASSERT(start >= 0);
755
756 current = start;
757
758 /*
759 * Separate the three sections of the OUTPUT string.
760 */
761 for (i = 0; i < 3; i++)
762 {
763 /*
764 * Skip space.
765 */
766 SkipWhiteSpace(line,current);
767
768 /*
769 * Tag the beginning of the substring.
770 */
771 substring[i] = &line[current];
772
773 /*
774 * Find the end of the substring.
775 */
776 while (line[current] != ';' AND line[current] != '\0')
777 current++;
778
779 /*
780 * Mark the end of the substring and remove trailing space.
781 */
782 if (line[current] == ';')
783 line[current++] = '\0';
784 else
785 break;
786
787 temp = current - 2;
788 while (line[temp] == ' ' OR line[temp] == '\t')
789 {
790 line[temp] = '\0';
791 temp--;
792 }
793 }
794
795 if (i < 2)
796 {
797 ErrorMessage
798 ("Encountered an erroneous OUTPUT specification on line %d.",
799 lineNumber);
800
801 goto error;
802 }
803
804 /*
805 * Parse the first substring: NAME.
806 */
807 char *begin_attributes, *end_attributes;
808 #if 0
809 begin_attributes = strchr(substring[0],'[');
810 end_attributes = strrchr(substring[0],']');
811 if (begin_attributes && end_attributes) {
812 *begin_attributes = '\0'; // Terminate identifier
813 begin_attributes++; // Point to beginning of attributes.
814 *end_attributes = '\0'; // Terminate attributes.
815 }
816 #else
817 begin_attributes = (char *) strchr(substring[0],'[');
818 if (begin_attributes) {
819 char *p = begin_attributes-1;
820 // strip trailing white space from name of parameter.
821 while (IsWhiteSpace(p)) {
822 *p = '\0';
823 p--;
824 }
825 *begin_attributes = '\0'; // Terminate identifier
826 begin_attributes++; // Point to beginning of attributes.
827
828 end_attributes = strrchr(begin_attributes,']');
829 if (end_attributes)
830 *end_attributes = '\0'; // Terminate attributes.
831 else
832 begin_attributes = NULL;
833 }
834 #endif
835 current = 0;
836 if (NOT IsIdentifier(substring[0], current) ||
837 (current != STRLEN(substring[0]) &&
838 !IsWhiteSpace(substring[0], current)))
839 {
840 ErrorMessage("Invalid %s: %s (file %s, line %d)",
841 "output name", substring[0], "MDF", lineNumber);
842 goto error;
843 }
844
845 /*
846 * Place the name into the parameter symbol table, and save its index.
847 */
848 symbol = theSymbolManager->registerSymbol(substring[0]);
849 output = new ParameterDefinition(symbol);
850 output->markAsOutput(); // Mark parameter as an output.
851 output->setDefaultVisibility(); // Default visibility is on.
852
853 //
854 // Now that we have a parameter, parse the attributes if there are any.
855 //
856 if (begin_attributes) {
857 if (!_ParseParameterAttributes(output,begin_attributes)) {
858 ErrorMessage("Unrecognized output attribute(s) (%s) in MDF line %d\n"
859 , lineNumber);
860 goto error;
861 }
862 }
863
864 /*
865 * Parse the second substring: TYPE.
866 */
867 p = substring[1];
868 if (!ParseMDFTypes(output, p, lineNumber))
869 goto error;
870
871 /*
872 * Parse the third substring: DESCRIPTION.
873 */
874 output->setDescription(substring[2]);
875
876 module->addOutput(output);
877
878 return TRUE;
879 error:
880 if (output) delete output;
881
882 return FALSE;
883 }
884
885
886 /*****************************************************************************/
887 /* _ParseOptionsLine - */
888 /* */
889 /* Parses and processes the OPTIONS line. */
890 /* */
891 /*****************************************************************************/
892
893 static
_ParseOptionsLine(Dictionary * mdf,NodeDefinition * module,char * line,int lineNumber,int start)894 boolean _ParseOptionsLine(Dictionary* mdf,
895 NodeDefinition* module,
896 char* line,
897 int lineNumber,
898 int start)
899 {
900 ASSERT(mdf != NUL(Dictionary*));
901 ASSERT(module != NUL(NodeDefinition*));
902 ASSERT(line);
903 ASSERT(lineNumber > 0);
904 ASSERT(start >= 0);
905
906 int inum = module->getInputCount();
907 char *p = &line[start];
908
909 // assumes we're working on the most recently added param,
910 // which should be an OK assumption.
911 ParameterDefinition* pd = module->getInputDefinition(inum);
912 return ParseMDFOptions (pd, p);
913 }
914
915
916 //
917 // Expose OPTIONS line parsing so that it can be called
918 // from MacroDefintion.
919 //
ParseMDFOptions(ParameterDefinition * pd,char * p)920 boolean ParseMDFOptions (ParameterDefinition* pd, char* p)
921 {
922 /*
923 * Parse Selection values (separated by ';').
924 */
925
926 char *value = new char[STRLEN(p) + 1];
927 while (*p) {
928 memset(value, 0, STRLEN(p) + 1);
929 SkipWhiteSpace(p);
930 char *from = p, *to = value;
931 while (*from && (*from != ';')) {
932 if ((*from == '\\') && (*(from+1) == ';'))
933 from++;
934 *to = *from;
935 from++;
936 to++;
937 }
938 if (to > value) {
939 if(*from == ';')
940 *(to--) = '\0';
941 //
942 // Clip trailing white space.
943 //
944 if(IsWhiteSpace(to))
945 while ((to > value) && IsWhiteSpace(to))
946 *(to--) = '\0';
947 else if(*to)
948 *(++to) = '\0';
949 }
950 pd->addValueOption(value);
951 if(*from)
952 p = from+1;
953 else
954 p = from;
955 }
956
957 delete[] value;
958 return TRUE;
959 }
960
961
962 /*****************************************************************************/
963 /* _ParseRepeatLine - */
964 /* */
965 /* Parses and processes the REPEAT line. */
966 /* */
967 /*****************************************************************************/
968
969 static
_ParseRepeatLine(Dictionary * mdf,NodeDefinition * module,char * line,int lineNumber,int start,int io_state)970 boolean _ParseRepeatLine(Dictionary* mdf,
971 NodeDefinition* module,
972 char* line,
973 int lineNumber,
974 int start,
975 int io_state)
976 {
977 int current;
978 int temp;
979 int value;
980 int cnt;
981 char *ioname;
982
983 ASSERT(mdf != NUL(Dictionary*));
984 ASSERT(module != NUL(NodeDefinition*));
985 ASSERT(line);
986 ASSERT(lineNumber > 0);
987 ASSERT(start >= 0);
988 ASSERT(io_state == ST_INPUT || io_state == ST_OUTPUT);
989
990
991 current = start;
992
993 /*
994 * Skip space.
995 */
996 SkipWhiteSpace(line,current);
997
998 /*
999 * Parse repeat value.
1000 */
1001 temp = current;
1002 if (NOT IsInteger(line, temp))
1003 {
1004 ErrorMessage
1005 ("Encountered error when expecting a repeat value on line %d.",
1006 lineNumber);
1007
1008 return FALSE;
1009 }
1010
1011 value = atoi(&line[current]);
1012
1013 if (io_state == ST_INPUT) {
1014 cnt = module->getInputCount();
1015 ioname = "input";
1016 module->setInputRepeatCount(value);
1017 } else {
1018 cnt = module->getOutputCount();
1019 ioname = "output";
1020 module->setOutputRepeatCount(value);
1021 }
1022
1023
1024 if (value > cnt)
1025 {
1026 ErrorMessage
1027 ("The repeat value on line %d is greater than the number of prior %s parameters.",
1028 lineNumber, ioname);
1029
1030 if (io_state == ST_INPUT)
1031 module->setInputRepeatCount(0);
1032 else
1033 module->setOutputRepeatCount(0);
1034 return FALSE;
1035 }
1036
1037 return TRUE;
1038 }
1039
1040
1041 /*****************************************************************************/
1042 /* _FinishNodeDefinition - */
1043 /* */
1044 /* Return TRUE if the module was added to the mdf dictionary */
1045 /* */
1046 /* */
1047 /*****************************************************************************/
1048
1049 static
_FinishNodeDefinition(Dictionary * mdf,NodeDefinition * module)1050 boolean _FinishNodeDefinition(Dictionary* mdf,
1051 NodeDefinition* module)
1052 {
1053
1054 ASSERT(mdf != NUL(Dictionary*));
1055 ASSERT(module != NUL(NodeDefinition*));
1056
1057 Symbol nameSym = module->getNameSymbol();
1058
1059 //
1060 // Allow, the Get and Set modules to be in the mdf. They can be placed
1061 // there even if there is not category, which allows us to change to
1062 // using GetLocal/Global and SetLocal/Global instead.
1063 // See GlobalLocalNode.h.
1064 //
1065
1066 if (module->getCategorySymbol() ||
1067 (nameSym == NDAllocatorDictionary::GetNodeNameSymbol) ||
1068 (nameSym == NDAllocatorDictionary::SetNodeNameSymbol)) {
1069 module->completeDefinition();
1070 mdf->addDefinition(nameSym,module);
1071 return TRUE;
1072 } else {
1073 return FALSE;
1074 }
1075
1076 }
1077
1078
1079 /*****************************************************************************/
1080 /* ReadMDF - */
1081 /* */
1082 /* Read and parse MDF from open file stream. */
1083 /* */
1084 /*****************************************************************************/
1085
ReadMDF(Dictionary * mdf,FILE * input,boolean uionly)1086 boolean ReadMDF(Dictionary* mdf, FILE* input, boolean uionly)
1087 {
1088 NodeDefinition *module;
1089 int state;
1090 int start;
1091 int end;
1092 Symbol category;
1093 int line_number;
1094 boolean parsed_flags, checked_flags=FALSE, finished;
1095 boolean parsed_category, parsed_description, parsed_outboard;
1096 boolean checked_category=FALSE, checked_description=FALSE, checked_outboard=FALSE;
1097 boolean parsed_loadable, checked_loadable=FALSE;
1098 boolean checked_repeat=FALSE;
1099 boolean get_another_line;
1100 char* p;
1101 char line[2048];
1102 int last_iostate;
1103
1104
1105 ASSERT(mdf != NUL(Dictionary*));
1106 ASSERT(input);
1107
1108 module = NUL(NodeDefinition*);
1109 line_number = 0;
1110 state = ST_PACKAGE;
1111 last_iostate = ST_NONE;
1112
1113 finished = FALSE;
1114 get_another_line = TRUE;
1115 parsed_description = parsed_outboard = parsed_loadable =
1116 parsed_category = parsed_flags = FALSE;
1117
1118 for (;;)
1119 {
1120 if (get_another_line)
1121 {
1122
1123 checked_description = parsed_description;
1124 checked_repeat = /*parsed_repeat =*/ FALSE;
1125 checked_loadable = parsed_loadable;
1126 checked_outboard = parsed_outboard;
1127 checked_category = parsed_category;
1128 checked_flags = parsed_flags;
1129
1130 for (;;)
1131 {
1132 /*
1133 * Get a line to parse.
1134 */
1135 p = fgets(line, sizeof(line), input);
1136 ASSERT(STRLEN(line) < 2048);
1137 line_number++;
1138
1139 /*
1140 * If no more lines, exit.
1141 */
1142 if (p == NUL(char*))
1143 {
1144 finished = TRUE;
1145 break;
1146 }
1147
1148 /*
1149 * Skip leading whitespace.
1150 */
1151 for(start = 0;
1152 line[start] == ' ' OR line[start] == '\t' OR
1153 line[start] == '\n' OR line[start] == '\r';
1154 start++)
1155 ;
1156
1157 /*
1158 * If the string is not all spaces and not a comment exit.
1159 */
1160 if (line[start] != '\0' AND line[start] != '#')
1161 break;
1162 }
1163
1164 if (NOT finished)
1165 {
1166 /*
1167 * Remove trailing whitespace.
1168 */
1169 for(end = STRLEN(line) - 1;
1170 line[end] == ' ' OR line[end] == '\t' OR line[end] == '\n' OR line[end] == '\r';
1171 end--)
1172 ;
1173
1174 line[end + 1] = '\0';
1175 }
1176 }
1177 else
1178 {
1179 get_another_line = TRUE;
1180 }
1181
1182 /*
1183 * If no more input, i.e. finished, then exit loop.
1184 */
1185 if (finished)
1186 break;
1187
1188 /*
1189 * Otherwise, parse according to the current state.
1190 */
1191 switch(state)
1192 {
1193 case ST_PACKAGE:
1194 /*
1195 * Parse the standalone "PACKAGE" keyword.
1196 */
1197 if (IsToken(line, "PACKAGE", start)) {
1198 if (!_ParsePackageLine(line,line_number,start)) {
1199 ErrorMessage
1200 ("Encountered error when parsing \"PACKAGE\" keyword "
1201 "on line %d.",
1202 line_number);
1203 goto error;
1204 }
1205 // Continue to try and parse PACKAGE until we move to MODULE
1206 } else {
1207 /*
1208 * Don't get another line yet...
1209 */
1210 get_another_line = FALSE;
1211 state = ST_MODULE;
1212 }
1213
1214
1215 break;
1216
1217 case ST_MODULE:
1218 /*
1219 * Parse "MODULE" keyword.
1220 */
1221 if (NOT IsToken(line, "MODULE", start))
1222 {
1223 ErrorMessage
1224 ("Encountered error when expecting \"MODULE\" keyword "
1225 "on line %d.",
1226 line_number);
1227
1228 goto error;
1229 }
1230
1231 /*
1232 * If a module definition has already begun, end it here.
1233 */
1234 if (module)
1235 {
1236 if (!_FinishNodeDefinition(mdf, module))
1237 delete module;
1238 }
1239
1240 checked_description = parsed_description = FALSE;
1241 checked_outboard = parsed_outboard = FALSE;
1242 checked_loadable = parsed_loadable = FALSE;
1243 checked_category = parsed_category = FALSE;
1244 checked_flags = parsed_flags = FALSE;
1245 checked_repeat = /*parsed_repeat =*/ FALSE;
1246
1247 /*
1248 * Add the module index to the module index list.
1249 */
1250
1251 if ( (module = _ParseModuleLine(mdf, line, line_number, start)) )
1252 {
1253 /*
1254 * Next, parse category line.
1255 */
1256 state = ST_CATEGORY;
1257 if (uionly)
1258 module->setUILoadedOnly();
1259 }
1260 else
1261 {
1262 goto error;
1263 }
1264 break;
1265
1266 case ST_CATEGORY:
1267 /*
1268 * Parse "CATEGORY" keyword.
1269 */
1270 checked_category = TRUE;
1271 if (IsToken(line, "CATEGORY", start))
1272 {
1273 /*
1274 * Skip space.
1275 */
1276 SkipWhiteSpace(line,start);
1277
1278 /*
1279 * Add category name to the category name symbol table and
1280 * remember the category index.
1281 */
1282 category = theSymbolManager->registerSymbol(&line[start]);
1283 if (!module) {
1284 ErrorMessage
1285 ("Encountered unexpected \"CATEGORY\" on line %d.",
1286 line_number);
1287 goto error;
1288 }
1289
1290 module->setCategory(category);
1291 parsed_category = TRUE;
1292
1293 if (!parsed_description)
1294 state = ST_DESCRIPTION;
1295 else if (!parsed_outboard)
1296 state = ST_OUTBOARD;
1297 else if (!parsed_flags)
1298 state = ST_FLAGS;
1299 else
1300 state = ST_INPUT;
1301 }
1302 else
1303 {
1304 /*
1305 * No category specified; e.g., mark category field as such.
1306 */
1307 module->setCategory(0);
1308
1309 /*
1310 * Don't get another line yet...
1311 */
1312 get_another_line = FALSE;
1313 if (!checked_description)
1314 state = ST_DESCRIPTION;
1315 else if (!checked_outboard)
1316 state = ST_OUTBOARD;
1317 else if (!checked_flags)
1318 state = ST_FLAGS;
1319 else
1320 state = ST_INPUT;
1321 }
1322
1323
1324 break;
1325
1326
1327 case ST_DESCRIPTION:
1328
1329 checked_description = TRUE;
1330
1331 /*
1332 * Parse "DESCRIPTION" keyword.
1333 */
1334 if (IsToken(line, "DESCRIPTION", start))
1335 {
1336 /*
1337 * Skip space.
1338 */
1339 SkipWhiteSpace(line,start);
1340
1341 /*
1342 * Store away the description string.
1343 */
1344 module->setDescription(&line[start]);
1345 parsed_description = TRUE;
1346
1347 if (!parsed_category)
1348 state = ST_CATEGORY;
1349 else if (!parsed_outboard)
1350 state = ST_OUTBOARD;
1351 else if (!parsed_flags)
1352 state = ST_FLAGS;
1353 else
1354 state = ST_INPUT;
1355 }
1356 else
1357 {
1358 /*
1359 * Don't get another line yet...
1360 */
1361 get_another_line = FALSE;
1362 if (!checked_category)
1363 state = ST_CATEGORY;
1364 else if (!checked_outboard)
1365 state = ST_OUTBOARD;
1366 else if (!checked_flags)
1367 state = ST_FLAGS;
1368 else
1369 state = ST_INPUT;
1370 }
1371
1372 break;
1373
1374 case ST_LOADABLE:
1375
1376 checked_loadable = TRUE;
1377 /*
1378 * Parse "LOADABLE" keyword.
1379 */
1380 if (IsToken(line, "LOADABLE", start))
1381 {
1382 /*
1383 * Skip space.
1384 */
1385 SkipWhiteSpace(line,start);
1386
1387 /*
1388 * Store away the description string.
1389 */
1390 if (!_ParseLoadableLine(module, line, line_number, start))
1391 goto error;
1392 parsed_loadable = TRUE;
1393
1394 if (!parsed_category)
1395 state = ST_CATEGORY;
1396 else if (!parsed_description)
1397 state = ST_DESCRIPTION;
1398 else if (!parsed_flags)
1399 state = ST_FLAGS;
1400 else
1401 state = ST_INPUT;
1402 }
1403 else
1404 {
1405 /*
1406 * Don't get another line yet...
1407 */
1408 get_another_line = FALSE;
1409
1410 if (!checked_category)
1411 state = ST_CATEGORY;
1412 else if (!checked_description)
1413 state = ST_DESCRIPTION;
1414 else if (!checked_flags)
1415 state = ST_FLAGS;
1416 else if (!checked_outboard)
1417 state = ST_OUTBOARD;
1418 else
1419 state = ST_INPUT;
1420 }
1421 break;
1422
1423 case ST_OUTBOARD:
1424
1425 checked_outboard = TRUE;
1426 /*
1427 * Parse "OUTBOARD" keyword.
1428 */
1429 if (IsToken(line, "OUTBOARD", start))
1430 {
1431 /*
1432 * Skip space.
1433 */
1434 SkipWhiteSpace(line,start);
1435
1436 /*
1437 * Store away the description string.
1438 */
1439 if (!_ParseOutboardLine(module, line, line_number, start))
1440 goto error;
1441 parsed_outboard = TRUE;
1442
1443 if (!parsed_category)
1444 state = ST_CATEGORY;
1445 else if (!parsed_description)
1446 state = ST_DESCRIPTION;
1447 else if (!parsed_flags)
1448 state = ST_FLAGS;
1449 else
1450 state = ST_INPUT;
1451 }
1452 else
1453 {
1454 /*
1455 * Don't get another line yet...
1456 */
1457 get_another_line = FALSE;
1458
1459 if (!checked_loadable)
1460 state = ST_LOADABLE;
1461 else if (!checked_category)
1462 state = ST_CATEGORY;
1463 else if (!checked_description)
1464 state = ST_DESCRIPTION;
1465 else if (!checked_flags)
1466 state = ST_FLAGS;
1467 else
1468 state = ST_INPUT;
1469 }
1470 break;
1471
1472 case ST_FLAGS:
1473
1474 checked_flags = TRUE;
1475 /*
1476 * Parse "FLAGS" keyword.
1477 */
1478 if (IsToken(line, "FLAGS", start)) {
1479
1480 parsed_flags = TRUE;
1481
1482 if (strstr(line,"SWITCH")) module->setMDFFlagSWITCH();
1483 if (strstr(line,"ERR_CONT")) module->setMDFFlagERR_CONT();
1484 if (strstr(line,"PIN")) module->setMDFFlagPIN();
1485 if (strstr(line,"SIDE_EFFECT")) module->setMDFFlagSIDE_EFFECT();
1486 if (strstr(line,"PERSISTENT")) module->setMDFFlagPERSISTENT();
1487 if (strstr(line,"ASYNC")) module->setMDFFlagASYNCHRONOUS();
1488 if (strstr(line,"REROUTABLE")) module->setMDFFlagREROUTABLE();
1489 if (strstr(line,"REACH")) module->setMDFFlagREACH();
1490 if (strstr(line,"LOOP")) module->setMDFFlagLOOP();
1491
1492 if (!parsed_category)
1493 state = ST_CATEGORY;
1494 else if (!parsed_description)
1495 state = ST_DESCRIPTION;
1496 else if (!parsed_outboard)
1497 state = ST_OUTBOARD;
1498 else
1499 state = ST_INPUT;
1500 }
1501 else
1502 {
1503 /*
1504 * Don't get another line yet...
1505 */
1506 get_another_line = FALSE;
1507
1508 if (!checked_category)
1509 state = ST_CATEGORY;
1510 else if (!checked_description)
1511 state = ST_DESCRIPTION;
1512 else if (!checked_outboard)
1513 state = ST_OUTBOARD;
1514 else
1515 state = ST_INPUT;
1516 }
1517 break;
1518
1519 case ST_INPUT:
1520 last_iostate = ST_INPUT;
1521 if (IsToken(line, "INPUT", start))
1522 {
1523 if (_ParseInputLine(mdf, module, line, line_number, start))
1524 {
1525 /*
1526 * Continue to parse input line.
1527 */
1528 state = ST_INPUT;
1529 }
1530 else
1531 {
1532 goto error;
1533 }
1534 }
1535 else
1536 {
1537 /*
1538 * Don't get another line yet...
1539 */
1540 get_another_line = FALSE;
1541
1542 /*
1543 * If not successful, try parsing repeat line.
1544 */
1545 if (checked_repeat)
1546 state = ST_OUTPUT;
1547 else
1548 state = ST_OPTIONS;
1549
1550 }
1551 break;
1552
1553
1554 case ST_OUTPUT:
1555 last_iostate = ST_OUTPUT;
1556 if (IsToken(line, "OUTPUT", start))
1557 {
1558 if (_ParseOutputLine(mdf, module, line, line_number, start))
1559 {
1560 /*
1561 * Continue to parse output line.
1562 */
1563 state = ST_OUTPUT;
1564 }
1565 else
1566 {
1567 goto error;
1568 }
1569 }
1570 else
1571 {
1572 /*
1573 * Don't get another line yet...
1574 */
1575 get_another_line = FALSE;
1576
1577 /*
1578 * If not successful, assume end of module definition...
1579 */
1580 state = ST_REPEAT;
1581 }
1582 break;
1583
1584 case ST_REPEAT:
1585 checked_repeat = TRUE;
1586 if (IsToken(line, "REPEAT", start))
1587 {
1588 if (_ParseRepeatLine(mdf, module, line, line_number,
1589 start, last_iostate))
1590 {
1591 /*
1592 * Next, parse output or module line.
1593 */
1594 if (last_iostate == ST_INPUT) {
1595 state = ST_OUTPUT;
1596 } else if (last_iostate == ST_OUTPUT) {
1597 state = ST_PACKAGE;
1598 } else
1599 ASSERT(0);
1600 /*parsed_repeat = TRUE;*/
1601 get_another_line = TRUE;
1602 }
1603 else
1604 {
1605 goto error;
1606 }
1607 }
1608 else
1609 {
1610 /*
1611 * Don't get another line yet...
1612 */
1613 get_another_line = FALSE;
1614
1615 /*
1616 * If not successful, try parsing output or module line.
1617 */
1618 if (last_iostate == ST_INPUT) {
1619 state = ST_INPUT;
1620 } else if (last_iostate == ST_OUTPUT) {
1621 state = ST_PACKAGE;
1622 } else
1623 ASSERT(0);
1624 }
1625 break;
1626
1627 case ST_OPTIONS:
1628 ASSERT(last_iostate == ST_INPUT);
1629 if (IsToken(line, "OPTIONS", start))
1630 {
1631 if (_ParseOptionsLine(mdf, module, line, line_number, start))
1632 {
1633 /*
1634 * Next, parse another line of selections
1635 */
1636 state = ST_OPTIONS;
1637 get_another_line = TRUE;
1638 }
1639 else
1640 {
1641 goto error;
1642 }
1643 }
1644 else
1645 {
1646 /*
1647 * Don't get another line yet...
1648 */
1649 get_another_line = FALSE;
1650
1651 /*
1652 * If not successful, try parsing output or module line.
1653 */
1654 if (!checked_repeat)
1655 state = ST_REPEAT;
1656 else
1657 state = ST_INPUT;
1658 }
1659 break;
1660
1661
1662 default:
1663 ASSERT(FALSE);
1664 }
1665 }
1666
1667 /*
1668 * Finish the module definition.
1669 */
1670 if (module)
1671 {
1672 if (!_FinishNodeDefinition(mdf, module))
1673 delete module;
1674 }
1675
1676 return TRUE;
1677
1678 error:
1679 if (module) delete module;
1680
1681 return FALSE;
1682 }
1683
LoadMDFFile(const char * file,const char * mdftype,Dictionary * mdf,boolean uionly)1684 boolean LoadMDFFile(const char *file, const char *mdftype, Dictionary *mdf,
1685 boolean uionly)
1686 {
1687 FILE *input;
1688 boolean parsed;
1689
1690 if (!file || !*file)
1691 return TRUE;
1692
1693 input = fopen(file, "r");
1694 if (input != NUL(FILE*))
1695 {
1696 parsed = ReadMDF(mdf, input, uionly);
1697 fclose(input);
1698
1699 if (NOT parsed)
1700 {
1701 ErrorMessage("Error found in %s module definition file \"%s\".",
1702 mdftype,file);
1703 return FALSE;
1704 }
1705 }
1706 else
1707 {
1708 ErrorMessage ("Cannot open %s module description file \"%s\".",
1709 mdftype,file);
1710 return FALSE;
1711 }
1712 return TRUE;
1713 }
1714
1715 #ifdef NOT_YET
ReadMDFFiles(const char * root,Dictionary * mdf)1716 boolean ReadMDFFiles(const char *root, Dictionary *mdf)
1717 {
1718
1719 FILE* input;
1720 boolean parsed;
1721 char pathname[256];
1722
1723
1724 /*
1725 * Load system module description file.
1726 */
1727 sprintf(pathname, "%s/lib/dx.mdf", root);
1728
1729 if (!LoadMDFFile(pathname,"system",mdf))
1730 return FALSE;
1731
1732 /*
1733 * Load UI module description file.
1734 */
1735 sprintf(pathname, "%s/ui/ui.mdf", root);
1736
1737 if (!LoadMDFFile(pathname,"UI",mdf))
1738 return FALSE;
1739
1740 /*
1741 * Load user module description file, if defined.
1742 */
1743 if (program->user_module)
1744 {
1745 input = fopen(program->user_module, "r");
1746 if (input != NUL(FILE*))
1747 {
1748 parsed = ReadMDF(program->mdf, input);
1749 fclose(input);
1750
1751 if (NOT parsed)
1752 {
1753 ErrorMessage
1754 ("Error found in user module definition file \"%s\".",
1755 program->user_module);
1756 return FALSE;
1757 }
1758 }
1759 else
1760 {
1761 ErrorMessage
1762 ("Cannot open user module description file \"%s\".",
1763 program->user_module);
1764 return FALSE;
1765 }
1766 }
1767
1768 /*
1769 * Need to initialize MDF after all the module description files have
1770 * been parsed, and all the macro definitions have been added.
1771 */
1772 InitializeMDF(program->mdf);
1773
1774 /*
1775 * Install the macros.
1776 */
1777 if (program->macros)
1778 {
1779 uipInstallMacros(program);
1780 }
1781
1782 /*
1783 * Return successfully.
1784 */
1785 return TRUE;
1786 }
1787 #endif // NOT_YET
1788
1789 #ifdef NOT_YET
1790 /*****************************************************************************/
1791 /* _CompareModules - */
1792 /* */
1793 /* Compares two module name strings. */
1794 /* */
1795 /*****************************************************************************/
1796
1797 static
_CompareModules(int * first,int * second)1798 int _CompareModules(int* first,
1799 int* second)
1800 {
1801 ASSERT(first);
1802 ASSERT(second);
1803
1804 return
1805 uiuStrcmp(_mdf->module[*first].function, _mdf->module[*second].function);
1806 }
1807
1808
1809 /*****************************************************************************/
1810 /* SortMDF - */
1811 /* */
1812 /* Sorts an MDF list by name. */
1813 /* */
1814 /*****************************************************************************/
1815
SortMDF(Dictionary * mdf)1816 void SortMDF(Dictionary* mdf)
1817 {
1818 ASSERT(mdf != NUL(Dictionary*));
1819
1820 /*
1821 * Sort the module list in alphabetical order.
1822 */
1823 _mdf = mdf;
1824 qsort(mdf->module_index, mdf->n_modules, sizeof(int), _CompareModules);
1825 }
1826
1827
1828
1829 /*****************************************************************************/
1830 /* InitializeMDF - */
1831 /* */
1832 /* Initializes an MDF after all the various module description files have */
1833 /* been read and parsed. */
1834 /* */
1835 /*****************************************************************************/
1836
InitializeMDF(UimMDF * mdf)1837 void InitializeMDF(UimMDF* mdf)
1838 {
1839 UimModule* module;
1840 int i;
1841 int k;
1842
1843 ASSERT(mdf);
1844
1845 /*
1846 * Sort the module list in alphabetical order.
1847 */
1848 _mdf = mdf;
1849 qsort(mdf->module_index, mdf->n_modules, sizeof(int), _CompareModules);
1850
1851 /*
1852 * Save special UI module names and categories (indices).
1853 */
1854 uiuStringTableFind(mdf->name_table, "Integer", &mdf->name.integer);
1855 uiuStringTableFind(mdf->name_table, "Scalar", &mdf->name.scalar);
1856 uiuStringTableFind(mdf->name_table, "Vector", &mdf->name.vector);
1857 uiuStringTableFind(mdf->name_table, "Value", &mdf->name.value);
1858 uiuStringTableFind(mdf->name_table, "String", &mdf->name.string);
1859 uiuStringTableFind(mdf->name_table, "Selector", &mdf->name.selector);
1860 uiuStringTableFind(mdf->name_table, "IntegerList", &mdf->name.integer_list);
1861 uiuStringTableFind(mdf->name_table, "ScalarList", &mdf->name.scalar_list);
1862 uiuStringTableFind(mdf->name_table, "VectorList", &mdf->name.vector_list);
1863 uiuStringTableFind(mdf->name_table, "ValueList", &mdf->name.value_list);
1864 uiuStringTableFind(mdf->name_table, "StringList", &mdf->name.string_list);
1865
1866 uiuStringTableFind
1867 (mdf->category_table, "Interactor", &mdf->name.interactors);
1868
1869 uiuStringTableFind(mdf->name_table, "Colormap", &mdf->name.colormap);
1870 uiuStringTableFind(mdf->name_table, "Image", &mdf->name.image);
1871 uiuStringTableFind(mdf->name_table, "Input", &mdf->name.input);
1872 uiuStringTableFind(mdf->name_table, "Output", &mdf->name.output);
1873 uiuStringTableFind(mdf->name_table, "Receiver", &mdf->name.receiver);
1874 uiuStringTableFind(mdf->name_table, "Sequencer", &mdf->name.sequencer);
1875 uiuStringTableFind(mdf->name_table, "Transmitter", &mdf->name.transmitter);
1876 uiuStringTableFind(mdf->name_table, "VCR", &mdf->name.vcr);
1877
1878 uiuStringTableFind(mdf->name_table, "Display", &mdf->name.display);
1879 uiuStringTableFind(mdf->name_table, "ProbeList", &mdf->name.probe_list);
1880 uiuStringTableFind(mdf->name_table, "Probe", &mdf->name.probe);
1881
1882 #ifdef EPIC
1883 uiuStringTableFind(mdf->name_table, "Epic", &mdf->name.epic);
1884 #else
1885 mdf->name.epic = -1;
1886 #endif
1887
1888 #ifdef CAD
1889 uiuStringTableFind(mdf->name_table, "Navigate", &mdf->name.navigate);
1890 #else
1891 mdf->name.navigate = -1;
1892 #endif
1893
1894 /*
1895 * Adjust certain parameters of various modules to be invisible.
1896 */
1897 FOR_EACH_MODULE(module, i, mdf)
1898 {
1899 if (module->dialog_type == CONF_DIALOG_COMPUTE)
1900 {
1901 module->input[0].visible = FALSE;
1902 }
1903 else if (module->name == mdf->name.colormap)
1904 {
1905 module->input[0].visible = FALSE;
1906 module->input[1].visible = FALSE;
1907 module->input[2].visible = FALSE;
1908 module->input[3].visible = FALSE;
1909 }
1910 else if (module->name == mdf->name.image)
1911 {
1912 /*
1913 * Make every parameter, except the second one, invisible.
1914 */
1915 for (k = 0; k < module->n_inputs; k++)
1916 {
1917 if (k != 1)
1918 {
1919 module->input[k].visible = FALSE;
1920 }
1921 }
1922 }
1923 else if (module->name == mdf->name.navigate)
1924 {
1925 /*
1926 * Make most parameters invisible.
1927 */
1928 for (k = 0; k < module->n_inputs; k++)
1929 {
1930 if (k != 1 AND k != 29 AND k != 30)
1931 {
1932 module->input[k].visible = FALSE;
1933 }
1934 }
1935 }
1936 }
1937 }
1938 #endif // NOT_YET
1939
1940 #ifdef COMMENT
1941
1942 /*****************************************************************************/
1943 /* _uimPrintMDF - */
1944 /* */
1945 /* Prints binary form of module descriptions in ASCII. prints only one */
1946 /* module name, if supplied; otherwise prints the entire table of modules. */
1947 /* */
1948 /*****************************************************************************/
1949
1950 static
_uimPrintMDF(UimMDF * mdf,FILE * output)1951 void _uimPrintMDF(UimMDF* mdf,
1952 FILE* output)
1953 {
1954 UimModule* module;
1955 UimParam* parameter;
1956 int i;
1957 int j;
1958 int k;
1959
1960 ASSERT(mdf);
1961 ASSERT(output);
1962
1963 FOR_EACH_MODULE(module, i, mdf)
1964 {
1965 fprintf(output, "MODULE %s\n",module->function);
1966
1967 fprintf(output,
1968 "CATEGORY %s\n",
1969 uiuStringTableGet(mdf->category_table, module->category));
1970
1971 if (module->description)
1972 {
1973 fprintf(output, "DESCRIPTION %s\n", module->description);
1974 }
1975
1976 FOR_EACH_MODULE_INPUT(parameter, j, module)
1977 {
1978 fprintf(output,
1979 "INPUT %s; ",
1980 uiuStringTableGet(mdf->label_table, parameter->label));
1981
1982 for (k = 0; k < parameter->type_count; k++)
1983 {
1984 fputs(uimTypeToString(module->type[parameter->type + k]),
1985 output);
1986
1987 if (k < parameter->type_count - 1)
1988 {
1989 fputs(" or ", output);
1990 }
1991 }
1992
1993 if (parameter->default_value)
1994 {
1995 fprintf(output, "; %s", parameter->default_value);
1996 }
1997
1998 if (parameter->description)
1999 {
2000 fprintf(output, "; %s", parameter->description);
2001 }
2002
2003 fputc('\n', output);
2004 }
2005
2006 if (module->n_repeats)
2007 {
2008 fprintf(output, "REPEAT %d\n", module->n_repeats);
2009 }
2010
2011 FOR_EACH_MODULE_OUTPUT(parameter, j, module)
2012 {
2013 fprintf(output,
2014 "OUTPUT %s; ",
2015 uiuStringTableGet(mdf->label_table, parameter->label));
2016
2017 for (k = 0; k < parameter->type_count; k++)
2018 {
2019 fputs(uimTypeToString(module->type[parameter->type + k]),
2020 output);
2021
2022 if (k < parameter->type_count - 1)
2023 {
2024 fputs(" or ", output);
2025 }
2026 }
2027
2028 if (parameter->description)
2029 {
2030 fprintf(output, "; %s", parameter->description);
2031 }
2032
2033 fputc('\n', output);
2034 }
2035
2036 fputc('\n', output);
2037 }
2038 }
2039
2040 #endif
2041