- introduced initializer
This commit is contained in:
139
initializer.c
Normal file
139
initializer.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
initializer.c
|
||||
|
||||
initializer routines
|
||||
|
||||
Markus Zolliker, March 2005
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "sics.h"
|
||||
#include "initializer.h"
|
||||
|
||||
typedef struct Item {
|
||||
struct Item *next;
|
||||
const char *type;
|
||||
const char *name;
|
||||
Initializer maker;
|
||||
int startupOnly;
|
||||
} Item;
|
||||
|
||||
static Item *list = NULL;
|
||||
static int startup = 1;
|
||||
|
||||
void MakeInitializer(const char *type, const char *name, Initializer maker, int startupOnly) {
|
||||
Item *item;
|
||||
|
||||
item = calloc(1, sizeof *item);
|
||||
assert(item);
|
||||
item->maker = maker;
|
||||
item->next = list;
|
||||
item->type = type;
|
||||
item->name = name;
|
||||
item->startupOnly = startupOnly;
|
||||
list = item;
|
||||
}
|
||||
|
||||
Initializer GetInitializer(const char *type, const char *name) {
|
||||
Item *p, **last;
|
||||
|
||||
if (startup && pServ->pReader != NULL) {
|
||||
/* pServ->pReader exists: startup finished */
|
||||
startup = 0;
|
||||
/* remove startup initializers */
|
||||
p = list;
|
||||
last = &list;
|
||||
while (p != NULL) {
|
||||
if (p->startupOnly) {
|
||||
*last = p->next;
|
||||
free(p);
|
||||
p = *last;
|
||||
} else {
|
||||
last = &p->next;
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = list;
|
||||
while (p != NULL && (strcasecmp(p->name, name) != 0 || strcasecmp(p->type, type) != 0)) {
|
||||
p = p->next;
|
||||
}
|
||||
if (p) {
|
||||
return p->maker;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int MakeObject(SConnection *con, SicsInterp *sics,
|
||||
void *data, int argc, char *argv[]) {
|
||||
CmdInitializer cmdin;
|
||||
CommandList *command;
|
||||
char *className;
|
||||
|
||||
if (argc < 3) {
|
||||
SCPrintf(con, eError, "%s needs more arguments", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmdin = (CmdInitializer)GetInitializer("Object", argv[2]);
|
||||
if (cmdin) {
|
||||
return cmdin(con, argc, argv, ! startup);
|
||||
} else {
|
||||
SCPrintf(con, eError, "do not know how to make a %s object", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int RemoveObject(SConnection *con, SicsInterp *sics,
|
||||
void *data, int argc, char *argv[]) {
|
||||
CmdInitializer cmdin;
|
||||
CommandList *command;
|
||||
char *className;
|
||||
|
||||
if (argc != 2) {
|
||||
SCPrintf(con, eError, "%s has 1 argument", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
command = FindCommand(sics, argv[1]);
|
||||
if (!command) {
|
||||
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
className = ((pDummy)command->pData)->pDescriptor->name;
|
||||
cmdin = (CmdInitializer)GetInitializer("Object", className);
|
||||
if (cmdin) {
|
||||
/* if we have an initializer, we are allowed to remove */
|
||||
if (pServ->pExecutor && isInRunMode(pServ->pExecutor)) {
|
||||
SCPrintf(con, eError, "ERROR: cannot remove %s while running", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
SCPrintf(con, eValue, "remove %s", argv[1]);
|
||||
SCparChange(con);
|
||||
return RemoveCommand(sics, argv[1]);
|
||||
} else {
|
||||
SCPrintf(con, eError, "ERROR: %s is not removable", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void KillInitializers(void *data) {
|
||||
KillDummy(data);
|
||||
Item *item, *next;
|
||||
|
||||
item = list;
|
||||
while (item) {
|
||||
next = item->next;
|
||||
free(item);
|
||||
item = next;
|
||||
}
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly) {
|
||||
if (! FindCommand(pServ->pSics, "MakeObject")) {
|
||||
AddCommandWithFlag(pServ->pSics, "MakeObject", MakeObject, KillInitializers, NULL, 0);
|
||||
AddCommandWithFlag(pServ->pSics, "RemoveObject", RemoveObject, NULL, NULL, 0);
|
||||
}
|
||||
MakeInitializer("Object", driver, (Initializer)maker, startupOnly);
|
||||
}
|
33
initializer.h
Normal file
33
initializer.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
initializer.h
|
||||
|
||||
initializer list routines
|
||||
|
||||
Markus Zolliker, March 2005
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SICSINIT_H
|
||||
#define SICSINIT_H
|
||||
|
||||
typedef void (*Initializer)(void);
|
||||
|
||||
void MakeInitializer(const char *type, const char *name, Initializer maker, int startupOnly);
|
||||
|
||||
Initializer GetInitializer(const char *type, const char *name);
|
||||
|
||||
/*
|
||||
MakeObject has the following syntax:
|
||||
|
||||
MakeObject objectName driver [ args ... ]
|
||||
|
||||
*/
|
||||
typedef int (*CmdInitializer) (SConnection *pCon, int argc, char *argv[], int dynamic);
|
||||
/*
|
||||
make a driver with the initializer function maker
|
||||
when the dynamic argument is not 0, the command was created after startup,
|
||||
i.e. the SaveStatus routine has also to write command creation code.
|
||||
*/
|
||||
void MakeDriver(const char *driver, CmdInitializer maker, int startupOnly);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user