/*************************************************************************\ * Copyright (c) 2010 Brookhaven National Laboratory. * Copyright (c) 2010 Helmholtz-Zentrum Berlin * fuer Materialien und Energie GmbH. * SPDX-License-Identifier: EPICS * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* * Author: Ralph Lange */ /* * Test the shorthand array notation [ start : incr : end ] * by registering a thin fake arr plugin * and checking if values are forwarded correctly */ #include #include "chfPlugin.h" #include "dbStaticLib.h" #include "dbAccessDefs.h" #include "registry.h" #include "errlog.h" #include "epicsExit.h" #include "dbUnitTest.h" #include "testMain.h" #include "osiFileName.h" typedef struct myStruct { epicsInt32 start; epicsInt32 incr; epicsInt32 end; } myStruct; static const chfPluginArgDef opts[] = { chfInt32 (myStruct, start, "s", 0, 1), chfInt32 (myStruct, incr, "i", 0, 1), chfInt32 (myStruct, end, "e", 0, 1), chfPluginArgEnd }; static myStruct my; static void * allocPvt(void) { my.start = 0; my.incr = 1; my.end = -1; return &my; } static chfPluginIf myPif = { allocPvt, NULL, /* freePvt, */ NULL, /* parse_error, */ NULL, /* parse_ok, */ NULL, /* channel_open, */ NULL, /* channelRegisterPre, */ NULL, /* channelRegisterPost, */ NULL, /* channel_report, */ NULL /* channel_close */ }; static int checkValues(epicsUInt32 s, epicsUInt32 i, epicsUInt32 e) { if (s == my.start && i == my.incr && e == my.end) return 1; else return 0; } static void testHead (char* title) { testDiag("--------------------------------------------------------"); testDiag("%s", title); testDiag("--------------------------------------------------------"); } void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); MAIN(arrShorthandTest) { dbChannel *pch; testPlan(26); testdbPrepare(); testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); dbTestIoc_registerRecordDeviceDriver(pdbbase); testdbReadDatabase("xRecord.db", NULL, NULL); testHead("Register plugin"); testOk(!chfPluginRegister("arr", &myPif, opts), "register fake arr plugin"); eltc(0); testIocInitOk(); eltc(1); #define TESTBAD(Title, Expr) \ testDiag(Title); \ testOk(!(pch = dbChannelCreate("x." Expr)), "dbChannelCreate (" Expr ") fails"); \ if (pch) dbChannelDelete(pch); #define TESTGOOD(Title, Expr, Start, Incr, End) \ testDiag(Title); \ testOk(!!(pch = dbChannelCreate("x." Expr)), "dbChannelCreate (" Expr ")"); \ testOk(checkValues(Start, Incr, End), "parameters set correctly: s=%d i=%d e=%d", Start, Incr, End); \ if (pch) dbChannelDelete(pch); TESTBAD("no parameters []", "[]"); TESTBAD("invalid char at beginning [x", "[x"); TESTBAD("invalid char after 1st arg [2x", "[2x"); TESTBAD("invalid char after 2nd arg [2:3x", "[2:3x"); TESTBAD("invalid char after 3rd arg [2:3:4x", "[2:3:4x"); TESTGOOD("one element [index]", "[2]", 2, 1, 2); TESTGOOD("to end [s:]", "[2:]", 2, 1, -1); TESTGOOD("to end [s::]", "[2::]", 2, 1, -1); TESTGOOD("to end with incr [s:i:]", "[2:3:]", 2, 3, -1); TESTGOOD("from beginning [:e]", "[:2]", 0, 1, 2); TESTGOOD("from beginning [::e]", "[::2]", 0, 1, 2); TESTGOOD("from begin with incr [:i:e]", "[:3:2]", 0, 3, 2); TESTGOOD("range [s:e]", "[2:4]", 2, 1, 4); TESTGOOD("range [s::e]", "[2::4]", 2, 1, 4); TESTGOOD("range with incr [s:i:e]", "[2:3:4]", 2, 3, 4); testIocShutdownOk(); testdbCleanup(); return testDone(); }