Files
sics/initializer.c
2006-08-17 15:37:32 +00:00

181 lines
4.5 KiB
C

/*---------------------------------------------------------------------------
initializer.c
initializer routines
Markus Zolliker, March 2005
----------------------------------------------------------------------------
*/
#include "sics.h"
#include "initializer.h"
typedef struct Item {
struct Item *next;
char *type;
char *name;
char *desc;
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, const char *desc) {
Item *item;
item = calloc(1, sizeof *item);
assert(item);
item->maker = maker;
item->next = list;
item->type = strdup(type);
item->name = strdup(name);
item->desc = strdup(desc);
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 DriverList(SConnection *con, SicsInterp *sics,
void *data, int argc, char *argv[]) {
Item *p;
char *name, *type;
if (argc < 2 || strcasecmp(argv[1], "list") == 0) {
for (p = list; p != NULL; p = p->next) {
if (argc < 3) {
SCPrintf(con, eStatus, "%s %s %s", p->type, p->name, p->desc);
} else if (strcasecmp(argv[2], p->type) == 0) {
SCPrintf(con, eStatus, "%s %s", p->name, p->desc);
}
}
} else {
if (argc == 2) {
name = argv[1];
type = "Object";
} else {
name = argv[2];
type = argv[1];
}
p = list;
while (p != NULL && (strcasecmp(p->type, type) != 0 || strcasecmp(p->name, name) != 0)) {
p = p->next;
}
if (p) {
SCPrintf(con, eValue, "%s", p->desc);
} else {
SCPrintf(con, eValue, "notfound");
}
}
return 1;
}
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 needs 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;
if (item->name) free(item->name);
if (item->type) free(item->type);
if (item->desc) free(item->desc);
free(item);
item = next;
}
list = NULL;
}
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, "RemoveObject", RemoveObject, NULL, NULL, 0);
AddCommandWithFlag(pServ->pSics, "DriverList", DriverList, NULL, NULL, 0);
}
MakeInitializer("Object", driver, (Initializer)maker, startupOnly, desc);
}