/*--------------------------------------------------------------------------- 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); }