diff --git a/initializer.c b/initializer.c index 0b77c6da..c1700ffb 100644 --- a/initializer.c +++ b/initializer.c @@ -9,12 +9,13 @@ Markus Zolliker, March 2005 #include "sics.h" #include "initializer.h" +#include "splitter.h" typedef struct Item { struct Item *next; - char *type; - char *name; - char *desc; + char *type; /* "Object" for all commands created by makeobject, else something more general */ + char *name; /* the name for identifying an initializer */ + char *desc; /* a description of the initializer. not the same as pObjectDescriptor->name */ Initializer maker; int startupOnly; } Item; @@ -40,7 +41,7 @@ void MakeInitializer(const char *type, const char *name, Initializer maker, Initializer GetInitializer(const char *type, const char *name) { Item *p, **last; - if (startup && pServ->pReader != NULL) { + if (startup && !ServerIsStarting(pServ)) { /* pServ->pReader exists: startup finished */ startup = 0; /* remove startup initializers */ @@ -70,7 +71,7 @@ static int MakeObject(SConnection *con, SicsInterp *sics, CmdInitializer cmdin; if (argc < 3) { - SCPrintf(con, eError, "%s needs more arguments", argv[0]); + SCPrintf(con, eError, "ERROR: should be: %s ...", argv[0]); return 0; } @@ -124,9 +125,10 @@ static int RemoveObject(SConnection *con, SicsInterp *sics, char *className; char shortClassName[32]; char *p; + int removeAllowed; if (argc != 2) { - SCPrintf(con, eError, "%s needs 1 argument", argv[0]); + SCPrintf(con, eError, "ERROR: should be: %s ", argv[0]); return 0; } @@ -135,18 +137,25 @@ static int RemoveObject(SConnection *con, SicsInterp *sics, SCPrintf(con, eError, "ERROR: %s not found", argv[1]); return 0; } - className = ((pDummy)command->pData)->pDescriptor->name; - 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); + + if (((pDummy)command->pData)->pDescriptor->creationCommand != NULL) { + /* if there is a creationCommand, we are allowed to remove */ + removeAllowed = 1; + } else { + /* if we have an initializer: we are also allowed to remove */ + className = ((pDummy)command->pData)->pDescriptor->name; + 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 we have an initializer, we are allowed to remove */ + if (removeAllowed) { if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) { SCPrintf(con, eError, "ERROR: cannot remove %s while running", argv[1]); 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 []", 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, ""); + } + } 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) { KillDummy(data); Item *item, *next; @@ -177,11 +245,17 @@ static void KillInitializers(void *data) { } 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); } + +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); +} diff --git a/obdes.c b/obdes.c index b94c717e..f19ccaa8 100644 --- a/obdes.c +++ b/obdes.c @@ -71,6 +71,7 @@ pRes->parNode = NULL; pRes->SaveStatus = DefaultSave; pRes->GetInterface = DefaultGetInterface; + pRes->creationCommand = NULL; return pRes; } /*---------------------------------------------------------------------------*/ diff --git a/obdes.h b/obdes.h index f842a2e9..4013e9db 100644 --- a/obdes.h +++ b/obdes.h @@ -31,6 +31,7 @@ void *(*GetInterface)(void *self, int iInterfaceID); IPair *pKeys; pHdb parNode; + char *creationCommand; /* NULL when a static object */ } ObjectDescriptor, *pObjectDescriptor; /*---------------------------------------------------------------------------*/ diff --git a/sicsobj.c b/sicsobj.c index a6f4ecf7..3ccbdab1 100644 --- a/sicsobj.c +++ b/sicsobj.c @@ -13,6 +13,8 @@ #include "dynstring.h" #include "macro.h" #include "sicshipadaba.h" +#include "initializer.h" +#include "splitter.h" extern int decodeSICSPriv(char *txt); /* from access.c */ /*--------------------------------------------------------------------------*/ @@ -55,8 +57,9 @@ void KillSICSOBJ(void *data){ if(self == NULL){ return; } + RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon); if(self->pDes != NULL){ - DeleteDescriptor(self->pDes); + DeleteDescriptor(self->pDes); /* kill descriptor including node */ } if(self->KillPrivate != NULL && self->pPrivate != NULL){ self->KillPrivate(self->pPrivate); @@ -249,16 +252,40 @@ pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]){ pSICSOBJ pNew = NULL; int status; + int type; + int priv; if(argc < 3){ SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError); 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){ SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError); return NULL; } + if (strcasecmp(argv[0],"DynSicsObj") == 0) { + /* save creation command */ + pNew->pDes->creationCommand = Arg2Tcl(argc, argv, NULL, -1); + } + status = AddCommand(pSics, argv[1], InvokeSICSOBJ,