- modified and improved various env. drivers

- implemented string array object
This commit is contained in:
zolliker
2006-06-20 13:29:32 +00:00
parent 8b12033cb2
commit c1bbdb935e
19 changed files with 1495 additions and 499 deletions

281
arrobj.c Normal file
View File

@ -0,0 +1,281 @@
/*---------------------------------------------------------------------------
arrobj.c
a array object based on pardef
Markus Zolliker, Feb 2006
----------------------------------------------------------------------------
*/
#include <stdio.h>
#include "sics.h"
#include "splitter.h"
#include "pardef.h"
#include "initializer.h"
typedef struct ArrayItem {
struct ArrayItem *next;
char *name;
char *value;
char *unit;
} ArrayItem;
typedef struct {
ParData p;
ArrayItem *items, *freeItems;
char *saveFile;
} ArrayObj;
static ParClass arrayObjClass = { "array", sizeof(ArrayObj) };
typedef struct WrtObjContext {
FILE *file;
char filename[PATH_MAX];
} WrtObjContext;
/*-----------------------------------------------------------------------*/
int WrtObjOpen(WrtObjContext *ctx, char *fileName) {
int iret;
/* create a temporary file first */
iret = snprintf(ctx->filename, sizeof(ctx->filename), ".%s", fileName);
if (iret < 0 || iret >= sizeof(ctx->filename)) {
return 0;
}
remove(ctx->filename); /* remove already existing temporary file */
ctx->file = fopen(ctx->filename,"w");
return ctx->file != NULL;
}
/*-----------------------------------------------------------------------*/
void WrtObj(WrtObjContext *ctx, char *objectName) {
CommandList *pCom = NULL;
Dummy *pDum = NULL;
if (ctx) {
pCom = FindCommand(pServ->pSics, objectName);
if (pCom == NULL) {
return;
}
pDum = pCom->pData;
if (pDum != NULL) {
pDum->pDescriptor->SaveStatus(pCom->pData,pCom->pName,ctx->file);
}
}
}
/*-----------------------------------------------------------------------*/
void WrtObjClose(WrtObjContext *ctx) {
if (ctx) {
fclose(ctx->file);
rename(ctx->filename, ctx->filename+1);
}
}
/*----------------------------------------------------------------------------*/
static int ArrayExists(void *object, void *arg, int argc, char *argv[]) {
ArrayObj *arr = ParCast(&arrayObjClass, object);
ArrayItem *item;
assert(arr);
if (argc == 1) {
for (item = arr->items; item != NULL; item = item->next) {
if (strcasecmp(argv[0], item->name) == 0) {
ParPrintf(object, eValue, "1");
return 1;
}
}
}
ParPrintf(object, eValue, "0");
return 1;
}
/*----------------------------------------------------------------------------*/
static int ArrayItems(void *object, void *arg, int argc, char *argv[]) {
ArrayObj *arr = ParCast(&arrayObjClass, object);
ArrayItem *item;
int l;
char *result, *p;
assert(arr);
l = 1;
for (item = arr->items; item != NULL; item = item->next) {
l += strlen(item->name); l++;
}
result = calloc(l, 1);
if (result) {
p = result;
for (item = arr->items; item != NULL; item = item->next) {
strcpy(p, item->name); p+=strlen(item->name);
*p = ' '; p++;
}
if (p > result) p--;
*p='\0';
ParPrintf(object, eValue, result);
free(result);
}
return 1;
}
/*----------------------------------------------------------------------------*/
static int ArrayMakeItem(void *object, void *delete, int argc, char *argv[]) {
ArrayObj *arr = ParCast(&arrayObjClass, object);
ArrayItem *item, **last;
int iarg;
assert(arr);
if (argc < 1) goto Usage;
last = &arr->items;
for (item = arr->items; item != NULL; item = item->next) {
if (strcasecmp(argv[0], item->name) == 0) {
if (delete) {
*last = item->next; /* remove item from list */
item->next = arr->freeItems;
arr->freeItems = item;
return 1;
}
break;
}
last = &item->next;
}
if (delete) {
ParPrintf(object, eError, "ERROR: %s.%s not found", arr->p.name, argv[0]);
return 0;
}
if (item == NULL) {
if (arr->freeItems) {
item = arr->freeItems;
arr->freeItems = item->next;
if (item->name) {
free(item->name); item->name = NULL;
}
item->next = NULL;
*last = item;
} else {
item = calloc(1, sizeof(ArrayItem));
if (item == NULL) return 0;
*last = item;
item->next = NULL;
item->unit = NULL;
item->value = NULL;
}
}
if (item->unit) {
free(item->unit); item->unit=NULL;
}
if (item->value) {
free(item->value); item->value=NULL;
}
if (item->name != NULL) {
if (0 != strcmp(item->name, argv[0])) {
free(item->name);
item->name = strdup(argv[0]);
}
} else {
item->name = strdup(argv[0]);
}
iarg = 1;
if (iarg < argc) {
if (argv[iarg] && argv[iarg][0]) {
item->value = argv[iarg];
}
iarg++;
if (iarg < argc) {
if (argv[iarg] && argv[iarg][0]) {
item->unit = argv[iarg];
}
iarg++;
if (iarg < argc) goto Usage;
}
}
if (item->unit) item->unit = strdup(item->unit);
if (item->value) item->value = strdup(item->value);
ParInitPar(object, item->name);
SCparChange(SCLoad(&arr->p.conn));
return 1;
Usage:
ParPrintf(object, eError, "Usage: %s makeitem <name> [value] [unit]"
, arr->p.name);
return 0;
}
/*----------------------------------------------------------------------------*/
static void ArrayObjParDef(void *object) {
ArrayObj *arr = ParCast(&arrayObjClass, object);
FILE *saveFile;
ArrayItem *item, *next;
char *u;
WrtObjContext context;
static int doNotNest = 0;
int saveObjects;
saveFile = ParSaveFile();
if (!doNotNest && saveFile && arr->saveFile && *arr->saveFile) {
saveObjects = WrtObjOpen(&context, arr->saveFile);
} else {
saveObjects = 0;
}
for (item = arr->items; item != NULL; item = item->next) {
if (saveFile) {
if (item->unit) {
u = item->unit;
} else {
u = "";
}
fprintf(saveFile, " %s makeitem %s \"%s\" \"%s\"\n", arr->p.name, item->name, item->value, u);
if (saveObjects) {
WrtObj(&context, item->name);
}
}
ParName(item->name); ParAccess(usUser);
if (item->unit) {
ParTail(item->unit);
} else {
ParList(NULL);
}
ParStr(&item->value, "");
}
if (saveObjects) {
doNotNest = 1;
WrtObj(&context, arr->p.name);
doNotNest = 0;
WrtObjClose(&context);
}
ParName("makeitem"); ParAccess(usUser); ParCmd(ArrayMakeItem, NULL);
ParName("deleteitem"); ParAccess(usUser); ParCmd(ArrayMakeItem, "del");
ParName("exists"); ParAccess(usSpy); ParCmd(ArrayExists, NULL);
ParName("items"); ParAccess(usSpy); ParCmd(ArrayItems, NULL);
ParName("saveFile"); ParAccess(usUser); ParStr(&arr->saveFile, "");
ParStdDef();
if (ParActionIs(PAR_KILL)) {
for (item = arr->items; item != NULL; item = next) {
next = item->next;
if (item->name) free(item->name);
if (item->unit) free(item->unit);
if (item->value) free(item->value);
free(item);
}
for (item = arr->freeItems; item != NULL; item = next) {
next = item->next;
if (item->name) free(item->name);
if (item->unit) free(item->unit);
if (item->value) free(item->value);
free(item);
}
}
}
/*----------------------------------------------------------------------------*/
static int ArrayObjInit(SConnection *con, int argc, char *argv[], int dynamic) {
ArrayObj *arr = NULL;
char *creationCmd = NULL;
if (dynamic) {
creationCmd = Arg2Tcl(argc, argv, NULL, 0);
}
arr = ParMake(con, argv[1], &arrayObjClass, ArrayObjParDef, creationCmd);
arr->freeItems = NULL;
arr->items = NULL;
return arr != NULL;
}
/*----------------------------------------------------------------------------*/
void ArrayObjStartup(void) {
ParMakeClass(&arrayObjClass, NULL);
MakeDriver("array", ArrayObjInit, 0);
}