#include <string.h>
#include <cadef.h>
+#include <tcl.h>
#include <allParam.h>
static void Param_copyBlobToAllocMem(struct event_handler_args args);
static void Param_returnPVName(const Param *my, const char *, const char *, const char *, char *);
static void Param_strerror(Param *, const char *);
+static int Param_getIntArrayCache(const Param *, const char *, const char *, int, int *, unsigned long int *);
+static int Param_getStringArrayCache(const Param *, const char *, const char *, int, int *, char **);
+static int Param_getFilenameArrayCache(const Param *, const char *, const char *, int, int *, char **);
+static int Param_storeIntCache(const Param *, const char *, const char *, unsigned long int);
+static int Param_storeStringCache(const Param *, const char *, const char *, const char *);
+
+typedef struct CaParamS {
+ Tcl_Interp *cache;
+} CaParam;
typedef struct ParamStringResultS {
char **val;
int conSetupParam(Param *my, const char *setup)
{
my->strerror = NULL;
+ my->specParam = malloc(sizeof(CaParam));
+
if(setup != NULL) {
my->setup = malloc(strlen(setup) + 1);
strcpy(my->setup, setup);
} else {
my->setup = NULL;
}
+ ((CaParam *) (my->specParam))->cache = Tcl_CreateInterp();
+
return 0;
}
void desParam(Param *my)
{
+ Tcl_DeleteInterp(((CaParam *) (my->specParam))->cache);
if(my->setup != NULL) {
free(my->setup);
}
int found = 1;
chid chan;
char *pPVName;
+ int i;
+ char buf[PARAM_MAX_NAME_LEN];
*rows = 0;
- if((status = ca_task_initialize()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- pPVName = malloc((strlen("HAD:PI:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
- Param_returnPVName(my, "PI", name, idx, pPVName);
-
- if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- } else if (status != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- retVal = 0;
- }
- if(found == 1) {
- ParamIntResult resultS, *result = &resultS;
- result->val = val;
- result->rows = rows;
- result->maxrows = maxrows;
- result->my = my;
- result->retVal = &retVal;
+ if(Param_getIntArrayCache(my, name, idx, maxrows, rows, val) || (*rows != maxrows)) {
+ if((status = ca_task_initialize()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
+ }
- status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyIntsToAllocMem, result);
- Param_strerror((Param *) my, ca_message(status));
+ pPVName = malloc((strlen("HAD:PI:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
+ Param_returnPVName(my, "PI", name, idx, pPVName);
- if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
Param_strerror((Param *) my, ca_message(status));
+ found = 0;
} else if (status != ECA_NORMAL) {
Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
}
- }
- if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- }
+ if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ found = 0;
+ retVal = 0;
+ }
+ if(found == 1) {
+ ParamIntResult resultS, *result = &resultS;
+ result->val = val;
+ result->rows = rows;
+ result->maxrows = maxrows;
+ result->my = my;
+ result->retVal = &retVal;
+
+ status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyIntsToAllocMem, result);
+ Param_strerror((Param *) my, ca_message(status));
- free(pPVName);
+ if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ Param_strerror((Param *) my, ca_message(status));
+ } else if (status != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ }
- if((status = ca_task_exit()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
+ if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+
+ free(pPVName);
+
+ if((status = ca_task_exit()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ if(maxrows == 1) {
+ Param_storeIntCache(my, name, idx, *val);
+ } else {
+ for (i = 0 ; i < *rows ; i++) {
+ sprintf(buf, "%s%d", idx, i);
+ Param_storeIntCache(my, name, buf, val[i]);
+ }
+ }
}
return retVal;
int found = 1;
chid chan;
char *pPVName;
+ int i;
+ char buf[PARAM_MAX_NAME_LEN];
*rows = 0;
- if((status = ca_task_initialize()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- pPVName = malloc((strlen("HAD:PS:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
- Param_returnPVName(my, "PS", name, idx, pPVName);
-
- if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- } else if (status != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- retVal = 0;
- }
- if(found == 1) {
- ParamStringResult resultS, *result = &resultS;
- result->val = val;
- result->rows = rows;
- result->maxrows = maxrows;
- result->my = my;
- result->retVal = &retVal;
+ if(Param_getStringArrayCache(my, name, idx, maxrows, rows, val) || (*rows != maxrows)) {
+ if((status = ca_task_initialize()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
+ }
- status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyStringsToAllocMem, result);
- Param_strerror((Param *) my, ca_message(status));
+ pPVName = malloc((strlen("HAD:PS:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
+ Param_returnPVName(my, "PS", name, idx, pPVName);
- if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
Param_strerror((Param *) my, ca_message(status));
+ found = 0;
} else if (status != ECA_NORMAL) {
Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
}
- }
- if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- }
+ if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ found = 0;
+ retVal = 0;
+ }
+ if(found == 1) {
+ ParamStringResult resultS, *result = &resultS;
+ result->val = val;
+ result->rows = rows;
+ result->maxrows = maxrows;
+ result->my = my;
+ result->retVal = &retVal;
+
+ status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyStringsToAllocMem, result);
+ Param_strerror((Param *) my, ca_message(status));
- free(pPVName);
+ if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ Param_strerror((Param *) my, ca_message(status));
+ } else if (status != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ }
- if((status = ca_task_exit()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
+ if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+
+ free(pPVName);
+
+ if((status = ca_task_exit()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ if(maxrows == 1) {
+ Param_storeStringCache(my, name, idx, *val);
+ } else {
+ for (i = 0 ; i < *rows ; i++) {
+ sprintf(buf, "%s%d", idx, i);
+ Param_storeStringCache(my, name, buf, val[i]);
+ }
+ }
}
return retVal;
int found = 1;
chid chan;
char *pPVName;
+ int i;
+ char buf[PARAM_MAX_NAME_LEN];
*rows = 0;
- if((status = ca_task_initialize()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- pPVName = malloc((strlen("HAD:PF:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
- Param_returnPVName(my, "PF", name, idx, pPVName);
-
- if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- } else if (status != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- retVal = -1;
- }
-
- if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- found = 0;
- retVal = 0;
- }
- if(found == 1) {
- ParamStringResult resultS, *result = &resultS;
- result->val = val;
- result->rows = rows;
- result->maxrows = maxrows;
- result->my = my;
- result->retVal = &retVal;
+ if(Param_getFilenameArrayCache(my, name, idx, maxrows, rows, val) || (*rows != maxrows)) {
+ if((status = ca_task_initialize()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
+ }
- status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyStringsToAllocMem, result);
- Param_strerror((Param *) my, ca_message(status));
+ pPVName = malloc((strlen("HAD:PF:") + (my->setup == NULL ? 0 : strlen(my->setup) + 1) + strlen(name) + 1 + strlen(idx) + 1) * sizeof(char));
+ Param_returnPVName(my, "PF", name, idx, pPVName);
- if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ if((status = ca_search(pPVName, &chan)) == ECA_GETFAIL) {
Param_strerror((Param *) my, ca_message(status));
+ found = 0;
} else if (status != ECA_NORMAL) {
Param_strerror((Param *) my, ca_message(status));
+ retVal = -1;
}
- }
- if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
- }
+ if((status = ca_pend_io(TIMEOUT)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ found = 0;
+ retVal = 0;
+ }
+ if(found == 1) {
+ ParamStringResult resultS, *result = &resultS;
+ result->val = val;
+ result->rows = rows;
+ result->maxrows = maxrows;
+ result->my = my;
+ result->retVal = &retVal;
+
+ status = ca_array_get_callback(ca_field_type(chan), ca_element_count(chan), chan, Param_copyStringsToAllocMem, result);
+ Param_strerror((Param *) my, ca_message(status));
- free(pPVName);
+ if((status = ca_pend_event(TIMEOUT)) == ECA_TIMEOUT) {
+ Param_strerror((Param *) my, ca_message(status));
+ } else if (status != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ }
- if((status = ca_task_exit()) != ECA_NORMAL) {
- Param_strerror((Param *) my, ca_message(status));
+ if((status = ca_clear_channel(chan)) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+
+ free(pPVName);
+
+ if((status = ca_task_exit()) != ECA_NORMAL) {
+ Param_strerror((Param *) my, ca_message(status));
+ }
+ if(maxrows == 1) {
+ Param_storeStringCache(my, name, idx, *val);
+ } else {
+ for (i = 0 ; i < *rows ; i++) {
+ sprintf(buf, "%s%d", idx, i);
+ Param_storeStringCache(my, name, buf, val[i]);
+ }
+ }
}
return retVal;
return retVal;
}
+void Param_clearCache(const Param *my)
+{
+ Tcl_DeleteInterp(((CaParam *) (my->specParam))->cache);
+ ((CaParam *) (my->specParam))->cache = Tcl_CreateInterp();
+}
+
const char *Param_getErrStr(const Param *my)
{
return my->strerror;
}
}
+static int Param_getIntArrayCache(const Param *my, const char *name, const char *idx, int maxrows, int *rows, unsigned long int *val)
+{
+ int retVal = 0;
+ int i;
+ char *endptr;
+ char *strval[PARAM_MAX_ARRAY_LEN];
+
+ for (i = 0 ; i < maxrows ; i++) {
+ strval[i] = malloc(PARAM_MAX_VALUE_LEN * sizeof(char));
+ }
+ *rows = 0;
+ if((retVal |= Param_getStringArray(my, name, idx, maxrows, rows, strval)) == 0) {
+ for (i = 0 ; i < *rows ; i++) {
+ val[i] = strtoul(strval[i], &endptr, 0);
+ if (*endptr != '\0') {
+ *rows = 0;
+ retVal = -1;
+ Param_strerror((Param *) my, "Value seems to be no integer.");
+ }
+ }
+ }
+ for (i = 0 ; i < maxrows ; i++) {
+ free(strval[i]);
+ }
+ return retVal;
+}
+
+static int Param_getStringArrayCache(const Param *my, const char *name, const char *idx, int maxrows, int *rows, char **val)
+{
+ int retVal = 0;
+ int i;
+ char lname[PARAM_MAX_NAME_LEN];
+ char lidx[PARAM_MAX_NAME_LEN];
+
+ for(i = 0 ; i <=strlen(name) ; i++) {
+ lname[i] = tolower(name[i]);
+ }
+ for(i = 0 ; i <=strlen(idx) ; i++) {
+ lidx[i] = tolower(idx[i]);
+ }
+
+ *rows = 0;
+ if(Tcl_GetVar2(((CaParam *) (my->specParam))->cache, lname, lidx, 0) != 0) {
+ strcpy(val[0], Tcl_GetVar2(((CaParam *) (my->specParam))->cache, lname, lidx, 0));
+ *rows = 1;
+ } else {
+ char index[PARAM_MAX_NAME_LEN];
+ for (i = 0 ; i < maxrows ; i++) {
+ sprintf(index,"%s%d", lidx, i);
+ if(Tcl_GetVar2(((CaParam *) (my->specParam))->cache, lname, index, 0) != 0) {
+ strcpy(val[i], Tcl_GetVar2(((CaParam *) (my->specParam))->cache, lname, index, 0));
+ (*rows)++;
+ } else {
+ i = maxrows;
+ }
+ }
+ }
+ return retVal;
+}
+
+static int Param_getFilenameArrayCache(const Param *my, const char *name, const char *idx, int maxrows, int *rows, char **val)
+{
+ int retVal = 0;
+ int row = 0;
+ int i;
+ char *value[PARAM_MAX_ARRAY_LEN];
+
+ for (i = 0 ; i < maxrows ; i++) {
+ value[i] = malloc(PARAM_MAX_VALUE_LEN);
+ }
+
+ if (((retVal = Param_getStringArray(my, name, idx, maxrows, rows, value)) == 0) && (*rows > 0)) {
+ char basedir[PARAM_MAX_VALUE_LEN];
+
+ if ((Param_getString(my, "glob", "basedir", &row, basedir) == 0) && (row == 1)) {
+ strcat(basedir, "/");
+ } else {
+ strcpy(basedir, "");
+ }
+ for (i = 0 ; i < *rows ; i++) {
+ if (value[i][0] != '/') {
+ strcpy(val[i], basedir);
+ } else {
+ strcpy(val[i], "");
+ }
+ strcat(val[i], value[i]);
+ }
+ } else {
+ *rows = 0;
+ }
+
+ for (i = 0 ; i < maxrows ; i++) {
+ free(value[i]);
+ }
+
+ return retVal;
+}
+
+static int Param_storeIntCache(const Param *my, const char *name, const char *idx, unsigned long int value)
+{
+ char buf[7 + 2 * PARAM_MAX_NAME_LEN + PARAM_MAX_VALUE_LEN];
+ sprintf(buf, "set %s(%s)\t%lu\n", name, idx, value);
+ Tcl_Eval(((CaParam *) (my->specParam))->cache, buf);
+ return 0;
+}
+
+static int Param_storeStringCache(const Param *my, const char *name, const char *idx, const char *value)
+{
+ char buf[7 + 2 * PARAM_MAX_NAME_LEN + PARAM_MAX_VALUE_LEN];
+ sprintf(buf, "set %s(%s)\t\"%s\"\n", name, idx, value);
+ Tcl_Eval(((CaParam *) (my->specParam))->cache, buf);
+ return 0;
+}
+