improvements:

- added is_running to driveable ease objects
- ighdriv.c: try <maxtry> times when status reply failes
- ipsdriv.c: fix trainedTo parameter
- reduced SEA version of SICS
This commit is contained in:
2021-09-16 12:35:06 +02:00
parent 21299efa80
commit f16d738b4a
10 changed files with 607 additions and 80 deletions

312
pardef.c
View File

@ -15,9 +15,12 @@ Markus Zolliker, March 2005
#include <limits.h>
#include <ctype.h>
#include "logger.h"
#include "logsetup.h"
#include "pardef.h"
#include "sugar.h"
#include "dynstring.h"
#include "sicshipadaba.h"
#include "ease.h"
#define ILLNUM -2
#define ILLARGC -3
@ -28,7 +31,10 @@ Markus Zolliker, March 2005
#define PARUNDEF -8
#define ERRCMD -9
typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP } ParOp;
Logger dummy_logger;
Logger *secop_logger = &dummy_logger; /* disable parlog, and do it with hdb logger */
typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP, UPD_OP } ParOp;
/* Context holds all the information needed during the pardef function */
typedef struct Context {
@ -58,6 +64,7 @@ typedef struct Context {
int exact;
char *callName; /* the called name of the object (different from obj->name in case of an alias) */
int enumText; /* show enum text */
hdbValue *hvalue;
} Context;
static char *loggerDir = NULL;
@ -293,6 +300,7 @@ static int ParSaveAll(void *object, char *name, FILE * fil)
ParDo(0, o, PAR_SAVE, NULL);
if (o->creationCmd) {
fprintf(fil, "%s endinit\n\n", name);
/* fprintf(fil, "put_secop_info %s\n\n", name); */
}
ctx->saveFile = NULL;
ret = ctx->returnValue;
@ -308,7 +316,15 @@ FILE *ParSaveFile(void)
}
return NULL;
}
/*--------------------------------------------------------------------------*/
void ParUpdateAll(void *object)
{
ParData *o = ParCheck(&parClass, object);
ParBegin();
ParDo(0, o, PAR_UPDATE, NULL);
ParEnd();
}
/*--------------------------------------------------------------------------*/
int ParLog(void *object)
{
@ -327,14 +343,16 @@ int ParLog(void *object)
ctx->now = time(NULL);
next = ctx->now - (o->logTime / o->period + 1) * o->period;
if (next < 0) {
ParEnd();
return 1;
}
showTime = 1;
ParDo(0, o, PAR_LOG, NULL);
o->logTime = ctx->now;
o->logPending = 0;
ParEnd();
if (!secop_logger) {
ParDo(0, o, PAR_LOG, NULL);
o->logTime = ctx->now;
o->logPending = 0;
ParEnd();
}
ParUpdateAll(o);
return 0;
}
@ -347,12 +365,15 @@ void ParLogForced(void *object)
ParBegin();
ctx->now = time(NULL);
showTime = 1;
ParDo(0, o, PAR_LOG, NULL);
o->logTime = ctx->now;
if (o->logPending) {
o->logPending = 2; /* tell ParLog that we are done already, but task is still pending */
if (!secop_logger) {
ParDo(0, o, PAR_LOG, NULL);
o->logTime = ctx->now;
if (o->logPending) {
o->logPending = 2; /* tell ParLog that we are done already, but task is still pending */
}
ParEnd();
}
ParEnd();
ParUpdateAll(o);
}
/*-------------------------------------------------------------------------*/
@ -474,7 +495,7 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
ParData *o = ParCheck(&parClass, object);
char *setArgv[2];
ParInfo *info;
/* debugging
int i;
printf("ParExecute");
@ -519,29 +540,27 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
SCSendOK(con);
ctx->returnValue = 1;
}
} else
if ((0 == strcasecmp(argv[1], "log")
} else if ((0 == strcasecmp(argv[1], "log")
|| 0 == strcasecmp(argv[1], "unlog"))) {
if (argc < 3) {
ctx->returnValue = ILLARGC;
ctx->thisPar = argv[1];
} else {
} else if (!secop_logger) {
ctx->argc = argc - 3;
ctx->argv = argv + 3;
ctx->doit = toupper(argv[1][0]) != 'U';
ctx->exact = 0;
ParDo(con, o, PAR_LOGSWITCH, argv[2]);
}
} else
if ((0 == strcasecmp(argv[1], "save")
} else if ((0 == strcasecmp(argv[1], "save")
|| 0 == strcasecmp(argv[1], "unsave"))) {
if (argc != 3) {
ctx->returnValue = ILLARGC;
} else {
} else if (!secop_logger) {
ctx->doit = toupper(argv[1][0]) != 'U';
ParDo(con, o, PAR_SAVESWITCH, argv[2]);
SCparChange(con);
}
SCparChange(con);
} else if (strcmp(argv[1], "interest") == 0) {
if (!o->pCall) {
o->pCall = CreateCallBackInterface();
@ -620,7 +639,7 @@ static int ParExecute(SConnection * con, SicsInterp * sics, void *object,
/*----------------------------------------------------------------------------*/
static void KillLogger(ParInfo * par)
{
if (par->log != NULL) {
if (par->log != NULL && par->log != secop_logger) {
LoggerKill(par->log);
if (par->sugarStatus == 1) {
RemoveCommand(pServ->pSics, LoggerName(par->log));
@ -651,9 +670,11 @@ int ParSwitchLog(int on, char *name)
loggerDir = "./";
LoggerSetDir(loggerDir);
}
ctx->par->log = LoggerMake(name, ctx->obj->period, ctx->exact);
if (ctx->par->log == NULL) {
return BADLOG;
if (!secop_logger) {
ctx->par->log = LoggerMake(name, ctx->obj->period, ctx->exact);
if (ctx->par->log == NULL) {
return BADLOG;
}
}
if (ctx->par->sugarStatus == 0 && name != buf
&& strcmp(name, buf) != 0) {
@ -704,6 +725,7 @@ void ParFind(void)
p->saveIt = 0;
p->saveLog = 0;
p->state = PAR_ALWAYS_READY;
p->node = NULL;
p->next = *last;
*last = p;
}
@ -773,6 +795,7 @@ void ParName(char *name)
switch (ctx->act) {
case PAR_SHOW:
case PAR_SET:
case PAR_HDBSET:
ctx->enumList = NULL;
if (0 == strcasecmp(name, ctx->thisPar)) {
ctx->access = -1;
@ -813,6 +836,9 @@ void ParName(char *name)
ctx->action = PAR_NOOP;
}
return;
case PAR_UPDATE:
ctx->doit = 0; /* affects visibility */
break;
case PAR_SAVE:
case PAR_KILL:
case PAR_NOOP:
@ -922,8 +948,12 @@ ParOp ParWhat(int numeric)
} else {
lname = NULL;
}
ParSwitchLog(1, lname);
LoggerSetNumeric(ctx->par->log, numeric);
if (secop_logger) {
ctx->par->log = secop_logger;
} else {
ParSwitchLog(1, lname);
LoggerSetNumeric(ctx->par->log, numeric);
}
}
}
return INIT_OP;
@ -934,6 +964,7 @@ ParOp ParWhat(int numeric)
}
ctx->returnValue = 1;
return FMT_OP;
case PAR_HDBSET:
case PAR_SET:
if (ctx->returnValue) {
ctx->returnValue = AMBIGUOS;
@ -971,6 +1002,8 @@ ParOp ParWhat(int numeric)
break;
}
return GET_OP;
case PAR_UPDATE:
return UPD_OP;
default:
return NO_OP;
}
@ -1078,6 +1111,7 @@ void ParOut(char *buf)
ParPrintf(NULL, eValue, "%s%s%s = %s", ctx->callName,
p, ctx->parName, buf);
break;
case PAR_HDBSET:
case PAR_SET:
if (ctx->parName[0]) {
p = " ";
@ -1178,6 +1212,8 @@ void ParList(char *group)
} else if (ctx->doit < 0) {
ctx->doit = 0;
}
} else if (ctx->action == PAR_UPDATE) {
ctx->doit = group == NULL || group[0] != '\0';
}
}
@ -1186,6 +1222,8 @@ void ParTail(char *tail)
{
if (ctx->action == PAR_LIST) {
ctx->listTail = tail;
} else if (ctx->action == PAR_UPDATE) {
ctx->doit = 1; /* always visible */
}
}
@ -1215,6 +1253,117 @@ void ParHasChanged(void)
}
}
}
/*----------------------------------------------------------------------------*/
static hdbCallbackReturn ParUpdateCB(pHdb node, void *userData, pHdbMessage msg) {
hdbDataMessage *setMsg;
if ((setMsg = GetHdbSetMessage(msg))){
ParBegin();
ctx->hvalue = setMsg->v;
ParDo(NULL, userData, PAR_HDBSET, node->name);
ParEnd();
}
return hdbContinue;
}
/*----------------------------------------------------------------------------*/
void ParUpdateNode(hdbValue value) {
pHdb node;
char sicscommand[128];
char path[128];
char secop_id[128];
int skip_unchanged = 1;
if (!ctx->obj->node) {
ctx->obj->secop_module = ctx->obj->name;
if (ctx->parName[0]) {
/* main node is not yet created -> assume it is of type NONE */
node = MakeHipadabaNode(ctx->obj->name, HIPNONE, 0);
if (ctx->obj->secop_module) {
SetHdbProperty(node, "secop_module", ctx->obj->secop_module);
}
} else {
node = MakeSICSHdbPar(ctx->obj->name, ctx->access, value);
if (ctx->par->log && ctx->obj->secop_module) {
snprintf(secop_id, sizeof secop_id, "%s:value", ctx->obj->secop_module);
SetHdbProperty(node, "secop_id", secop_id);
snprintf(path, sizeof path, "/%s", ctx->obj->name);
LogMakeInternal(node, path, 0); /* secop_module */
skip_unchanged = 0;
}
}
ctx->obj->node = node;
AddHipadabaChild(GetHipadabaRoot(), node, NULL);
SetHdbProperty(node, "sicscommand", ctx->obj->name);
SetHdbProperty(node, "group", "_pardef_");
}
node = ctx->par->node;
if (node == NULL) { /* node is not yet set */
if (ctx->parName[0]) {
if (strchr(ctx->parName, '/') != NULL) {
return; /* do not allow parameter names containing '/' */
}
node = AddSICSHdbPar(ctx->obj->node, ctx->parName, ctx->access, value);
if (ctx->par->log && ctx->obj->secop_module) {
snprintf(secop_id, sizeof secop_id, "%s:%s", ctx->obj->secop_module, ctx->parName);
SetHdbProperty(node, "secop_id", secop_id);
snprintf(path, sizeof path, "/%s/%s", ctx->obj->name, ctx->parName);
LogMakeInternal(node, path, 0);
skip_unchanged = 0;
}
ctx->par->node = node;
snprintf(sicscommand, sizeof sicscommand, "%s %s", ctx->obj->name, ctx->parName);
} else {
/* bare object (parameter "") */
node = ctx->obj->node;
snprintf(sicscommand, sizeof sicscommand, "%s = ", ctx->obj->name);
}
SetHdbProperty(node, "sicscommand", sicscommand);
AppendHipadabaCallback(node, MakeHipadabaCallback(ParUpdateCB, ctx->obj, NULL));
}
if (ctx->action == PAR_UPDATE) {
char *visible = GetHdbProp(node, "visible");
if (ctx->doit) {
if (visible) {
SetHdbProperty(node, "visible", NULL);
}
} else {
if (!visible || strcasecmp(visible, "false") != 0) {
SetHdbProperty(node, "visible", "false");
}
}
switch (value.dataType) {
case HIPFLOAT:
if (value.v.doubleValue == PAR_NAN) {
if (GetHdbProp(node, "geterror") == NULL) {
SetHdbProperty(node, "geterror", "undefined");
value.v.doubleValue = 0;
UpdateHipadabaPar(node, value, ctx->con);
}
return;
}
if (skip_unchanged && node->value.v.doubleValue == value.v.doubleValue) return;
break;
case HIPINT:
if (value.v.intValue == PAR_LNAN) {
if (GetHdbProp(node, "geterror") == NULL) {
SetHdbProperty(node, "geterror", "undefined");
value.v.intValue = 0;
UpdateHipadabaPar(node, value, ctx->con);
}
return;
}
if (skip_unchanged && node->value.v.intValue == value.v.intValue) return;
break;
case HIPTEXT:
if (strcmp(node->value.v.text, value.v.text) == 0) return;
break;
default:
return;
}
}
SetHdbProperty(node, "geterror", NULL);
UpdateHipadabaPar(node, value, ctx->con);
}
/*----------------------------------------------------------------------------*/
void ParFloat(float *value, float defValue)
@ -1225,6 +1374,10 @@ void ParFloat(float *value, float defValue)
switch (ParWhat(1)) {
case SET_OP:
if (ctx->action == PAR_HDBSET) {
*value = ctx->hvalue->v.doubleValue;
break;
}
if (ctx->argc > 1) {
ctx->returnValue = ILLARGC;
return;
@ -1262,6 +1415,10 @@ void ParFloat(float *value, float defValue)
break;
case INIT_OP:
*value = defValue;
ParUpdateNode(MakeHdbFloat(*value));
break;
case UPD_OP:
ParUpdateNode(MakeHdbFloat(*value));
break;
case NO_OP:
break;
@ -1277,6 +1434,10 @@ void ParInt(int *value, int defValue)
switch (ParWhat(1)) {
case SET_OP:
if (ctx->action == PAR_HDBSET) {
*value = ctx->hvalue->v.intValue;
break;
}
if (ctx->argc > 1) {
ctx->returnValue = ILLARGC;
return;
@ -1309,6 +1470,10 @@ void ParInt(int *value, int defValue)
break;
case INIT_OP:
*value = defValue;
ParUpdateNode(MakeHdbInt(defValue));
break;
case UPD_OP:
ParUpdateNode(MakeHdbInt(*value));
break;
default:
break;
@ -1319,11 +1484,17 @@ void ParInt(int *value, int defValue)
void ParStr(char **value, char *defValue)
{
static char *empty = "";
char *to_free;
switch (ParWhat(0)) {
case SET_OP:
if (*value != NULL)
free(*value);
to_free = *value;
if (ctx->action == PAR_HDBSET) {
if (to_free) free(to_free);
*value = strdup(ctx->hvalue->v.text);
break;
}
if (to_free) free(to_free);
if (ctx->argc > 0 && strcmp(ctx->argv[0], "=") == 0) {
*value = ParArg2Str(ctx->argc - 1, ctx->argv + 1, NULL, 0);
} else {
@ -1332,14 +1503,26 @@ void ParStr(char **value, char *defValue)
ParHasChanged();
/* fall through */
case FMT_OP:
if (*value == NULL)
value = &empty;
ParOut(*value);
if (*value == NULL) {
ParOut(empty);
} else {
ParOut(*value);
}
break;
case INIT_OP:
ctx->exact = 1;
if (defValue != NULL) {
if (defValue == NULL) {
ParUpdateNode(MakeHdbText(""));
} else{
*value = strdup(defValue);
ParUpdateNode(MakeHdbText(*value));
}
break;
case UPD_OP:
if (*value == NULL) {
ParUpdateNode(MakeHdbText(""));
} else {
ParUpdateNode(MakeHdbText(*value));
}
break;
default:
@ -1357,6 +1540,10 @@ void ParFixedStr(char *value, int maxsize, char *defValue)
switch (ParWhat(0)) {
case SET_OP:
if (ctx->action == PAR_HDBSET) {
snprintf(value, maxsize, "%s", ctx->hvalue->v.text);
break;
}
ParArg2Str(ctx->argc, ctx->argv, value, maxsize);
ParHasChanged();
/* fall through */
@ -1367,10 +1554,16 @@ void ParFixedStr(char *value, int maxsize, char *defValue)
break;
case INIT_OP:
ctx->exact = 1;
if (defValue != NULL) {
if (defValue == NULL) {
ParUpdateNode(MakeHdbText(""));
} else{
snprintf(value, maxsize, "%s", defValue);
ParUpdateNode(MakeHdbText(value));
}
break;
case UPD_OP:
ParUpdateNode(MakeHdbText(value));
break;
default:
break;
}
@ -1464,6 +1657,36 @@ void ParGetFloat(SConnection * con, void *object, char *name, float *value)
ParEnd();
}
/*----------------------------------------------------------------------------*/
void ParKillThisPar(ParInfo *p)
{
p->next = NULL;
if (p->node) {
RemoveSICSPar(p->node, NULL);
}
KillLogger(p);
if (p->name) {
free(p->name);
}
free(p);
}
/*----------------------------------------------------------------------------*/
void ParKillPar(void *object, char *name)
{
ParData *o = object;
ParInfo *p, **last;
last = &o->infoList;
for (p=o->infoList; p!=NULL; last=&p->next, p=p->next) {
if (strcasecmp(name, p->name) == 0) {
*last = p->next;
ParKillThisPar(p);
return;
}
}
}
/*----------------------------------------------------------------------------*/
void ParKill(void *object)
{
@ -1485,14 +1708,13 @@ void ParKill(void *object)
p = o->infoList;
while (p) {
q = p->next;
p->next = NULL;
KillLogger(p);
if (p->name) {
free(p->name);
}
free(p);
ParKillThisPar(p);
p = q;
}
if (o->node) {
RemoveSICSPar(o->node, NULL); /* this deletes also all children */
o->node = NULL;
}
if (o->logPending) { /* will be free in scheduled ParLog function */
o->desc = NULL;
} else {
@ -1510,15 +1732,22 @@ void ParKill(void *object)
}
/*----------------------------------------------------------------------------*/
void ParInitPar(void *object, char *name)
void ParInitPar(void *object, char *name, int logged)
{
ParBegin();
ctx->obj = object;
ctx->parName = name;
ctx->par = NULL;
ParFind();
ParSwitchLog(1, NULL);
if (logged) {
if (secop_logger) {
if (ctx->par) {
ctx->par->log = secop_logger;
}
} else {
ParSwitchLog(1, NULL);
}
}
ParEnd();
}
@ -1558,6 +1787,7 @@ void *ParMake(SConnection * con, char *name, ParClass * class,
o->verbose = 0;
o->logPending = 0;
o->conn = NULL;
o->node = NULL;
ParSaveConn(o, con);
o->pardef = pardef;
ParBegin();