From 311ad57e9340629ffec17953a11be2b144c23fa9 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 24 Apr 2017 15:18:52 -0500 Subject: [PATCH] printfRecord: Handle const long-strings in "%ls" Adds some tests for printfRecord. --- src/std/rec/printfRecord.c | 14 ++++++-- src/std/rec/test/linkInitTest.c | 55 +++++++++++++++++++++++++++++++- src/std/rec/test/linkInitTest.db | 10 ++++++ 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/std/rec/printfRecord.c b/src/std/rec/printfRecord.c index 17114712e..7011453d4 100644 --- a/src/std/rec/printfRecord.c +++ b/src/std/rec/printfRecord.c @@ -203,9 +203,10 @@ static void doPrintf(printfRecord *prec) } break; - case 's': /* FIXME: const strings are now supported */ - if (flags & F_LONG && !dbLinkIsConstant(plink)) { + case 's': + if (flags & F_LONG) { long n = vspace + 1; + long status; if (precision && n > precision) n = precision + 1; @@ -213,7 +214,14 @@ static void doPrintf(printfRecord *prec) * characters to be printed from the string. * It does not limit the field width however. */ - if (dbGetLink(plink++, DBR_CHAR, pval, 0, &n)) + if (dbLinkIsConstant(plink)) { + epicsUInt32 len = n; + status = dbLoadLinkLS(plink++, pval, n, &len); + n = len; + } + else + status = dbGetLink(plink++, DBR_CHAR, pval, 0, &n); + if (status) flags |= F_BADLNK; else { int padding; diff --git a/src/std/rec/test/linkInitTest.c b/src/std/rec/test/linkInitTest.c index f904ffa67..ac849ba4a 100644 --- a/src/std/rec/test/linkInitTest.c +++ b/src/std/rec/test/linkInitTest.c @@ -95,10 +95,63 @@ static void testCalcInit() testdbCleanup(); } +static void testPrintfInit() +{ + testDiag("testPrintfInit"); + + testdbPrepare(); + + testdbReadDatabase("recTestIoc.dbd", NULL, NULL); + + recTestIoc_registerRecordDeviceDriver(pdbbase); + + testdbReadDatabase("linkInitTest.db", NULL, NULL); + + eltc(0); + testIocInitOk(); + eltc(1); + + { + const char buf1[] = "Test string, exactly 40 characters long"; + const char buf2[] = "Longer test string, more that 40 characters long"; + const char buf2t[] = "Longer test string, more that 40 charac"; + + /* The FMT field is pp(TRUE), so this put triggers processing */ + testdbPutFieldOk("printf1.FMT", DBF_STRING, "%s"); + testdbGetArrFieldEqual("printf1.VAL$", DBF_CHAR, NELEMENTS(buf1)+2, + NELEMENTS(buf1), buf1); + testdbGetFieldEqual("printf1.VAL", DBR_STRING, buf1); + + testdbPutFieldOk("printf1.FMT", DBF_STRING, "%ls"); + testdbGetArrFieldEqual("printf1.VAL$", DBF_CHAR, NELEMENTS(buf1)+2, + NELEMENTS(buf1), buf1); + testdbGetFieldEqual("printf1.VAL", DBR_STRING, buf1); + + testdbPutFieldOk("printf2.FMT", DBF_STRING, "%s"); + testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, + NELEMENTS(buf2t), buf2t); + testdbGetFieldEqual("printf2.VAL", DBR_STRING, buf2t); + + testdbPutFieldOk("printf2.FMT", DBF_STRING, "%ls"); + testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, + NELEMENTS(buf2), buf2); + testdbGetFieldEqual("printf2.VAL", DBR_STRING, buf2t); + + testdbPutFieldOk("printf2.FMT", DBF_STRING, "%.39ls"); + testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, + NELEMENTS(buf2t), buf2t); + } + + testIocShutdownOk(); + + testdbCleanup(); +} + MAIN(linkInitTest) { - testPlan(16); + testPlan(30); testLongStringInit(); testCalcInit(); + testPrintfInit(); return testDone(); } diff --git a/src/std/rec/test/linkInitTest.db b/src/std/rec/test/linkInitTest.db index 15230c30a..a8063a899 100644 --- a/src/std/rec/test/linkInitTest.db +++ b/src/std/rec/test/linkInitTest.db @@ -21,3 +21,13 @@ record(ai, "emptylink" ) { record(ai, "emptylink1" ) { field(INP, {calc: {expr:"1"}}) } + +record(printf, "printf1") { + field(SIZV, "100") + field(INP0, ["Test string, exactly 40 characters long"]) +} +record(printf, "printf2") { + field(SIZV, "100") + field(INP0, ["Longer test string, more that 40 characters long"]) +} +