- added FindCommandDescriptor to SCinter.*

- modified support for dynamic objects
- improved logger system
- various fixes
This commit is contained in:
zolliker
2008-03-03 14:49:15 +00:00
parent 33c0b7dcaa
commit a529bda307
13 changed files with 337 additions and 285 deletions

View File

@ -976,6 +976,11 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
if(!pCom->pData)
return NULL;
if (cclass == NULL)
{
return pCom->pData;
}
pDum = (pDummy)pCom->pData;
if(strcmp(pDum->pDescriptor->name,cclass) == 0)
{
@ -983,6 +988,19 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
}
return NULL;
}
/*---------------------------------------------------------------------------*/
pObjectDescriptor FindCommandDescriptor(SicsInterp *pSics, char *name)
{
CommandList *pCom;
pCom = FindCommand(pSics,name);
if(pCom == NULL || pCom->pData == NULL)
{
return NULL;
}
return ((pDummy)pCom->pData)->pDescriptor;
}
/*------------------------------------------------------------------------*/
void *FindDrivable(SicsInterp *pSics, char *name){
pIDrivable pDriv;

View File

@ -143,10 +143,16 @@ typedef struct __SINTER
/*-------------------------------------------------------------------------
FindCommandData finds a command with the name given. It tests the name in the
ObjectDescriptor to be of name class. If all this succeeds a pointer
to the commands data structure is retuned. Else NULL
to the commands data structure is retuned. Else NULL.
Do not test the Object Descriptor name when comclass == NULL.
*/
void *FindCommandData(SicsInterp *pSics, char *name, char *comclass);
/*-------------------------------------------------------------------------
FindCommandDescriptor finds the descriptor of a command with the name given.
*/
pObjectDescriptor FindCommandDescriptor(SicsInterp *pSics, char *name);
/*------------------------------------------------------------------------
FindDrivable tries to find Drivable object by the name given. Returns a
pointer to the drivable interface in the case of success, NULL in

View File

@ -121,29 +121,31 @@ static int DriverList(SConnection *con, SicsInterp *sics,
static int RemoveObject(SConnection *con, SicsInterp *sics,
void *data, int argc, char *argv[]) {
CmdInitializer cmdin;
CommandList *command;
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;
}
command = FindCommand(sics, argv[1]);
if (!command) {
desc = FindCommandDescriptor(sics, argv[1]);
if (!desc) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
if (((pDummy)command->pData)->pDescriptor->creationCommand != NULL) {
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 = ((pDummy)command->pData)->pDescriptor->name;
className = desc->name;
cmdin = (CmdInitializer)GetInitializer("Object", className);
if (cmdin == 0) {
/* allow also a longer descriptor starting with the initializer name and a blank */
@ -169,22 +171,33 @@ static int RemoveObject(SConnection *con, SicsInterp *sics,
}
}
static int SaveCreationCommands(void *object, char *name, FILE *fil) {
CommandList *p;
ObjectDescriptor *desc;
int printHeader = 0;
typedef struct {
int printHeader;
FILE *fil;
} SaveData;
static int SaveCreationCommand(char *name, pDummy object, void *userData) {
SaveData *saveData = userData;
char *creationCommand;
for (p = pServ->pSics->pCList; p != NULL; p = p->pNext) {
desc = ((pDummy)p->pData)->pDescriptor;
if (desc->creationCommand && strcmp(desc->creationCommand, "0") != 0) {
if (printHeader == 0) {
printHeader = 1;
fprintf(fil, "\n#--- BEGIN creation commands\n");
}
fprintf(fil, "%s\n", desc->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);
}
if (printHeader == 1) {
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;
@ -193,37 +206,43 @@ static int SaveCreationCommands(void *object, char *name, FILE *fil) {
static int CreationCommand(SConnection *con, SicsInterp *sics,
void *data, int argc, char *argv[]) {
CmdInitializer cmdin;
CommandList *command;
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;
}
command = FindCommand(sics, argv[1]);
if (!command) {
desc = FindCommandDescriptor(sics, argv[1]);
if (!desc) {
SCPrintf(con, eError, "ERROR: %s not found", argv[1]);
return 0;
}
desc = ((pDummy)command->pData)->pDescriptor;
creationCommand = GetDescriptorKey(desc, "creationCommand");
if (argc < 3) {
if (desc->creationCommand != NULL) {
SCPrintf(con, eValue, "%s", desc->creationCommand);
if (creationCommand != NULL) {
SCPrintf(con, eValue, "%s", creationCommand);
} else {
SCPrintf(con, eValue, "<static object>");
}
} else {
if (! desc->creationCommand) {
if (!creationCommand) {
SCPrintf(con, eValue, "ERROR: %s is a static object", argv[1]);
return 0;
}
free(desc->creationCommand);
desc->creationCommand = Arg2Tcl(argc - 2, argv + 2, NULL, -1);
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;
}

198
logger.c
View File

@ -20,21 +20,16 @@ struct Logger {
char *old;
int oldsize;
int period;
time_t last;
int lastLn; /* 0 or the number chars counted from the second
last newline character. */
int overwrite; /* overwrite last line when value has not changed */
time_t last, lastWrite;
int numeric;
int exact;
double oldFloat, newFloat;
time_t newTime;
Logger *next;
};
static char *dir = NULL;
static Logger *list;
static time_t lastLife = 0;
static time_t lastWritten = 0;
/*--------------------------------------------------------------------------*/
char *LoggerName(Logger *log) {
return log->name;
@ -60,45 +55,55 @@ Logger *LoggerFind(const char *name) {
/*--------------------------------------------------------------------------*/
#define LASTLOGTXT "#last logging entry at:\n"
void LoggerSetDir(char *dirarg) {
time_t LoggerGetLastLife(char *dirarg) {
char path[256], line[32];
FILE *fil;
dir = dirarg;
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
time_t t = 0;
if (dirarg == NULL) {
return lastWritten;
}
snprintf(path, sizeof path, "%s/lastlife.dat", dirarg);
fil = fopen(path, "r");
if (fil) {
fgets(line, sizeof line, fil);
if (strcmp(line, LASTLOGTXT) == 0) {
fgets(line, sizeof line, fil);
lastLife = atol(line);
if (lastLife < 1000000000) {
printf("bad lastLife %ld\n", (long)lastLife);
t = atol(line);
if (t < 1000000000) {
printf("bad lastLife %ld\n", (long)t);
}
}
fclose(fil);
} else {
printf("can not read %s\n", path);
}
return t;
}
/*--------------------------------------------------------------------------*/
time_t LoggerSetDir(char *dirarg) {
dir = dirarg;
lastLife = LoggerGetLastLife(dir);
return lastLife;
}
/*--------------------------------------------------------------------------*/
char *LoggerGetDir(void) {
char path[256];
FILE *fil;
time_t now;
static time_t last;
now = time(NULL);
if (now != last) {
lastWritten = time(NULL);
if (lastWritten != last) { /* do not write more than once per second */
snprintf(path, sizeof path, "%s/lastlife.dat", dir);
fil = fopen(path, "w");
if (fil) {
fprintf(fil, "%s%ld\n", LASTLOGTXT, (long)now);
fprintf(fil, "%s%ld\n", LASTLOGTXT, (long)lastWritten);
fclose(fil);
} else {
printf("can not write %s\n", path);
}
last = now;
last = lastWritten;
}
return dir;
}
@ -122,123 +127,80 @@ int LoggerVarPath(char *dir, char *path, int pathLen, char *name) {
}
/*--------------------------------------------------------------------------*/
int LoggerWrite0(Logger *log, time_t now, int period, char *value) {
char path[256], stim[32], buf[32], chr;
struct tm *tm;
int yday;
int isdst;
int l, ext, skip, changed;
char path[256], stim[32], buf[32];
struct tm tm, lasttm;
int l, ext, writeInfo;
FILE *fil;
long endPos, pos1, p;
char info[80];
time_t beforenow;
LoggerGetDir();
if (dir == NULL) return 0;
if (now == 0) {
printf("now==0\n");
}
tm = localtime(&log->last);
isdst = tm->tm_isdst; /* last isdst */
yday = tm->tm_yday; /* last day */
tm = localtime(&now);
if (tm->tm_yday != yday) {
log->period = -1;
}
lasttm = *localtime(&log->last);
tm = *localtime(&now);
l = LoggerVarPath(dir, path, sizeof path, log->name);
strftime(path + l, sizeof path - l, "%m-%d.log", tm);
strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S", tm);
strftime(path + l, sizeof path - l, "%m-%d.log", &tm);
strftime(stim, sizeof stim, "#%Y-%m-%d %H:%M:%S", &tm);
fil = fopen(path, "r+");
skip = 0;
if (period <= 0) period = 1;
if (fil == NULL) { /* create new file */
fil = fopen(path, "w+");
if (fil == NULL) return 0;
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm->tm_isdst, period, log->exact);
log->period = period;
isdst = tm->tm_isdst;
endPos = ftell(fil);
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else { /* check if file is from today */
fgets(buf, sizeof buf, fil);
if (0 != strncmp(buf, stim, 11)) {
fclose(fil);
fil=fopen(path, "w+"); /* overwrite old logfile */
writeInfo = (tm.tm_isdst != lasttm.tm_isdst ||
tm.tm_yday != lasttm.tm_yday ||
(period != log->period && log->numeric));
if (strcmp(value, log->old) != 0 || writeInfo) {
fil = fopen(path, "r+");
if (fil == NULL) { /* create new file */
fil = fopen(path, "w+");
if (fil == NULL) return 0;
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm->tm_isdst, period, log->exact);
log->period = period;
isdst = tm->tm_isdst;
endPos = ftell(fil);
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else {
fseek(fil, -log->lastLn, SEEK_END); /* set position to last line */
endPos = ftell(fil) + log->lastLn;
if (endPos > 0 && log->lastLn == 0) {
/* find last newline in newly opened file */
fseek(fil, -1, SEEK_CUR);
chr = fgetc(fil);
while (chr != '\n' && ftell(fil) >= 2) {
fseek(fil, -2, SEEK_CUR);
chr = fgetc(fil);
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm.tm_isdst, period, log->exact);
} else { /* check if file is from today */
fgets(buf, sizeof buf, fil);
if (0 != strncmp(buf, stim, 11)) {
fclose(fil); /* it was file from an earlier year */
fil=fopen(path, "w+"); /* overwrite old logfile */
if (fil == NULL) return 0;
fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm.tm_isdst, period, log->exact);
} else {
fseek(fil, 0, SEEK_END); /* set position to end */
if (writeInfo) {
fprintf(fil, "#isdst %d period %d exact %d\n", tm.tm_isdst, period, log->exact);
}
if (log->lastWrite != 0 && now >= log->lastWrite + 2 * period) {
/* this is only useful for direct access of the log files */
beforenow = now - period;
lasttm = *localtime(&beforenow);
if (lasttm.tm_yday == tm.tm_yday) {
strftime(stim, sizeof stim,"%H:%M:%S", &lasttm);
} else {
snprintf(stim, sizeof stim, "00:00:00");
}
fprintf(fil, "%s\t%s\n", stim, log->old);
}
fseek(fil, -1, SEEK_CUR); /* position to newline */
} else if (now != log->last) {
skip = 1;
}
}
strftime(stim, sizeof stim,"%H:%M:%S", &tm);
fprintf(fil, "%s\t%s\n", stim, value);
log->lastWrite = now;
fclose(fil);
}
changed = (0 != strcmp(value, log->old));
info[0]='\0';
if (period != log->period) {
log->period = period;
if (log->numeric) {
changed = 1;
snprintf(info, sizeof info, "period %d exact %d ", period, log->exact);
}
}
if (log->overwrite && !changed) {
skip = 0;
}
/* go to next newline */
chr = fgetc(fil);
while (chr != EOF) {
if (chr == '\n') {
skip--;
if (skip < 0) break;
}
chr = fgetc(fil);
}
if (chr == EOF) {
fputs("\n#no newline found\n", fil);
}
if (tm->tm_isdst != isdst || info[0] != '\0') {
fprintf(fil, "#isdst %d %s\n", tm->tm_isdst, info);
}
pos1 = ftell(fil);
strftime(stim, sizeof stim,"%H:%M:%S", tm);
fprintf(fil, "%s\t%s\n", stim, value);
for (p = ftell(fil); p < endPos; p++) { /* overwrite dirt after last line */
fprintf(fil, " ");
}
endPos = ftell(fil);
fclose(fil);
log->lastLn = (endPos - pos1) + 1;
/* overwrite next time when value has not changed */
log->overwrite = ! changed;
log->period = period;
l = strlen(value);
if (l >= log->oldsize) {
if (l >= log->oldsize) { /* increase log->old size, optimized for linux/i386 */
ext = ((l - log->oldsize)/16 + 1) * 16;
if (ext < log->oldsize / 4) ext += (log->oldsize / 64) * 16;
log->oldsize += ext;
free(log->old);
log->old = calloc(1, log->oldsize);
assert(log->old);
assert(l < log->oldsize);
}
assert(log->old);
assert(l < log->oldsize);
strcpy(log->old, value);
log->old[l] = '\0';
assert(log->old[l] == '\0');
log->last = now;
return 1;
}
@ -263,6 +225,7 @@ int LoggerWrite(Logger *log, time_t now, int period, char *value) {
yday = tm->tm_yday;
/* -- debug logging if dir/debug exists */
l = LoggerVarPath(dir, path, sizeof path, "debug");
strftime(path + l, sizeof path - l, "%m-%d.log", tm);
fil=fopen(path, "a");
@ -274,15 +237,16 @@ int LoggerWrite(Logger *log, time_t now, int period, char *value) {
/* log old values (forced midnight log) */
p = list;
while (p != NULL) {
if (fil) {
if (fil) { /* debug logging */
strftime(tim, sizeof tim, "last %m-%d %H:%M:%S, ", localtime(&p->last));
fputs(tim, fil);
fprintf(fil, "period %d, name %s, old %s\n", p->period, p->name, p->old);
}
if (p->last < h0 && p->last != 0 &&
p->period >= 0 && p->old[0] != '\0') {
LoggerWrite0(p, h0, p->period, p->old);
p->overwrite = 0;
}
p = p->next;
}
@ -302,6 +266,10 @@ int LoggerPeriod(Logger *log) {
return log->period;
}
/*--------------------------------------------------------------------------*/
void LoggerSetPeriod(Logger *log, int period) {
LoggerWrite0(log, time(NULL), period, log->old);
}
/*--------------------------------------------------------------------------*/
void LoggerKill(Logger *log) {
/* we do not really free the logger, it might be reused
for the same variable later. We set the value to undefined */
@ -344,7 +312,7 @@ Logger *LoggerMake(char *name, int period, int exact) {
log->old = calloc(1,12);
log->oldsize = 12;
log->last = 0;
log->lastLn = 0;
log->lastWrite = 0;
log->numeric = 1;
log->next = list;
list = log;

View File

@ -17,10 +17,12 @@ void LoggerKill(Logger *log);
int LoggerWrite(Logger *log, time_t now, int period, char *value);
char *LoggerName(Logger *log);
void LoggerSetNumeric(Logger *log, int numeric);
void LoggerSetDir(char *dirarg);
time_t LoggerSetDir(char *dirarg);
time_t LoggerGetLastLife(char *dirarg);
void LoggerWriteOld(Logger *log, time_t now);
time_t LoggerLastTime(Logger *log);
int LoggerPeriod(Logger *log);
void LoggerSetPeriod(Logger *log, int period);
int LoggerVarPath(char *dir, char *path, int pathLen, char *name);
void LoggerFreeAll(void);

View File

@ -4,6 +4,7 @@
#include <fortify.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include "logger.h"
#include "sics.h"
@ -13,19 +14,26 @@
typedef enum { NUMERIC, TEXT } CompType;
typedef struct {
time_t t;
float y;
} Point;
typedef struct {
SConnection *pCon;
char var[1024];
int exact;
CompType type;
time_t step;
time_t tlim;
time_t tmin, tmax, tlast, told;
float ymin, ymax, ylast, yold;
char slast[LLEN];
/* char set[LLEN]; */
time_t tlim; /* 0: initial state */
Point best; /* best point, to be written if tlim > 0 */
Point written; /* last written point */
Point last; /* last point */
char buf[LLEN];
int np;
char *none;
char *header;
time_t period;
int omitEqual;
} Compressor;
static char *dir = NULL;
@ -34,112 +42,103 @@ static char *dir2 = NULL;
static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) {
c->pCon = pCon;
c->step = step;
c->tmin = -2;
c->tmax = 0;
c->tlast = 0;
c->tlim = 0;
c->told = 0;
c->slast[0]='\0';
c->ylast = LOGGER_NAN;
c->last.y = LOGGER_NAN;
c->last.t = 0;
c->buf[0]='\0';
c->written.t = 0;
c->written.y = LOGGER_NAN;
c->omitEqual = 1;
}
static void OutString(Compressor *c, time_t t, char *str) {
char line[LLEN];
static void OutFloat(Compressor *c, Point p) {
char *value;
/* printf("out %ld %g\n", t, y); */
if (0 != strcmp(str, c->slast)) {
snprintf(line, sizeof line, "%ld %s\n", (long)(t - c->tlast), str);
c->tlast = t;
c->slast[0]='\0';
strncat(c->slast, str, sizeof c->slast - 1);
SCWrite(c->pCon, line, eWarning);
c->np--;
}
}
static void OutFloat(Compressor *c, time_t t, float y) {
char line[80];
/* printf("out %ld %g\n", t, y); */
if (y != c->ylast || (!c->exact && t != c->tlast)) {
c->ylast = y;
if (y == LOGGER_NAN) {
if (c->none) {
snprintf(line, sizeof line, "%ld %s\n", (long)(t - c->tlast), c->none);
} else {
snprintf(line, sizeof line, "%ld\n", (long)(t - c->tlast));
}
if (p.y == LOGGER_NAN) {
if (c->omitEqual && c->written.y == LOGGER_NAN) return;
if (c->none) {
value = c->none;
} else {
snprintf(line, sizeof line, "%ld %g\n", (long)(t - c->tlast), y);
value = "";
}
/* printf("-%s\n", line); */
c->tlast = t;
SCWrite(c->pCon, line, eWarning);
c->np--;
} else {
if (c->omitEqual && c->written.y == p.y) return;
snprintf(c->buf, sizeof(c->buf), "%g", p.y);
value = c->buf;
}
SCPrintf(c->pCon, eWarning, "%ld %s", (long)(p.t - c->written.t), value);
c->written = p;
c->np--;
}
static void WriteHeader(Compressor *c) {
if (c->header) {
SCPrintf(c->pCon, eWarning, "*%s period %ld\n", c->header, c->period);
c->header = NULL;
}
}
static void PutValue(Compressor *c, time_t t, char *value) {
char *p;
double y;
if (c->var[0]) {
SCPrintf(c->pCon, eWarning, "*%s exact %d\n", c->var, c->exact);
c->var[0] = 0;
}
Point new;
WriteHeader(c);
if (c->type == NUMERIC) {
if (t == 0) { /* finish */
t = c->tlim + 3 * c->step;
y = 0;
new.y = strtod(value, &p);
if (p == value) {
new.y = LOGGER_NAN;
} else {
y = strtod(value, &p);
if (p == value) {
y = LOGGER_NAN;
} else {
if (y == LOGGER_NAN) y *= 1.0000002;
}
if (new.y == LOGGER_NAN) new.y *= 1.0000002;
}
/* printf("put %ld %g\n", t, y); */
if (c->tlim == 0) goto first;
if (t >= c->tlim) {
new.t = t;
if (t >= c->tlim) { /* a new interval starts */
if (c->tlim == 0) {
c->tlim = t;
} else if (c->best.y != c->written.y) {
OutFloat(c, c->best);
}
c->best = new;
c->tlim += c->step;
if (c->tmin > c->tmax) {
OutFloat(c, c->tmax, c->ymax);
c->ymax = c->ymin;
c->tmax = c->tmin;
} else {
OutFloat(c, c->tmin, c->ymin);
if (c->tmin == c->tmax) goto first;
c->ymin = c->ymax;
c->tmin = c->tmax;
}
if (t >= c->tlim) {
OutFloat(c, c->tmin, c->ymin);
if (t >= c->tlim + c->step) {
OutFloat(c, c->told, c->yold);
if (t > c->tlim) {
if (c->last.y != c->written.y) {
OutFloat(c, c->last);
}
goto first;
c->tlim = t + c->step;
}
} else { /* not the first point */
if (fabs(new.y - c->best.y) > fabs(c->written.y - c->best.y)) {
c->best = new;
}
}
if (y <= c->ymin) {
c->ymin = y;
c->tmin = t;
} else if (y > c->ymax) {
c->ymax = y;
c->tmax = t;
}
c->yold = y;
c->told = t;
return;
first:
c->tlim = t + 2 * c->step;
c->tmin = t;
c->tmax = t;
c->ymin = y;
c->ymax = y;
return;
c->last = new;
} else if (c->type == TEXT) {
if (t != 0) OutString(c, t, value);
if (0 != strncmp(value, c->buf, sizeof(c->buf)-1)) {
snprintf(c->buf, sizeof(c->buf), "%s", value);
SCPrintf(c->pCon, eWarning, "%ld %s\n", (long)(t - c->written.t), value);
c->written.t = t;
c->np--;
}
}
}
static void PutFinish(Compressor *c, time_t now) {
char value[32];
if (c->tlim != 0) { /* there is data already */
c->omitEqual = 0;
if (c->type == NUMERIC) {
if (now > c->last.t) { /* copy last value to the actual time */
if (c->last.y != LOGGER_NAN) {
snprintf(value, sizeof value, "%g", c->last.y);
PutValue(c, now, value);
}
if (c->best.t > c->written.t) {
OutFloat(c, c->best); /* write last buffered value */
}
}
} if (now > c->last.t) {
PutValue(c, now, c->buf);
}
}
}
/*--------------------------------------------------------------------------*/
@ -194,7 +193,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
First line: returning the actual time on the server (this time is used for relative times)
For each variable which has data in the given interval,
the variable name is returned preceeded by a '*', followed by some options* separated with
the variable name is returned preceeded by a '*', followed by some infos* separated with
blanks.
After the header line for every data point a line follows with
a time relative to the last point and the value.
@ -207,13 +206,13 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
<overflow> is 1, when overflow occured, 0 else. Overflow may happen only
when np is given and a text variable was demanded.
*actually only one option exists (you might ignore it):
exact <value>
<value> is 1 when the value is exact, i.e. an integer.
<value> is 0 else.
*actually only one info exists: period <value>. This is the update rate in seconds.
As equal values are not transmitted, two points (t1,y1) and (t2,y2) with a distance
(t2 - t1) > period should not be connected directly. The plot software should generate
an intermediate point at (t2-period,y1).
*/
time_t from, to, step, xs, lastt, now;
long lxs;
time_t from, to, step, xs, lastt;
char *p, *varp;
int i, j, iarg, l, iret, loss, np;
int inRange;
@ -230,6 +229,8 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
char *opt;
int isdst;
int overflow;
time_t now, now1, now2, nowi;
char var[256];
/* argtolower(argc, argv); */
if (argc < 4) goto illarg;
@ -293,12 +294,16 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon, "ERROR: LoggerDir not found", eError);
return 0;
}
LoggerSetDir(dir);
}
if (dir2 == NULL) {
dir2 = IFindOption(pSICSOptions, "LoggerDir2");
if (dir2 == NULL) dir2="";
if (dir2 == NULL) {
dir2="";
}
}
now1 = LoggerGetLastLife(NULL);
if (now1 == 0) now1 = now;
now2 = 0;
loss = 0;
overflow = 0;
@ -312,23 +317,32 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
/* convert slashes to dots */
varp = argv[i];
if (*varp == '/') varp++;
for (j = 0; j < sizeof(c.var) && *varp != 0; j++, varp++) {
for (j = 0; j < sizeof(var)-1 && *varp != 0; j++, varp++) {
if (*varp == '/') {
c.var[j] = '.';
var[j] = '.';
} else {
c.var[j] = *varp;
var[j] = *varp;
}
}
c.header = argv[i];
c.period = 0;
var[j] = '\0';
c.type = type0;
c.np = np;
l = LoggerVarPath(dir, path, sizeof path, c.var);
l = LoggerVarPath(dir, path, sizeof path, var);
dr = opendir(path);
if (dr) {
nowi = now1;
closedir(dr);
} else {
l = LoggerVarPath(dir2, path, sizeof path, c.var);
if (now2 == 0) {
now2 = LoggerGetLastLife(dir2);
if (now2 == 0) now2 = now;
}
l = LoggerVarPath(dir2, path, sizeof path, var);
nowi = now2;
dr = opendir(path);
if (dr) {
closedir(dr);
@ -337,7 +351,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
isdst = -1;
fil = NULL;
while (startim <= to && c.tlast <= to) {
while (startim <= to && c.last.t <= to) {
tm = *localtime(&startim);
if (tm.tm_yday != yday) {
if (fil != NULL) { /* close file if day changed */
@ -356,13 +370,14 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
fclose(fil);
fil = NULL;
} else {
lxs = getOpt(line, &isdst, &c.exact);
if (lxs >= 0) {
if (lxs == 0) {
c.period = getOpt(line, &isdst, &c.exact);
/* if (c.exact) c.period = 0; */
if (c.period >= 0) {
if (c.period == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
xs = c.period;
}
if (xs < step) {
loss = 1;
@ -380,13 +395,13 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
/* printf("%s\n", line); */
if (lin == NULL) break;
if (line[0] == '#') {
lxs = getOpt(line, &isdst, &c.exact);
if (lxs >= 0) {
if (lxs == 0) {
c.period = getOpt(line, &isdst, &c.exact);
if (c.period >= 0) {
if (c.period == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
xs = c.period;
}
if (xs < step) {
loss = 1;
@ -413,13 +428,13 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
if (p) {
stp = p+1;
*p='\0';
iret = sscanf(stp, "%ld", &lxs);
iret = sscanf(stp, "%ld", &c.period);
if (iret == 1) {
if (lxs == 0) {
if (c.period == 0) {
c.type = TEXT;
} else {
c.type = type0;
xs = lxs;
xs = c.period;
}
if (xs < step) {
loss = 1;
@ -464,8 +479,8 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
PutValue(&c, lastt, lastval);
}
}
c.ylast = LOGGER_NAN; /* force output of last value */
PutValue(&c, 0, ""); /* finish */
WriteHeader(&c); /* write header, if not already done */
PutFinish(&c, nowi);
if (fil) {
fclose(fil);
fil = NULL;

View File

@ -73,11 +73,17 @@ static int LogSetup(SConnection *pCon, SicsInterp *pSics, void *pData,
} else {
numeric = 0;
}
logger = LoggerMake(name, period, !numeric);
LoggerSetNumeric(logger, numeric);
cb = MakeHipadabaCallback(LoggerUpdateCallback, logger, (void (*)(void *))LoggerKill, -1, NULL);
assert(cb);
AppendHipadabaCallback(node, HCBUPDATE, cb);
logger = FindHdbCallbackData(node, HCBUPDATE, LoggerUpdateCallback, NULL);
if (logger != 0) { /* logger exists already, changed only period */
LoggerSetPeriod(logger, period);
} else {
logger = LoggerMake(name, period, !numeric);
LoggerSetNumeric(logger, numeric);
cb = MakeHipadabaCallback(LoggerUpdateCallback, logger, (void (*)(void *))LoggerKill, -1, NULL);
assert(cb);
AppendHipadabaCallback(node, HCBUPDATE, cb);
}
return 1;
}

View File

@ -71,7 +71,6 @@
pRes->parNode = NULL;
pRes->SaveStatus = DefaultSave;
pRes->GetInterface = DefaultGetInterface;
pRes->creationCommand = NULL;
return pRes;
}
/*---------------------------------------------------------------------------*/
@ -157,7 +156,7 @@
{
if(NULL!=self)
{
IFSetOption(self->pKeys,keyName,eltValue);
self->pKeys = IFSetOption(self->pKeys,keyName,eltValue);
}
}
/*--------------------------------------------------------------------------*/
@ -167,7 +166,7 @@
{
return;
}
IFSetOption(self->pKeys,"group",group);
self->pKeys = IFSetOption(self->pKeys,"group",group);
}
/*--------------------------------------------------------------------------*/
void SetDescriptorDescription(pObjectDescriptor self, char *description)
@ -176,7 +175,7 @@
{
return;
}
IFSetOption(self->pKeys,"description", description);
self->pKeys = IFSetOption(self->pKeys,"description", description);
}
/*--------------------------------------------------------------------------*/
char * GetDescriptorKey(pObjectDescriptor self, char *keyName)

View File

@ -31,7 +31,6 @@
void *(*GetInterface)(void *self, int iInterfaceID);
IPair *pKeys;
pHdb parNode;
char *creationCommand; /* NULL when a static object */
} ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/

View File

@ -3,8 +3,6 @@
#include "statusfile.h"
#include "sicshipadaba.h"
static pDummy creationCommands = NULL;
static void SaveHdbBranch(pHdb node, FILE *fil) {
pHdb child;
char prop[16];

View File

@ -28,6 +28,7 @@ typedef enum {
sct_take_keyword,
sct_get_keyword,
sct_complete_keyword,
sct_retry_keyword,
sct_chain_keyword,
sct_next_keyword,
sct_steplist_keyword,
@ -44,6 +45,7 @@ static char *sctKeywords[]={
"take",
"get",
"complete",
"retry",
"chain",
"next",
"steplist",
@ -116,6 +118,7 @@ struct Sct {
char *result;
char *nextScript;
SctChain *runningChain;
int tryCnt;
SCStore debugConn;
char *debugCommand;
int sent;
@ -259,6 +262,7 @@ static int SctReadCallback(void *user, void *conn, pHdb node, hdbValue value) {
int SctCallDynamicScript(Sct *sct, char *name, char *script) {
SctList *sl;
SctChain *sc;
for (sl = sct->scriptLists.head; sl != NULL; sl = sl->next) {
for (sc = sl->chains.head; sc != NULL; sc = sc->next) { /* don't touch the list pos */
if (sc->dynamic && strcasecmp(name, sc->dynamic) == 0) {
@ -408,6 +412,25 @@ static int SctExec(SConnection *con, SicsInterp *sics, void *object, int argc, c
}
goto missingScriptList;
case sct_retry_keyword:
if (argc < 3) {
SCPrintf(con, eInError, "ERROR: should be: %s retry <max try> <message>", argv[0]);
goto quit;
}
if (sct->runningChain == NULL) {
SCPrintf(con, eInError, "ERROR: no running chain (fatal error)", argv[0]);
goto quit;
}
sct->tryCnt++;
if (sct->tryCnt >= atoi(argv[2])) {
SCPrintf(con, eInError, "ERROR: too may retries (%d) after %s",
sct->tryCnt, ConcatArgs(argc-3, argv+3));
goto quit;
}
sct->nextScript = sct->runningChain->command;
if (sct->result) free(sct->result);
sct->result = NULL;
break;
case sct_chain_keyword:
if (argc < 4) {
SCPrintf(con, eInError, "ERROR: should be: %s chain <name> <script>", argv[0]);
@ -496,6 +519,7 @@ static char *SctCallChain(SctChain *sc) {
return NULL; /* empty script: do nothing */
}
sct->runningChain = sc;
sct->tryCnt = 0;
sct->relatedPath = sc->relatedPath;
sc->msg = NULL;
return SctCall(sc->command);
@ -759,14 +783,14 @@ int SctAddNode2Script(Sct *sct, SctChain *sc, pHdb node, SConnection *con) {
if (child == NULL) {
child = MakeSICSHdbPar("error", usInternal, MakeHdbText(""));
AddHipadabaChild(node, child, NULL);
SetHdbProperty(child, "hidden", "whenempty");
SetHdbProperty(child, "visible", "false");
}
if (sc->scriptList->type == set_type) {
child = GetHipadabaNode(node, "target");
if (child == NULL) {
child = MakeSICSHdbPar("target", usInternal, node->value);
AddHipadabaChild(node, child, NULL);
SetHdbProperty(child, "hidden","target");
SetHdbProperty(child, "visible","false");
}
data->setChain = sc;
} else {

View File

@ -282,8 +282,8 @@ pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
return NULL;
}
if (strcasecmp(argv[0],"DynSicsObj") == 0) {
/* save creation command */
pNew->pDes->creationCommand = Arg2Tcl(argc, argv, NULL, -1);
/* make object dynamic by defining a descriptor command */
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
}
status = AddCommand(pSics,

View File

@ -222,7 +222,6 @@ static int listRestoreErr(pRestoreObj self, SConnection *pCon){
assert(pSics);
assert(pCon);
assert(self != NULL);
StatusFileTask(NULL); /* do a save now, see also parameterChange = 0 at the end */
if(argc < 2)
{
@ -272,8 +271,7 @@ static int listRestoreErr(pRestoreObj self, SConnection *pCon){
/*
if we do not override parameterChange here, the backup file
would be overwritten after each restore... Not the right thing
to do! As we have called StatusFileTask before, we are sure not
to loose a change
to do!
*/
parameterChange = 0;
SCSendOK(pCon);