1 /*******************************************************/
2 /* "C" Language Integrated Production System */
4 /* CLIPS Version 6.30 02/05/15 */
7 /*******************************************************/
9 /*************************************************************/
10 /* Purpose: Generic Functions Interface Routines */
12 /* Principal Programmer(s): */
15 /* Contributing Programmer(s): */
17 /* Revision History: */
18 /* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
20 /* Corrected compilation errors for files */
21 /* generated by constructs-to-c. DR0861 */
23 /* Changed name of variable log to logName */
24 /* because of Unix compiler warnings of shadowed */
27 /* 6.24: Removed IMPERATIVE_METHODS compilation flag. */
29 /* Renamed BOOLEAN macro type to intBool. */
31 /* Corrected code to remove run-time program */
32 /* compiler warning. */
34 /* 6.30: Removed conditional code for unsupported */
35 /* compilers/operating systems (IBM_MCW, */
36 /* MAC_MCW, and IBM_TBC). */
38 /* Changed integer type/precision. */
40 /* Added const qualifiers to remove C++ */
41 /* deprecation warnings. */
43 /* Converted API macros to function calls. */
45 /* Fixed linkage issue when DEBUGGING_FUNCTIONS */
46 /* is set to 0 and PROFILING_FUNCTIONS is set to */
49 /* Changed find construct functionality so that */
50 /* imported modules are search when locating a */
51 /* named construct. */
53 /* Added code to keep track of pointers to */
54 /* constructs that are contained externally to */
55 /* to constructs, DanglingConstructs. */
57 /*************************************************************/
59 /* =========================================
60 *****************************************
62 =========================================
63 ***************************************** */
66 #if DEFGENERIC_CONSTRUCT
74 #if BLOAD || BLOAD_AND_BSAVE
78 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
82 #if CONSTRUCT_COMPILER
86 #if (! BLOAD_ONLY) && (! RUN_TIME)
96 #if DEBUGGING_FUNCTIONS
100 #include "argacces.h"
101 #include "cstrcpsr.h"
102 #include "envrnmnt.h"
103 #include "extnfunc.h"
104 #include "genrcexe.h"
105 #include "memalloc.h"
106 #include "modulpsr.h"
107 #include "multifld.h"
110 #define _GENRCCOM_SOURCE_
111 #include "genrccom.h"
113 /* =========================================
114 *****************************************
115 INTERNALLY VISIBLE FUNCTION HEADERS
116 =========================================
117 ***************************************** */
119 static void PrintGenericCall(void *,const char *,void *);
120 static intBool EvaluateGenericCall(void *,void *,DATA_OBJECT *);
121 static void DecrementGenericBusyCount(void *,void *);
122 static void IncrementGenericBusyCount(void *,void *);
123 static void DeallocateDefgenericData(void *);
125 static void DestroyDefgenericAction(void *,struct constructHeader *,void *);
128 #if (! BLOAD_ONLY) && (! RUN_TIME)
130 static void SaveDefgenerics(void *,void *,const char *);
131 static void SaveDefmethods(void *,void *,const char *);
132 static void SaveDefmethodsForDefgeneric(void *,struct constructHeader *,void *);
133 static void RemoveDefgenericMethod(void *,DEFGENERIC *,long);
137 #if DEBUGGING_FUNCTIONS
138 static long ListMethodsForGeneric(void *,const char *,DEFGENERIC *);
139 static unsigned DefgenericWatchAccess(void *,int,unsigned,EXPRESSION *);
140 static unsigned DefgenericWatchPrint(void *,const char *,int,EXPRESSION *);
141 static unsigned DefmethodWatchAccess(void *,int,unsigned,EXPRESSION *);
142 static unsigned DefmethodWatchPrint(void *,const char *,int,EXPRESSION *);
143 static unsigned DefmethodWatchSupport(void *,const char *,const char *,unsigned,
144 void (*)(void *,const char *,void *,long),
145 void (*)(void *,unsigned,void *,long),
147 static void PrintMethodWatchFlag(void *,const char *,void *,long);
150 /* =========================================
151 *****************************************
152 EXTERNALLY VISIBLE FUNCTIONS
153 =========================================
154 ***************************************** */
156 /***********************************************************
157 NAME : SetupGenericFunctions
158 DESCRIPTION : Initializes all generic function
159 data structures, constructs and functions
161 RETURNS : Nothing useful
162 SIDE EFFECTS : Generic function H/L functions set up
164 ***********************************************************/
165 globle void SetupGenericFunctions(
168 ENTITY_RECORD genericEntityRecord =
169 { "GCALL", GCALL,0,0,1,
170 PrintGenericCall,PrintGenericCall,
171 NULL,EvaluateGenericCall,NULL,
172 DecrementGenericBusyCount,IncrementGenericBusyCount,
173 NULL,NULL,NULL,NULL,NULL };
175 AllocateEnvironmentData(theEnv,DEFGENERIC_DATA,sizeof(struct defgenericData),DeallocateDefgenericData);
176 memcpy(&DefgenericData(theEnv)->GenericEntityRecord,&genericEntityRecord,sizeof(struct entityRecord));
178 InstallPrimitive(theEnv,&DefgenericData(theEnv)->GenericEntityRecord,GCALL);
180 DefgenericData(theEnv)->DefgenericModuleIndex =
181 RegisterModuleItem(theEnv,"defgeneric",
183 AllocateDefgenericModule,FreeDefgenericModule,
187 #if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
188 BloadDefgenericModuleReference,
192 #if CONSTRUCT_COMPILER && (! RUN_TIME)
193 DefgenericCModuleReference,
197 EnvFindDefgenericInModule);
199 DefgenericData(theEnv)->DefgenericConstruct = AddConstruct(theEnv,"defgeneric","defgenerics",
200 #if (! BLOAD_ONLY) && (! RUN_TIME)
206 GetConstructNamePointer,GetConstructPPForm,
207 GetConstructModuleItem,EnvGetNextDefgeneric,
208 SetNextConstruct,EnvIsDefgenericDeletable,
210 #if (! BLOAD_ONLY) && (! RUN_TIME)
218 AddClearReadyFunction(theEnv,"defgeneric",ClearDefgenericsReady,0);
220 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
221 SetupGenericsBload(theEnv);
224 #if CONSTRUCT_COMPILER
225 SetupGenericsCompiler(theEnv);
229 #if DEFMODULE_CONSTRUCT
230 AddPortConstructItem(theEnv,"defgeneric",SYMBOL);
232 AddConstruct(theEnv,"defmethod","defmethods",ParseDefmethod,
233 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
235 /* ================================================================
236 Make sure defmethods are cleared last, for other constructs may
237 be using them and need to be cleared first
239 Need to be cleared in two stages so that mutually dependent
240 constructs (like classes) can be cleared
241 ================================================================ */
242 AddSaveFunction(theEnv,"defgeneric",SaveDefgenerics,1000);
243 AddSaveFunction(theEnv,"defmethod",SaveDefmethods,-1000);
244 EnvDefineFunction2(theEnv,"undefgeneric",'v',PTIEF UndefgenericCommand,"UndefgenericCommand","11w");
245 EnvDefineFunction2(theEnv,"undefmethod",'v',PTIEF UndefmethodCommand,"UndefmethodCommand","22*wg");
248 EnvDefineFunction2(theEnv,"call-next-method",'u',PTIEF CallNextMethod,"CallNextMethod","00");
249 FuncSeqOvlFlags(theEnv,"call-next-method",TRUE,FALSE);
250 EnvDefineFunction2(theEnv,"call-specific-method",'u',PTIEF CallSpecificMethod,
251 "CallSpecificMethod","2**wi");
252 FuncSeqOvlFlags(theEnv,"call-specific-method",TRUE,FALSE);
253 EnvDefineFunction2(theEnv,"override-next-method",'u',PTIEF OverrideNextMethod,
254 "OverrideNextMethod",NULL);
255 FuncSeqOvlFlags(theEnv,"override-next-method",TRUE,FALSE);
256 EnvDefineFunction2(theEnv,"next-methodp",'b',PTIEF NextMethodP,"NextMethodP","00");
257 FuncSeqOvlFlags(theEnv,"next-methodp",TRUE,FALSE);
259 EnvDefineFunction2(theEnv,"(gnrc-current-arg)",'u',PTIEF GetGenericCurrentArgument,
260 "GetGenericCurrentArgument",NULL);
262 #if DEBUGGING_FUNCTIONS
263 EnvDefineFunction2(theEnv,"ppdefgeneric",'v',PTIEF PPDefgenericCommand,"PPDefgenericCommand","11w");
264 EnvDefineFunction2(theEnv,"list-defgenerics",'v',PTIEF ListDefgenericsCommand,"ListDefgenericsCommand","01");
265 EnvDefineFunction2(theEnv,"ppdefmethod",'v',PTIEF PPDefmethodCommand,"PPDefmethodCommand","22*wi");
266 EnvDefineFunction2(theEnv,"list-defmethods",'v',PTIEF ListDefmethodsCommand,"ListDefmethodsCommand","01w");
267 EnvDefineFunction2(theEnv,"preview-generic",'v',PTIEF PreviewGeneric,"PreviewGeneric","1**w");
270 EnvDefineFunction2(theEnv,"get-defgeneric-list",'m',PTIEF GetDefgenericListFunction,
271 "GetDefgenericListFunction","01");
272 EnvDefineFunction2(theEnv,"get-defmethod-list",'m',PTIEF GetDefmethodListCommand,
273 "GetDefmethodListCommand","01w");
274 EnvDefineFunction2(theEnv,"get-method-restrictions",'m',PTIEF GetMethodRestrictionsCommand,
275 "GetMethodRestrictionsCommand","22iw");
276 EnvDefineFunction2(theEnv,"defgeneric-module",'w',PTIEF GetDefgenericModuleCommand,
277 "GetDefgenericModuleCommand","11w");
280 EnvDefineFunction2(theEnv,"type",'u',PTIEF ClassCommand,"ClassCommand","11u");
282 EnvDefineFunction2(theEnv,"type",'u',PTIEF TypeCommand,"TypeCommand","11u");
287 #if DEBUGGING_FUNCTIONS
288 AddWatchItem(theEnv,"generic-functions",0,&DefgenericData(theEnv)->WatchGenerics,34,
289 DefgenericWatchAccess,DefgenericWatchPrint);
290 AddWatchItem(theEnv,"methods",0,&DefgenericData(theEnv)->WatchMethods,33,
291 DefmethodWatchAccess,DefmethodWatchPrint);
295 /*****************************************************/
296 /* DeallocateDefgenericData: Deallocates environment */
297 /* data for the defgeneric construct. */
298 /*****************************************************/
299 static void DeallocateDefgenericData(
303 struct defgenericModule *theModuleItem;
306 #if BLOAD || BLOAD_AND_BSAVE
307 if (Bloaded(theEnv)) return;
310 DoForAllConstructs(theEnv,DestroyDefgenericAction,DefgenericData(theEnv)->DefgenericModuleIndex,FALSE,NULL);
312 for (theModule = EnvGetNextDefmodule(theEnv,NULL);
314 theModule = EnvGetNextDefmodule(theEnv,theModule))
316 theModuleItem = (struct defgenericModule *)
317 GetModuleItem(theEnv,(struct defmodule *) theModule,
318 DefgenericData(theEnv)->DefgenericModuleIndex);
320 rtn_struct(theEnv,defgenericModule,theModuleItem);
324 #pragma unused(theEnv)
330 /****************************************************/
331 /* DestroyDefgenericAction: Action used to remove */
332 /* defgenerics as a result of DestroyEnvironment. */
333 /****************************************************/
334 static void DestroyDefgenericAction(
336 struct constructHeader *theConstruct,
340 #pragma unused(buffer)
342 #if (! BLOAD_ONLY) && (! RUN_TIME)
343 struct defgeneric *theDefgeneric = (struct defgeneric *) theConstruct;
346 if (theDefgeneric == NULL) return;
348 for (i = 0 ; i < theDefgeneric->mcnt ; i++)
349 { DestroyMethodInfo(theEnv,theDefgeneric,&theDefgeneric->methods[i]); }
351 if (theDefgeneric->mcnt != 0)
352 rm(theEnv,(void *) theDefgeneric->methods,(sizeof(DEFMETHOD) * theDefgeneric->mcnt));
354 DestroyConstructHeader(theEnv,&theDefgeneric->header);
356 rtn_struct(theEnv,defgeneric,theDefgeneric);
359 #pragma unused(theEnv,theConstruct)
365 /***************************************************
366 NAME : EnvFindDefgeneric
367 DESCRIPTION : Searches for a generic
368 INPUTS : The name of the generic
369 (possibly including a module name)
370 RETURNS : Pointer to the generic if
371 found, otherwise NULL
374 ***************************************************/
375 globle void *EnvFindDefgeneric(
377 const char *genericModuleAndName)
379 return(FindNamedConstructInModuleOrImports(theEnv,genericModuleAndName,DefgenericData(theEnv)->DefgenericConstruct));
382 /***************************************************
383 NAME : EnvFindDefgenericInModule
384 DESCRIPTION : Searches for a generic
385 INPUTS : The name of the generic
386 (possibly including a module name)
387 RETURNS : Pointer to the generic if
388 found, otherwise NULL
391 ***************************************************/
392 globle void *EnvFindDefgenericInModule(
394 const char *genericModuleAndName)
396 return(FindNamedConstructInModule(theEnv,genericModuleAndName,DefgenericData(theEnv)->DefgenericConstruct));
399 /***************************************************
400 NAME : LookupDefgenericByMdlOrScope
401 DESCRIPTION : Finds a defgeneric anywhere (if
402 module is specified) or in current
404 INPUTS : The defgeneric name
405 RETURNS : The defgeneric (NULL if not found)
406 SIDE EFFECTS : Error message printed on
409 ***************************************************/
410 globle DEFGENERIC *LookupDefgenericByMdlOrScope(
412 const char *defgenericName)
414 return((DEFGENERIC *) LookupConstruct(theEnv,DefgenericData(theEnv)->DefgenericConstruct,defgenericName,TRUE));
417 /***************************************************
418 NAME : LookupDefgenericInScope
419 DESCRIPTION : Finds a defgeneric in current or
420 imported modules (module
421 specifier is not allowed)
422 INPUTS : The defgeneric name
423 RETURNS : The defgeneric (NULL if not found)
424 SIDE EFFECTS : Error message printed on
427 ***************************************************/
428 globle DEFGENERIC *LookupDefgenericInScope(
430 const char *defgenericName)
432 return((DEFGENERIC *) LookupConstruct(theEnv,DefgenericData(theEnv)->DefgenericConstruct,defgenericName,FALSE));
435 /***********************************************************
436 NAME : EnvGetNextDefgeneric
437 DESCRIPTION : Finds first or next generic function
438 INPUTS : The address of the current generic function
439 RETURNS : The address of the next generic function
442 NOTES : If ptr == NULL, the first generic function
444 ***********************************************************/
445 globle void *EnvGetNextDefgeneric(
449 return((void *) GetNextConstructItem(theEnv,(struct constructHeader *) ptr,DefgenericData(theEnv)->DefgenericModuleIndex));
452 /***********************************************************
453 NAME : EnvGetNextDefmethod
454 DESCRIPTION : Find the next method for a generic function
455 INPUTS : 1) The generic function address
456 2) The index of the current method
457 RETURNS : The index of the next method
460 NOTES : If index == 0, the index of the first
462 ***********************************************************/
463 globle long EnvGetNextDefmethod(
471 #pragma unused(theEnv)
474 gfunc = (DEFGENERIC *) ptr;
477 if (gfunc->methods != NULL)
478 return(gfunc->methods[0].index);
481 mi = FindMethodByIndex(gfunc,theIndex);
482 if ((mi+1) == gfunc->mcnt)
484 return(gfunc->methods[mi+1].index);
487 /*****************************************************
488 NAME : GetDefmethodPointer
489 DESCRIPTION : Returns a pointer to a method
490 INPUTS : 1) Pointer to a defgeneric
491 2) Array index of method in generic's
493 RETURNS : Pointer to the method.
496 *****************************************************/
497 globle DEFMETHOD *GetDefmethodPointer(
501 return(&((DEFGENERIC *) ptr)->methods[theIndex-1]);
504 /***************************************************
505 NAME : EnvIsDefgenericDeletable
506 DESCRIPTION : Determines if a generic function
508 INPUTS : Address of the generic function
509 RETURNS : TRUE if deletable, FALSE otherwise
512 ***************************************************/
513 globle int EnvIsDefgenericDeletable(
517 if (! ConstructsDeletable(theEnv))
520 return ((((DEFGENERIC *) ptr)->busy == 0) ? TRUE : FALSE);
523 /***************************************************
524 NAME : EnvIsDefmethodDeletable
525 DESCRIPTION : Determines if a generic function
526 method can be deleted
527 INPUTS : 1) Address of the generic function
528 2) Index of the method
529 RETURNS : TRUE if deletable, FALSE otherwise
532 ***************************************************/
533 globle int EnvIsDefmethodDeletable(
538 if (! ConstructsDeletable(theEnv))
541 if (((DEFGENERIC *) ptr)->methods[FindMethodByIndex((DEFGENERIC *) ptr,theIndex)].system)
544 #if (! BLOAD_ONLY) && (! RUN_TIME)
545 return((MethodsExecuting((DEFGENERIC *) ptr) == FALSE) ? TRUE : FALSE);
551 /**********************************************************
552 NAME : UndefgenericCommand
553 DESCRIPTION : Deletes all methods for a generic function
555 RETURNS : Nothing useful
556 SIDE EFFECTS : methods deallocated
557 NOTES : H/L Syntax: (undefgeneric <name> | *)
558 **********************************************************/
559 globle void UndefgenericCommand(
562 UndefconstructCommand(theEnv,"undefgeneric",DefgenericData(theEnv)->DefgenericConstruct);
565 /****************************************************************
566 NAME : GetDefgenericModuleCommand
567 DESCRIPTION : Determines to which module a defgeneric belongs
569 RETURNS : The symbolic name of the module
571 NOTES : H/L Syntax: (defgeneric-module <generic-name>)
572 ****************************************************************/
573 globle void *GetDefgenericModuleCommand(
576 return(GetConstructModuleCommand(theEnv,"defgeneric-module",DefgenericData(theEnv)->DefgenericConstruct));
579 /**************************************************************
580 NAME : UndefmethodCommand
581 DESCRIPTION : Deletes one method for a generic function
583 RETURNS : Nothing useful
584 SIDE EFFECTS : methods deallocated
585 NOTES : H/L Syntax: (undefmethod <name> <index> | *)
586 **************************************************************/
587 globle void UndefmethodCommand(
594 if (EnvArgTypeCheck(theEnv,"undefmethod",1,SYMBOL,&temp) == FALSE)
596 gfunc = LookupDefgenericByMdlOrScope(theEnv,DOToString(temp));
597 if ((gfunc == NULL) ? (strcmp(DOToString(temp),"*") != 0) : FALSE)
599 PrintErrorID(theEnv,"GENRCCOM",1,FALSE);
600 EnvPrintRouter(theEnv,WERROR,"No such generic function ");
601 EnvPrintRouter(theEnv,WERROR,DOToString(temp));
602 EnvPrintRouter(theEnv,WERROR," in function undefmethod.\n");
605 EnvRtnUnknown(theEnv,2,&temp);
606 if (temp.type == SYMBOL)
608 if (strcmp(DOToString(temp),"*") != 0)
610 PrintErrorID(theEnv,"GENRCCOM",2,FALSE);
611 EnvPrintRouter(theEnv,WERROR,"Expected a valid method index in function undefmethod.\n");
616 else if (temp.type == INTEGER)
618 mi = (long) DOToLong(temp);
621 PrintErrorID(theEnv,"GENRCCOM",2,FALSE);
622 EnvPrintRouter(theEnv,WERROR,"Expected a valid method index in function undefmethod.\n");
628 PrintErrorID(theEnv,"GENRCCOM",2,FALSE);
629 EnvPrintRouter(theEnv,WERROR,"Expected a valid method index in function undefmethod.\n");
632 EnvUndefmethod(theEnv,(void *) gfunc,mi);
635 /**************************************************************
636 NAME : EnvUndefgeneric
637 DESCRIPTION : Deletes all methods for a generic function
638 INPUTS : The generic-function address (NULL for all)
639 RETURNS : TRUE if generic successfully deleted,
641 SIDE EFFECTS : methods deallocated
643 **************************************************************/
644 globle intBool EnvUndefgeneric(
648 #if RUN_TIME || BLOAD_ONLY
654 gfunc = (DEFGENERIC *) vptr;
657 if (ClearDefmethods(theEnv) == FALSE)
659 if (ClearDefgenerics(theEnv) == FALSE)
663 if (EnvIsDefgenericDeletable(theEnv,vptr) == FALSE)
665 RemoveConstructFromModule(theEnv,(struct constructHeader *) vptr);
666 RemoveDefgeneric(theEnv,gfunc);
671 /**************************************************************
672 NAME : EnvUndefmethod
673 DESCRIPTION : Deletes one method for a generic function
674 INPUTS : 1) Address of generic function (can be NULL)
675 2) Method index (0 for all)
676 RETURNS : TRUE if method deleted successfully,
678 SIDE EFFECTS : methods deallocated
680 **************************************************************/
681 globle intBool EnvUndefmethod(
688 #if RUN_TIME || BLOAD_ONLY
689 gfunc = (DEFGENERIC *) vptr;
690 PrintErrorID(theEnv,"PRNTUTIL",4,FALSE);
691 EnvPrintRouter(theEnv,WERROR,"Unable to delete method ");
694 PrintGenericName(theEnv,WERROR,gfunc);
695 EnvPrintRouter(theEnv,WERROR," #");
696 PrintLongInteger(theEnv,WERROR,(long long) mi);
699 EnvPrintRouter(theEnv,WERROR,"*");
700 EnvPrintRouter(theEnv,WERROR,".\n");
705 gfunc = (DEFGENERIC *) vptr;
706 #if BLOAD || BLOAD_AND_BSAVE
707 if (Bloaded(theEnv) == TRUE)
709 PrintErrorID(theEnv,"PRNTUTIL",4,FALSE);
710 EnvPrintRouter(theEnv,WERROR,"Unable to delete method ");
713 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
714 EnvPrintRouter(theEnv,WERROR," #");
715 PrintLongInteger(theEnv,WERROR,(long long) mi);
718 EnvPrintRouter(theEnv,WERROR,"*");
719 EnvPrintRouter(theEnv,WERROR,".\n");
727 PrintErrorID(theEnv,"GENRCCOM",3,FALSE);
728 EnvPrintRouter(theEnv,WERROR,"Incomplete method specification for deletion.\n");
731 return(ClearDefmethods(theEnv));
733 if (MethodsExecuting(gfunc))
735 MethodAlterError(theEnv,gfunc);
739 RemoveAllExplicitMethods(theEnv,gfunc);
742 nmi = CheckMethodExists(theEnv,"undefmethod",gfunc,mi);
745 RemoveDefgenericMethod(theEnv,gfunc,nmi);
751 #if DEBUGGING_FUNCTIONS || PROFILING_FUNCTIONS
753 /*****************************************************
754 NAME : EnvGetDefmethodDescription
755 DESCRIPTION : Prints a synopsis of method parameter
756 restrictions into caller's buffer
757 INPUTS : 1) Caller's buffer
758 2) Buffer size (not including space
759 for terminating '\0')
760 3) Address of generic function
762 RETURNS : Nothing useful
763 SIDE EFFECTS : Caller's buffer written
764 NOTES : Terminating '\n' not written
765 *****************************************************/
766 globle void EnvGetDefmethodDescription(
776 #pragma unused(theEnv)
779 gfunc = (DEFGENERIC *) ptr;
780 mi = FindMethodByIndex(gfunc,theIndex);
781 PrintMethod(theEnv,buf,buflen,&gfunc->methods[mi]);
783 #endif /* DEBUGGING_FUNCTIONS || PROFILING_FUNCTIONS */
785 #if DEBUGGING_FUNCTIONS
787 /*********************************************************
788 NAME : EnvGetDefgenericWatch
789 DESCRIPTION : Determines if trace messages are
790 gnerated when executing generic function
791 INPUTS : A pointer to the generic
792 RETURNS : TRUE if a trace is active,
796 *********************************************************/
797 globle unsigned EnvGetDefgenericWatch(
802 #pragma unused(theEnv)
805 return(((DEFGENERIC *) theGeneric)->trace);
808 /*********************************************************
809 NAME : EnvSetDefgenericWatch
810 DESCRIPTION : Sets the trace to ON/OFF for the
812 INPUTS : 1) TRUE to set the trace on,
814 2) A pointer to the generic
815 RETURNS : Nothing useful
816 SIDE EFFECTS : Watch flag for the generic set
818 *********************************************************/
819 globle void EnvSetDefgenericWatch(
825 #pragma unused(theEnv)
828 ((DEFGENERIC *) theGeneric)->trace = newState;
831 /*********************************************************
832 NAME : EnvGetDefmethodWatch
833 DESCRIPTION : Determines if trace messages for calls
834 to this method will be generated or not
835 INPUTS : 1) A pointer to the generic
836 2) The index of the method
837 RETURNS : TRUE if a trace is active,
841 *********************************************************/
842 globle unsigned EnvGetDefmethodWatch(
850 #pragma unused(theEnv)
853 gfunc = (DEFGENERIC *) theGeneric;
854 mi = FindMethodByIndex(gfunc,theIndex);
855 return(gfunc->methods[mi].trace);
858 /*********************************************************
859 NAME : EnvSetDefmethodWatch
860 DESCRIPTION : Sets the trace to ON/OFF for the
861 calling of the method
862 INPUTS : 1) TRUE to set the trace on,
864 2) A pointer to the generic
865 3) The index of the method
866 RETURNS : Nothing useful
867 SIDE EFFECTS : Watch flag for the method set
869 *********************************************************/
870 globle void EnvSetDefmethodWatch(
879 #pragma unused(theEnv)
882 gfunc = (DEFGENERIC *) theGeneric;
883 mi = FindMethodByIndex(gfunc,theIndex);
884 gfunc->methods[mi].trace = newState;
888 /********************************************************
889 NAME : PPDefgenericCommand
890 DESCRIPTION : Displays the pretty-print form of
891 a generic function header
893 RETURNS : Nothing useful
895 NOTES : H/L Syntax: (ppdefgeneric <name>)
896 ********************************************************/
897 globle void PPDefgenericCommand(
900 PPConstructCommand(theEnv,"ppdefgeneric",DefgenericData(theEnv)->DefgenericConstruct);
903 /**********************************************************
904 NAME : PPDefmethodCommand
905 DESCRIPTION : Displays the pretty-print form of
908 RETURNS : Nothing useful
910 NOTES : H/L Syntax: (ppdefmethod <name> <index>)
911 **********************************************************/
912 globle void PPDefmethodCommand(
920 if (EnvArgTypeCheck(theEnv,"ppdefmethod",1,SYMBOL,&temp) == FALSE)
922 gname = DOToString(temp);
923 if (EnvArgTypeCheck(theEnv,"ppdefmethod",2,INTEGER,&temp) == FALSE)
925 gfunc = CheckGenericExists(theEnv,"ppdefmethod",gname);
928 gi = CheckMethodExists(theEnv,"ppdefmethod",gfunc,(long) DOToLong(temp));
931 if (gfunc->methods[gi].ppForm != NULL)
932 PrintInChunks(theEnv,WDISPLAY,gfunc->methods[gi].ppForm);
935 /******************************************************
936 NAME : ListDefmethodsCommand
937 DESCRIPTION : Lists a brief description of methods
938 for a particular generic function
940 RETURNS : Nothing useful
942 NOTES : H/L Syntax: (list-defmethods <name>)
943 ******************************************************/
944 globle void ListDefmethodsCommand(
950 if (EnvRtnArgCount(theEnv) == 0)
951 EnvListDefmethods(theEnv,WDISPLAY,NULL);
954 if (EnvArgTypeCheck(theEnv,"list-defmethods",1,SYMBOL,&temp) == FALSE)
956 gfunc = CheckGenericExists(theEnv,"list-defmethods",DOToString(temp));
958 EnvListDefmethods(theEnv,WDISPLAY,(void *) gfunc);
962 /***************************************************************
963 NAME : EnvGetDefmethodPPForm
964 DESCRIPTION : Getsa generic function method pretty print form
965 INPUTS : 1) Address of the generic function
966 2) Index of the method
967 RETURNS : Method ppform
970 ***************************************************************/
971 globle const char *EnvGetDefmethodPPForm(
979 #pragma unused(theEnv)
982 gfunc = (DEFGENERIC *) ptr;
983 mi = FindMethodByIndex(gfunc,theIndex);
984 return(gfunc->methods[mi].ppForm);
987 /***************************************************
988 NAME : ListDefgenericsCommand
989 DESCRIPTION : Displays all defgeneric names
991 RETURNS : Nothing useful
992 SIDE EFFECTS : Defgeneric names printed
993 NOTES : H/L Interface
994 ***************************************************/
995 globle void ListDefgenericsCommand(
998 ListConstructCommand(theEnv,"list-defgenerics",DefgenericData(theEnv)->DefgenericConstruct);
1001 /***************************************************
1002 NAME : EnvListDefgenerics
1003 DESCRIPTION : Displays all defgeneric names
1004 INPUTS : 1) The logical name of the output
1006 RETURNS : Nothing useful
1007 SIDE EFFECTS : Defgeneric names printed
1009 ***************************************************/
1010 globle void EnvListDefgenerics(
1012 const char *logicalName,
1013 struct defmodule *theModule)
1015 ListConstruct(theEnv,DefgenericData(theEnv)->DefgenericConstruct,logicalName,theModule);
1018 /******************************************************
1019 NAME : EnvListDefmethods
1020 DESCRIPTION : Lists a brief description of methods
1021 for a particular generic function
1022 INPUTS : 1) The logical name of the output
1023 2) Generic function to list methods for
1024 (NULL means list all methods)
1025 RETURNS : Nothing useful
1028 ******************************************************/
1029 globle void EnvListDefmethods(
1031 const char *logicalName,
1037 count = ListMethodsForGeneric(theEnv,logicalName,(DEFGENERIC *) vptr);
1041 for (gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL) ;
1043 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc))
1045 count += ListMethodsForGeneric(theEnv,logicalName,gfunc);
1046 if (EnvGetNextDefgeneric(theEnv,(void *) gfunc) != NULL)
1047 EnvPrintRouter(theEnv,logicalName,"\n");
1050 PrintTally(theEnv,logicalName,count,"method","methods");
1053 #endif /* DEBUGGING_FUNCTIONS */
1055 /***************************************************************
1056 NAME : GetDefgenericListFunction
1057 DESCRIPTION : Groups all defgeneric names into
1059 INPUTS : A data object buffer to hold
1060 the multifield result
1061 RETURNS : Nothing useful
1062 SIDE EFFECTS : Multifield allocated and filled
1063 NOTES : H/L Syntax: (get-defgeneric-list [<module>])
1064 ***************************************************************/
1065 globle void GetDefgenericListFunction(
1067 DATA_OBJECT*returnValue)
1069 GetConstructListFunction(theEnv,"get-defgeneric-list",returnValue,DefgenericData(theEnv)->DefgenericConstruct);
1072 /***************************************************************
1073 NAME : EnvGetDefgenericList
1074 DESCRIPTION : Groups all defgeneric names into
1076 INPUTS : 1) A data object buffer to hold
1077 the multifield result
1078 2) The module from which to obtain defgenerics
1079 RETURNS : Nothing useful
1080 SIDE EFFECTS : Multifield allocated and filled
1081 NOTES : External C access
1082 ***************************************************************/
1083 globle void EnvGetDefgenericList(
1085 DATA_OBJECT *returnValue,
1086 struct defmodule *theModule)
1088 GetConstructList(theEnv,returnValue,DefgenericData(theEnv)->DefgenericConstruct,theModule);
1091 /***********************************************************
1092 NAME : GetDefmethodListCommand
1093 DESCRIPTION : Groups indices of all methdos for a generic
1094 function into a multifield variable
1095 (NULL means get methods for all generics)
1096 INPUTS : A data object buffer
1097 RETURNS : Nothing useful
1098 SIDE EFFECTS : Multifield set to list of method indices
1100 ***********************************************************/
1101 globle void GetDefmethodListCommand(
1103 DATA_OBJECT_PTR returnValue)
1108 if (EnvRtnArgCount(theEnv) == 0)
1109 EnvGetDefmethodList(theEnv,NULL,returnValue);
1112 if (EnvArgTypeCheck(theEnv,"get-defmethod-list",1,SYMBOL,&temp) == FALSE)
1114 EnvSetMultifieldErrorValue(theEnv,returnValue);
1117 gfunc = CheckGenericExists(theEnv,"get-defmethod-list",DOToString(temp));
1119 EnvGetDefmethodList(theEnv,(void *) gfunc,returnValue);
1121 EnvSetMultifieldErrorValue(theEnv,returnValue);
1125 /***********************************************************
1126 NAME : EnvGetDefmethodList
1127 DESCRIPTION : Groups indices of all methdos for a generic
1128 function into a multifield variable
1129 (NULL means get methods for all generics)
1130 INPUTS : 1) A pointer to a generic function
1131 2) A data object buffer
1132 RETURNS : Nothing useful
1133 SIDE EFFECTS : Multifield set to list of method indices
1135 ***********************************************************/
1136 globle void EnvGetDefmethodList(
1139 DATA_OBJECT_PTR returnValue)
1141 DEFGENERIC *gfunc,*svg,*svnxt;
1143 unsigned long count;
1144 MULTIFIELD_PTR theList;
1148 gfunc = (DEFGENERIC *) vgfunc;
1149 svnxt = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,vgfunc);
1150 SetNextDefgeneric(vgfunc,NULL);
1154 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL);
1155 svnxt = (gfunc != NULL) ? (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc) : NULL;
1160 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc))
1161 count += (unsigned long) gfunc->mcnt;
1163 SetpType(returnValue,MULTIFIELD);
1164 SetpDOBegin(returnValue,1);
1165 SetpDOEnd(returnValue,count);
1166 theList = (MULTIFIELD_PTR) EnvCreateMultifield(theEnv,count);
1167 SetpValue(returnValue,theList);
1168 for (gfunc = svg , i = 1 ;
1170 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc))
1172 for (j = 0 ; j < gfunc->mcnt ; j++)
1174 SetMFType(theList,i,SYMBOL);
1175 SetMFValue(theList,i++,GetDefgenericNamePointer((void *) gfunc));
1176 SetMFType(theList,i,INTEGER);
1177 SetMFValue(theList,i++,EnvAddLong(theEnv,(long long) gfunc->methods[j].index));
1181 SetNextDefgeneric((void *) svg,(void *) svnxt);
1184 /***********************************************************************************
1185 NAME : GetMethodRestrictionsCommand
1186 DESCRIPTION : Stores restrictions of a method in multifield
1187 INPUTS : A data object buffer to hold a multifield
1188 RETURNS : Nothing useful
1189 SIDE EFFECTS : Multifield created (length zero on errors)
1190 NOTES : Syntax: (get-method-restrictions <generic-function> <method-index>)
1191 ***********************************************************************************/
1192 globle void GetMethodRestrictionsCommand(
1194 DATA_OBJECT *result)
1199 if (EnvArgTypeCheck(theEnv,"get-method-restrictions",1,SYMBOL,&temp) == FALSE)
1201 EnvSetMultifieldErrorValue(theEnv,result);
1204 gfunc = CheckGenericExists(theEnv,"get-method-restrictions",DOToString(temp));
1207 EnvSetMultifieldErrorValue(theEnv,result);
1210 if (EnvArgTypeCheck(theEnv,"get-method-restrictions",2,INTEGER,&temp) == FALSE)
1212 EnvSetMultifieldErrorValue(theEnv,result);
1215 if (CheckMethodExists(theEnv,"get-method-restrictions",gfunc,(long) DOToLong(temp)) == -1)
1217 EnvSetMultifieldErrorValue(theEnv,result);
1220 EnvGetMethodRestrictions(theEnv,(void *) gfunc,(unsigned) DOToLong(temp),result);
1223 /***********************************************************************
1224 NAME : EnvGetMethodRestrictions
1225 DESCRIPTION : Stores restrictions of a method in multifield
1226 INPUTS : 1) Pointer to the generic function
1228 3) A data object buffer to hold a multifield
1229 RETURNS : Nothing useful
1230 SIDE EFFECTS : Multifield created (length zero on errors)
1231 NOTES : The restrictions are stored in the multifield
1232 in the following format:
1234 <min-number-of-arguments>
1235 <max-number-of-arguments> (-1 if wildcard allowed)
1237 <index of 1st restriction>
1240 <index of nth restriction>
1253 Thus, for the method
1254 (defmethod foo ((?a NUMBER SYMBOL) (?b (= 1 1)) $?c))
1255 (get-method-restrictions foo 1) would yield
1257 (2 -1 3 7 11 13 FALSE 2 NUMBER SYMBOL TRUE 0 FALSE 0)
1258 ***********************************************************************/
1259 globle void EnvGetMethodRestrictions(
1263 DATA_OBJECT *result)
1266 register DEFMETHOD *meth;
1267 register RESTRICTION *rptr;
1269 int roffset,rstrctIndex;
1270 MULTIFIELD_PTR theList;
1272 meth = ((DEFGENERIC *) vgfunc)->methods + FindMethodByIndex((DEFGENERIC *) vgfunc,mi);
1274 for (i = 0 ; i < meth->restrictionCount ; i++)
1275 count += meth->restrictions[i].tcnt + 3;
1276 theList = (MULTIFIELD_PTR) EnvCreateMultifield(theEnv,count);
1277 SetpType(result,MULTIFIELD);
1278 SetpValue(result,theList);
1279 SetpDOBegin(result,1);
1280 SetpDOEnd(result,count);
1281 SetMFType(theList,1,INTEGER);
1282 SetMFValue(theList,1,EnvAddLong(theEnv,(long long) meth->minRestrictions));
1283 SetMFType(theList,2,INTEGER);
1284 SetMFValue(theList,2,EnvAddLong(theEnv,(long long) meth->maxRestrictions));
1285 SetMFType(theList,3,INTEGER);
1286 SetMFValue(theList,3,EnvAddLong(theEnv,(long long) meth->restrictionCount));
1287 roffset = 3 + meth->restrictionCount + 1;
1289 for (i = 0 ; i < meth->restrictionCount ; i++)
1291 rptr = meth->restrictions + i;
1292 SetMFType(theList,rstrctIndex,INTEGER);
1293 SetMFValue(theList,rstrctIndex++,EnvAddLong(theEnv,(long long) roffset));
1294 SetMFType(theList,roffset,SYMBOL);
1295 SetMFValue(theList,roffset++,(rptr->query != NULL) ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv));
1296 SetMFType(theList,roffset,INTEGER);
1297 SetMFValue(theList,roffset++,EnvAddLong(theEnv,(long long) rptr->tcnt));
1298 for (j = 0 ; j < rptr->tcnt ; j++)
1300 SetMFType(theList,roffset,SYMBOL);
1302 SetMFValue(theList,roffset++,EnvAddSymbol(theEnv,EnvGetDefclassName(theEnv,rptr->types[j])));
1304 SetMFValue(theList,roffset++,EnvAddSymbol(theEnv,TypeName(theEnv,ValueToInteger(rptr->types[j]))));
1310 /* =========================================
1311 *****************************************
1312 INTERNALLY VISIBLE FUNCTIONS
1313 =========================================
1314 ***************************************** */
1316 /***************************************************
1317 NAME : PrintGenericCall
1318 DESCRIPTION : PrintExpression() support function
1319 for generic function calls
1320 INPUTS : 1) The output logical name
1321 2) The generic function
1322 RETURNS : Nothing useful
1323 SIDE EFFECTS : Call expression printed
1325 ***************************************************/
1326 static void PrintGenericCall(
1328 const char *logName,
1333 EnvPrintRouter(theEnv,logName,"(");
1334 EnvPrintRouter(theEnv,logName,EnvGetDefgenericName(theEnv,value));
1335 if (GetFirstArgument() != NULL)
1337 EnvPrintRouter(theEnv,logName," ");
1338 PrintExpression(theEnv,logName,GetFirstArgument());
1340 EnvPrintRouter(theEnv,logName,")");
1343 #pragma unused(theEnv)
1344 #pragma unused(logName)
1345 #pragma unused(value)
1350 /*******************************************************
1351 NAME : EvaluateGenericCall
1352 DESCRIPTION : Primitive support function for
1353 calling a generic function
1354 INPUTS : 1) The generic function
1355 2) A data object buffer to hold
1356 the evaluation result
1357 RETURNS : FALSE if the generic function
1358 returns the symbol FALSE,
1360 SIDE EFFECTS : Data obejct buffer set and any
1361 side-effects of calling the generic
1363 *******************************************************/
1364 static intBool EvaluateGenericCall(
1367 DATA_OBJECT *result)
1369 GenericDispatch(theEnv,(DEFGENERIC *) value,NULL,NULL,GetFirstArgument(),result);
1370 if ((GetpType(result) == SYMBOL) &&
1371 (GetpValue(result) == EnvFalseSymbol(theEnv)))
1376 /***************************************************
1377 NAME : DecrementGenericBusyCount
1378 DESCRIPTION : Lowers the busy count of a
1379 generic function construct
1380 INPUTS : The generic function
1381 RETURNS : Nothing useful
1382 SIDE EFFECTS : Busy count decremented if a clear
1383 is not in progress (see comment)
1385 ***************************************************/
1386 static void DecrementGenericBusyCount(
1390 /* ==============================================
1391 The generics to which expressions in other
1392 constructs may refer may already have been
1393 deleted - thus, it is important not to modify
1394 the busy flag during a clear.
1395 ============================================== */
1396 if (! ConstructData(theEnv)->ClearInProgress)
1397 ((DEFGENERIC *) value)->busy--;
1400 /***************************************************
1401 NAME : IncrementGenericBusyCount
1402 DESCRIPTION : Raises the busy count of a
1403 generic function construct
1404 INPUTS : The generic function
1405 RETURNS : Nothing useful
1406 SIDE EFFECTS : Busy count incremented
1408 ***************************************************/
1409 static void IncrementGenericBusyCount(
1414 #pragma unused(theEnv)
1416 #if (! RUN_TIME) && (! BLOAD_ONLY)
1417 if (! ConstructData(theEnv)->ParsingConstruct)
1418 { ConstructData(theEnv)->DanglingConstructs++; }
1421 ((DEFGENERIC *) value)->busy++;
1424 #if (! BLOAD_ONLY) && (! RUN_TIME)
1426 /**********************************************************************
1427 NAME : SaveDefgenerics
1428 DESCRIPTION : Outputs pretty-print forms of generic function headers
1429 INPUTS : The logical name of the output
1430 RETURNS : Nothing useful
1433 **********************************************************************/
1434 static void SaveDefgenerics(
1437 const char *logName)
1439 SaveConstruct(theEnv,theModule,logName,DefgenericData(theEnv)->DefgenericConstruct);
1442 /**********************************************************************
1443 NAME : SaveDefmethods
1444 DESCRIPTION : Outputs pretty-print forms of generic function methods
1445 INPUTS : The logical name of the output
1446 RETURNS : Nothing useful
1449 **********************************************************************/
1450 static void SaveDefmethods(
1453 const char *logName)
1455 DoForAllConstructsInModule(theEnv,theModule,SaveDefmethodsForDefgeneric,
1456 DefgenericData(theEnv)->DefgenericModuleIndex,
1457 FALSE,(void *) logName);
1460 /***************************************************
1461 NAME : SaveDefmethodsForDefgeneric
1462 DESCRIPTION : Save the pretty-print forms of
1463 all methods for a generic function
1465 INPUTS : 1) The defgeneric
1466 2) The logical name of the output
1467 RETURNS : Nothing useful
1468 SIDE EFFECTS : Methods written
1470 ***************************************************/
1471 static void SaveDefmethodsForDefgeneric(
1473 struct constructHeader *theDefgeneric,
1476 DEFGENERIC *gfunc = (DEFGENERIC *) theDefgeneric;
1477 const char *logName = (const char *) userBuffer;
1480 for (i = 0 ; i < gfunc->mcnt ; i++)
1482 if (gfunc->methods[i].ppForm != NULL)
1484 PrintInChunks(theEnv,logName,gfunc->methods[i].ppForm);
1485 EnvPrintRouter(theEnv,logName,"\n");
1490 /****************************************************
1491 NAME : RemoveDefgenericMethod
1492 DESCRIPTION : Removes a generic function method
1493 from the array and removes the
1494 generic too if its the last method
1495 INPUTS : 1) The generic function
1496 2) The array index of the method
1497 RETURNS : Nothing useful
1498 SIDE EFFECTS : List adjusted
1500 NOTES : Assumes deletion is safe
1501 ****************************************************/
1502 static void RemoveDefgenericMethod(
1510 if (gfunc->methods[gi].system)
1512 SetEvaluationError(theEnv,TRUE);
1513 PrintErrorID(theEnv,"GENRCCOM",4,FALSE);
1514 EnvPrintRouter(theEnv,WERROR,"Cannot remove implicit system function method for generic function ");
1515 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
1516 EnvPrintRouter(theEnv,WERROR,".\n");
1519 DeleteMethodInfo(theEnv,gfunc,&gfunc->methods[gi]);
1520 if (gfunc->mcnt == 1)
1522 rm(theEnv,(void *) gfunc->methods,(int) sizeof(DEFMETHOD));
1524 gfunc->methods = NULL;
1529 narr = (DEFMETHOD *) gm2(theEnv,(sizeof(DEFMETHOD) * gfunc->mcnt));
1530 for (b = e = 0 ; b < gfunc->mcnt ; b++ , e++)
1532 if (((int) b) == gi)
1534 GenCopyMemory(DEFMETHOD,1,&narr[b],&gfunc->methods[e]);
1536 rm(theEnv,(void *) gfunc->methods,(sizeof(DEFMETHOD) * (gfunc->mcnt+1)));
1537 gfunc->methods = narr;
1543 #if DEBUGGING_FUNCTIONS
1545 /******************************************************
1546 NAME : ListMethodsForGeneric
1547 DESCRIPTION : Lists a brief description of methods
1548 for a particular generic function
1549 INPUTS : 1) The logical name of the output
1550 2) Generic function to list methods for
1551 RETURNS : The number of methods printed
1554 ******************************************************/
1555 static long ListMethodsForGeneric(
1557 const char *logicalName,
1563 for (gi = 0 ; gi < gfunc->mcnt ; gi++)
1565 EnvPrintRouter(theEnv,logicalName,EnvGetDefgenericName(theEnv,(void *) gfunc));
1566 EnvPrintRouter(theEnv,logicalName," #");
1567 PrintMethod(theEnv,buf,255,&gfunc->methods[gi]);
1568 EnvPrintRouter(theEnv,logicalName,buf);
1569 EnvPrintRouter(theEnv,logicalName,"\n");
1571 return((long) gfunc->mcnt);
1574 /******************************************************************
1575 NAME : DefgenericWatchAccess
1576 DESCRIPTION : Parses a list of generic names passed by
1577 AddWatchItem() and sets the traces accordingly
1578 INPUTS : 1) A code indicating which trace flag is to be set
1580 2) The value to which to set the trace flags
1581 3) A list of expressions containing the names
1582 of the generics for which to set traces
1583 RETURNS : TRUE if all OK, FALSE otherwise
1584 SIDE EFFECTS : Watch flags set in specified generics
1585 NOTES : Accessory function for AddWatchItem()
1586 ******************************************************************/
1587 static unsigned DefgenericWatchAccess(
1591 EXPRESSION *argExprs)
1594 #pragma unused(code)
1597 return(ConstructSetWatchAccess(theEnv,DefgenericData(theEnv)->DefgenericConstruct,newState,argExprs,
1598 EnvGetDefgenericWatch,EnvSetDefgenericWatch));
1601 /***********************************************************************
1602 NAME : DefgenericWatchPrint
1603 DESCRIPTION : Parses a list of generic names passed by
1604 AddWatchItem() and displays the traces accordingly
1605 INPUTS : 1) The logical name of the output
1606 2) A code indicating which trace flag is to be examined
1608 3) A list of expressions containing the names
1609 of the generics for which to examine traces
1610 RETURNS : TRUE if all OK, FALSE otherwise
1611 SIDE EFFECTS : Watch flags displayed for specified generics
1612 NOTES : Accessory function for AddWatchItem()
1613 ***********************************************************************/
1614 static unsigned DefgenericWatchPrint(
1616 const char *logName,
1618 EXPRESSION *argExprs)
1621 #pragma unused(code)
1624 return(ConstructPrintWatchAccess(theEnv,DefgenericData(theEnv)->DefgenericConstruct,logName,argExprs,
1625 EnvGetDefgenericWatch,EnvSetDefgenericWatch));
1628 /******************************************************************
1629 NAME : DefmethodWatchAccess
1630 DESCRIPTION : Parses a list of methods passed by
1631 AddWatchItem() and sets the traces accordingly
1632 INPUTS : 1) A code indicating which trace flag is to be set
1634 2) The value to which to set the trace flags
1635 3) A list of expressions containing the methods
1636 for which to set traces
1637 RETURNS : TRUE if all OK, FALSE otherwise
1638 SIDE EFFECTS : Watch flags set in specified methods
1639 NOTES : Accessory function for AddWatchItem()
1640 ******************************************************************/
1641 static unsigned DefmethodWatchAccess(
1645 EXPRESSION *argExprs)
1648 #pragma unused(code)
1651 return(DefmethodWatchSupport(theEnv,"watch",NULL,newState,NULL,EnvSetDefmethodWatch,argExprs));
1653 return(DefmethodWatchSupport(theEnv,"unwatch",NULL,newState,NULL,EnvSetDefmethodWatch,argExprs));
1656 /***********************************************************************
1657 NAME : DefmethodWatchPrint
1658 DESCRIPTION : Parses a list of methods passed by
1659 AddWatchItem() and displays the traces accordingly
1660 INPUTS : 1) The logical name of the output
1661 2) A code indicating which trace flag is to be examined
1663 3) A list of expressions containing the methods for
1664 which to examine traces
1665 RETURNS : TRUE if all OK, FALSE otherwise
1666 SIDE EFFECTS : Watch flags displayed for specified methods
1667 NOTES : Accessory function for AddWatchItem()
1668 ***********************************************************************/
1669 static unsigned DefmethodWatchPrint(
1671 const char *logName,
1673 EXPRESSION *argExprs)
1676 #pragma unused(code)
1678 return(DefmethodWatchSupport(theEnv,"list-watch-items",logName,0,
1679 PrintMethodWatchFlag,NULL,argExprs));
1682 /*******************************************************
1683 NAME : DefmethodWatchSupport
1684 DESCRIPTION : Sets or displays methods specified
1685 INPUTS : 1) The calling function name
1686 2) The logical output name for displays
1688 3) The new set state
1689 4) The print function (can be NULL)
1690 5) The trace function (can be NULL)
1691 6) The methods expression list
1692 RETURNS : TRUE if all OK,
1694 SIDE EFFECTS : Method trace flags set or displayed
1696 *******************************************************/
1697 static unsigned DefmethodWatchSupport(
1699 const char *funcName,
1700 const char *logName,
1702 void (*printFunc)(void *,const char *,void *,long),
1703 void (*traceFunc)(void *,unsigned,void *,long),
1704 EXPRESSION *argExprs)
1707 unsigned long theMethod = 0;
1709 DATA_OBJECT genericName,methodIndex;
1710 struct defmodule *theModule;
1712 /* ==============================
1713 If no methods are specified,
1714 show the trace for all methods
1716 ============================== */
1717 if (argExprs == NULL)
1719 SaveCurrentModule(theEnv);
1720 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
1721 while (theModule != NULL)
1723 EnvSetCurrentModule(theEnv,(void *) theModule);
1724 if (traceFunc == NULL)
1726 EnvPrintRouter(theEnv,logName,EnvGetDefmoduleName(theEnv,(void *) theModule));
1727 EnvPrintRouter(theEnv,logName,":\n");
1729 theGeneric = EnvGetNextDefgeneric(theEnv,NULL);
1730 while (theGeneric != NULL)
1732 theMethod = EnvGetNextDefmethod(theEnv,theGeneric,0);
1733 while (theMethod != 0)
1735 if (traceFunc != NULL)
1736 (*traceFunc)(theEnv,newState,theGeneric,theMethod);
1739 EnvPrintRouter(theEnv,logName," ");
1740 (*printFunc)(theEnv,logName,theGeneric,theMethod);
1742 theMethod = EnvGetNextDefmethod(theEnv,theGeneric,theMethod);
1744 theGeneric = EnvGetNextDefgeneric(theEnv,theGeneric);
1746 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,(void *) theModule);
1748 RestoreCurrentModule(theEnv);
1752 /* =========================================
1753 Set the traces for every method specified
1754 ========================================= */
1755 while (argExprs != NULL)
1757 if (EvaluateExpression(theEnv,argExprs,&genericName))
1759 if ((genericName.type != SYMBOL) ? TRUE :
1760 ((theGeneric = (void *)
1761 LookupDefgenericByMdlOrScope(theEnv,DOToString(genericName))) == NULL))
1763 ExpectedTypeError1(theEnv,funcName,argIndex,"generic function name");
1766 if (GetNextArgument(argExprs) == NULL)
1770 argExprs = GetNextArgument(argExprs);
1772 if (EvaluateExpression(theEnv,argExprs,&methodIndex))
1774 if ((methodIndex.type != INTEGER) ? FALSE :
1775 ((DOToLong(methodIndex) <= 0) ? FALSE :
1776 (FindMethodByIndex((DEFGENERIC *) theGeneric,theMethod) != -1)))
1777 theMethod = (long) DOToLong(methodIndex);
1780 ExpectedTypeError1(theEnv,funcName,argIndex,"method index");
1786 theMethod = EnvGetNextDefmethod(theEnv,theGeneric,0);
1787 while (theMethod != 0)
1789 if (traceFunc != NULL)
1790 (*traceFunc)(theEnv,newState,theGeneric,theMethod);
1792 (*printFunc)(theEnv,logName,theGeneric,theMethod);
1793 theMethod = EnvGetNextDefmethod(theEnv,theGeneric,theMethod);
1798 if (traceFunc != NULL)
1799 (*traceFunc)(theEnv,newState,theGeneric,theMethod);
1801 (*printFunc)(theEnv,logName,theGeneric,theMethod);
1803 argExprs = GetNextArgument(argExprs);
1809 /***************************************************
1810 NAME : PrintMethodWatchFlag
1811 DESCRIPTION : Displays trace value for method
1812 INPUTS : 1) The logical name of the output
1813 2) The generic function
1815 RETURNS : Nothing useful
1818 ***************************************************/
1819 static void PrintMethodWatchFlag(
1821 const char *logName,
1827 EnvPrintRouter(theEnv,logName,EnvGetDefgenericName(theEnv,theGeneric));
1828 EnvPrintRouter(theEnv,logName," ");
1829 EnvGetDefmethodDescription(theEnv,buf,59,theGeneric,theMethod);
1830 EnvPrintRouter(theEnv,logName,buf);
1831 if (EnvGetDefmethodWatch(theEnv,theGeneric,theMethod))
1832 EnvPrintRouter(theEnv,logName," = on\n");
1834 EnvPrintRouter(theEnv,logName," = off\n");
1841 /***************************************************
1843 DESCRIPTION : Works like "class" in COOL
1845 RETURNS : Nothing useful
1847 NOTES : H/L Syntax: (type <primitive>)
1848 ***************************************************/
1849 globle void TypeCommand(
1851 DATA_OBJECT *result)
1853 EvaluateExpression(theEnv,GetFirstArgument(),result);
1854 result->value = (void *) EnvAddSymbol(theEnv,TypeName(theEnv,result->type));
1855 result->type = SYMBOL;
1860 /*#############################*/
1861 /* Additional Access Functions */
1862 /*#############################*/
1864 globle SYMBOL_HN *GetDefgenericNamePointer(
1865 void *theDefgeneric)
1867 return GetConstructNamePointer((struct constructHeader *) theDefgeneric);
1870 globle void SetNextDefgeneric(
1871 void *theDefgeneric,
1872 void *targetDefgeneric)
1874 SetNextConstruct((struct constructHeader *) theDefgeneric,
1875 (struct constructHeader *) targetDefgeneric);
1878 /*##################################*/
1879 /* Additional Environment Functions */
1880 /*##################################*/
1882 globle const char *EnvDefgenericModule(
1884 void *theDefgeneric)
1886 return GetConstructModuleName((struct constructHeader *) theDefgeneric);
1889 globle const char *EnvGetDefgenericName(
1891 void *theDefgeneric)
1893 return GetConstructNameString((struct constructHeader *) theDefgeneric);
1896 globle const char *EnvGetDefgenericPPForm(
1898 void *theDefgeneric)
1900 return GetConstructPPForm(theEnv,(struct constructHeader *) theDefgeneric);
1903 globle SYMBOL_HN *EnvGetDefgenericNamePointer(
1905 void *theDefgeneric)
1907 return GetConstructNamePointer((struct constructHeader *) theDefgeneric);
1910 globle void EnvSetDefgenericPPForm(
1912 void *theDefgeneric,
1913 const char *thePPForm)
1915 SetConstructPPForm(theEnv,(struct constructHeader *) theDefgeneric,thePPForm);
1918 /*#####################################*/
1919 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
1920 /*#####################################*/
1922 #if ALLOW_ENVIRONMENT_GLOBALS
1924 globle void SetDefgenericPPForm(
1925 void *theDefgeneric,
1926 const char *thePPForm)
1928 EnvSetDefgenericPPForm(GetCurrentEnvironment(),theDefgeneric,thePPForm);
1931 globle const char *DefgenericModule(
1932 void *theDefgeneric)
1934 return EnvDefgenericModule(GetCurrentEnvironment(),theDefgeneric);
1937 globle void *FindDefgeneric(
1938 const char *genericModuleAndName)
1940 return EnvFindDefgeneric(GetCurrentEnvironment(),genericModuleAndName);
1943 globle void GetDefgenericList(
1944 DATA_OBJECT *returnValue,
1945 struct defmodule *theModule)
1947 EnvGetDefgenericList(GetCurrentEnvironment(),returnValue,theModule);
1950 globle const char *GetDefgenericName(
1951 void *theDefgeneric)
1953 return EnvGetDefgenericName(GetCurrentEnvironment(),theDefgeneric);
1956 globle const char *GetDefgenericPPForm(
1957 void *theDefgeneric)
1959 return EnvGetDefgenericPPForm(GetCurrentEnvironment(),theDefgeneric);
1962 globle void *GetNextDefgeneric(
1965 return EnvGetNextDefgeneric(GetCurrentEnvironment(),ptr);
1968 globle int IsDefgenericDeletable(
1971 return EnvIsDefgenericDeletable(GetCurrentEnvironment(),ptr);
1974 globle intBool Undefgeneric(
1977 return EnvUndefgeneric(GetCurrentEnvironment(),vptr);
1980 globle void GetDefmethodList(
1982 DATA_OBJECT_PTR returnValue)
1984 EnvGetDefmethodList(GetCurrentEnvironment(),vgfunc,returnValue);
1987 globle void GetMethodRestrictions(
1990 DATA_OBJECT *result)
1992 EnvGetMethodRestrictions(GetCurrentEnvironment(),vgfunc,mi,result);
1995 globle long GetNextDefmethod(
1999 return EnvGetNextDefmethod(GetCurrentEnvironment(),ptr,theIndex);
2002 globle int IsDefmethodDeletable(
2006 return EnvIsDefmethodDeletable(GetCurrentEnvironment(),ptr,theIndex);
2009 globle intBool Undefmethod(
2013 return EnvUndefmethod(GetCurrentEnvironment(),vptr,mi);
2016 #if DEBUGGING_FUNCTIONS
2018 globle unsigned GetDefgenericWatch(
2021 return EnvGetDefgenericWatch(GetCurrentEnvironment(),theGeneric);
2024 globle void ListDefgenerics(
2025 const char *logicalName,
2026 struct defmodule *theModule)
2028 EnvListDefgenerics(GetCurrentEnvironment(),logicalName,theModule);
2031 globle void SetDefgenericWatch(
2035 EnvSetDefgenericWatch(GetCurrentEnvironment(),newState,theGeneric);
2038 globle const char *GetDefmethodPPForm(
2042 return EnvGetDefmethodPPForm(GetCurrentEnvironment(),ptr,theIndex);
2045 globle unsigned GetDefmethodWatch(
2049 return EnvGetDefmethodWatch(GetCurrentEnvironment(),theGeneric,theIndex);
2052 globle void ListDefmethods(
2053 const char *logicalName,
2056 EnvListDefmethods(GetCurrentEnvironment(),logicalName,vptr);
2059 globle void SetDefmethodWatch(
2064 EnvSetDefmethodWatch(GetCurrentEnvironment(),newState,theGeneric,theIndex);
2067 #endif /* DEBUGGING_FUNCTIONS */
2069 #if DEBUGGING_FUNCTIONS || PROFILING_FUNCTIONS
2071 globle void GetDefmethodDescription(
2077 EnvGetDefmethodDescription(GetCurrentEnvironment(),buf,buflen,ptr,theIndex);
2080 #endif /* DEBUGGING_FUNCTIONS || PROFILING_FUNCTIONS */
2082 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
2084 #endif /* DEFGENERIC_CONSTRUCT */