diff --git a/client/castApp/src/Makefile b/client/castApp/src/Makefile index 8d95a8e..0cb31e8 100644 --- a/client/castApp/src/Makefile +++ b/client/castApp/src/Makefile @@ -48,6 +48,11 @@ testAddEnvVars_SRCS += testAddEnvVars.c testAddEnvVars_SYS_LIBS_WIN32 = ws2_32 TESTS += testAddEnvVars +TESTPROD_HOST += testAddExcludePattern +testAddExcludePattern_SRCS += testAddExcludePattern.c +testAddExcludePattern_SYS_LIBS_WIN32 = ws2_32 +TESTS += testAddExcludePattern + TESTSCRIPTS_HOST += $(TESTS:%=%.t) ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),) TESTPROD = $(TESTPROD_HOST) diff --git a/client/castApp/src/caster.c b/client/castApp/src/caster.c index 7ae2cea..15da501 100644 --- a/client/castApp/src/caster.c +++ b/client/castApp/src/caster.c @@ -114,14 +114,21 @@ void casterInit(caster_t *self) self->onmsg = &casterShowMsgDefault; self->current = casterStateInit; self->timeout = reccastTimeout; + ellInit(&self->extra_envs); + ellInit(&self->exclude_patterns); if(shSocketPair(self->wakeup)) errlogPrintf("Error: casterInit failed to create shutdown socket: %d\n", SOCKERRNO); } +static void nodeFree(void *node) { + string_list_t *temp = (string_list_t *)node; + free(temp->item_str); + free(temp); +} + void casterShutdown(caster_t *self) { - int i; epicsUInt32 junk = htonl(0xdeadbeef); epicsMutexMustLock(self->lock); @@ -136,10 +143,11 @@ void casterShutdown(caster_t *self) epicsEventMustWait(self->shutdownEvent); epicsMutexMustLock(self->lock); - for (i = 0; i < self->num_extra_envs; i++) { - free(self->extra_envs[i]); - } - free(self->extra_envs); + ellFree2(&self->extra_envs, &nodeFree); + epicsMutexUnlock(self->lock); + + epicsMutexMustLock(self->lock); + ellFree2(&self->exclude_patterns, &nodeFree); epicsMutexUnlock(self->lock); epicsEventDestroy(self->shutdownEvent); diff --git a/client/castApp/src/caster.h b/client/castApp/src/caster.h index a4172df..659ff92 100644 --- a/client/castApp/src/caster.h +++ b/client/castApp/src/caster.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "sockhelpers.h" @@ -35,6 +36,11 @@ typedef enum { casterStateDone, } casterState; +typedef struct { + ELLNODE node; + char *item_str; +} string_list_t; + typedef struct _caster_t { double timeout; @@ -68,8 +74,9 @@ typedef struct _caster_t { int shutdown; char lastmsg[MAX_STRING_SIZE]; - char **extra_envs; - int num_extra_envs; + ELLLIST extra_envs; + + ELLLIST exclude_patterns; } caster_t; @@ -101,6 +108,9 @@ int casterPushPDB(void *junk, caster_t *caster); epicsShareFunc void addReccasterEnvVars(caster_t* self, int argc, char **argv); +epicsShareFunc +void addReccasterExcludePattern(caster_t* self, int argc, char **argv); + /* internal */ epicsShareFunc diff --git a/client/castApp/src/castinit.c b/client/castApp/src/castinit.c index 4efe4e7..9326b5e 100644 --- a/client/castApp/src/castinit.c +++ b/client/castApp/src/castinit.c @@ -74,7 +74,6 @@ static void casthook(initHookState state) void addReccasterEnvVars(caster_t* self, int argc, char **argv) { size_t i, j; - int ret = 0; argv++; argc--; /* skip function arg */ if(argc < 1) { @@ -95,91 +94,54 @@ void addReccasterEnvVars(caster_t* self, int argc, char **argv) epicsMutexUnlock(self->lock); return; } - int new_extra_envs_size = self->num_extra_envs + argc; - int num_new_extra_envs = self->num_extra_envs; - char **new_extra_envs = calloc(new_extra_envs_size, sizeof(*new_extra_envs)); - if(new_extra_envs == NULL) { - errlogSevPrintf(errlogMajor, "Error in memory allocation of new_extra_envs from addReccasterEnvVars\n"); - epicsMutexUnlock(self->lock); - return; - } - /* copy self->extra_envs into new_extra_envs with room for new envs */ - for(i=0; i < self->num_extra_envs; i++) { - if((new_extra_envs[i] = strdup(self->extra_envs[i])) == NULL) { - errlogSevPrintf(errlogMinor, "strdup error for copying %s to new_extra_envs[%zu] from addReccasterEnvVars\n", self->extra_envs[i], i); - ret = 1; - break; - } - } int found_dup; /* sanitize input - check for dups and empty args */ - if(!ret) { - for(i=0; i < argc; i++) { - if(argv[i] == NULL) { - errlogSevPrintf(errlogMinor, "Arg is NULL for addReccasterEnvVars\n"); - continue; - } - else if(argv[i][0] == '\0') { - errlogSevPrintf(errlogMinor, "Arg is empty for addReccasterEnvVars\n"); - continue; - } - found_dup = 0; - /* check if dup in self->default_envs */ - for(j = 0; default_envs[j]; j++) { - if(strcmp(argv[i], default_envs[j]) == 0) { - found_dup = 1; - errlogSevPrintf(errlogMinor, "Env var %s is already in env list sent by reccaster by default\n", argv[i]); - break; - } - } - if(found_dup) { - continue; - } - /* check if dup in self->extra_envs */ - for(j = 0; j < num_new_extra_envs; j++) { - if(new_extra_envs[j] == NULL) { - continue; - } - if(strcmp(argv[i], new_extra_envs[j]) == 0) { - found_dup = 1; - errlogSevPrintf(errlogMinor, "Env var %s is already in extra_envs list\n", argv[i]); - break; - } - } - if(found_dup) { - continue; + for(i=0; i < argc; i++) { + if(argv[i][0] == '\0') { + errlogSevPrintf(errlogMinor, "Arg is empty for addReccasterEnvVars\n"); + continue; + } + found_dup = 0; + /* check if dup in self->default_envs */ + for(j = 0; default_envs[j]; j++) { + if(strcmp(argv[i], default_envs[j]) == 0) { + found_dup = 1; + break; } - if((new_extra_envs[num_new_extra_envs] = strdup(argv[i])) == NULL) { - errlogSevPrintf(errlogMinor, "strdup error for copying %s to new_extra_envs[%d] from addReccasterEnvVars\n", argv[i], num_new_extra_envs); - ret = 1; + } + if(found_dup) { + errlogSevPrintf(errlogMinor, "Env var %s is already in env list sent by reccaster by default\n", argv[i]); + continue; + } + /* check if dup in self->extra_envs */ + ELLNODE *cur = ellFirst(&self->extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + if (strcmp(argv[i], temp->item_str) == 0) { + found_dup = 1; break; } - /* this is a valid arg and we have added the new env var to our array, increment new_extra_envs count */ - num_new_extra_envs++; + cur = ellNext(cur); } + if(found_dup) { + errlogSevPrintf(errlogMinor, "Env var %s is already in extra_envs list\n", argv[i]); + continue; + } + string_list_t *new_list = malloc(sizeof(string_list_t)); + if (new_list == NULL) { + errlogSevPrintf(errlogMajor, "Error in addReccasterEnvVars - malloc error for creating linked list node"); + break; + } + new_list->item_str = strdup(argv[i]); + if (new_list->item_str == NULL) { + errlogSevPrintf(errlogMajor, "Error in addReccasterEnvVars - strdup error for copying %s to new->item_str from addReccasterEnvVars\n", argv[i]); + free(new_list); /* frees if strdup fails */ + break; + } + ellAdd(&self->extra_envs, &new_list->node); } - /* if we have no allocation issues and have at least one new env var that is valid, add to self->extra_envs */ - if(!ret && num_new_extra_envs > self->num_extra_envs) { - /* from this point, nothing can fail */ - char ** tmp; - tmp = self->extra_envs; /* swap pointers so we can clean up new_extra_envs on success/failure */ - self->extra_envs = new_extra_envs; - new_extra_envs = tmp; - - new_extra_envs_size = self->num_extra_envs; /* with swap of pointers also swap size */ - self->num_extra_envs = num_new_extra_envs; - } - /* cleanup new_extra_envs[] on success or failure */ - for(i = 0; i < new_extra_envs_size; i++) { - free(new_extra_envs[i]); - } - free(new_extra_envs); epicsMutexUnlock(self->lock); - - if(ret) { - errlogSevPrintf(errlogMajor, "Error in addReccasterEnvVars - reccaster might not send the extra env vars specified\n"); - } } static const iocshArg addReccasterEnvVarsArg0 = { "environmentVar", iocshArgArgv }; @@ -200,6 +162,74 @@ static void addReccasterEnvVarsCallFunc(const iocshArgBuf *args) addReccasterEnvVars(&thecaster, args[0].aval.ac, args[0].aval.av); } +void addReccasterExcludePattern(caster_t* self, int argc, char **argv) { + size_t i; + argv++; argc--; /* skip function arg */ + if (argc < 1) { + errlogSevPrintf(errlogMinor, "At least one argument expected for addReccasterExcludePattern\n"); + return; + } + epicsMutexMustLock(self->lock); + if (self->shutdown) { + /* shutdown in progress, silent no-op */ + epicsMutexUnlock(self->lock); + return; + } + /* error if called after iocInit() */ + if (self->current != casterStateInit) { + errlogSevPrintf(errlogMinor, "addReccasterExcludePattern called after iocInit() when reccaster might already be connected. Not supported\n"); + epicsMutexUnlock(self->lock); + return; + } + + for (i = 0; i < argc; i++) { + if (argv[i][0] == '\0') { + errlogSevPrintf(errlogMinor, "Arg is empty for addReccasterExcludePattern\n"); + continue; + } + /* check duplicates */ + int dup = 0; + ELLNODE *cur = ellFirst(&self->exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + if (strcmp(argv[i], temp->item_str) == 0) { + dup = 1; + break; + } + cur = ellNext(cur); + } + if (dup) { + errlogSevPrintf(errlogMinor, "Duplicate pattern %s in addReccasterExcludePattern\n", argv[i]); + continue; + } + string_list_t *new_list = malloc(sizeof(string_list_t)); + if (new_list == NULL) { + errlogSevPrintf(errlogMajor, "Error in addReccasterExcludePattern - malloc error for creating linked list node"); + break; + } + new_list->item_str = strdup(argv[i]); + if (new_list->item_str == NULL) { + errlogSevPrintf(errlogMajor, "Error in addReccasterExcludePattern - strdup error for copying %s to new->item_str from addReccasterExcludePattern\n", argv[i]); + free(new_list); /* frees if strdup fails */ + break; + } + ellAdd(&self->exclude_patterns, &new_list->node); + } + epicsMutexUnlock(self->lock); +} + +static const iocshArg addReccasterExcludePatternArg0 = { "excludePattern", iocshArgArgv }; +static const iocshArg * const addReccasterExcludePatternArgs[] = { &addReccasterExcludePatternArg0 }; +static const iocshFuncDef addReccasterExcludePatternFuncDef = { + "addReccasterExcludePattern", + 1, + addReccasterExcludePatternArgs +}; + +static void addReccasterExcludePatternCallFunc(const iocshArgBuf *args) { + addReccasterExcludePattern(&thecaster, args[0].aval.ac, args[0].aval.av); +} + static void reccasterRegistrar(void) { osiSockAttach(); @@ -210,6 +240,7 @@ static void reccasterRegistrar(void) thepriv.laststate=casterStateInit; strcpy(thepriv.lastmsg, "Initializing"); iocshRegister(&addReccasterEnvVarsFuncDef,addReccasterEnvVarsCallFunc); + iocshRegister(&addReccasterExcludePatternFuncDef,addReccasterExcludePatternCallFunc); } static long init_record(void* prec) diff --git a/client/castApp/src/dbcb.c b/client/castApp/src/dbcb.c index 4d9cc04..e68239e 100644 --- a/client/castApp/src/dbcb.c +++ b/client/castApp/src/dbcb.c @@ -71,12 +71,15 @@ static int pushEnv(caster_t *caster) } epicsMutexMustLock(caster->lock); - for (i = 0; !ret && i < caster->num_extra_envs; i++) { - const char *val = getenv(caster->extra_envs[i]); + ELLNODE *env = ellFirst(&caster->extra_envs); + while (!ret && env != NULL) { + string_list_t *temp = (string_list_t *)env; + const char *val = getenv(temp->item_str); if (val && val[0] != '\0') - ret = casterSendInfo(caster, 0, caster->extra_envs[i], val); + ret = casterSendInfo(caster, 0, temp->item_str, val); if (ret) - casterMsg(caster, "Error sending env %s", caster->extra_envs[i]); + casterMsg(caster, "Error sending env %s", temp->item_str); + env = ellNext(env); } epicsMutexUnlock(caster->lock); @@ -87,12 +90,21 @@ static int pushRecord(caster_t *caster, DBENTRY *pent) { dbCommon *prec = pent->precnode->precord; ssize_t rid; + ELLNODE *cur; int ret = 0; long status; if(dbIsAlias(pent)) return 0; + cur = ellFirst(&caster->exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + if(epicsStrGlobMatch(prec->name, temp->item_str)) + return 0; + cur = ellNext(cur); + } + rid = casterSendRecord(caster, prec->rdes->name, prec->name); if(rid<=0) return rid; diff --git a/client/castApp/src/testAddEnvVars.c b/client/castApp/src/testAddEnvVars.c index fb81f12..93ed22d 100644 --- a/client/castApp/src/testAddEnvVars.c +++ b/client/castApp/src/testAddEnvVars.c @@ -14,7 +14,7 @@ static void testLog(void* arg, struct _caster_t* self) static void testAddEnvVarsX(void) { - int i; + int i = 0; caster_t caster; casterInit(&caster); caster.onmsg = &testLog; @@ -29,7 +29,6 @@ static void testAddEnvVarsX(void) "BUILDING", "CONTACT", "DEVICE", - "Field", "FAMILY" }; int expectedNumExtraEnvs = 0; @@ -37,71 +36,84 @@ static void testAddEnvVarsX(void) testDiag("Testing addReccasterEnvVars with one good env"); argvlist[1] = "SECTOR"; argc = 2; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); expectedNumExtraEnvs++; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + ELLNODE *cur; + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } testDiag("Testing addReccasterEnvVars with two more good envs"); argvlist[1] = "BUILDING"; argvlist[2] = "CONTACT"; argc = 3; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); expectedNumExtraEnvs += 2; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } testDiag("Testing addReccasterEnvVars with duplicate env"); argvlist[1] = "SECTOR"; argc = 2; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } testDiag("Testing addReccasterEnvVars with one dup and one good env"); argvlist[1] = "CONTACT"; argvlist[2] = "DEVICE"; argc = 3; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); expectedNumExtraEnvs++; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); - } - - testDiag("Testing addReccasterEnvVars with NULL argument and then a good env"); - argvlist[1] = NULL; - argvlist[2] = "Field"; - argc = 3; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - addReccasterEnvVars(&caster, argc, argvlist); - expectedNumExtraEnvs++; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } testDiag("Testing addReccasterEnvVars with a good env and a dup of that env"); - argvlist[1] = NULL; + argvlist[1] = "FAMILY"; argvlist[2] = "FAMILY"; - argvlist[3] = "FAMILY"; - argc = 4; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + argc = 3; + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); expectedNumExtraEnvs++; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } testDiag("Testing addReccasterEnvVars with a env vars from default list"); @@ -111,11 +123,16 @@ static void testAddEnvVarsX(void) argvlist[4] = "RSRV_SERVER_PORT"; argvlist[5] = "ENGINEER"; argc = 6; - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); + i = 0; + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); addReccasterEnvVars(&caster, argc, argvlist); - testOk1(caster.num_extra_envs==expectedNumExtraEnvs); - for(i=0; i < expectedNumExtraEnvs; i++) { - testOk1(strcmp(caster.extra_envs[i], expectedExtraEnvs[i]) == 0); + testOk1(caster.extra_envs.count==expectedNumExtraEnvs); + cur = ellFirst(&caster.extra_envs); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedExtraEnvs[i]) == 0); + i++; + cur = ellNext(cur); } epicsEventSignal(caster.shutdownEvent); @@ -134,23 +151,16 @@ static void testAddEnvVarsBadInput(void) testDiag("Testing addReccasterEnvVars with no arguments"); argc = 1; - testOk1(caster.num_extra_envs==0); + testOk1(caster.extra_envs.count==0); addReccasterEnvVars(&caster, argc, argvlist); - testOk1(caster.num_extra_envs==0); + testOk1(caster.extra_envs.count==0); testDiag("Testing addReccasterEnvVars with empty string argument"); argvlist[1] = ""; argc = 2; - testOk1(caster.num_extra_envs==0); - addReccasterEnvVars(&caster, argc, argvlist); - testOk1(caster.num_extra_envs==0); - - testDiag("Testing addReccasterEnvVars with NULL argument"); - argvlist[1] = NULL; - argc = 2; - testOk1(caster.num_extra_envs==0); + testOk1(caster.extra_envs.count==0); addReccasterEnvVars(&caster, argc, argvlist); - testOk1(caster.num_extra_envs==0); + testOk1(caster.extra_envs.count==0); epicsEventSignal(caster.shutdownEvent); casterShutdown(&caster); @@ -158,7 +168,7 @@ static void testAddEnvVarsBadInput(void) MAIN(testAddEnvVars) { - testPlan(48); + testPlan(37); osiSockAttach(); testAddEnvVarsX(); testAddEnvVarsBadInput(); diff --git a/client/castApp/src/testAddExcludePattern.c b/client/castApp/src/testAddExcludePattern.c new file mode 100644 index 0000000..8f0a9d6 --- /dev/null +++ b/client/castApp/src/testAddExcludePattern.c @@ -0,0 +1,173 @@ +#include + +#include +#include + +#include "caster.h" + +void* epicsRtemsFSImage; + +static void testLog(void* arg, struct _caster_t* self) +{ + testDiag("ERR %s", self->lastmsg); +} + +static void testAddExcludePatternX(void) +{ + int i = 0; + caster_t caster; + casterInit(&caster); + caster.onmsg = &testLog; + + int argc; + char *argvlist[5]; + argvlist[0] = "addReccasterExcludePattern"; + + char *expectedPatterns[] = + { + "*_", + "*__", + "*:Intrnl:*", + "*_internal", + "*exclude_me" + }; + int expectedNumPatterns = 0; + + testDiag("Testing addReccasterExcludePattern with one good env"); + argvlist[1] = "*_"; + argc = 2; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + expectedNumPatterns++; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + ELLNODE *cur; + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + testDiag("Testing addReccasterExcludePattern with two more patterns"); + argvlist[1] = "*__"; + argvlist[2] = "*:Intrnl:*"; + argc = 3; + i = 0; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + expectedNumPatterns += 2; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + testDiag("Testing addReccasterExcludePattern with a duplicate pattern"); + argvlist[1] = "*_"; + argc = 2; + i = 0; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + testDiag("Testing addReccasterExcludePattern with a new and a duplicate"); + argvlist[1] = "*_internal"; + argvlist[2] = "*__"; + argc = 3; + i = 0; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + expectedNumPatterns++; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + testDiag("Testing addReccasterExcludePattern with two of the same pattern"); + argvlist[1] = "*exclude_me"; + argvlist[2] = "*exclude_me"; + argc = 3; + i = 0; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + expectedNumPatterns++; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + testDiag("Testing addReccasterExcludePattern with duplicates in argv and exclude pattern list"); + argvlist[1] = "*__"; + argvlist[2] = "*__"; + argc = 3; + i = 0; + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + addReccasterExcludePattern(&caster, argc, argvlist); + testOk1(caster.exclude_patterns.count==expectedNumPatterns); + cur = ellFirst(&caster.exclude_patterns); + while (cur != NULL) { + string_list_t *temp = (string_list_t *)cur; + testOk1(strcmp(temp->item_str, expectedPatterns[i]) == 0); + i++; + cur = ellNext(cur); + } + + epicsEventSignal(caster.shutdownEvent); + casterShutdown(&caster); +} + +static void testAddExcludePatternBadInput() +{ + caster_t caster; + casterInit(&caster); + caster.onmsg = &testLog; + + int argc; + char *argvlist[2]; + argvlist[0] = "addReccasterExcludePattern"; + + testDiag("Testing addReccasterExcludePattern with no arguments"); + argc = 1; + testOk1(caster.exclude_patterns.count==0); + addReccasterExcludePattern(&caster, argc, argvlist); + testOk1(caster.exclude_patterns.count==0); + + testDiag("Testing addReccasterExcludePattern with empty string argument"); + argvlist[1] = ""; + argc = 2; + testOk1(caster.exclude_patterns.count==0); + addReccasterExcludePattern(&caster, argc, argvlist); + testOk1(caster.exclude_patterns.count==0); + + epicsEventSignal(caster.shutdownEvent); + casterShutdown(&caster); +} + +MAIN(testAddExcludePattern) +{ + testPlan(37); + osiSockAttach(); + testAddExcludePatternX(); + testAddExcludePatternBadInput(); + osiSockRelease(); + return testDone(); +} diff --git a/client/iocBoot/iocdemo/st.cmd b/client/iocBoot/iocdemo/st.cmd index fe81b08..35c72fa 100755 --- a/client/iocBoot/iocdemo/st.cmd +++ b/client/iocBoot/iocdemo/st.cmd @@ -23,6 +23,9 @@ epicsEnvSet("SECTOR", "mysector") addReccasterEnvVars("CONTACT", "SECTOR") addReccasterEnvVars("BUILDING") +addReccasterExcludePattern("*_", "*__") +addReccasterExcludePattern("*exclude_this") + ## Load record instances dbLoadRecords("../../db/reccaster.db", "P=$(IOCSH_NAME):") dbLoadRecords("../../db/somerecords.db","P=$(IOCSH_NAME):")