Files
sics/initializer.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
2015-04-23 20:49:26 +10:00

312 lines
8.1 KiB
C

/*---------------------------------------------------------------------------
initializer.c
initializer routines
Markus Zolliker, March 2005
----------------------------------------------------------------------------
*/
#include "sics.h"
#include "initializer.h"
#include "splitter.h"
typedef struct Item {
struct Item *next;
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;
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 && !ServerIsStarting(pServ)) {
/* 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;
}
}
}
for (p = list; p != NULL; p = p->next) {
if (strcasecmp(p->name, name) == 0 && strcasecmp(p->type, type) == 0) {
return p->maker;
}
}
return NULL;
}
static int MakeObject(SConnection * con, SicsInterp * sics,
void *data, int argc, char *argv[])
{
CmdInitializer cmdin;
if (argc < 3) {
SCPrintf(con, eError, "ERROR: should be: %s <object> <type> ...",
argv[0]);
return 0;
}
/* missing check for user (manager?) privilege */
cmdin = (CmdInitializer) GetInitializer("Object", argv[2]);
if (cmdin) {
return cmdin(con, argc, argv, strcasecmp(argv[0], "makeobject") == 0);
} 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, eValue, "%s %s %s", p->type, p->name, p->desc);
} else if (strcasecmp(argv[2], p->type) == 0) {
SCPrintf(con, eValue, "%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;
ObjectDescriptor *desc;
char *className;
char shortClassName[32];
char *p;
int removeAllowed;
char *creationCommand;
if (argc != 2) {
SCPrintf(con, eError, "ERROR: should be: %s <object>", argv[0]);
return 0;
}
/* missing check for user (manager?) privilege */
desc = FindCommandDescriptor(sics, argv[1]);
if (!desc) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
creationCommand = GetDescriptorKey(desc, "creationCommand");
if (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 = desc->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",
(int)(p - className), className);
cmdin = (CmdInitializer) GetInitializer("Object", shortClassName);
}
}
removeAllowed = (cmdin != NULL);
}
if (removeAllowed) {
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;
}
}
typedef struct {
int printHeader;
FILE *fil;
} SaveData;
static int SaveCreationCommand(char *name, pDummy object, void *userData)
{
SaveData *saveData = userData;
char *creationCommand;
creationCommand =
GetDescriptorKey(object->pDescriptor, "creationCommand");
if (creationCommand && strcmp(creationCommand, "0") != 0) {
if (saveData->printHeader == 0) {
saveData->printHeader = 1;
fprintf(saveData->fil, "\n#--- BEGIN creation commands\n");
}
fprintf(saveData->fil, "%s\n", creationCommand);
}
return 1;
}
static int SaveCreationCommands(void *object, char *name, FILE * fil)
{
SaveData saveData;
saveData.fil = fil;
saveData.printHeader = 0;
ForEachCommand(SaveCreationCommand, &saveData);
if (saveData.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;
char *className;
char shortClassName[32];
char *p;
int removeAllowed;
ObjectDescriptor *desc;
char *creationCommand;
char buf[256];
if (argc < 2) {
SCPrintf(con, eError,
"ERROR: should be: %s <object> [<creation command>]",
argv[0]);
return 0;
}
desc = FindCommandDescriptor(sics, argv[1]);
if (!desc) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
creationCommand = GetDescriptorKey(desc, "creationCommand");
if (argc < 3) {
if (creationCommand != NULL) {
SCPrintf(con, eValue, "%s", creationCommand);
} else {
SCPrintf(con, eValue, "<static object>");
}
} else {
if (!creationCommand) {
SCPrintf(con, eValue, "ERROR: %s is a static object", argv[1]);
return 0;
}
creationCommand = Arg2Tcl(argc - 2, argv + 2, buf, sizeof buf);
if (creationCommand) {
SetDescriptorKey(desc, "creationCommand", creationCommand);
if (creationCommand != buf)
free(creationCommand);
} else {
SetDescriptorKey(desc, "creationCommand", "0");
}
}
return 1;
}
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)
{
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);
}