#include <string.h>
#include "setup.h"
#if OBJECT_SYSTEM
#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
#include "bload.h"
#endif
#include "argacces.h"
#include "classfun.h"
#include "classini.h"
#include "envrnmnt.h"
#include "modulutl.h"
#include "msgcom.h"
#include "prntutil.h"
#include "router.h"
#include "classcom.h"
#if (! BLOAD_ONLY) && (! RUN_TIME) && DEBUGGING_FUNCTIONS
static void SaveDefclass(Environment *,ConstructHeader *,void *);
#endif
static const char *GetClassDefaultsModeName(ClassDefaultsMode);
Defclass *FindDefclass( Environment *theEnv,
const char *classAndModuleName)
{
CLIPSLexeme *classSymbol = NULL;
Defclass *cls;
Defmodule *theModule = NULL;
const char *className;
SaveCurrentModule(theEnv);
className = ExtractModuleAndConstructName(theEnv,classAndModuleName);
if (className != NULL)
{
classSymbol = FindSymbolHN(theEnv,ExtractModuleAndConstructName(theEnv,classAndModuleName),SYMBOL_BIT);
theModule = GetCurrentModule(theEnv);
}
RestoreCurrentModule(theEnv);
if (classSymbol == NULL)
{ return NULL; }
cls = DefclassData(theEnv)->ClassTable[HashClass(classSymbol)];
while (cls != NULL)
{
if (cls->header.name == classSymbol)
{
if (cls->system || (cls->header.whichModule->theModule == theModule))
{ return cls->installed ? cls : NULL; }
}
cls = cls->nxtHash;
}
return NULL;
}
Defclass *FindDefclassInModule(
Environment *theEnv,
const char *classAndModuleName)
{
CLIPSLexeme *classSymbol = NULL;
Defclass *cls;
Defmodule *theModule = NULL;
const char *className;
SaveCurrentModule(theEnv);
className = ExtractModuleAndConstructName(theEnv,classAndModuleName);
if (className != NULL)
{
classSymbol = FindSymbolHN(theEnv,ExtractModuleAndConstructName(theEnv,classAndModuleName),SYMBOL_BIT);
theModule = GetCurrentModule(theEnv);
}
RestoreCurrentModule(theEnv);
if (classSymbol == NULL)
{ return NULL; }
cls = DefclassData(theEnv)->ClassTable[HashClass(classSymbol)];
while (cls != NULL)
{
if (cls->header.name == classSymbol)
{
if (cls->system || (cls->header.whichModule->theModule == theModule))
{ return cls->installed ? cls : NULL; }
}
cls = cls->nxtHash;
}
return NULL;
}
Defclass *LookupDefclassByMdlOrScope(
Environment *theEnv,
const char *classAndModuleName)
{
Defclass *cls;
const char *className;
CLIPSLexeme *classSymbol;
Defmodule *theModule;
if (FindModuleSeparator(classAndModuleName) == 0)
{ return LookupDefclassInScope(theEnv,classAndModuleName); }
SaveCurrentModule(theEnv);
className = ExtractModuleAndConstructName(theEnv,classAndModuleName);
theModule = GetCurrentModule(theEnv);
RestoreCurrentModule(theEnv);
if (className == NULL)
{ return NULL; }
if ((classSymbol = FindSymbolHN(theEnv,className,SYMBOL_BIT)) == NULL)
{ return NULL; }
cls = DefclassData(theEnv)->ClassTable[HashClass(classSymbol)];
while (cls != NULL)
{
if ((cls->header.name == classSymbol) &&
(cls->header.whichModule->theModule == theModule))
return(cls->installed ? cls : NULL);
cls = cls->nxtHash;
}
return NULL;
}
Defclass *LookupDefclassInScope(
Environment *theEnv,
const char *className)
{
Defclass *cls;
CLIPSLexeme *classSymbol;
if ((classSymbol = FindSymbolHN(theEnv,className,SYMBOL_BIT)) == NULL)
{ return NULL; }
cls = DefclassData(theEnv)->ClassTable[HashClass(classSymbol)];
while (cls != NULL)
{
if ((cls->header.name == classSymbol) && DefclassInScope(theEnv,cls,NULL))
return cls->installed ? cls : NULL;
cls = cls->nxtHash;
}
return NULL;
}
Defclass *LookupDefclassAnywhere(
Environment *theEnv,
Defmodule *theModule,
const char *className)
{
Defclass *cls;
CLIPSLexeme *classSymbol;
if ((classSymbol = FindSymbolHN(theEnv,className,SYMBOL_BIT)) == NULL)
{ return NULL; }
cls = DefclassData(theEnv)->ClassTable[HashClass(classSymbol)];
while (cls != NULL)
{
if ((cls->header.name == classSymbol) &&
((theModule == NULL) ||
(cls->header.whichModule->theModule == theModule)))
{ return cls->installed ? cls : NULL; }
cls = cls->nxtHash;
}
return NULL;
}
bool DefclassInScope(
Environment *theEnv,
Defclass *theDefclass,
Defmodule *theModule)
{
#if DEFMODULE_CONSTRUCT
unsigned long moduleID;
char *scopeMap;
scopeMap = (char *) theDefclass->scopeMap->contents;
if (theModule == NULL)
{ theModule = GetCurrentModule(theEnv); }
moduleID = theModule->header.bsaveID;
return TestBitMap(scopeMap,moduleID);
#else
#if MAC_XCD
#pragma unused(theEnv,theDefclass,theModule)
#endif
return true;
#endif
}
Defclass *GetNextDefclass(
Environment *theEnv,
Defclass *theDefclass)
{
return (Defclass *) GetNextConstructItem(theEnv,&theDefclass->header,
DefclassData(theEnv)->DefclassModuleIndex);
}
bool DefclassIsDeletable(
Defclass *theDefclass)
{
Environment *theEnv = theDefclass->header.env;
if (! ConstructsDeletable(theEnv))
{ return false; }
if (theDefclass->system == 1)
{ return false; }
#if (! BLOAD_ONLY) && (! RUN_TIME)
return (IsClassBeingUsed(theDefclass) == false) ? true : false;
#else
return false;
#endif
}
void UndefclassCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
UndefconstructCommand(context,"undefclass",DefclassData(theEnv)->DefclassConstruct);
}
bool Undefclass(
Defclass *theDefclass,
Environment *allEnv)
{
#if RUN_TIME || BLOAD_ONLY
return false;
#else
Environment *theEnv;
bool success;
GCBlock gcb;
if (theDefclass == NULL)
{ theEnv = allEnv; }
else
{ theEnv = theDefclass->header.env; }
#if BLOAD || BLOAD_AND_BSAVE
if (Bloaded(theEnv))
return false;
#endif
GCBlockStart(theEnv,&gcb);
if (theDefclass == NULL)
{
success = RemoveAllUserClasses(theEnv);
GCBlockEnd(theEnv,&gcb);
return success;
}
success = DeleteClassUAG(theEnv,theDefclass);
GCBlockEnd(theEnv,&gcb);
return success;
#endif
}
#if DEBUGGING_FUNCTIONS
void PPDefclassCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
PPConstructCommand(context,"ppdefclass",DefclassData(theEnv)->DefclassConstruct,returnValue);
}
void ListDefclassesCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
ListConstructCommand(context,DefclassData(theEnv)->DefclassConstruct);
}
void ListDefclasses(
Environment *theEnv,
const char *logicalName,
Defmodule *theModule)
{
ListConstruct(theEnv,DefclassData(theEnv)->DefclassConstruct,logicalName,theModule);
}
bool DefclassGetWatchInstances(
Defclass *theDefclass)
{
return theDefclass->traceInstances;
}
void DefclassSetWatchInstances(
Defclass *theDefclass,
bool newState)
{
if (theDefclass->abstract)
{ return; }
theDefclass->traceInstances = newState;
}
bool DefclassGetWatchSlots(
Defclass *theDefclass)
{
return theDefclass->traceSlots;
}
void DefclassSetWatchSlots(
Defclass *theDefclass,
bool newState)
{
theDefclass->traceSlots = newState;
}
bool DefclassWatchAccess(
Environment *theEnv,
int code,
bool newState,
Expression *argExprs)
{
if (code)
return(ConstructSetWatchAccess(theEnv,DefclassData(theEnv)->DefclassConstruct,newState,argExprs,
(ConstructGetWatchFunction *) DefclassGetWatchSlots,
(ConstructSetWatchFunction *) DefclassSetWatchSlots));
else
return(ConstructSetWatchAccess(theEnv,DefclassData(theEnv)->DefclassConstruct,newState,argExprs,
(ConstructGetWatchFunction *) DefclassGetWatchInstances,
(ConstructSetWatchFunction *) DefclassSetWatchInstances));
}
bool DefclassWatchPrint(
Environment *theEnv,
const char *logName,
int code,
Expression *argExprs)
{
if (code)
return(ConstructPrintWatchAccess(theEnv,DefclassData(theEnv)->DefclassConstruct,logName,argExprs,
(ConstructGetWatchFunction *) DefclassGetWatchSlots,
(ConstructSetWatchFunction *) DefclassSetWatchSlots));
else
return(ConstructPrintWatchAccess(theEnv,DefclassData(theEnv)->DefclassConstruct,logName,argExprs,
(ConstructGetWatchFunction *) DefclassGetWatchInstances,
(ConstructSetWatchFunction *) DefclassSetWatchInstances));
}
#endif
void GetDefclassListFunction(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
GetConstructListFunction(context,returnValue,DefclassData(theEnv)->DefclassConstruct);
}
void GetDefclassList(
Environment *theEnv,
CLIPSValue *returnValue,
Defmodule *theModule)
{
UDFValue result;
GetConstructList(theEnv,&result,DefclassData(theEnv)->DefclassConstruct,theModule);
NormalizeMultifield(theEnv,&result);
returnValue->value = result.value;
}
bool HasSuperclass(
Defclass *c1,
Defclass *c2)
{
unsigned long i;
for (i = 1 ; i < c1->allSuperclasses.classCount ; i++)
if (c1->allSuperclasses.classArray[i] == c2)
return true;
return false;
}
CLIPSLexeme *CheckClassAndSlot(
UDFContext *context,
const char *func,
Defclass **cls)
{
UDFValue theArg;
Environment *theEnv = context->environment;
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
return NULL;
*cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents);
if (*cls == NULL)
{
ClassExistError(theEnv,func,theArg.lexemeValue->contents);
return NULL;
}
if (! UDFNextArgument(context,SYMBOL_BIT,&theArg))
return NULL;
return theArg.lexemeValue;
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
void SaveDefclasses(
Environment *theEnv,
Defmodule *theModule,
const char *logName,
void *context)
{
#if DEBUGGING_FUNCTIONS
DoForAllConstructsInModule(theEnv,theModule,SaveDefclass,
DefclassData(theEnv)->DefclassModuleIndex,
false,(void *) logName);
#else
#if MAC_XCD
#pragma unused(theEnv,theModule,logName)
#endif
#endif
}
#endif
#if (! BLOAD_ONLY) && (! RUN_TIME) && DEBUGGING_FUNCTIONS
static void SaveDefclass(
Environment *theEnv,
ConstructHeader *theConstruct,
void *userBuffer)
{
const char *logName = (const char *) userBuffer;
Defclass *theDefclass = (Defclass *) theConstruct;
unsigned hnd;
const char *ppForm;
ppForm = DefclassPPForm(theDefclass);
if (ppForm != NULL)
{
WriteString(theEnv,logName,ppForm);
WriteString(theEnv,logName,"\n");
hnd = GetNextDefmessageHandler(theDefclass,0);
while (hnd != 0)
{
ppForm = DefmessageHandlerPPForm(theDefclass,hnd);
if (ppForm != NULL)
{
WriteString(theEnv,logName,ppForm);
WriteString(theEnv,logName,"\n");
}
hnd = GetNextDefmessageHandler(theDefclass,hnd);
}
}
}
#endif
ClassDefaultsMode SetClassDefaultsMode(
Environment *theEnv,
ClassDefaultsMode value)
{
ClassDefaultsMode ov;
ov = DefclassData(theEnv)->ClassDefaultsModeValue;
DefclassData(theEnv)->ClassDefaultsModeValue = value;
return ov;
}
ClassDefaultsMode GetClassDefaultsMode(
Environment *theEnv)
{
return DefclassData(theEnv)->ClassDefaultsModeValue;
}
void GetClassDefaultsModeCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
returnValue->lexemeValue = CreateSymbol(theEnv,GetClassDefaultsModeName(GetClassDefaultsMode(theEnv)));
}
void SetClassDefaultsModeCommand(
Environment *theEnv,
UDFContext *context,
UDFValue *returnValue)
{
UDFValue theArg;
const char *argument;
ClassDefaultsMode oldMode;
oldMode = DefclassData(theEnv)->ClassDefaultsModeValue;
if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg))
{ return; }
argument = theArg.lexemeValue->contents;
if (strcmp(argument,"conservation") == 0)
{ SetClassDefaultsMode(theEnv,CONSERVATION_MODE); }
else if (strcmp(argument,"convenience") == 0)
{ SetClassDefaultsMode(theEnv,CONVENIENCE_MODE); }
else
{
UDFInvalidArgumentMessage(context,"symbol with value conservation or convenience");
returnValue->lexemeValue = CreateSymbol(theEnv,GetClassDefaultsModeName(GetClassDefaultsMode(theEnv)));
return;
}
returnValue->lexemeValue = CreateSymbol(theEnv,GetClassDefaultsModeName(oldMode));
}
static const char *GetClassDefaultsModeName(
ClassDefaultsMode mode)
{
const char *sname;
switch (mode)
{
case CONSERVATION_MODE:
sname = "conservation";
break;
case CONVENIENCE_MODE:
sname = "convenience";
break;
default:
sname = "unknown";
break;
}
return(sname);
}
CLIPSLexeme *GetDefclassNamePointer(
Defclass *theClass)
{
return GetConstructNamePointer(&theClass->header);
}
void SetNextDefclass(
Defclass *theClass,
Defclass *targetClass)
{
SetNextConstruct(&theClass->header,
&targetClass->header);
}
const char *DefclassName(
Defclass *theClass)
{
return GetConstructNameString(&theClass->header);
}
const char *DefclassPPForm(
Defclass *theClass)
{
return GetConstructPPForm(&theClass->header);
}
struct defmoduleItemHeader *GetDefclassModule(
Environment *theEnv,
Defclass *theClass)
{
return GetConstructModuleItem(&theClass->header);
}
const char *DefclassModule(
Defclass *theClass)
{
return GetConstructModuleName(&theClass->header);
}
void SetDefclassPPForm(
Environment *theEnv,
Defclass *theClass,
char *thePPForm)
{
SetConstructPPForm(theEnv,&theClass->header,thePPForm);
}
#endif