- support for dynamic objects

This commit is contained in:
zolliker
2008-02-13 09:54:57 +00:00
parent f723000564
commit 5ee27af961
4 changed files with 127 additions and 24 deletions

View File

@ -9,12 +9,13 @@ Markus Zolliker, March 2005
#include "sics.h" #include "sics.h"
#include "initializer.h" #include "initializer.h"
#include "splitter.h"
typedef struct Item { typedef struct Item {
struct Item *next; struct Item *next;
char *type; char *type; /* "Object" for all commands created by makeobject, else something more general */
char *name; char *name; /* the name for identifying an initializer */
char *desc; char *desc; /* a description of the initializer. not the same as pObjectDescriptor->name */
Initializer maker; Initializer maker;
int startupOnly; int startupOnly;
} Item; } Item;
@ -40,7 +41,7 @@ void MakeInitializer(const char *type, const char *name, Initializer maker,
Initializer GetInitializer(const char *type, const char *name) { Initializer GetInitializer(const char *type, const char *name) {
Item *p, **last; Item *p, **last;
if (startup && pServ->pReader != NULL) { if (startup && !ServerIsStarting(pServ)) {
/* pServ->pReader exists: startup finished */ /* pServ->pReader exists: startup finished */
startup = 0; startup = 0;
/* remove startup initializers */ /* remove startup initializers */
@ -70,7 +71,7 @@ static int MakeObject(SConnection *con, SicsInterp *sics,
CmdInitializer cmdin; CmdInitializer cmdin;
if (argc < 3) { if (argc < 3) {
SCPrintf(con, eError, "%s needs more arguments", argv[0]); SCPrintf(con, eError, "ERROR: should be: %s <object> <type> ...", argv[0]);
return 0; return 0;
} }
@ -124,9 +125,10 @@ static int RemoveObject(SConnection *con, SicsInterp *sics,
char *className; char *className;
char shortClassName[32]; char shortClassName[32];
char *p; char *p;
int removeAllowed;
if (argc != 2) { if (argc != 2) {
SCPrintf(con, eError, "%s needs 1 argument", argv[0]); SCPrintf(con, eError, "ERROR: should be: %s <object>", argv[0]);
return 0; return 0;
} }
@ -135,18 +137,25 @@ static int RemoveObject(SConnection *con, SicsInterp *sics,
SCPrintf(con, eError, "ERROR: %s not found", argv[1]); SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0; return 0;
} }
className = ((pDummy)command->pData)->pDescriptor->name;
cmdin = (CmdInitializer)GetInitializer("Object", className); if (((pDummy)command->pData)->pDescriptor->creationCommand != NULL) {
if (cmdin == 0) { /* if there is a creationCommand, we are allowed to remove */
/* allow also a longer descriptor starting with the initializer name and a blank */ removeAllowed = 1;
p = strchr(className, ' '); } else {
if (p) { /* if we have an initializer: we are also allowed to remove */
snprintf(shortClassName, sizeof shortClassName, "%.*s", p - className, className); className = ((pDummy)command->pData)->pDescriptor->name;
cmdin = (CmdInitializer)GetInitializer("Object", shortClassName); cmdin = (CmdInitializer)GetInitializer("Object", className);
if (cmdin == 0) {
/* allow also a longer descriptor starting with the initializer name and a blank */
p = strchr(className, ' ');
if (p) {
snprintf(shortClassName, sizeof shortClassName, "%.*s", p - className, className);
cmdin = (CmdInitializer)GetInitializer("Object", shortClassName);
}
} }
removeAllowed = (cmdin != NULL);
} }
if (cmdin) { if (removeAllowed) {
/* if we have an initializer, we are allowed to remove */
if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) { if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
SCPrintf(con, eError, "ERROR: cannot remove %s while running", argv[1]); SCPrintf(con, eError, "ERROR: cannot remove %s while running", argv[1]);
return 0; return 0;
@ -160,6 +169,65 @@ static int RemoveObject(SConnection *con, SicsInterp *sics,
} }
} }
static int SaveCreationCommands(void *object, char *name, FILE *fil) {
CommandList *p;
ObjectDescriptor *desc;
int printHeader = 0;
for (p = pServ->pSics->pCList; p != NULL; p = p->pNext) {
desc = ((pDummy)p->pData)->pDescriptor;
if (desc->creationCommand && strcmp(desc->creationCommand, "0") != 0) {
if (printHeader == 0) {
printHeader = 1;
fprintf(fil, "\n#--- BEGIN creation commands\n");
}
fprintf(fil, "%s\n", desc->creationCommand);
}
}
if (printHeader == 1) {
fprintf(fil, "#--- END creation commands\n\n");
}
return 1;
}
static int CreationCommand(SConnection *con, SicsInterp *sics,
void *data, int argc, char *argv[]) {
CmdInitializer cmdin;
CommandList *command;
char *className;
char shortClassName[32];
char *p;
int removeAllowed;
ObjectDescriptor *desc;
if (argc < 2) {
SCPrintf(con, eError, "ERROR: should be: %s <object> [<creation command>]", argv[0]);
return 0;
}
command = FindCommand(sics, argv[1]);
if (!command) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
desc = ((pDummy)command->pData)->pDescriptor;
if (argc < 3) {
if (desc->creationCommand != NULL) {
SCPrintf(con, eValue, "%s", desc->creationCommand);
} else {
SCPrintf(con, eValue, "<static object>");
}
} else {
if (! desc->creationCommand) {
SCPrintf(con, eValue, "ERROR: %s is a static object", argv[1]);
return 0;
}
free(desc->creationCommand);
desc->creationCommand = Arg2Tcl(argc - 2, argv + 2, NULL, -1);
}
return 1;
}
static void KillInitializers(void *data) { static void KillInitializers(void *data) {
KillDummy(data); KillDummy(data);
Item *item, *next; Item *item, *next;
@ -177,11 +245,17 @@ static void KillInitializers(void *data) {
} }
void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly, const char *desc) { void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly, const char *desc) {
if (! FindCommand(pServ->pSics, "MakeObject")) {
AddCommandWithFlag(pServ->pSics, "MakeObject", MakeObject, KillInitializers, NULL, 0);
AddCommandWithFlag(pServ->pSics, "MakeStaticObject", MakeObject, NULL, NULL, 0);
AddCommandWithFlag(pServ->pSics, "RemoveObject", RemoveObject, NULL, NULL, 0);
AddCommandWithFlag(pServ->pSics, "DriverList", DriverList, NULL, NULL, 0);
}
MakeInitializer("Object", driver, (Initializer)maker, startupOnly, desc); MakeInitializer("Object", driver, (Initializer)maker, startupOnly, desc);
} }
void InitializerInit(void) {
pDummy cc = NULL;
AddCommandWithFlag(pServ->pSics, "MakeObject", MakeObject, KillInitializers, NULL, 0);
AddCommandWithFlag(pServ->pSics, "MakeStaticObject", MakeObject, NULL, NULL, 0);
AddCommandWithFlag(pServ->pSics, "RemoveObject", RemoveObject, NULL, NULL, 0);
AddCommandWithFlag(pServ->pSics, "DriverList", DriverList, NULL, NULL, 0);
cc = CreateDummy("creation commands");
cc->pDescriptor->SaveStatus = SaveCreationCommands;
AddCommandWithFlag(pServ->pSics, "CreationCommand", CreationCommand,
KillDummy, cc, 0);
}

View File

@ -71,6 +71,7 @@
pRes->parNode = NULL; pRes->parNode = NULL;
pRes->SaveStatus = DefaultSave; pRes->SaveStatus = DefaultSave;
pRes->GetInterface = DefaultGetInterface; pRes->GetInterface = DefaultGetInterface;
pRes->creationCommand = NULL;
return pRes; return pRes;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -31,6 +31,7 @@
void *(*GetInterface)(void *self, int iInterfaceID); void *(*GetInterface)(void *self, int iInterfaceID);
IPair *pKeys; IPair *pKeys;
pHdb parNode; pHdb parNode;
char *creationCommand; /* NULL when a static object */
} ObjectDescriptor, *pObjectDescriptor; } ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -13,6 +13,8 @@
#include "dynstring.h" #include "dynstring.h"
#include "macro.h" #include "macro.h"
#include "sicshipadaba.h" #include "sicshipadaba.h"
#include "initializer.h"
#include "splitter.h"
extern int decodeSICSPriv(char *txt); /* from access.c */ extern int decodeSICSPriv(char *txt); /* from access.c */
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
@ -55,8 +57,9 @@ void KillSICSOBJ(void *data){
if(self == NULL){ if(self == NULL){
return; return;
} }
RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon);
if(self->pDes != NULL){ if(self->pDes != NULL){
DeleteDescriptor(self->pDes); DeleteDescriptor(self->pDes); /* kill descriptor including node */
} }
if(self->KillPrivate != NULL && self->pPrivate != NULL){ if(self->KillPrivate != NULL && self->pPrivate != NULL){
self->KillPrivate(self->pPrivate); self->KillPrivate(self->pPrivate);
@ -249,16 +252,40 @@ pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
int argc, char *argv[]){ int argc, char *argv[]){
pSICSOBJ pNew = NULL; pSICSOBJ pNew = NULL;
int status; int status;
int type;
int priv;
if(argc < 3){ if(argc < 3){
SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError); SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError);
return NULL; return NULL;
} }
pNew = MakeSICSOBJ(argv[1], argv[2]); if (argc < 5) {
type = HIPNONE;
priv = usInternal;
} else {
/* convert privilege */
priv = decodeSICSPriv(argv[3]);
/* convert datatype */
strtolower(argv[4]);
type = convertHdbType(argv[4]);
if(type > HIPFLOAT){
SCWrite(pCon,
"ERROR: invalid type requested: none, int, float supported",
eError);
return 0;
}
}
pNew = MakeSICSOBJv(argv[1], argv[2], type, priv);
if(pNew == NULL){ if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError); SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError);
return NULL; return NULL;
} }
if (strcasecmp(argv[0],"DynSicsObj") == 0) {
/* save creation command */
pNew->pDes->creationCommand = Arg2Tcl(argc, argv, NULL, -1);
}
status = AddCommand(pSics, status = AddCommand(pSics,
argv[1], argv[1],
InvokeSICSOBJ, InvokeSICSOBJ,