4 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
5 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
6 * the full copyright text.
13 static char rcsid[] = "$XConsortium: wmlresolve.c /main/9 1995/08/29 11:11:05 drk $"
17 * (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
20 * This module contains all routines which perform semantic analysis of
21 * the parsed WML specification. It is responsible for building all
22 * ordered structures which can be directly translated into literal
23 * code values for the various .h files. It is responsible for performing
24 * inheritance of resources for all classes.
27 * the ordered list of syntactic objects in wml_synobj_ptr
42 * Routines used only in this module
44 void wmlResolveGenerateSymK ();
45 void wmlResolveValidateClass ();
46 void wmlResolvePrintReport ();
48 void wmlResolveSymKDataType ();
49 void wmlResolveSymKChild ();
50 void wmlResolveSymKEnumVal ();
51 void wmlResolveSymKEnumSet ();
52 void wmlResolveSymKReason ();
53 void wmlResolveSymKArgument ();
54 void wmlResolveSymKRelated ();
55 void wmlResolveSymKClass ();
56 void wmlResolveSymKCtrlList ();
57 void wmlResolveSymKCharSet ();
59 void wmlResolveClassInherit ();
60 void wmlResolveClearRefPointers ();
61 void wmlResolveInitRefObj ();
62 void wmlResolveInitChildRefObj ();
64 void wmlResolvePrintClass ();
65 void wmlResolvePrintClassArgs ();
66 void wmlResolvePrintClassReasons ();
68 ObjectPtr wmlResolveFindObject ();
69 void wmlIssueReferenceError ();
70 void wmlIssueIllegalReferenceError ();
71 void wmlIssueError ();
76 * The control routine for semantic analysis. It calls the various phases.
79 void wmlResolveDescriptors ()
84 * Perform the code assignment pass. This results in assignment of sym_k_...
85 * codes to all entities. Also, all objects and cross-linking are validated.
87 wmlResolveGenerateSymK ();
88 printf ("\nInitial validation and reference resolution complete");
91 * Perform class inheritance and validation
93 wmlResolveValidateClass ();
94 printf ("\nClass validation and inheritance complete");
99 if ( wml_err_count > 0 ) return;
100 wmlResolvePrintReport ();
107 * Routine to linearize and assign sym_k... literals for objects. Simply
108 * a dispatching routine.
111 void wmlResolveGenerateSymK ()
116 * Process the datatype objects
118 wmlResolveSymKDataType ();
121 * Process the enumeration value and enumeration sets
123 wmlResolveSymKEnumVal ();
124 wmlResolveSymKEnumSet ();
127 * Process the resources, producing argument and reason vectors.
129 wmlResolveSymKReason ();
130 wmlResolveSymKArgument ();
133 * Bind related arguments
135 wmlResolveSymKRelated ();
138 * Process the class definitions
140 wmlResolveSymKClass ();
143 * Process the controls list definitions
145 wmlResolveSymKCtrlList ();
148 * Process the charset objects
150 wmlResolveSymKCharSet ();
152 /* Process the child definitions. */
153 wmlResolveSymKChild();
160 * Routine to linearize data types
162 * - Generate the wml_obj_datatype... vector of resolved data type objects,
163 * ordered lexicographically.
164 * Do name processing, and acquire links to any other objects named in
165 * the syntactic descriptor.
168 void wmlResolveSymKDataType ()
172 WmlSynDataTypeDefPtr cursyn; /* current syntactic object */
173 WmlDataTypeDefPtr newobj; /* new resolved object */
174 int ndx; /* loop index */
177 * Initialize the object vector. Then process the syntactic vector,
178 * processing each datatype object encountered (the vector is ordered).
179 * create and append a resolved object for each one encountered. This
180 * will be ordered as well.
182 wmlInitHList (wml_obj_datatype_ptr, 50, TRUE);
183 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
185 cursyn = (WmlSynDataTypeDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
186 if ( cursyn->validation != WmlDataTypeDefValid ) continue;
189 * Create and initialize new object. Append to resolved object vector.
191 newobj = (WmlDataTypeDefPtr) malloc (sizeof(WmlDataTypeDef));
192 newobj->syndef = cursyn;
193 cursyn->rslvdef = newobj;
194 if ( cursyn->int_lit != NULL )
195 newobj->tkname = cursyn->int_lit;
197 newobj->tkname = cursyn->name;
198 wmlInsertInHList (wml_obj_datatype_ptr, newobj->tkname, (ObjectPtr)newobj);
201 * Validate any object references in the syntactic object
210 * Routine to linearize children
212 * - Generate the wml_obj_child... vector of resolved child objects,
213 * ordered lexicographically. Assign sym_k_... values while doing so.
214 * Link child to its class.
217 void wmlResolveSymKChild ()
221 WmlSynChildDefPtr cursyn; /* current syntactic object */
222 WmlChildDefPtr newobj; /* new resolved object */
223 int code; /* assigned sym_k code value */
224 int ndx; /* loop index */
227 * Initialize the object vector. Then process the syntactic vector,
228 * processing each child object encountered (the vector is ordered).
229 * create and append a resolved object for each one encountered. This
230 * will be ordered as well.
232 wmlInitHList (wml_obj_child_ptr, 50, TRUE);
233 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
235 cursyn = (WmlSynChildDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
236 if ( cursyn->validation != WmlChildDefValid ) continue;
239 * Create and initialize new object. Append to resolved object vector.
241 newobj = (WmlChildDefPtr) malloc (sizeof(WmlChildDef));
242 newobj->syndef = cursyn;
243 cursyn->rslvdef = newobj;
244 newobj->tkname = cursyn->name;
245 wmlInsertInHList (wml_obj_child_ptr, newobj->tkname, (ObjectPtr)newobj);
247 /* Link class to the resolved object. */
248 if (cursyn->class != NULL)
249 newobj->class = (WmlClassDefPtr)
250 wmlResolveFindObject(cursyn->class, WmlClassDefValid, cursyn->name);
254 * All objects are in the vector. The order is the code order, so
255 * process it again and assign codes to each object
258 for ( ndx=0 ; ndx<wml_obj_child_ptr->cnt ; ndx++ )
260 newobj = (WmlChildDefPtr) wml_obj_child_ptr->hvec[ndx].objptr;
261 newobj->sym_code = code;
270 * Routine to linearize and assign sym_k values to enumeration values
272 * - Generate the wml_obj_datatype... vector of resolved data type objects,
273 * ordered lexicographically. No sym_k_... values are needed for
274 * enumeration values, so don't assign any.
277 void wmlResolveSymKEnumVal ()
281 WmlSynEnumSetDefPtr cures; /* current enumeration set */
282 WmlSynEnumSetValDefPtr curesv; /* current enum set value */
283 WmlSynEnumValueDefPtr cursyn; /* current syntactic object */
284 WmlEnumValueDefPtr newobj; /* new resolved object */
285 int ndx; /* loop index */
286 int code; /* sym_k_... code */
290 * Perform defaulting. Process all the enumeration sets, and define a
291 * syntactic object for every enumeration value named in an enumeration set
292 * which has no syntactic entry. If there is an error in a name, then
293 * this error won't be detected until we attempt to compile the output .h files.
295 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
297 cures = (WmlSynEnumSetDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
298 if ( cures->validation != WmlEnumSetDefValid ) continue;
299 for (curesv=cures->values ; curesv!=NULL ; curesv=curesv->next)
300 if ( wmlFindInHList(wml_synobj_ptr,curesv->name) < 0 )
301 wmlCreateEnumValue (curesv->name);
305 * Initialize the object vector. Then process the syntactic vector,
306 * processing each enumeration value object encountered (the vector is ordered).
307 * create and append a resolved object for each one encountered. This
308 * will be ordered as well.
310 wmlInitHList (wml_obj_enumval_ptr, 50, TRUE);
311 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
313 cursyn = (WmlSynEnumValueDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
314 if ( cursyn->validation != WmlEnumValueDefValid ) continue;
317 * Create and initialize new object. Append to resolved object vector.
319 newobj = (WmlEnumValueDefPtr) malloc (sizeof(WmlEnumValueDef));
320 newobj->syndef = cursyn;
321 cursyn->rslvdef = newobj;
322 wmlInsertInHList (wml_obj_enumval_ptr, cursyn->name, (ObjectPtr)newobj);
326 * All objects are in the vector. That order is the code order, so
327 * process it again and assign codes to each object
330 for ( ndx=0 ; ndx<wml_obj_enumval_ptr->cnt ; ndx++ )
332 newobj = (WmlEnumValueDefPtr) wml_obj_enumval_ptr->hvec[ndx].objptr;
333 newobj->sym_code = code;
342 * Routine to linearize and assign sym_k values to enumeration sets
344 * - Generate the wml_obj_datatype... vector of resolved data type objects,
345 * ordered lexicographically. No sym_k_... values are needed for
346 * enumeration values, so don't assign any.
349 void wmlResolveSymKEnumSet ()
353 WmlSynEnumSetDefPtr cursyn; /* current syntactic object */
354 WmlEnumSetDefPtr newobj; /* new resolved object */
355 int ndx; /* loop index */
356 int code; /* sym_k_... code */
357 WmlSynEnumSetValDefPtr esvelm; /* current syntactic list element */
358 WmlEnumValueDefPtr evobj; /* current enumeration value */
359 WmlEnumSetValDefPtr esvobj; /* current list element */
362 * Initialize the object vector. Then process the syntactic vector,
363 * processing each enumeration set object encountered (the vector is ordered).
364 * create and append a resolved object for each one encountered. This
365 * will be ordered as well.
367 wmlInitHList (wml_obj_enumset_ptr, 20, TRUE);
368 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
370 cursyn = (WmlSynEnumSetDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
371 if ( cursyn->validation != WmlEnumSetDefValid ) continue;
374 * Create and initialize new object. Append to resolved object vector.
376 newobj = (WmlEnumSetDefPtr) malloc (sizeof(WmlEnumSetDef));
377 newobj->syndef = cursyn;
378 cursyn->rslvdef = newobj;
379 newobj->tkname = cursyn->name;
380 newobj->dtype_def = (WmlDataTypeDefPtr)
381 wmlResolveFindObject (cursyn->datatype,
384 wmlInsertInHList (wml_obj_enumset_ptr, newobj->tkname, (ObjectPtr)newobj);
388 * All objects are in the vector. That order is the code order, so
389 * process it again and assign codes to each object. Simultaneously construct
390 * a vector of resolved enumeration values, and count them.
393 for ( ndx=0 ; ndx<wml_obj_enumset_ptr->cnt ; ndx++ )
395 newobj = (WmlEnumSetDefPtr) wml_obj_enumset_ptr->hvec[ndx].objptr;
396 newobj->sym_code = code;
400 * Validate and construct a resolved enumeration value list
402 cursyn = newobj->syndef;
403 newobj->values_cnt = 0;
404 newobj->values = NULL;
405 for ( esvelm=cursyn->values ; esvelm!=NULL ; esvelm=esvelm->next )
407 evobj = (WmlEnumValueDefPtr)
408 wmlResolveFindObject (esvelm->name,
409 WmlEnumValueDefValid,
411 if ( evobj == NULL ) continue;
412 esvobj = (WmlEnumSetValDefPtr) malloc (sizeof(WmlEnumSetValDef));
413 esvobj->value = evobj;
414 esvobj->next = newobj->values;
415 newobj->values = esvobj;
416 newobj->values_cnt += 1;
425 * Routine to linearize and assign sym_k values to reasons.
427 * - Generate the wml_obj_reason... vector of resolved reason objects,
428 * ordered lexicographically. Assign a sym_k_... value as this is done.
429 * Do name processing, and acquire links to any other objects named in
430 * the syntactic descriptor.
433 void wmlResolveSymKReason ()
437 WmlSynResourceDefPtr cursyn; /* current syntactic object */
438 WmlResourceDefPtr newobj; /* new resolved object */
439 int ndx; /* loop index */
440 int code; /* assigned sym_k code value */
444 * Initialize the object vector. Then process the syntactic vector,
445 * processing each reason resource object encountered (the vector is ordered).
446 * create and append a resolved object for each one encountered. This
447 * will be ordered as well.
449 wmlInitHList (wml_obj_reason_ptr, 100, TRUE);
450 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
452 cursyn = (WmlSynResourceDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
453 if ( cursyn->validation != WmlResourceDefValid ) continue;
454 if ( cursyn->type != WmlResourceTypeReason ) continue;
455 newobj = (WmlResourceDefPtr) malloc (sizeof(WmlResourceDef));
458 * Create and initialize new object. Append to resolved object vector.
460 newobj->syndef = cursyn;
461 cursyn->rslvdef = newobj;
462 if ( cursyn->int_lit != NULL )
463 newobj->tkname = cursyn->int_lit;
465 newobj->tkname = cursyn->name;
466 newobj->dtype_def = NULL;
467 newobj->enumset_def = NULL;
468 newobj->related_code = 0;
469 wmlInsertInHList (wml_obj_reason_ptr, newobj->tkname, (ObjectPtr)newobj);
472 * Validate any object references in the syntactic object
473 * Reason can't bind to some objects.
475 if ( cursyn->datatype != NULL )
476 wmlIssueIllegalReferenceError (cursyn->name, "DataType");
481 * All objects are in the vector. That order is the code order, so
482 * process it again and assign codes to each object
485 for ( ndx=0 ; ndx<wml_obj_reason_ptr->cnt ; ndx++ )
487 newobj = (WmlResourceDefPtr) wml_obj_reason_ptr->hvec[ndx].objptr;
488 newobj->sym_code = code;
497 * Routine to linearize and assign sym_k values to arguments.
499 * - Generate the wml_obj_arg... vector of resovled reason objects,
500 * ordered lexicographically. Assign a sym_k_... values while doing so.
501 * validate the data type for each argument, and link it to its data type
503 * Do name processing, and acquire links to any other objects named in
504 * the syntactic descriptor.
507 void wmlResolveSymKArgument ()
512 WmlSynResourceDefPtr cursyn; /* current syntactic object */
513 WmlResourceDefPtr newobj; /* new resolved object */
514 int ndx; /* loop index */
515 int code; /* assigned sym_k code value */
519 * Initialize the object vector. Then process the syntactic vector,
520 * processing each reason resource object encountered (the vector is ordered).
521 * create and append a resolved object for each one encountered. This
522 * will be ordered as well.
524 wmlInitHList (wml_obj_arg_ptr, 500, TRUE);
525 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
527 cursyn = (WmlSynResourceDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
528 if ( cursyn->validation != WmlResourceDefValid ) continue;
529 if ( cursyn->type == WmlResourceTypeReason ) continue;
530 newobj = (WmlResourceDefPtr) malloc (sizeof(WmlResourceDef));
533 * Create and initialize new object. Append to resolved object vector.
535 newobj->syndef = cursyn;
536 cursyn->rslvdef = newobj;
537 if ( cursyn->int_lit != NULL )
538 newobj->tkname = cursyn->int_lit;
540 newobj->tkname = cursyn->name;
541 newobj->related_code = 0;
542 newobj->enumset_def = NULL;
543 wmlInsertInHList (wml_obj_arg_ptr, newobj->tkname, (ObjectPtr)newobj);
546 * Validate any object references in the syntactic object
548 newobj->dtype_def = (WmlDataTypeDefPtr)
549 wmlResolveFindObject (cursyn->datatype,
552 if ( cursyn->enumset != NULL )
553 newobj->enumset_def = (WmlEnumSetDefPtr)
554 wmlResolveFindObject (cursyn->enumset,
561 * All objects are in the vector. The order is the code order, so
562 * process it again and assign codes to each object
565 for ( ndx=0 ; ndx<wml_obj_arg_ptr->cnt ; ndx++ )
567 newobj = (WmlResourceDefPtr) wml_obj_arg_ptr->hvec[ndx].objptr;
568 newobj->sym_code = code;
577 * Routine to resolve related argument references.
579 * Search the argument vector for any argument with its related
580 * argument set. Find the related argument, and bind the relation.
581 * The binding only goes one way.
584 void wmlResolveSymKRelated ()
588 WmlResourceDefPtr srcobj; /* object with related reference */
589 WmlResourceDefPtr dstobj; /* other object in binding */
590 WmlSynResourceDefPtr srcsynobj; /* source syntactic object */
591 int ndx; /* loop index */
595 * Scan all arguments for related argument bindings.
597 for ( ndx=0 ; ndx<wml_obj_arg_ptr->cnt ; ndx++ )
599 srcobj = (WmlResourceDefPtr) wml_obj_arg_ptr->hvec[ndx].objptr;
600 srcsynobj = srcobj->syndef;
601 if ( srcsynobj->related != NULL )
603 dstobj = (WmlResourceDefPtr)
604 wmlResolveFindObject (srcsynobj->related,
607 if ( dstobj != NULL )
608 srcobj->related_code = dstobj->sym_code;
616 * Routine to linearize and assign sym_k values to classes
618 * There are two linearizations of classes:
619 * - all classes in wml_obj_allclass...
620 * - all widgets and gadgets in wml_obj_class...
621 * Create and linearize all class objects into these vectors. Assign sym_k
622 * codes. Link all subclasses to their superclasses. Perform name processing
623 * and link to any other named object.
625 * Resources are not inherited and linked at this time.
628 void wmlResolveSymKClass ()
632 WmlSynClassDefPtr cursyn; /* current syntactic object */
633 WmlClassDefPtr newobj; /* new resolved object */
634 int ndx; /* loop index */
635 int code; /* assigned sym_k code value */
640 * Initialize the object vectors. Then process the syntactic vector,
641 * processing each class object encountered (the vector is ordered).
642 * create and append a resolved object for each one encountered. This
643 * will be ordered as well.
645 wmlInitHList (wml_obj_allclass_ptr, 200, TRUE);
646 wmlInitHList (wml_obj_class_ptr, 200, TRUE);
647 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
649 cursyn = (WmlSynClassDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
650 if ( cursyn->validation != WmlClassDefValid ) continue;
653 * Create and initialize new object. Append to resolved object vector.
655 newobj = (WmlClassDefPtr) malloc (sizeof(WmlClassDef));
656 newobj->syndef = cursyn;
657 cursyn->rslvdef = newobj;
658 newobj->superclass = NULL;
659 newobj->parentclass = NULL;
660 if ( cursyn->int_lit != NULL )
661 newobj->tkname = cursyn->int_lit;
663 newobj->tkname = cursyn->name;
664 newobj->inherit_done = FALSE;
665 newobj->arguments = NULL;
666 newobj->reasons = NULL;
667 newobj->controls = NULL;
668 newobj->children = NULL;
669 newobj->variant = NULL;
670 newobj->nondialog = NULL;
671 newobj->ctrlmapto = NULL;
672 switch ( cursyn->type )
674 case WmlClassTypeMetaclass:
676 (wml_obj_allclass_ptr, newobj->tkname, (ObjectPtr)newobj);
678 case WmlClassTypeGadget:
679 case WmlClassTypeWidget:
681 (wml_obj_allclass_ptr, newobj->tkname, (ObjectPtr)newobj);
683 (wml_obj_class_ptr, newobj->tkname, (ObjectPtr)newobj);
688 * Require a convenience function name
690 if ( cursyn->type != WmlClassTypeMetaclass )
691 if ( cursyn->convfunc == NULL )
693 sprintf (errmsg, "Class %s does not have a convenience function",
695 wmlIssueError (errmsg);
699 * Validate any object references in the syntactic object
701 if ( cursyn->ctrlmapto != NULL )
702 newobj->ctrlmapto = (WmlResourceDefPtr)
703 wmlResolveFindObject (cursyn->ctrlmapto,
710 * All objects are in the vector. That order is the code order, so
711 * process it again and assign codes to each object
714 for ( ndx=0 ; ndx<wml_obj_class_ptr->cnt ; ndx++ )
716 newobj = (WmlClassDefPtr) wml_obj_class_ptr->hvec[ndx].objptr;
717 newobj->sym_code = code;
726 * Routine to validate controls lists
728 * Construct and linearize resolved controls lists. The linearized list
729 * is used to resolve references.
732 void wmlResolveSymKCtrlList ()
736 WmlSynCtrlListDefPtr cursyn; /* current syntactic object */
737 WmlCtrlListDefPtr newobj; /* new resolved object */
738 WmlSynClassCtrlDefPtr refptr; /* current controls reference */
739 WmlClassCtrlDefPtr ctrlobj; /* resolved control reference */
740 WmlClassDefPtr classobj; /* the controlled class */
741 int ndx; /* loop index */
745 * Process each control list. Construct a resolved control list for each
747 wmlInitHList (wml_obj_ctrlist_ptr, 20, TRUE);
748 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
750 cursyn = (WmlSynCtrlListDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
751 if ( cursyn->validation != WmlCtrlListDefValid ) continue;
754 * Create and initialize new object. Append to resolved object vector.
756 newobj = (WmlCtrlListDefPtr) malloc (sizeof(WmlCtrlListDef));
757 newobj->syndef = cursyn;
758 cursyn->rslvdef = newobj;
759 newobj->controls = NULL;
760 wmlInsertInHList (wml_obj_ctrlist_ptr, cursyn->name, (ObjectPtr)newobj);
763 * Validate and construct a resolved controls reference list.
765 for ( refptr=cursyn->controls ; refptr!=NULL ; refptr=refptr->next )
767 classobj = (WmlClassDefPtr)
768 wmlResolveFindObject (refptr->name,
771 if ( classobj == NULL ) continue;
772 ctrlobj = (WmlClassCtrlDefPtr) malloc (sizeof(WmlClassCtrlDef));
773 ctrlobj->next = newobj->controls;
774 newobj->controls = ctrlobj;
775 ctrlobj->ctrl = classobj;
784 * Routine to linearize and assign sym_k values to character sets
786 * - Generate the wml_obj_charset... vector of resolved data type objects,
787 * ordered lexicographically. Assign a sym_k... value as this is done.
788 * Do name processing, and acquire links to any other objects named in
789 * the syntactic descriptor.
792 void wmlResolveSymKCharSet ()
796 WmlSynCharSetDefPtr cursyn; /* current syntactic object */
797 WmlCharSetDefPtr newobj; /* new resolved object */
798 int ndx; /* loop index */
799 int code; /* assigned sym_k code value */
804 * Initialize the object vector. Then process the syntactic vector,
805 * processing each charset object encountered (the vector is ordered).
806 * create and append a resolved object for each one encountered. This
807 * will be ordered as well.
809 wmlInitHList (wml_obj_charset_ptr, 50, TRUE);
810 for ( ndx=0 ; ndx<wml_synobj_ptr->cnt ; ndx++ )
812 cursyn = (WmlSynCharSetDefPtr) wml_synobj_ptr->hvec[ndx].objptr;
813 if ( cursyn->validation != WmlCharSetDefValid ) continue;
816 * Create and initialize new object. Append to resolved object vector.
818 newobj = (WmlCharSetDefPtr) malloc (sizeof(WmlCharSetDef));
819 newobj->syndef = cursyn;
820 cursyn->rslvdef = newobj;
821 if ( cursyn->int_lit != NULL )
822 newobj->tkname = cursyn->int_lit;
824 newobj->tkname = cursyn->name;
825 wmlInsertInHList (wml_obj_charset_ptr, newobj->tkname, (ObjectPtr)newobj);
828 * Parsing direction defaults to writing direction if unspecified
830 if ( cursyn->parsedirection == WmlAttributeUnspecified )
831 cursyn->parsedirection = cursyn->direction;
834 * Require StandardsName attribute for character set
836 if ( cursyn->xms_name == NULL )
838 sprintf (errmsg, "CharacterSet %s does not have a StandardsName",
840 wmlIssueError (errmsg);
846 * All objects are in the vector. That order is the code order, so
847 * process it again and assign codes to each object. We start at code
848 * 2 since 1 is reserved for sym_k_userdefined_charset
851 for ( ndx=0 ; ndx<wml_obj_charset_ptr->cnt ; ndx++ )
853 newobj = (WmlCharSetDefPtr) wml_obj_charset_ptr->hvec[ndx].objptr;
854 newobj->sym_code = code;
863 * Routine to perform class inheritance and validation.
865 * This routine has two major phases:
866 * - Complete resolution of class references, and expand out
868 * - Perform inheritance of resources, partitioning them into
869 * into arguments and reasons. When complete, the class has
870 * a list of all its resources, including copies from a
871 * superclass and possibly a parentclass.
872 * Excluded resources remain in the list, and are simply marked.
875 void wmlResolveValidateClass ()
879 int ndx; /* loop index */
880 int max; /* maximum code value */
881 WmlClassDefPtr clsobj; /* current class object */
882 WmlSynClassDefPtr synobj; /* syntactic class object */
883 WmlClassDefPtr superobj; /* superclass */
884 WmlClassDefPtr parentobj; /* parentclass */
885 WmlClassDefPtr widgobj; /* gadget's widget class */
886 WmlSynClassCtrlDefPtr refptr; /* current controls reference */
887 WmlClassCtrlDefPtr ctrlobj; /* resolved control reference */
888 int refndx; /* index in vector */
889 WmlClassDefPtr refcls; /* referenced class object */
890 WmlCtrlListDefPtr reflist; /* controls list object */
891 WmlClassCtrlDefPtr listelem; /* control reference in list */
896 * Acquire the superclass pointer for each widget and gadget class
898 for ( ndx=0 ; ndx<wml_obj_allclass_ptr->cnt ; ndx++ )
900 clsobj = (WmlClassDefPtr) wml_obj_allclass_ptr->hvec[ndx].objptr;
901 synobj = clsobj->syndef;
902 if ( synobj->superclass != NULL )
904 superobj = (WmlClassDefPtr)
905 wmlResolveFindObject (synobj->superclass,
908 if ( superobj == NULL ) continue;
909 clsobj->superclass = superobj;
914 * Acquire the parentclass pointer (if one exists),
915 * for each widget and gadget class
917 for ( ndx=0 ; ndx<wml_obj_allclass_ptr->cnt ; ndx++ )
919 clsobj = (WmlClassDefPtr) wml_obj_allclass_ptr->hvec[ndx].objptr;
920 synobj = clsobj->syndef;
921 if ( synobj->parentclass != NULL )
923 parentobj = (WmlClassDefPtr)
924 wmlResolveFindObject (synobj->parentclass,
927 if ( parentobj == NULL ) continue;
928 clsobj->parentclass = parentobj;
933 * Link each gadget class with its widget class (both ways).
934 * Link any class with a non-dialog version to the non-dialog class.
936 for ( ndx=0 ; ndx<wml_obj_class_ptr->cnt ; ndx++ )
938 clsobj = (WmlClassDefPtr) wml_obj_class_ptr->hvec[ndx].objptr;
939 synobj = clsobj->syndef;
940 if ( synobj->type == WmlClassTypeGadget )
942 if ( synobj->widgetclass == NULL )
944 sprintf (errmsg, "Gadget class %s has no widgetclass reference",
946 wmlIssueError (errmsg);
950 widgobj = (WmlClassDefPtr)
952 (synobj->widgetclass,
955 if ( widgobj != NULL )
957 clsobj->variant = widgobj;
958 widgobj->variant = clsobj;
962 if ( synobj->dialog == TRUE )
964 clsobj->nondialog = clsobj->superclass;
965 while ( clsobj->nondialog->syndef->dialog == TRUE )
966 clsobj->nondialog = clsobj->nondialog->superclass;
969 if ( clsobj->superclass != NULL )
971 synobj->dialog = clsobj->superclass->syndef->dialog;
972 clsobj->nondialog = clsobj->superclass->nondialog;
977 * Construct the list of resolved controls. Control lists are expanded
980 for ( ndx=0 ; ndx<wml_obj_class_ptr->cnt ; ndx++ )
982 clsobj = (WmlClassDefPtr) wml_obj_class_ptr->hvec[ndx].objptr;
983 synobj = clsobj->syndef;
984 for ( refptr=synobj->controls ; refptr!= NULL ; refptr=refptr->next )
986 refndx = wmlFindInHList (wml_obj_class_ptr, refptr->name);
989 refcls = (WmlClassDefPtr) wml_obj_class_ptr->hvec[refndx].objptr;
990 ctrlobj = (WmlClassCtrlDefPtr) malloc (sizeof(WmlClassCtrlDef));
991 ctrlobj->next = clsobj->controls;
992 clsobj->controls = ctrlobj;
993 ctrlobj->ctrl = refcls;
996 refndx = wmlFindInHList (wml_obj_ctrlist_ptr, refptr->name);
999 reflist = (WmlCtrlListDefPtr)
1000 wml_obj_ctrlist_ptr->hvec[refndx].objptr;
1001 for ( listelem=reflist->controls ;
1003 listelem=listelem->next)
1005 ctrlobj = (WmlClassCtrlDefPtr)
1006 malloc (sizeof(WmlClassCtrlDef));
1007 ctrlobj->next = clsobj->controls;
1008 clsobj->controls = ctrlobj;
1009 ctrlobj->ctrl = listelem->ctrl;
1013 wmlIssueReferenceError (synobj->name, refptr->name);
1019 * Perform resource inheritance for each class. This constructs the
1020 * arguments and reasons reference vectors.
1022 for ( ndx=0 ; ndx<wml_obj_allclass_ptr->cnt ; ndx++ )
1024 clsobj = (WmlClassDefPtr) wml_obj_allclass_ptr->hvec[ndx].objptr;
1025 wmlResolveClassInherit (clsobj);
1033 * Routine to perform resource inheritance for a class.
1035 * This routine constructs the argument and reason resource and child reference
1036 * vectors for a class. It first ensures the superclass (if any) has
1037 * been inited. It then makes a copy of the superclass lists. It repeats this
1038 * procedure for the parentclass (if any.) Finally, it
1039 * merges in the resources from the syntactic object. It uses the
1040 * resolved resource or child object to point to the matching reference object
1041 * in the list being created as an aid to search doing overrides. This also
1042 * detects whether a resource or child is already in the list (if so, it is
1043 * assumed to be inherited).
1046 void wmlResolveClassInherit (clsobj)
1047 WmlClassDefPtr clsobj;
1051 WmlClassDefPtr superobj; /* superclass object */
1052 WmlClassDefPtr parentobj; /* parentclass object */
1053 int ndx; /* loop index */
1054 WmlResourceDefPtr resobj; /* current resource object */
1055 WmlClassResDefPtr refobj; /* current resource reference */
1056 WmlClassResDefPtr srcref; /* source of copy */
1057 WmlChildDefPtr childobj; /* current child object */
1058 WmlClassChildDefPtr crefobj; /* current child reference */
1059 WmlClassChildDefPtr csrcref; /* child source of copy */
1060 WmlSynClassDefPtr synobj; /* this class' syntactic object */
1061 WmlSynClassResDefPtr refptr; /* syntactic resource reference */
1062 WmlSynClassChildDefPtr crefptr; /* syntactic child reference */
1066 * Done if inheritance previously performed. Ensure the superclass is
1069 if ( clsobj == NULL ) return;
1070 if ( clsobj->inherit_done ) return;
1071 superobj = clsobj->superclass;
1072 wmlResolveClassInherit (superobj);
1073 parentobj = clsobj->parentclass;
1074 wmlResolveClassInherit (parentobj);
1075 synobj = clsobj->syndef;
1078 * Clear the active reference pointer in the resolved resource objects.
1080 wmlResolveClearRefPointers ();
1083 * Copy the superclass resources, setting the reference pointer as we go.
1085 if ( superobj != NULL )
1087 for ( srcref=superobj->arguments ; srcref!=NULL ; srcref=srcref->next )
1089 refobj = (WmlClassResDefPtr) malloc (sizeof(WmlClassResDef));
1090 refobj->next = clsobj->arguments;
1091 clsobj->arguments = refobj;
1092 wmlResolveInitRefObj (refobj, srcref);
1094 for ( srcref=superobj->reasons ; srcref!=NULL ; srcref=srcref->next )
1096 refobj = (WmlClassResDefPtr) malloc (sizeof(WmlClassResDef));
1097 refobj->next = clsobj->reasons;
1098 clsobj->reasons = refobj;
1099 wmlResolveInitRefObj (refobj, srcref);
1101 for (csrcref = superobj->children ; csrcref!=NULL ; csrcref=csrcref->next)
1103 crefobj = (WmlClassChildDefPtr) malloc (sizeof(WmlClassChildDef));
1104 crefobj->next = clsobj->children;
1105 clsobj->children = crefobj;
1106 wmlResolveInitChildRefObj (crefobj, csrcref);
1111 * Copy the parentclass resources, setting the reference pointer as we go.
1113 if ( parentobj != NULL )
1115 for ( srcref=parentobj->arguments ; srcref!=NULL ; srcref=srcref->next )
1117 if (srcref->act_resource->ref_ptr == NULL)
1119 refobj = (WmlClassResDefPtr) malloc (sizeof(WmlClassResDef));
1120 refobj->next = clsobj->arguments;
1121 clsobj->arguments = refobj;
1122 wmlResolveInitRefObj (refobj, srcref);
1125 for ( srcref=parentobj->reasons ; srcref!=NULL ; srcref=srcref->next )
1127 if (srcref->act_resource->ref_ptr == NULL)
1129 refobj = (WmlClassResDefPtr) malloc (sizeof(WmlClassResDef));
1130 refobj->next = clsobj->reasons;
1131 clsobj->reasons = refobj;
1132 wmlResolveInitRefObj (refobj, srcref);
1135 for (csrcref = parentobj->children ; csrcref!=NULL ; csrcref=csrcref->next)
1137 if (csrcref->act_child->ref_ptr == NULL)
1139 crefobj = (WmlClassChildDefPtr) malloc (sizeof(WmlClassChildDef));
1140 crefobj->next = clsobj->children;
1141 clsobj->children = crefobj;
1142 wmlResolveInitChildRefObj (crefobj, csrcref);
1148 * Process the resources belonging to this class. They may either be
1149 * new resources, or override ones already in the list. Partition them
1150 * into arguments and reasons.
1152 for ( refptr=synobj->resources ; refptr!=NULL ; refptr=refptr->next )
1154 resobj = (WmlResourceDefPtr) wmlResolveFindObject (refptr->name,
1155 WmlResourceDefValid,
1157 if ( resobj == NULL ) continue;
1160 * Acquire the resolved resource object, and the resource reference.
1161 * New references are linked in to the proper list, and have their
1164 if ( resobj->ref_ptr != NULL )
1165 refobj = resobj->ref_ptr;
1168 refobj = (WmlClassResDefPtr) malloc (sizeof(WmlClassResDef));
1169 refobj->act_resource = resobj;
1170 resobj->ref_ptr = refobj;
1171 refobj->over_dtype = NULL;
1172 refobj->dflt = NULL;
1173 refobj->exclude = WmlAttributeUnspecified;
1174 if ( resobj->syndef->type == WmlResourceTypeReason )
1176 refobj->next = clsobj->reasons;
1177 clsobj->reasons = refobj;
1181 refobj->next = clsobj->arguments;
1182 clsobj->arguments = refobj;
1187 * Override any values in the reference which are explicit in the
1188 * syntactic reference.
1190 if ( refptr->type != NULL )
1191 refobj->over_dtype = (WmlDataTypeDefPtr)
1192 wmlResolveFindObject (refptr->type,
1193 WmlDataTypeDefValid,
1195 if ( refptr->dflt != NULL )
1196 refobj->dflt = refptr->dflt;
1197 if ( refptr->exclude != WmlAttributeUnspecified )
1198 refobj->exclude = refptr->exclude;
1202 * Process the children belonging to this class.
1204 for ( crefptr = synobj->children ; crefptr!=NULL ; crefptr = crefptr->next )
1206 childobj = (WmlChildDefPtr) wmlResolveFindObject (crefptr->name,
1209 if ( childobj == NULL ) continue;
1212 * Acquire the resolved child object, and the child reference.
1213 * New references are linked in to the proper list, and have their
1216 if ( childobj->ref_ptr != NULL )
1217 crefobj = childobj->ref_ptr;
1220 crefobj = (WmlClassChildDefPtr) malloc (sizeof(WmlClassChildDef));
1221 crefobj->act_child = childobj;
1222 childobj->ref_ptr = crefobj;
1223 crefobj->next = clsobj->children;
1224 clsobj->children = crefobj;
1229 * inheritance complete
1231 clsobj->inherit_done = TRUE;
1238 * Routine to copy a resource reference
1241 void wmlResolveInitRefObj (dstobj, srcobj)
1242 WmlClassResDefPtr dstobj;
1243 WmlClassResDefPtr srcobj;
1247 WmlResourceDefPtr resobj;
1250 resobj = srcobj->act_resource;
1251 dstobj->act_resource = resobj;
1252 resobj->ref_ptr = dstobj;
1253 dstobj->over_dtype = srcobj->over_dtype;
1254 dstobj->dflt = srcobj->dflt;
1255 dstobj->exclude = srcobj->exclude;
1261 * Routine to copy a child reference
1264 void wmlResolveInitChildRefObj (dstobj, srcobj)
1265 WmlClassChildDefPtr dstobj;
1266 WmlClassChildDefPtr srcobj;
1270 WmlChildDefPtr childobj;
1272 childobj = srcobj->act_child;
1273 dstobj->act_child = childobj;
1274 childobj->ref_ptr = dstobj;
1281 * Routine to print a report in a file.
1283 * This routine dumps the developed database into the file 'wml.report'
1286 void wmlResolvePrintReport ()
1290 FILE *outfil; /* output file */
1291 int ndx; /* loop index */
1292 WmlClassDefPtr clsobj; /* current class */
1296 * Open the output file.
1298 outfil = fopen ( "wml.report", "w");
1299 if ( outfil == NULL )
1301 printf ("\nCouldn't open wml.report");
1306 * Go through all classes. Print basic information, then dump their
1307 * resources. The main purpose of this report is to show the actual
1308 * resources and controls for the class.
1311 for ( ndx=0 ; ndx<wml_obj_allclass_ptr->cnt ; ndx++ )
1313 clsobj = (WmlClassDefPtr) wml_obj_allclass_ptr->hvec[ndx].objptr;
1314 wmlMarkReferencePointers (clsobj);
1315 wmlResolvePrintClass (outfil, clsobj);
1320 * close the output file
1322 fprintf (outfil, "\n\n");
1323 printf ("\nCreated report file wml.report");
1331 * Print the information for a class
1334 void wmlResolvePrintClass (outfil, clsobj)
1336 WmlClassDefPtr clsobj;
1340 int ndx; /* loop index */
1341 WmlSynClassDefPtr synobj; /* syntactic object */
1342 WmlClassCtrlDefPtr ctrlref; /* controls reference */
1343 WmlClassDefPtr ctrlobj; /* current class in control */
1346 synobj = clsobj->syndef;
1347 fprintf (outfil, "\n\n\nClass %s:", synobj->name);
1348 switch ( synobj->type )
1350 case WmlClassTypeMetaclass:
1351 fprintf (outfil, "\n Type: Metaclass\t");
1352 if ( synobj->superclass != NULL )
1353 fprintf (outfil, "Superclass: %s\t", synobj->superclass);
1354 if ( synobj->parentclass != NULL )
1355 fprintf (outfil, "Parentclass: %s\t", synobj->parentclass);
1357 case WmlClassTypeWidget:
1358 fprintf (outfil, "\n Type: Widget\t");
1359 if ( synobj->superclass != NULL )
1360 fprintf (outfil, "Superclass: %s\t", synobj->superclass);
1361 if ( synobj->parentclass != NULL )
1362 fprintf (outfil, "Parentclass: %s\t", synobj->parentclass);
1363 if ( clsobj->variant != NULL )
1364 fprintf (outfil, "\n Associated gadget class: %s\t",
1365 clsobj->variant->syndef->name);
1366 if ( synobj->convfunc != NULL )
1367 fprintf (outfil, "Convenience function: %s", synobj->convfunc);
1369 case WmlClassTypeGadget:
1370 fprintf (outfil, "\n Type: Gadget\t");
1371 if ( synobj->superclass != NULL )
1372 fprintf (outfil, "Superclass: %s\t", synobj->superclass);
1373 if ( synobj->parentclass != NULL )
1374 fprintf (outfil, "Parentclass: %s\t", synobj->parentclass);
1375 if ( clsobj->variant != NULL )
1376 fprintf (outfil, "\n Associated widget class: %s\t",
1377 clsobj->variant->syndef->name);
1378 if ( synobj->convfunc != NULL )
1379 fprintf (outfil, "Convenience function: %s", synobj->convfunc);
1384 * Print associated non-dialog class
1386 if ( clsobj->nondialog != NULL )
1387 fprintf (outfil, "\n DialogClass: True\tNon-dialog ancestor: %s\t",
1388 clsobj->nondialog->syndef->name);
1391 * Print the arguments valid in the class. First the new resources for the
1392 * class are printed, then each ancestor's contribution is printed. This
1393 * is intended to match the way resources are printed in the toolkit manual,
1394 * so that checking is as easy as possible.
1396 fprintf (outfil, "\n Arguments:");
1397 wmlResolvePrintClassArgs (outfil, clsobj);
1400 * Print the reasons valid in the class
1402 fprintf (outfil, "\n Reasons:");
1403 wmlResolvePrintClassReasons (outfil, clsobj);
1406 * Print the controls valid in the class
1408 fprintf (outfil, "\n Controls:");
1409 for ( ndx=0 ; ndx<wml_obj_class_ptr->cnt ; ndx++ )
1411 ctrlobj = (WmlClassDefPtr) wml_obj_class_ptr->hvec[ndx].objptr;
1412 if ( ctrlobj->ref_ptr == NULL ) continue;
1413 fprintf (outfil, "\n %s", ctrlobj->syndef->name);
1421 * Routine to print the arguments for a class
1423 * This routine prints out the currently marked arguments which are
1424 * present in this class. Each argument which is printed is remarked
1425 * so that it won't be printed again. This routine first prints the
1426 * superclass arguments, so that the printing order becomes the top-down
1427 * inheritance order.
1430 void wmlResolvePrintClassArgs (outfil, clsobj)
1432 WmlClassDefPtr clsobj;
1436 int prthdr = TRUE; /* print header line */
1437 int ndx; /* loop index */
1438 WmlSynClassDefPtr synobj; /* syntactic object */
1439 WmlClassResDefPtr resref; /* resource reference */
1440 int constr = FALSE; /* check for constraints */
1441 WmlResourceDefPtr resobj; /* current resource */
1442 WmlSynResourceDefPtr synres; /* syntactic resource object */
1446 * Print the superclass arguments
1448 if ( clsobj->superclass != NULL )
1449 wmlResolvePrintClassArgs (outfil, clsobj->superclass);
1452 * Print the parentclass arguments
1454 if ( clsobj->parentclass != NULL )
1455 wmlResolvePrintClassArgs (outfil, clsobj->parentclass);
1458 * Print the arguments for this class. Unmark the reference so it won't
1461 synobj = clsobj->syndef;
1462 for ( ndx=0 ; ndx<wml_obj_arg_ptr->cnt ; ndx++ )
1464 resobj = (WmlResourceDefPtr) wml_obj_arg_ptr->hvec[ndx].objptr;
1465 resref = resobj->ref_ptr;
1466 if ( resref == NULL ) continue;
1467 if ( wmlResolveResIsMember(resobj,clsobj->arguments) == NULL ) continue;
1468 synres = resobj->syndef;
1469 switch ( synres->type )
1471 case WmlResourceTypeArgument:
1472 case WmlResourceTypeSubResource:
1474 case WmlResourceTypeConstraint:
1483 fprintf (outfil, "\n %s argument set:", synobj->name);
1487 fprintf (outfil, "\n %s", synres->name);
1488 fprintf (outfil, "\n\tType = %s", resobj->dtype_def->syndef->name);
1489 if ( strcmp(synres->name,synres->resliteral) != 0 )
1490 fprintf (outfil, "\tResourceLiteral = %s", synres->resliteral);
1491 switch ( resref->exclude )
1493 case WmlAttributeTrue:
1494 fprintf (outfil, "\n\tExclude = True;");
1496 case WmlAttributeFalse:
1497 fprintf (outfil, "\n\tExclude = False;");
1500 if ( resref->dflt != NULL )
1501 fprintf (outfil, "\n\tDefault = \"%s\"", resref->dflt);
1503 if ( synres->dflt != NULL )
1504 fprintf (outfil, "\n\tDefault = \"%s\"", synres->dflt);
1505 resobj->ref_ptr = NULL;
1509 * Print the constraints valid in the class
1514 for ( ndx=0 ; ndx<wml_obj_arg_ptr->cnt ; ndx++ )
1516 resobj = (WmlResourceDefPtr) wml_obj_arg_ptr->hvec[ndx].objptr;
1517 resref = resobj->ref_ptr;
1518 if ( resref == NULL ) continue;
1519 if ( wmlResolveResIsMember(resobj,clsobj->arguments) == NULL ) continue;
1520 synres = resobj->syndef;
1521 switch ( synres->type )
1523 case WmlResourceTypeConstraint:
1531 fprintf (outfil, "\n %s constraint set:", synobj->name);
1534 fprintf (outfil, "\n %s", synres->name);
1535 if ( strcmp(synres->name,synres->resliteral) != 0 )
1536 fprintf (outfil, "\tResourceLiteral = %s", synres->resliteral);
1537 switch ( resref->exclude )
1539 case WmlAttributeTrue:
1540 fprintf (outfil, "\n\tExclude = True;");
1542 case WmlAttributeFalse:
1543 fprintf (outfil, "\n\tExclude = False;");
1546 if ( resref->dflt != NULL )
1547 fprintf (outfil, "\n\tDefault = \"%s\"", resref->dflt);
1549 if ( synres->dflt != NULL )
1550 fprintf (outfil, "\n\tDefault = \"%s\"", synres->dflt);
1551 resobj->ref_ptr = NULL;
1560 * Routine to print reasons in a class.
1562 * Like printing arguments, only reasons instead.
1565 void wmlResolvePrintClassReasons (outfil, clsobj)
1567 WmlClassDefPtr clsobj;
1571 int prthdr = TRUE; /* print header flag */
1572 int ndx; /* loop index */
1573 WmlSynClassDefPtr synobj; /* syntactic object */
1574 WmlClassResDefPtr resref; /* resource reference */
1575 WmlResourceDefPtr resobj; /* current resource */
1576 WmlSynResourceDefPtr synres; /* syntactic resource object */
1580 * Print the superclass reasons
1582 if ( clsobj->superclass != NULL )
1583 wmlResolvePrintClassReasons (outfil, clsobj->superclass);
1586 * Print the parentclass reasons
1588 if ( clsobj->parentclass != NULL )
1589 wmlResolvePrintClassReasons (outfil, clsobj->parentclass);
1592 * Print the reasons for this class. Unmark the reference so it won't
1595 synobj = clsobj->syndef;
1596 for ( ndx=0 ; ndx<wml_obj_reason_ptr->cnt ; ndx++ )
1598 resobj = (WmlResourceDefPtr) wml_obj_reason_ptr->hvec[ndx].objptr;
1599 resref = resobj->ref_ptr;
1600 if ( resref == NULL ) continue;
1601 if ( wmlResolveResIsMember(resobj,clsobj->reasons) == NULL ) continue;
1602 synres = resobj->syndef;
1605 fprintf (outfil, "\n %s reason set:", synobj->name);
1608 fprintf (outfil, "\n %s", synres->name);
1609 if ( strcmp(synres->name,synres->resliteral) != 0 )
1610 fprintf (outfil, "\tResourceLiteral = %s", synres->resliteral);
1611 switch ( resref->exclude )
1613 case WmlAttributeTrue:
1614 fprintf (outfil, "\n\tExclude = True;");
1616 case WmlAttributeFalse:
1617 fprintf (outfil, "\n\tExclude = False;");
1620 resobj->ref_ptr = NULL;
1627 * Routine to mark reference pointers for a class
1629 * This routine clears all reference pointers, then marks the class and
1630 * resource objects to flag those contained in the current class. This
1631 * allows processing of the widget and resource vectors in order to produce
1632 * bit masks or reports.
1635 void wmlMarkReferencePointers (clsobj)
1636 WmlClassDefPtr clsobj;
1640 int ndx; /* loop index */
1641 WmlClassDefPtr mrkcls; /* class object to mark */
1642 WmlResourceDefPtr mrkres; /* resource object to mark */
1643 WmlClassResDefPtr resref; /* resource reference */
1644 WmlClassCtrlDefPtr ctrlref; /* controls reference */
1648 * Clear the reference pointers. Then go through the arguments, reasons,
1649 * and controls lists, and mark the referenced classes.
1651 wmlResolveClearRefPointers ();
1652 for ( resref=clsobj->arguments ; resref!= NULL ; resref=resref->next )
1653 resref->act_resource->ref_ptr = resref;
1654 for ( resref=clsobj->reasons ; resref!= NULL ; resref=resref->next )
1655 resref->act_resource->ref_ptr = resref;
1656 for ( ctrlref=clsobj->controls ; ctrlref!=NULL ; ctrlref=ctrlref->next )
1657 ctrlref->ctrl->ref_ptr = ctrlref;
1664 * Routine to clear reference pointers
1667 void wmlResolveClearRefPointers ()
1671 int ndx; /* loop index */
1672 WmlClassDefPtr mrkcls; /* class object to mark */
1673 WmlResourceDefPtr mrkres; /* resource object to mark */
1674 WmlChildDefPtr mrkcld; /* child object to mark */
1676 for ( ndx=0 ; ndx<wml_obj_allclass_ptr->cnt ; ndx++ )
1678 mrkcls = (WmlClassDefPtr) wml_obj_allclass_ptr->hvec[ndx].objptr;
1679 mrkcls->ref_ptr = NULL;
1681 for ( ndx=0 ; ndx<wml_obj_reason_ptr->cnt ; ndx++ )
1683 mrkres = (WmlResourceDefPtr) wml_obj_reason_ptr->hvec[ndx].objptr;
1684 mrkres->ref_ptr = NULL;
1686 for ( ndx=0 ; ndx<wml_obj_arg_ptr->cnt ; ndx++ )
1688 mrkres = (WmlResourceDefPtr) wml_obj_arg_ptr->hvec[ndx].objptr;
1689 mrkres->ref_ptr = NULL;
1691 for ( ndx=0 ; ndx<wml_obj_child_ptr->cnt ; ndx++ )
1693 mrkcld = (WmlChildDefPtr) wml_obj_child_ptr->hvec[ndx].objptr;
1694 mrkcld->ref_ptr = NULL;
1702 * Routine to find an object for binding. The name is always looked
1703 * in the syntactic object list, since all references made by the
1704 * user are in that list (resolved objects may be entered under
1705 * an internal literal, and not be found). This routine always attempts to
1706 * return a resolved object (which depends on object type). It also guarantees
1707 * that the object it finds matches the given type.
1709 * name the object to be found
1710 * type type the object should match
1711 * requester requester name, for error messages
1713 * Returns: pointer to the object found
1716 ObjectPtr wmlResolveFindObject (name, type, requester)
1723 int objndx; /* the object index in the list */
1724 WmlSynDefPtr synobj; /* syntactic object */
1728 objndx = wmlFindInHList (wml_synobj_ptr, name);
1731 wmlIssueReferenceError (requester, name);
1734 synobj = (WmlSynDefPtr) wml_synobj_ptr ->hvec[objndx].objptr;
1735 if ( synobj->validation != type )
1738 "Object %s references object %s\n\tin a context where a different type of object is required",
1740 wmlIssueError (errmsg);
1743 switch ( synobj->validation )
1745 case WmlClassDefValid:
1746 case WmlResourceDefValid:
1747 case WmlDataTypeDefValid:
1748 case WmlCtrlListDefValid:
1749 case WmlEnumSetDefValid:
1750 case WmlEnumValueDefValid:
1751 case WmlChildDefValid:
1752 return (ObjectPtr) synobj->rslvdef;
1755 return (ObjectPtr) synobj;
1762 * Report an object reference error
1764 * srcname the object making the reference
1765 * badname the missing object
1768 void wmlIssueReferenceError (srcname, badname)
1774 printf ("\nObject %s references undefined object %s", srcname, badname);
1781 * Report an attempt to make a reference which is not supported.
1784 void wmlIssueIllegalReferenceError (srcname, badname)
1790 printf ("\nObject %s cannot reference a %s object", srcname, badname);
1797 * Report an error string.
1799 void wmlIssueError (errstg)
1804 printf ("\n%s", errstg);