From c38f8de89aceb7c5c0cb201c7c5595805f1a1a72 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Tue, 21 Apr 2026 18:14:54 -0600 Subject: [PATCH 01/11] NOT YET FULLY TESTED: Changes to make backward compatible, and C-style API clgetSVal() work. --- code/CMakeLists.txt | 2 +- code/cl.h | 3 +- code/clgetBaseCode.h | 4 +- code/clgetFullVal.cc | 5 +-- code/clgetSVal.cc | 74 ++++++++++++++++++------------- code/clgetValp.cc | 2 +- code/clparseVal.cc | 6 +-- code/clparseVal.h | 13 +++--- code/clstring.cc | 29 ++++++------ code/clstring.h | 26 +++++++++-- code/test/unittest/ParafeedTest.h | 18 ++++---- 11 files changed, 105 insertions(+), 77 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index b9f5721..15d012e 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -176,7 +176,7 @@ set(shccl_sources ParseCmdLine.cc clparseVal.cc InstallSymb.cc -# clgetSVal.cc + clgetSVal.cc # clgetNSVal.cc clgetFullVal.cc diff --git a/code/cl.h b/code/cl.h index bba5608..d454018 100644 --- a/code/cl.h +++ b/code/cl.h @@ -151,7 +151,7 @@ int clgetIVal(char *Name, int *Val, int *N); int dbgclgetIVal(char *Name, int *Val, int *N); int clgetFVal(char *Name, float *Val, int *N); int dbgclgetFVal(char *Name, float *Val, int *N); -int clgetSVal(const char *Name, char *Val, int *N); +int clgetSVal(const char *Name, char *Val, int *N,SMap smap=SMap(),bool dbg=false); int dbgclgetSVal(const char *Name, char *Val, int *N); int clgetNIVal(char *Key, int *Val, int *m); int dbgclgetNIVal(char *Key, int *Val, int *m); @@ -277,6 +277,7 @@ int clgetBaseCore(const std::string& Name, int& Val, int& N, SMap &smap); int clgetFullValp(const std::string& Name, std::string& Val); int dbgclgetFullValp(const std::string& Name, std::string& Val); int clgetFullp(const std::string& Arg, int &N); +int clgetSValp(const std::string& Name, std::string& Val, int& N, SMap &smap,bool dbg); // //------------------------------------------------------------------------------------------------ // Wrappers for clgetValp(...,T& val,...) and clgetValp(...,vector&,...) diff --git a/code/clgetBaseCode.h b/code/clgetBaseCode.h index 700891e..46c0ea8 100644 --- a/code/clgetBaseCode.h +++ b/code/clgetBaseCode.h @@ -109,8 +109,6 @@ Symbol *clgetNValBaseCode(const string& Name, vector& val, int& m, const SMap } // //---------------------------------------------------------------------- -// This has the API-level templated functions that use the BaseCode -// functions above. -//#include +// #endif diff --git a/code/clgetFullVal.cc b/code/clgetFullVal.cc index c07976a..ed42a73 100644 --- a/code/clgetFullVal.cc +++ b/code/clgetFullVal.cc @@ -17,11 +17,8 @@ * */ /* $Id: clgetFullVal.c,v 2.0 1998/11/11 07:13:01 sanjay Exp $ */ -#include -#include #include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif diff --git a/code/clgetSVal.cc b/code/clgetSVal.cc index bb3543f..b1668c9 100644 --- a/code/clgetSVal.cc +++ b/code/clgetSVal.cc @@ -17,19 +17,19 @@ * */ /* $Id: clgetSVal.c,v 2.0 1998/11/11 07:13:01 sanjay Exp $ */ -#include -#include -#include +#include #include -#include -#include -#include +//#include +//#include +//#include +//#include +//#include +//#include //#include -//#include #ifdef __cplusplus extern "C" { #endif - + /*------------------------------------------------------------------------ Return the Nth value of Name as a string ------------------------------------------------------------------------*/ @@ -43,11 +43,21 @@ extern "C" { // return r; // ); // } + int clgetSVal(const char *Name, char *val, int *n, SMap smap, bool dbg) +{ + HANDLE_EXCEPTIONS( + string valp; + int r; + if ((r = clgetSValp(std::string(Name), valp, *n,smap,dbg))!= CL_FAIL) + strncpy(val,valp.c_str(),valp.size()+1); + return r; + ); +} #ifdef __cplusplus } #endif -#ifdef __cplusplus +//#ifdef __cplusplus // int clgetSValp(const string &Name, string& val, int& n) // { @@ -56,26 +66,28 @@ extern "C" { // return clgetSValp(Name, val, n, emptyMap); // ); // } -// int clgetSValp(const string& Name, string& val, int& n, SMap &smap) -// { -// Symbol *S; -// unsigned int N; +int clgetSValp(const string& Name, string& val, int& n, SMap &smap,bool dbg=false) +{ + Symbol *S; + unsigned int N; -// HANDLE_EXCEPTIONS( -// S = clgetBaseCode(Name, val, n, smap); -// N = _ABS(n); -// if (S!=NULL) -// { -// if (N <= S->NVals) -// { -// val = trim(S->Val[N-1]); -// return val.size(); -// } -// else -// return CL_FAIL; -// } -// else -// return CL_FAIL; -// ); -// } -#endif +HANDLE_EXCEPTIONS( + S = clgetBaseCode(Name, val, n, smap,dbg); + + N = _ABS(n); + if (S!=NULL) + { + if (N <= S->NVals) + { + val = trim(S->Val[N-1]); + // val = S->Val[N-1]; + return val.size(); + } + else + return CL_FAIL; + } + else + return CL_FAIL; + ); +} +//#endif diff --git a/code/clgetValp.cc b/code/clgetValp.cc index 3ad2ae8..e7ec1e0 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -159,7 +159,7 @@ inline int clgetBValp(const std::string& Name, bool& val, int& n, SMap &smap) inline int clgetNBValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} inline int clgetNBValp(const std::string& Name, std::vector& val, int& n, SMap &smap){return clgetValp(Name,val,n,smap);} -//inline int clgetSVal(const char *Name, char *val, int *n) {return clgetValp(std::string(Name), *val, *n);} +//inline int clgetSVal(const char *Name, char *val, int *n) {return clgetValp(std::string(Name), val, *n);} inline int clgetSValp(const std::string& Name, std::string& val, int &n) {return clgetValp(Name,val,n);} inline int clgetSValp(const std::string& Name, std::string& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} inline int clgetNSValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} diff --git a/code/clparseVal.cc b/code/clparseVal.cc index d8b64fa..b671ae4 100644 --- a/code/clparseVal.cc +++ b/code/clparseVal.cc @@ -20,10 +20,10 @@ #include #include #include -#include -#include #include -#include +//#include +//#include +//#include #ifdef __cplusplus extern "C" { #endif diff --git a/code/clparseVal.h b/code/clparseVal.h index 4027758..d7b2ed9 100644 --- a/code/clparseVal.h +++ b/code/clparseVal.h @@ -21,13 +21,12 @@ #define CLPARSEVAL_H #include -#include -#include -#include -#include -#include -#include -#include +//#include +//#include +//#include +//#include +//#include +//#include template int clparseVal(Symbol *S, int *Which, T &d) diff --git a/code/clstring.cc b/code/clstring.cc index e03befc..f6e8b1d 100644 --- a/code/clstring.cc +++ b/code/clstring.cc @@ -121,23 +121,24 @@ char *clstrtok(char *str, const char *sep,char esc) /*------------------------------------------------------------------------ Bunch of functions to remove whitespaces from a given string ------------------------------------------------------------------------*/ -const std::string WHITESPACE = " \n\r\t\f\v"; +// const std::string WHITESPACE = " \n\r\t\f\v"; -std::string ltrim(const std::string &s) -{ - size_t start = s.find_first_not_of(WHITESPACE); - return (start == std::string::npos) ? std::string("") : s.substr(start); -} +// std::string ltrim(const std::string &s) +// { +// size_t start = s.find_first_not_of(WHITESPACE); +// return (start == std::string::npos) ? std::string("") : s.substr(start); +// } -std::string rtrim(const std::string &s) -{ - size_t end = s.find_last_not_of(WHITESPACE); - return (end == std::string::npos) ? std::string("") : s.substr(0, end + 1); -} +// std::string rtrim(const std::string &s) +// { +// size_t end = s.find_last_not_of(WHITESPACE); +// return (end == std::string::npos) ? std::string("") : s.substr(0, end + 1); +// } -std::string trim(const std::string &s) { - return rtrim(ltrim(s)); -} +// std::string trim(const std::string &s) { +// string tt=rtrim(ltrim(s)); +// return tt; +// } #if defined(TESTBED) diff --git a/code/clstring.h b/code/clstring.h index 6c8e270..901e389 100644 --- a/code/clstring.h +++ b/code/clstring.h @@ -32,8 +32,28 @@ extern "C" { #ifdef __cplusplus } #endif -std::string ltrim(const std::string &s); -std::string rtrim(const std::string &s); -std::string trim(const std::string &s); +// std::string ltrim(const std::string &s); +// std::string rtrim(const std::string &s); +// std::string trim(const std::string &s); + +const std::string CL_STRING_WHITESPACE = " \n\r\t\f\v"; + +inline std::string ltrim(const std::string &s) +{ + size_t start = s.find_first_not_of(CL_STRING_WHITESPACE); + return (start == std::string::npos) ? std::string("") : s.substr(start); +} + +inline std::string rtrim(const std::string &s) +{ + size_t end = s.find_last_not_of(CL_STRING_WHITESPACE); + return (end == std::string::npos) ? std::string("") : s.substr(0, end + 1); +} + +inline std::string trim(const std::string &s) { + string tt=rtrim(ltrim(s)); + return tt; +} + #endif diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index c2ebbae..1cad49d 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -128,16 +128,16 @@ auto canonicalTest=[]() clgetValp("string", str, i, watchPoints); EXPECT_EQ(str, "showstrarr"); - // { - // char sstr[100]; - // clgetSVal("string", sstr, &i, watchPoints); - // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! - // EXPECT_EQ(sstr, str); + { + char sstr[100]; + clgetSVal("string", sstr, &i, watchPoints); + //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! + EXPECT_EQ(sstr, str); - // clgetSVal("string", sstr, &i); - // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! - // EXPECT_EQ(sstr, str); - // } + clgetSVal("string", sstr, &i); + //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! + EXPECT_EQ(sstr, str); + } // fullval std::string fullVal; From 371d89fe1926956e55f91f035262ad3929e819b8 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Wed, 22 Apr 2026 07:13:11 -0600 Subject: [PATCH 02/11] Not yet tested code. --- code/cl.h | 5 +- code/clgetBaseCode.h | 5 + code/clgetSVal.cc | 23 +--- code/clgetValp.cc | 2 + code/clparseVal.h | 14 ++- code/test/unittest/ParafeedTest.h | 108 +++++++++++++++++- .../unittest/test_parafeed_interactive.cpp | 38 ++++++ code/tstcpp.cc | 2 +- 8 files changed, 170 insertions(+), 27 deletions(-) diff --git a/code/cl.h b/code/cl.h index d454018..730726f 100644 --- a/code/cl.h +++ b/code/cl.h @@ -151,8 +151,6 @@ int clgetIVal(char *Name, int *Val, int *N); int dbgclgetIVal(char *Name, int *Val, int *N); int clgetFVal(char *Name, float *Val, int *N); int dbgclgetFVal(char *Name, float *Val, int *N); -int clgetSVal(const char *Name, char *Val, int *N,SMap smap=SMap(),bool dbg=false); -int dbgclgetSVal(const char *Name, char *Val, int *N); int clgetNIVal(char *Key, int *Val, int *m); int dbgclgetNIVal(char *Key, int *Val, int *m); int clgetNFVal(char *Name, float *Val, int *N); @@ -164,6 +162,9 @@ int dbgclgetBVal(char *Name, bool *Val, int *N); int clgetNBVal(char *Name, bool *Val, int *N); int dbgclgetNBVal(char *Name, bool *Val, int *N); +int clgetSVal(const char *Name, char *Val, int *N,SMap smap=SMap(),bool dbg=false); +inline int dbgclgetSVal(const char *Name, char *Val, int *N) {return clgetSVal(Name,Val,N,SMap(),true);}; + #ifdef __cplusplus int clTgetOptp(const std::string& Name, std::string& Type); int clgetOptp(const std::string& Name); diff --git a/code/clgetBaseCode.h b/code/clgetBaseCode.h index 46c0ea8..a60d240 100644 --- a/code/clgetBaseCode.h +++ b/code/clgetBaseCode.h @@ -95,6 +95,11 @@ Symbol *clgetNValBaseCode(const string& Name, vector& val, int& m, const SMap { // Use templated function that works for all values of T setAutoDefaults(S,val); + if (type_int == CL_FLOATTYPE) + { + cerr << ">>>> " << S->NVals << endl; + for(auto f : S->DefaultVal) cerr << ">>>> " << f << endl; + } S->Class=CL_APPLNCLASS; if (dbg) S->Class=CL_DBGCLASS; diff --git a/code/clgetSVal.cc b/code/clgetSVal.cc index b1668c9..3b4d342 100644 --- a/code/clgetSVal.cc +++ b/code/clgetSVal.cc @@ -33,17 +33,7 @@ extern "C" { /*------------------------------------------------------------------------ Return the Nth value of Name as a string ------------------------------------------------------------------------*/ -// int clgetSVal(const char *Name, char *val, int *n) -// { -// HANDLE_EXCEPTIONS( -// string valp; -// int r; -// if ((r = clgetSValp(std::string(Name), valp, *n))!= CL_FAIL) -// strncpy(val,valp.c_str(),valp.size()+1); -// return r; -// ); -// } - int clgetSVal(const char *Name, char *val, int *n, SMap smap, bool dbg) +int clgetSVal(const char *Name, char *val, int *n, SMap smap, bool dbg) { HANDLE_EXCEPTIONS( string valp; @@ -57,15 +47,8 @@ extern "C" { } #endif -//#ifdef __cplusplus +#ifdef __cplusplus -// int clgetSValp(const string &Name, string& val, int& n) -// { -// HANDLE_EXCEPTIONS( -// SMap emptyMap; -// return clgetSValp(Name, val, n, emptyMap); -// ); -// } int clgetSValp(const string& Name, string& val, int& n, SMap &smap,bool dbg=false) { Symbol *S; @@ -90,4 +73,4 @@ HANDLE_EXCEPTIONS( return CL_FAIL; ); } -//#endif +#endif diff --git a/code/clgetValp.cc b/code/clgetValp.cc index e7ec1e0..c43dfb3 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -64,6 +64,8 @@ int clgetValpVec(const std::string& Name, std::vector& val, int& m, const SMa HANDLE_EXCEPTIONS( S=clgetNValBaseCode(Name,val,m,smap,dbg); int n0=S->NVals; + if (n0==0) n0=S->DefaultVal.size(); + cerr << "???? " << n0 << endl; int i=1; for(int j=0;j int clparseVal(Symbol *S, int *Which, T &d) { unsigned int N = _ABS(*Which); + string val; + std::vector inputVal; HANDLE_EXCEPTIONS( if (S != NULL) { - if (N > S->NVals) return 0; + if (N <= S->NVals) inputVal=S->Val; + // else + // if (N <= S->DefaultVal.size()) inputVal=S->DefaultVal; + else return 0; + //if (N > S->NVals) return 0; + if (ISSET(S->Attributes,CL_BOOLTYPE)) { int retVal; - string val(S->Val[N-1]); + // val=S->Val[N-1]; + val=inputVal[N-1]; if ((retVal=clIsTrue(val))==1) d=1; else if ((retVal=clIsFalse(val))==1) d=0; //*d = clIsTrue(val); @@ -52,7 +60,7 @@ HANDLE_EXCEPTIONS( else { double dd=d; - int n=calc((char *)S->Val[N-1].c_str(),&dd); + int n=calc((char *)inputVal[N-1].c_str(),&dd); d=dd; if (n < 0) { diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index 1cad49d..92ad85d 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -67,6 +67,112 @@ auto makeCanonicalArgs=[](std::string defFile=std::string(), // //-------------------------------------------------------------------- // +auto FactoryCanonicalTest=[]() +{ + int i; + + // bool + bool b = false; + SMap watchPoints; + VString exposedKeys = {"bool1"}; + watchPoints["1"] = exposedKeys; + i = 1; + clgetValp("bool", b, i, watchPoints); + EXPECT_FALSE(b); + + // bool1 + bool b1 = true; + ClearMap(watchPoints); + exposedKeys = {"int"}; + watchPoints["0"] = exposedKeys; + i = 1; + clgetValp("bool1", b1, i, watchPoints); + EXPECT_TRUE(b1); + + // int + int intVal = 0; + ClearMap(watchPoints); + exposedKeys = {"float"}; + watchPoints["1"] = exposedKeys; + i = 1; + clgetValp("int", intVal, i, watchPoints); + EXPECT_EQ(intVal, 0); + + // dbgint + int dbgInt = 10; + i = 1; + cldbggetValp("dbgint", dbgInt, i); + EXPECT_EQ(dbgInt, 10); + + // float + float fVal = 10.96f; + i = 1; + clgetValp("float", fVal, i); + EXPECT_FLOAT_EQ(fVal, 10.96f); + + // oneint + int oneintVal = 3; + i = 1; + clgetValp("oneint", oneintVal, i); + EXPECT_EQ(oneintVal, 3); + + // string + std::string str; + ClearMap(watchPoints); + exposedKeys = {"strarr"}; + watchPoints["showstrarr"] = exposedKeys; + exposedKeys = {"fullval"}; + watchPoints["showfullval"] = exposedKeys; + str = "showstrarr"; + i = 1; + clgetValp("string", str, i, watchPoints); + EXPECT_EQ(str, "showstrarr"); + + // { + // char sstr[100]; + // clgetSVal("string", sstr, &i, watchPoints); + // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! + // EXPECT_EQ(sstr, str); + + // clgetSVal("string", sstr, &i); + // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! + // EXPECT_EQ(sstr, str); + // } + + // fullval + std::string fullVal; + i = 0; + clgetFullValp("fullval", fullVal); + EXPECT_EQ(fullVal, ""); + + // dbgfullval + std::string dbgFullVal="This is dbg full val factory setting"; + i = 0; + dbgclgetFullValp("dbgfullval", dbgFullVal); + EXPECT_EQ(dbgFullVal, "This is dbg full val factory setting"); + + // strarr + VString strarr={"v1","v2"}; + i = 0; + clgetValp("strarr", strarr, i); + ASSERT_EQ(strarr.size(), 2u); + EXPECT_EQ(strarr[0], "v1"); + EXPECT_EQ(strarr[1], "v2"); + + // farray + std::vector fv={3.14,2*3.14,3*3.14}; + + cerr << "########## " << fv.size() << endl; + int N = 0; + int count = clgetValp("farray", fv, N); + EXPECT_EQ(count, 3); + EXPECT_FLOAT_EQ(fv[0], 3.14f); + EXPECT_FLOAT_EQ(fv[1], 2*3.14f); + EXPECT_FLOAT_EQ(fv[2], 3*3.14f); +}; +// +//-------------------------------------------------------------------- +// auto canonicalTest=[]() { int i; @@ -160,7 +266,7 @@ auto canonicalTest=[]() EXPECT_EQ(strarr[1], "val2"); // farray - std::vector fv(3); + std::vector fv; int N = 3; int count = clgetValp("farray", fv, N); EXPECT_EQ(count, 3); diff --git a/code/test/unittest/test_parafeed_interactive.cpp b/code/test/unittest/test_parafeed_interactive.cpp index 1c90b2c..881f0ed 100644 --- a/code/test/unittest/test_parafeed_interactive.cpp +++ b/code/test/unittest/test_parafeed_interactive.cpp @@ -1,4 +1,42 @@ #include +TEST_F(ParafeedTest, InteractiveFactoryCanonical) +{ + // std::vector args=makeCanonicalArgs("","help=dbg"); + std::vector args={"test2","help=dbg"}; + auto [argc, argv] = MakeArgv(args); + sendCmd("inp\n go\n"); + BeginCL(argc, argv); + { + clInteractive(0); + + FactoryCanonicalTest(); + + // // Get a pointer to the named symbol from the internal symbol + // // table. + // // + // // The following keys should be of the CL_DBGCLASS class and + // // CL_DBG_ON==true. In the interactive shell, these keys will be + // // visible. + // // + // Symbol *S; + // S=SearchVSymb("dbgint"); + // EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); + + // S=SearchVSymb("dbgfullval"); + // EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); + + // if (cl_Pass > 0) + // { + // S=SearchVSymb("int"); + // EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,1); + + // S=SearchVSymb("float"); + // EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,0); + // } + } + EndCL(); + FreeArgv(argc, argv); +} // // Test the canonical Args setting in the interactive mode. This has // "bool1=false int=42" setting. Check that bool1=false exposes diff --git a/code/tstcpp.cc b/code/tstcpp.cc index 828fb80..e729529 100644 --- a/code/tstcpp.cc +++ b/code/tstcpp.cc @@ -32,7 +32,7 @@ void UI(bool restart, int argc, char **argv) { int i,j=0,dj=11,oi=0,N; float f=0; - vector fv(10); + vector fv; VString strarr; string str; string fullVal="this is the default value"; From c9693e71610cfd7dd121e92feabef81e17ac7a5f Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Wed, 22 Apr 2026 14:29:46 -0600 Subject: [PATCH 03/11] cl.h: Added dbgclgetSVal() signature (and inline function) clgetBaseCode.h, clgetValp.cc, clparseVal.cc: Remove debugging cout setAutoDefaults.h: Setting S->Val to S->Defaults if S->NVals == 0. ParafeedTest.h: Added more tests in FactoryCanonical test. _parafeed_interactive.cpp: Using FactoryCanonical() in a new test to test the case where only factory defaults are used. --- code/cl.h | 2 +- code/clgetBaseCode.h | 5 -- code/clgetValp.cc | 3 +- code/clparseVal.h | 19 +++---- code/setAutoDefaults.h | 5 +- code/test/unittest/ParafeedTest.h | 38 +++++++++----- .../unittest/test_parafeed_interactive.cpp | 51 ++++++++++--------- code/tstcpp.cc | 2 +- 8 files changed, 70 insertions(+), 55 deletions(-) diff --git a/code/cl.h b/code/cl.h index 730726f..9a24b45 100644 --- a/code/cl.h +++ b/code/cl.h @@ -163,7 +163,7 @@ int clgetNBVal(char *Name, bool *Val, int *N); int dbgclgetNBVal(char *Name, bool *Val, int *N); int clgetSVal(const char *Name, char *Val, int *N,SMap smap=SMap(),bool dbg=false); -inline int dbgclgetSVal(const char *Name, char *Val, int *N) {return clgetSVal(Name,Val,N,SMap(),true);}; +inline int dbgclgetSVal(const char *Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name,Val,N,smap,true);}; #ifdef __cplusplus int clTgetOptp(const std::string& Name, std::string& Type); diff --git a/code/clgetBaseCode.h b/code/clgetBaseCode.h index a60d240..46c0ea8 100644 --- a/code/clgetBaseCode.h +++ b/code/clgetBaseCode.h @@ -95,11 +95,6 @@ Symbol *clgetNValBaseCode(const string& Name, vector& val, int& m, const SMap { // Use templated function that works for all values of T setAutoDefaults(S,val); - if (type_int == CL_FLOATTYPE) - { - cerr << ">>>> " << S->NVals << endl; - for(auto f : S->DefaultVal) cerr << ">>>> " << f << endl; - } S->Class=CL_APPLNCLASS; if (dbg) S->Class=CL_DBGCLASS; diff --git a/code/clgetValp.cc b/code/clgetValp.cc index c43dfb3..ebeb044 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -65,7 +65,6 @@ int clgetValpVec(const std::string& Name, std::vector& val, int& m, const SMa S=clgetNValBaseCode(Name,val,m,smap,dbg); int n0=S->NVals; if (n0==0) n0=S->DefaultVal.size(); - cerr << "???? " << n0 << endl; int i=1; for(int j=0;j& val, int& n, SMap smap // These calls are used in other parts of parafeed code. This file // therefore needs to be compiled into the libparafeed library for // internal linking. -// +// template inline int cldbggetValp(const std::string& Name, T& val, int& n) {return dbgclgetValp(Name,val,n);} diff --git a/code/clparseVal.h b/code/clparseVal.h index f010fab..5c7ab77 100644 --- a/code/clparseVal.h +++ b/code/clparseVal.h @@ -33,21 +33,22 @@ int clparseVal(Symbol *S, int *Which, T &d) { unsigned int N = _ABS(*Which); string val; - std::vector inputVal; HANDLE_EXCEPTIONS( if (S != NULL) { - if (N <= S->NVals) inputVal=S->Val; - // else - // if (N <= S->DefaultVal.size()) inputVal=S->DefaultVal; - else return 0; - //if (N > S->NVals) return 0; + // Transfer S-DefaultVal to S->Val if S->NVals == 0. Is this + // always the correct thing to do? + if (S->NVals == 0) + { + S->Val=S->DefaultVal; + S->NVals = S->Val.size(); + }; + if (N > S->NVals) return 0; if (ISSET(S->Attributes,CL_BOOLTYPE)) { int retVal; - // val=S->Val[N-1]; - val=inputVal[N-1]; + val=S->Val[N-1]; if ((retVal=clIsTrue(val))==1) d=1; else if ((retVal=clIsFalse(val))==1) d=0; //*d = clIsTrue(val); @@ -60,7 +61,7 @@ HANDLE_EXCEPTIONS( else { double dd=d; - int n=calc((char *)inputVal[N-1].c_str(),&dd); + int n=calc((char *)S->Val[N-1].c_str(),&dd); d=dd; if (n < 0) { diff --git a/code/setAutoDefaults.h b/code/setAutoDefaults.h index 1362a27..5a346cd 100644 --- a/code/setAutoDefaults.h +++ b/code/setAutoDefaults.h @@ -38,7 +38,8 @@ void setAutoDefaults(Symbol *S, T const & val) { std::vector tmp; tmp.push_back(val); - setAutoDefaults(S, tmp); + // If S->Val.size() == 0, always set S->Val = S->DefaultVal; + setAutoDefaults(S, tmp,true); return; } /*---------------------------------------------------------------------------*/ @@ -59,7 +60,7 @@ void setAutoDefaults(Symbol *S, const vector& val,const bool def2val=false) S->DefaultVal[i] = os.str(); } } - + if (def2val) { if (S->Val.size() == 0) diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index 92ad85d..f6fa817 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -66,7 +66,7 @@ auto makeCanonicalArgs=[](std::string defFile=std::string(), }; // //-------------------------------------------------------------------- -// +// auto FactoryCanonicalTest=[]() { int i; @@ -128,16 +128,31 @@ auto FactoryCanonicalTest=[]() clgetValp("string", str, i, watchPoints); EXPECT_EQ(str, "showstrarr"); - // { - // char sstr[100]; - // clgetSVal("string", sstr, &i, watchPoints); - // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! - // EXPECT_EQ(sstr, str); - - // clgetSVal("string", sstr, &i); - // //EXPECT_EQ(sstr, "showstrarr");// DOES NOT WORK! - // EXPECT_EQ(sstr, str); - // } + // Test backward compatible API: [dbg]clgetSVal(...,[watchPoints]) + { + char sstr[100]; + clgetSVal("string", sstr, &i, watchPoints); + // EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! + EXPECT_EQ(str, sstr); + } + { + char sstr[100]; + clgetSVal("string", sstr, &i); + // EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! + EXPECT_EQ(str, sstr); + } + { + char sstr[100]; + dbgclgetSVal("string", sstr, &i,watchPoints); + //EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! + EXPECT_EQ(sstr, str); + } + { + char sstr[100]; + dbgclgetSVal("string", sstr, &i); + //EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! + EXPECT_EQ(sstr, str); + } // fullval std::string fullVal; @@ -162,7 +177,6 @@ auto FactoryCanonicalTest=[]() // farray std::vector fv={3.14,2*3.14,3*3.14}; - cerr << "########## " << fv.size() << endl; int N = 0; int count = clgetValp("farray", fv, N); EXPECT_EQ(count, 3); diff --git a/code/test/unittest/test_parafeed_interactive.cpp b/code/test/unittest/test_parafeed_interactive.cpp index 881f0ed..acfed35 100644 --- a/code/test/unittest/test_parafeed_interactive.cpp +++ b/code/test/unittest/test_parafeed_interactive.cpp @@ -1,38 +1,43 @@ #include +// +// Test for default factory settings (i.e., defaults in the compiled +// code). TEST_F(ParafeedTest, InteractiveFactoryCanonical) { // std::vector args=makeCanonicalArgs("","help=dbg"); std::vector args={"test2","help=dbg"}; auto [argc, argv] = MakeArgv(args); - sendCmd("inp\n go\n"); + sendCmd("go\n"); BeginCL(argc, argv); { clInteractive(0); FactoryCanonicalTest(); - // // Get a pointer to the named symbol from the internal symbol - // // table. - // // - // // The following keys should be of the CL_DBGCLASS class and - // // CL_DBG_ON==true. In the interactive shell, these keys will be - // // visible. - // // - // Symbol *S; - // S=SearchVSymb("dbgint"); - // EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); - - // S=SearchVSymb("dbgfullval"); - // EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); - - // if (cl_Pass > 0) - // { - // S=SearchVSymb("int"); - // EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,1); - - // S=SearchVSymb("float"); - // EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,0); - // } + // Get a pointer to the named symbol from the internal symbol + // table. + // + // The following keys should be of the CL_DBGCLASS class and + // CL_DBG_ON==true. In the interactive shell, these keys will be + // visible. + // + Symbol *S; + S=SearchVSymb("dbgint"); + EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); + + S=SearchVSymb("dbgfullval"); + EXPECT_EQ(CL_DBG_ON && S->Class==CL_DBGCLASS, true); + + if (cl_Pass > 0) + { + // default settings are bool=false. That hides "int", which + // hides "float" + S=SearchVSymb("int"); + EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,0); + + S=SearchVSymb("float"); + EXPECT_NE(S,nullptr); EXPECT_EQ(S->Exposed,0); + } } EndCL(); FreeArgv(argc, argv); diff --git a/code/tstcpp.cc b/code/tstcpp.cc index e729529..828fb80 100644 --- a/code/tstcpp.cc +++ b/code/tstcpp.cc @@ -32,7 +32,7 @@ void UI(bool restart, int argc, char **argv) { int i,j=0,dj=11,oi=0,N; float f=0; - vector fv; + vector fv(10); VString strarr; string str; string fullVal="this is the default value"; From 4668f07e022bddcccd9ba3f7542b88d5d403ca0e Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Thu, 23 Apr 2026 12:49:57 -0600 Subject: [PATCH 04/11] clgetValp.cc: Added [dbg]clgetSVal(string&, char *,...) interfaces. ParafeedTest.h: Added tests for the above interface. --- code/clgetValp.cc | 3 +++ code/test/unittest/ParafeedTest.h | 25 +++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/code/clgetValp.cc b/code/clgetValp.cc index ebeb044..d890505 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -161,6 +161,9 @@ inline int clgetNBValp(const std::string& Name, std::vector& val, int& n) inline int clgetNBValp(const std::string& Name, std::vector& val, int& n, SMap &smap){return clgetValp(Name,val,n,smap);} //inline int clgetSVal(const char *Name, char *val, int *n) {return clgetValp(std::string(Name), val, *n);} +inline int clgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,false);}; +inline int dbgclgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,true);}; + inline int clgetSValp(const std::string& Name, std::string& val, int &n) {return clgetValp(Name,val,n);} inline int clgetSValp(const std::string& Name, std::string& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} inline int clgetNSValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index f6fa817..8c49e9f 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -129,29 +129,38 @@ auto FactoryCanonicalTest=[]() EXPECT_EQ(str, "showstrarr"); // Test backward compatible API: [dbg]clgetSVal(...,[watchPoints]) + // ensuring that sstr goes out of scope after each call to + // clgetSVal(). { char sstr[100]; clgetSVal("string", sstr, &i, watchPoints); - // EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! - EXPECT_EQ(str, sstr); + EXPECT_EQ(string("showstrarr"),sstr); } { char sstr[100]; clgetSVal("string", sstr, &i); - // EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! - EXPECT_EQ(str, sstr); + EXPECT_EQ(string("showstrarr"),sstr); } { char sstr[100]; dbgclgetSVal("string", sstr, &i,watchPoints); - //EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! - EXPECT_EQ(sstr, str); + EXPECT_EQ(string("showstrarr"),sstr); } { char sstr[100]; dbgclgetSVal("string", sstr, &i); - //EXPECT_EQ("showstrarr",sstr);// DOES NOT WORK! - EXPECT_EQ(sstr, str); + EXPECT_EQ(string("showstrarr"),sstr); + } + // Check for clgetSVal(string&, char *, int *, SMap) interface. + { + char sstr[100]; + clgetSVal(string("string"), sstr, &i, watchPoints); + EXPECT_EQ(string("showstrarr"),sstr); + } + { + char sstr[100]; + dbgclgetSVal(string("string"), sstr, &i); + EXPECT_EQ(string("showstrarr"),sstr); } // fullval From b23ef307bf0d68905394708818d7ce02d1ab0a67 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Thu, 23 Apr 2026 18:28:21 -0600 Subject: [PATCH 05/11] Text cleanup only (M-x rm-whitespaces). --- code/cl.h | 10 +++++----- code/clgetBaseCode.h | 6 +++--- code/clgetFullVal.cc | 2 +- code/clparseVal.cc | 8 ++++---- code/clstring.cc | 22 +++++++++++----------- code/clstring.h | 6 +++--- code/test/unittest/ParafeedTest.h | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/code/cl.h b/code/cl.h index 9a24b45..3478ff7 100644 --- a/code/cl.h +++ b/code/cl.h @@ -56,7 +56,7 @@ { \ throw; \ } - + #else #define HANDLE_EXCEPTIONS(str) str @@ -73,9 +73,9 @@ extern "C" { #define CL_SEVERE -20 #define CL_FATAL -10 #define CL_WARNING -5 - /* + /* Define readline stuff as readline.h is - NOT ANSI C + NOT ANSI C */ #ifdef __cplusplus /* @@ -127,7 +127,7 @@ extern int add_history(char *); Symbol *IntallSymb(char *, char *, Symbol *); Symbol *SearchQSymb(const std::string& Name, const std::string& Type); Symbol *SearchVSymb(const char *Name, Symbol *Tab); - Symbol *AddQKey(const char *Name, const char *Type, + Symbol *AddQKey(const char *Name, const char *Type, Symbol **Head, Symbol **Tail); int ParseCmdLine(int, char **); std::vector clMakeArgvFromFile(const std::string& Name); @@ -197,7 +197,7 @@ std::string stripwhitep (std::string& str); int redirect(char *, char *); void yyerror(char *); int clgetConfigFile(char *, char *); -int AddCmd(const char *Name, char *Doc, int (*func)(char *), +int AddCmd(const char *Name, char *Doc, int (*func)(char *), CmdSymbol **Head, CmdSymbol **Tail); int BreakStr(char *, char **, char **); int BreakStrp(const std::string& str, std::string& Name, std::string& Val, diff --git a/code/clgetBaseCode.h b/code/clgetBaseCode.h index 46c0ea8..2c18ee0 100644 --- a/code/clgetBaseCode.h +++ b/code/clgetBaseCode.h @@ -56,7 +56,7 @@ Symbol* clgetBaseCode(const string& Name, T& val, int& n, SMap &smap=SMap(), boo else S=SearchQSymb((char *)Name.c_str(),type_str); - if (S!=NULL) + if (S!=NULL) { // Use templated function that works for all values of T setAutoDefaults(S,val); @@ -74,7 +74,7 @@ Symbol* clgetBaseCode(const string& Name, T& val, int& n, SMap &smap=SMap(), boo }; // -// Templated functions for NVal calls. +// Templated functions for NVal calls. // template Symbol *clgetNValBaseCode(const string& Name, vector& val, int& m, const SMap &smap=SMap(), bool dbg=false) @@ -91,7 +91,7 @@ Symbol *clgetNValBaseCode(const string& Name, vector& val, int& m, const SMap HANDLE_EXCEPTIONS( S = SearchQSymb((char *)Name.c_str(), os.str()); - if (S!=NULL) + if (S!=NULL) { // Use templated function that works for all values of T setAutoDefaults(S,val); diff --git a/code/clgetFullVal.cc b/code/clgetFullVal.cc index ed42a73..4a85389 100644 --- a/code/clgetFullVal.cc +++ b/code/clgetFullVal.cc @@ -91,7 +91,7 @@ Symbol* clgetFullValpBase(const string& Name, string& val, bool dbg) // Do not modify val if S->Val is empty. The // in-comming val may have a default value // that is not yet tranferred to S-Val. - if (S->NVals > 0) + if (S->NVals > 0) val = vecStr2Str(S->Val); } ); diff --git a/code/clparseVal.cc b/code/clparseVal.cc index b671ae4..4cb45ce 100644 --- a/code/clparseVal.cc +++ b/code/clparseVal.cc @@ -45,15 +45,15 @@ extern "C" { int clparseVal(Symbol *S, int *Which, string& val) { unsigned int N = _ABS(*Which); - - if (S!=NULL) + + if (S!=NULL) { - if (N <= S->NVals) + if (N <= S->NVals) { val = trim(S->Val[N-1]); return val.size(); } - else + else return CL_FAIL; } else diff --git a/code/clstring.cc b/code/clstring.cc index f6e8b1d..233c4e9 100644 --- a/code/clstring.cc +++ b/code/clstring.cc @@ -43,7 +43,7 @@ int ntok(char *str, const char *sep,char esc) if (!STRING && str[i]==sep[0] && (str[i-1] != esc)) count++; } if (STRING && str[i]=='"' && str[i-1] != esc) STRING=0; - if (i>=N && STRING) + if (i>=N && STRING) { fprintf(stderr,"###Error: Missing \'\"\'\n"); return -1; @@ -51,13 +51,13 @@ int ntok(char *str, const char *sep,char esc) return count+1; } /*------------------------------------------------------------------------ - Given a null terminated string, this will write the string on the file - pointed to by fd. Special characters ',','"' and esc are escaped + Given a null terminated string, this will write the string on the file + pointed to by fd. Special characters ',','"' and esc are escaped using the char. esc. ------------------------------------------------------------------------*/ int tokenize(FILE *fd, char *str, const char *sep,char esc) { - while(*str) + while(*str) { //if (!strncmp(str,"/*",2)) // { @@ -89,10 +89,10 @@ char *clstrtok(char *str, const char *sep,char esc) if (!strncmp(&t[i],"/*",2)) { while(i < len) - if (!strncmp(&t[i++],"*/",2)) + if (!strncmp(&t[i++],"*/",2)) {i++;break;} } - if (!STRING && t[i] == esc) + if (!STRING && t[i] == esc) { int j=i+1; while (j<=len) {t[j-1]=t[j];j++;} @@ -101,7 +101,7 @@ char *clstrtok(char *str, const char *sep,char esc) else if (!STRING && t[i]==sep[0]) break; else { - if (t[i]=='"') + if (t[i]=='"') { int j=i+1; while (j<=len) {t[j-1]=t[j];j++;} @@ -116,25 +116,25 @@ char *clstrtok(char *str, const char *sep,char esc) if (prev >= len) return NULL; else t[i]='\0'; return &t[prev]; -} +} /*------------------------------------------------------------------------ Bunch of functions to remove whitespaces from a given string ------------------------------------------------------------------------*/ // const std::string WHITESPACE = " \n\r\t\f\v"; - + // std::string ltrim(const std::string &s) // { // size_t start = s.find_first_not_of(WHITESPACE); // return (start == std::string::npos) ? std::string("") : s.substr(start); // } - + // std::string rtrim(const std::string &s) // { // size_t end = s.find_last_not_of(WHITESPACE); // return (end == std::string::npos) ? std::string("") : s.substr(0, end + 1); // } - + // std::string trim(const std::string &s) { // string tt=rtrim(ltrim(s)); // return tt; diff --git a/code/clstring.h b/code/clstring.h index 901e389..d8c89e6 100644 --- a/code/clstring.h +++ b/code/clstring.h @@ -37,19 +37,19 @@ extern "C" { // std::string trim(const std::string &s); const std::string CL_STRING_WHITESPACE = " \n\r\t\f\v"; - + inline std::string ltrim(const std::string &s) { size_t start = s.find_first_not_of(CL_STRING_WHITESPACE); return (start == std::string::npos) ? std::string("") : s.substr(start); } - + inline std::string rtrim(const std::string &s) { size_t end = s.find_last_not_of(CL_STRING_WHITESPACE); return (end == std::string::npos) ? std::string("") : s.substr(0, end + 1); } - + inline std::string trim(const std::string &s) { string tt=rtrim(ltrim(s)); return tt; diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index 8c49e9f..6da3a35 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -66,7 +66,7 @@ auto makeCanonicalArgs=[](std::string defFile=std::string(), }; // //-------------------------------------------------------------------- -// +// auto FactoryCanonicalTest=[]() { int i; From 70ede99353b0623b35e74bd966b338f7084b7c93 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Thu, 23 Apr 2026 20:44:39 -0600 Subject: [PATCH 06/11] ParafeedTest.h: Test using different vectors in cl_Pass == 0 and cl_Pass > 0 --- code/test/unittest/ParafeedTest.h | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index 6da3a35..6d2479e 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -185,13 +185,27 @@ auto FactoryCanonicalTest=[]() // farray std::vector fv={3.14,2*3.14,3*3.14}; - + std::vector fv0; int N = 0; - int count = clgetValp("farray", fv, N); + int count; + + // Test that the values returned after the "go" command are actually + // filled from internal symbol table. + if (cl_Pass == 0) + { + // Registeration Pass: fv is used for factory setting. + count = clgetValp("farray", fv, N); + } + else + { + // Get the values in a vector different from the vector used to + // set the defaults (fv) + count = clgetValp("farray", fv0, N); + EXPECT_FLOAT_EQ(fv0[0], 3.14f); + EXPECT_FLOAT_EQ(fv0[1], 2*3.14f); + EXPECT_FLOAT_EQ(fv0[2], 3*3.14f); + } EXPECT_EQ(count, 3); - EXPECT_FLOAT_EQ(fv[0], 3.14f); - EXPECT_FLOAT_EQ(fv[1], 2*3.14f); - EXPECT_FLOAT_EQ(fv[2], 3*3.14f); }; // //-------------------------------------------------------------------- From 49d725d354595e3f91fb6980f195752fff94f65e Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Mon, 27 Apr 2026 14:39:46 -0600 Subject: [PATCH 07/11] calgetValp.cc: removed 'inline' from clgetSVal(...,char *,...). ParseCmdLine.cc: Enabled loadDefaults() in startShell(). _interactive.cpp: Added the test for auto loding the .def file, if found. Whitespace cleanup throughout. --- code/ErrorObj.h | 6 +- code/ParseCmdLine.cc | 2 +- code/SetVar.cc | 15 ++- code/callbacks.cc | 93 ++++++++++------- code/clgetValp.cc | 10 +- .../unittest/test_parafeed_interactive.cpp | 99 +++++++++++++++++++ 6 files changed, 175 insertions(+), 50 deletions(-) diff --git a/code/ErrorObj.h b/code/ErrorObj.h index 76bbadb..67f3289 100644 --- a/code/ErrorObj.h +++ b/code/ErrorObj.h @@ -33,7 +33,7 @@ class ErrorObj: public std::exception{ // Id.resize(0);Msg.resize(0);Src.resize(0);Message.resize(0);}; ErrorObj(const char *m, const char *i, int l=0): - Id(i), Msg(m), Src(), Message(),Level(l) + Id(i), Msg(m), Src(), Message(),Level(l) {}; ErrorObj(const string &m, const string &i, int l): @@ -43,10 +43,12 @@ class ErrorObj: public std::exception{ ErrorObj(const ErrorObj& that); ~ErrorObj() {}; - + void SetSource(const char *m=0); + void SetMsg(const string& m) {Msg=m;} const char *Source() {return Src.c_str();} int Severity() {return Level;} + string GetMsg() {return Msg;}; const char *what(); ostream &operator<<(const std::string& m) {return cerr << m;} diff --git a/code/ParseCmdLine.cc b/code/ParseCmdLine.cc index 4805169..bce4e4b 100644 --- a/code/ParseCmdLine.cc +++ b/code/ParseCmdLine.cc @@ -383,7 +383,7 @@ int startShell() { if (!cl_defaultsLoaded) /* Load the defaults */ { - loadDefaults(1); cl_defaultsLoaded=1; + loadDefaults(0); cl_defaultsLoaded=1; } if (doInp && !cl_NoPrompt) { diff --git a/code/SetVar.cc b/code/SetVar.cc index 71e9a85..684e0bd 100644 --- a/code/SetVar.cc +++ b/code/SetVar.cc @@ -87,7 +87,7 @@ int UnsetVar(Symbol *S, int setFactoryDefaults) if(pos==0) return -2; // if (pos->Exposed!=1) // { - // string msg="Attempted modification of a hidden variable (named \'" + string(pos->Name) + "\')."; + // string msg="Attempted modification of a hidden variable (named \'" + string(pos->Name) + "\')."; // //clThrowUp(msg.c_str(),"###Error",CL_INFORMATIONAL); // clError x(msg.c_str(),"###Error",CL_INFORMATIONAL); // throw(x); @@ -97,12 +97,12 @@ int UnsetVar(Symbol *S, int setFactoryDefaults) if (!Force) if (pos->Class == CL_USERCLASS) { - string msg="Attempted modification of a shell-constant (named \'" + string(pos->Name) + "\'). Ignored."; + string msg="Attempted modification of a shell-constant (named \'" + string(pos->Name) + "\'). Ignored."; clThrowUp(msg.c_str(),"###Error",CL_INFORMATIONAL); return -2; } - if ((val==NULL) || (strlen(val) == 0)) + if ((val==NULL) || (strlen(val) == 0)) { ret= UnsetVar(pos,1); } @@ -176,7 +176,7 @@ std::function noMatchExceptionLambda_ptr=noMatchException; newval=v; // if (S->Exposed!=1) // { - // string msg="Attempted modification of a hidden variable (named \'" + string(S->Name) + "\')."; + // string msg="Attempted modification of a hidden variable (named \'" + string(S->Name) + "\')."; // //clThrowUp(msg.c_str(),"###Error",CL_INFORMATIONAL); // clError x(msg.c_str(),"###Error",CL_INFORMATIONAL); // throw(x); @@ -242,7 +242,12 @@ void SetVal(const char *v, Symbol *S, int i) { // Same as cerr << x.what(), except that the output // stream is centrally specified in clError. - x << x << " at position " << i << endl; + std::stringstream msg; + + msg << x.GetMsg(); + if (i > 0) msg << " at position " << i; + //x << msg.str().c_str() << endl; + x.SetMsg(msg.str()); throw(x); } diff --git a/code/callbacks.cc b/code/callbacks.cc index ae99819..0e74080 100644 --- a/code/callbacks.cc +++ b/code/callbacks.cc @@ -487,6 +487,7 @@ int dosavefd(FILE *fd, const std::vector& opts) ifs.open(defFile.c_str()); + std::stringstream errorMessages; if (!ifs.good()) { clThrowUp(std::string("Error in opening file \"")+defFile+std::string("\""), "###Error", CL_FATAL); @@ -495,54 +496,72 @@ int dosavefd(FILE *fd, const std::vector& opts) else { Symbol *pos; - + uint lineNo=0; while(!ifs.eof()) { string line; - if (getline(ifs,line)) + try { - stripwhitep(line); - if ((line.size() > 0) && (line[0] != '#')) + if (getline(ifs,line)) { - // Separate the line into name and value strings - // separated by the first '=' char. Strip the - // white spaces. - std::string Name_str, Val_str; - BreakStrp(line,Name_str,Val_str); - stripwhitep(Name_str); - stripwhitep(Val_str); - - // Seperate the Name string into scope and Name - // string seperated by ':' - std::string Scope_str; - BreakStrp(Name_str, Scope_str, Name_str,"::"); - stripwhitep(Name_str); - stripwhitep(Scope_str); - if (Name_str == Scope_str) Scope_str=""; - - pos = NULL; - if ((Scope_str == "") || (Scope_str == ProgName())) + lineNo++; + stripwhitep(line); + if ((line.size() > 0) && (line[0] != '#')) { - if (Complement) - { - pos=SearchVSymbFullMatch(Name_str.c_str(), - cl_SymbTab); - if ((pos == (Symbol *)NULL)) - pos=AddVar(Name_str.c_str(),&cl_SymbTab, - &cl_TabTail); - if ((pos->NVals == 0)) - pos = (Symbol *)NULL; - } - if (pos==NULL) + // Separate the line into name and value strings + // separated by the first '=' char. Strip the + // white spaces. + std::string Name_str, Val_str; + BreakStrp(line,Name_str,Val_str); + stripwhitep(Name_str); + stripwhitep(Val_str); + + // Seperate the Name string into scope and Name + // string seperated by ':' + std::string Scope_str; + BreakStrp(Name_str, Scope_str, Name_str,"::"); + stripwhitep(Name_str); + stripwhitep(Scope_str); + if (Name_str == Scope_str) Scope_str=""; + + pos = NULL; + if ((Scope_str == "") || (Scope_str == ProgName())) { - if (doregister) - pos=AddVar(Name_str.c_str(),&cl_SymbTab,&cl_TabTail); - SetVar((char*)Name_str.c_str(),(char *)Val_str.c_str(), - cl_SymbTab,0,1,cl_do_doinp); + if (Complement) + { + pos=SearchVSymbFullMatch(Name_str.c_str(), + cl_SymbTab); + if ((pos == (Symbol *)NULL)) + pos=AddVar(Name_str.c_str(),&cl_SymbTab, + &cl_TabTail); + if ((pos->NVals == 0)) + pos = (Symbol *)NULL; + } + if (pos==NULL) + { + if (doregister) + pos=AddVar(Name_str.c_str(),&cl_SymbTab,&cl_TabTail); + SetVar((char*)Name_str.c_str(),(char *)Val_str.c_str(), + cl_SymbTab,0,1,cl_do_doinp); + } } } } } + catch(clError& x) + { + errorMessages + << "In " << defFile << ":" << lineNo << endl + << x + << endl << "-----------------------" << endl; + } + } + if (!errorMessages.str().empty()) + { + clExit x("","###Error",CL_INFORMATIONAL); + x.SetMsg(errorMessages.str()); + x << x << endl; + throw(x); } // Set all symbols loaded in the table to USERCLASS. The ones // that get queried (via clget*Val() functions) are converted diff --git a/code/clgetValp.cc b/code/clgetValp.cc index d890505..73a7466 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -164,11 +164,11 @@ inline int clgetNBValp(const std::string& Name, std::vector& val, int& n, inline int clgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,false);}; inline int dbgclgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,true);}; -inline int clgetSValp(const std::string& Name, std::string& val, int &n) {return clgetValp(Name,val,n);} -inline int clgetSValp(const std::string& Name, std::string& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetNSValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} -inline int clgetNSValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetNSValp(const std::string& Name, std::vector& val, int& n, const SMap smap) {return clgetValp(Name,val,n,smap);} +int clgetSValp(const std::string& Name, std::string& val, int &n) {return clgetValp(Name,val,n);} +int clgetSValp(const std::string& Name, std::string& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetNSValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} +int clgetNSValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetNSValp(const std::string& Name, std::vector& val, int& n, const SMap smap) {return clgetValp(Name,val,n,smap);} inline int cldbggetIValp(const std::string& Name, int& val, int& n) {return dbgclgetValp(Name,val,n);} inline int cldbggetFValp(const std::string& Name, float& val, int& n) {return dbgclgetValp(Name,val,n);} diff --git a/code/test/unittest/test_parafeed_interactive.cpp b/code/test/unittest/test_parafeed_interactive.cpp index acfed35..5568cea 100644 --- a/code/test/unittest/test_parafeed_interactive.cpp +++ b/code/test/unittest/test_parafeed_interactive.cpp @@ -84,6 +84,105 @@ TEST_F(ParafeedTest, InteractiveCanonical) EndCL(); FreeArgv(argc, argv); } + +TEST_F(ParafeedTest, InteractiveDefFile) +{ + std::vector args = + { + "test2", + //"help=noprompt", + "bool=x", + "oneint=xy", + "string=showstrarr", + "strarr=foo,barrr", + "farray=1,3,4,5,6,7,8,9,10" + }; + + std::string defFile("test2.def"); + std::remove(defFile.c_str()); + makeDefFile(args,defFile); + + args={"test2"}; + + auto [argc, argv] = MakeArgv(args); + + // sendCmd() sets the parser input stream to be the given string. + // The parser scans this string in the interactive shell (started + // in the EndCL() call below). + + sendCmd("bool=true\n strarr=foo,bar\n oneint=100\n fullval=this is full val\n inp\n go\n"); + + BeginCL(argc, argv); + clInteractive(1); + + bool b = false; + int oneint = 0; + int N = 10; + int i = 1; + + std::string s; + std::vector strarr; + std::vector farray(N); + string fullVal="this is the default value"; + + i=1;clgetValp("bool", b, i); + + i=1; + + // + // The setting from argv is used in the first pass + // (a.k.a. "registeration pass"). Without the "help=noprompt" + // detected in this first pass, the EndCL() call starts the + // interactive shell, which triggers the second pass on the "go" + // command (setjmp() called in EndCL() to restart execution from + // the location of the clInteractive() call). In this second pass + // the interactive settings (here, vis the sendCmd() call) + // replaces the values which are then available in the clgetValp() + // calls. + // + // if (cl_Pass == 0) // cl_Pass is a global parafeed lib. control + // // variable + // EXPECT_THROW(clgetValp("oneint", oneint, i),clError); + // else + clgetValp("oneint", oneint, i); + + i=1;clgetValp("string", s, i); + + i=0;clgetValp("strarr", strarr, i); + + clgetValp("farray", farray, N); + + i=0;clgetFullValp("fullval",fullVal); + + try + { + if (cl_Pass == 0) + { + // Registraction pass should throw clExit() exception + cerr << "[INFO] parafeed Registeration pass..." << endl; + EXPECT_THROW(EndCL(),clExit); + } + else + { + // This should never be reached. + cerr << "[INFO] parafeed post-regsitration pass..." << endl; + EndCL(); + + // Expect the value as set interactively vis sendCmd() + EXPECT_EQ(oneint,100); + EXPECT_EQ(fullVal,"this is full val"); + } + } + catch(clExit& x) + { + x << x << endl; + } + + std::remove(defFile.c_str()); + FreeArgv(argc, argv); +} + + // //-------------------------------------------------------------------- // Test for incorrect values in argv. Here, oneint=x, instead of a From e250d32837b0b1f863dd61a9e8a6dd1e993b8623 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Tue, 28 Apr 2026 21:22:20 -0600 Subject: [PATCH 08/11] Added top-level include file parafeed.h Reverted to complining clgetValp.cc. Keeping it header-only needs carefully organized code (especially templates). Using parafeed.h in testing code. Added copyright header where it was missing. --- code/CMakeLists.txt | 2 +- code/ParseCmdLine.cc | 2 +- code/clgetValp.cc | 68 +++++++++---------- code/clgetValp.h | 2 +- code/parafeed.h | 24 +++++++ code/test/tst2.cc | 4 +- code/test/unittest/CMakeLists.txt | 16 +++++ code/test/unittest/ParafeedTest.h | 23 +++++-- .../unittest/test_parafeed_interactive.cpp | 25 ++++++- .../unittest/test_parafeed_noninteractive.cpp | 18 +++++ code/tstcpp.cc | 5 +- 11 files changed, 140 insertions(+), 49 deletions(-) create mode 100644 code/parafeed.h diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 15d012e..21b16f9 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -180,7 +180,7 @@ set(shccl_sources # clgetNSVal.cc clgetFullVal.cc -# clgetValp.cc + clgetValp.cc clStartInteractive.cc clRestartShell.cc clfInteractive.cc diff --git a/code/ParseCmdLine.cc b/code/ParseCmdLine.cc index bce4e4b..c5c94cf 100644 --- a/code/ParseCmdLine.cc +++ b/code/ParseCmdLine.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012, 2013 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + * Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/code/clgetValp.cc b/code/clgetValp.cc index 73a7466..078914a 100644 --- a/code/clgetValp.cc +++ b/code/clgetValp.cc @@ -143,26 +143,26 @@ int dbgclgetValp(const std::string& Name, std::vector& val, int& n, SMap smap // template -inline int cldbggetValp(const std::string& Name, T& val, int& n) {return dbgclgetValp(Name,val,n);} +int cldbggetValp(const std::string& Name, T& val, int& n) {return dbgclgetValp(Name,val,n);} -inline int clgetFValp(const std::string& Name, float& val, int& n) {return clgetValp(Name,val,n);} -inline int clgetFValp(const std::string& Name, float& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetNFValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} -inline int clgetNFValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetFValp(const std::string& Name, float& val, int& n) {return clgetValp(Name,val,n);} +int clgetFValp(const std::string& Name, float& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetNFValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} +int clgetNFValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetIValp(const std::string& Name, int &val, int &n) {return clgetValp(Name,val,n);} -inline int clgetIValp(const std::string& Name, int& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetNIValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} -inline int clgetNIValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetIValp(const std::string& Name, int &val, int &n) {return clgetValp(Name,val,n);} +int clgetIValp(const std::string& Name, int& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetNIValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} +int clgetNIValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetBValp(const std::string& Name, bool& val, int &n) {return clgetValp(Name,val,n);} -inline int clgetBValp(const std::string& Name, bool& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} -inline int clgetNBValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} -inline int clgetNBValp(const std::string& Name, std::vector& val, int& n, SMap &smap){return clgetValp(Name,val,n,smap);} +int clgetBValp(const std::string& Name, bool& val, int &n) {return clgetValp(Name,val,n);} +int clgetBValp(const std::string& Name, bool& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} +int clgetNBValp(const std::string& Name, std::vector& val, int& n) {return clgetValp(Name,val,n);} +int clgetNBValp(const std::string& Name, std::vector& val, int& n, SMap &smap){return clgetValp(Name,val,n,smap);} //inline int clgetSVal(const char *Name, char *val, int *n) {return clgetValp(std::string(Name), val, *n);} -inline int clgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,false);}; -inline int dbgclgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,true);}; +int clgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,false);}; +int dbgclgetSVal(const string& Name, char *Val, int *N, SMap smap=SMap()) {return clgetSVal(Name.c_str(),Val,N,smap,true);}; int clgetSValp(const std::string& Name, std::string& val, int &n) {return clgetValp(Name,val,n);} int clgetSValp(const std::string& Name, std::string& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} @@ -170,23 +170,23 @@ int clgetNSValp(const std::string& Name, std::vector& val, int& n) int clgetNSValp(const std::string& Name, std::vector& val, int& n, SMap &smap) {return clgetValp(Name,val,n,smap);} int clgetNSValp(const std::string& Name, std::vector& val, int& n, const SMap smap) {return clgetValp(Name,val,n,smap);} -inline int cldbggetIValp(const std::string& Name, int& val, int& n) {return dbgclgetValp(Name,val,n);} -inline int cldbggetFValp(const std::string& Name, float& val, int& n) {return dbgclgetValp(Name,val,n);} -inline int cldbggetBValp(const std::string& Name, bool& val, int& n) {return dbgclgetValp(Name,val,n);} -inline int cldbggetSValp(const std::string& Name, std::string& val, int& n) {return dbgclgetValp(Name,val,n);} - -inline int cldbggetIValp(const std::string& Name, int& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} -inline int cldbggetFValp(const std::string& Name, float& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} -inline int cldbggetBValp(const std::string& Name, bool& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n, smap);} -inline int cldbggetSValp(const std::string& Name, std::string& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} - -inline int cldbggetNIValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} -inline int cldbggetNFValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} -inline int cldbggetNBValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} -inline int cldbggetNSValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} - -inline int cldbggetNIValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} -inline int cldbggetNFValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} -inline int cldbggetNBValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} -inline int cldbggetNSValp(const std::string& Key, std::vector& val, int& m, SMap& smap){return dbgclgetValp(Key, val, m,smap);} +int cldbggetIValp(const std::string& Name, int& val, int& n) {return dbgclgetValp(Name,val,n);} +int cldbggetFValp(const std::string& Name, float& val, int& n) {return dbgclgetValp(Name,val,n);} +int cldbggetBValp(const std::string& Name, bool& val, int& n) {return dbgclgetValp(Name,val,n);} +int cldbggetSValp(const std::string& Name, std::string& val, int& n) {return dbgclgetValp(Name,val,n);} + +int cldbggetIValp(const std::string& Name, int& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} +int cldbggetFValp(const std::string& Name, float& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} +int cldbggetBValp(const std::string& Name, bool& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n, smap);} +int cldbggetSValp(const std::string& Name, std::string& val, int& n, SMap& smap) {return dbgclgetValp(Name,val,n,smap);} + +int cldbggetNIValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} +int cldbggetNFValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} +int cldbggetNBValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} +int cldbggetNSValp(const std::string& Key, std::vector& val, int& m) {return dbgclgetValp(Key, val, m);} + +int cldbggetNIValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} +int cldbggetNFValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} +int cldbggetNBValp(const std::string& Key, std::vector& val, int& m, SMap& smap) {return dbgclgetValp(Key, val, m,smap);} +int cldbggetNSValp(const std::string& Key, std::vector& val, int& m, SMap& smap){return dbgclgetValp(Key, val, m,smap);} #endif diff --git a/code/clgetValp.h b/code/clgetValp.h index e11c489..63c27d5 100644 --- a/code/clgetValp.h +++ b/code/clgetValp.h @@ -30,5 +30,5 @@ //---------------------------------------------------------------------- // Templated code and wrapper functions // -#include +//#include #endif diff --git a/code/parafeed.h b/code/parafeed.h new file mode 100644 index 0000000..b9a5884 --- /dev/null +++ b/code/parafeed.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +//#include +//#include +//#include diff --git a/code/test/tst2.cc b/code/test/tst2.cc index 3cc09c8..ae1fa72 100644 --- a/code/test/tst2.cc +++ b/code/test/tst2.cc @@ -1,6 +1,4 @@ /* $Id: tst2.c,v 2.0 1998/11/11 07:13:02 sanjay Exp $ */ -#include -#include /* * Copyright (c) 2000-2021, 2022 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) * @@ -19,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include +#include #include /* Test program to test the embedded shell via the commandline library diff --git a/code/test/unittest/CMakeLists.txt b/code/test/unittest/CMakeLists.txt index b7fa92d..70f2f48 100644 --- a/code/test/unittest/CMakeLists.txt +++ b/code/test/unittest/CMakeLists.txt @@ -1,3 +1,19 @@ +# Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + cmake_minimum_required(VERSION 3.14) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED OFF) diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index 6d2479e..f985544 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -1,8 +1,23 @@ +/* + * Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include #include -#include -#include -#include -#include #include #include #include diff --git a/code/test/unittest/test_parafeed_interactive.cpp b/code/test/unittest/test_parafeed_interactive.cpp index 5568cea..67935fb 100644 --- a/code/test/unittest/test_parafeed_interactive.cpp +++ b/code/test/unittest/test_parafeed_interactive.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ #include // // Test for default factory settings (i.e., defaults in the compiled @@ -84,7 +102,12 @@ TEST_F(ParafeedTest, InteractiveCanonical) EndCL(); FreeArgv(argc, argv); } - +// +// Test the most standard way of running an application in the default +// mode. The test2.def file, with error, is written before starting +// the UI. EndCL() should throw clExit exception, which is reported, +// before it can start the interactive shell. +// TEST_F(ParafeedTest, InteractiveDefFile) { std::vector args = diff --git a/code/test/unittest/test_parafeed_noninteractive.cpp b/code/test/unittest/test_parafeed_noninteractive.cpp index db39764..8f8a98d 100644 --- a/code/test/unittest/test_parafeed_noninteractive.cpp +++ b/code/test/unittest/test_parafeed_noninteractive.cpp @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2026 S. Bhatnagar (bhatnagar dot sanjay at gmail dot com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ #include // // --------------------------------------------------------------------------------- diff --git a/code/tstcpp.cc b/code/tstcpp.cc index 828fb80..cd5bc87 100644 --- a/code/tstcpp.cc +++ b/code/tstcpp.cc @@ -17,13 +17,10 @@ * */ /* $Id: tst2.c,v 2.0 1998/11/11 07:13:02 sanjay Exp $ */ -#include -#include -#include #include #include #include -//#include +#include /* Test program to test the embedded shell via the commandline library */ From 973ed255e7fdb2d4b4acdb648a19b139fd468df7 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Wed, 29 Apr 2026 08:06:09 -0600 Subject: [PATCH 09/11] CMakeLists.txt: Install parafeed.h clinteract.h, parafeed.h: Moved clgetValp.cc from clinteract.h to parafeed.h Added include guard in parafeed.h --- code/CMakeLists.txt | 1 + code/clinteract.h | 2 +- code/parafeed.h | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 21b16f9..f3441ed 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -49,6 +49,7 @@ target_include_directories(parafeed PUBLIC $) # install target set(header_list + parafeed.h clbool.h clconvert.h clError.h diff --git a/code/clinteract.h b/code/clinteract.h index 07ba820..2b81431 100644 --- a/code/clinteract.h +++ b/code/clinteract.h @@ -17,7 +17,7 @@ * */ /* $Id: clinteract.h,v 2.0 1998/11/11 07:13:01 sanjay Exp $ */ -#include +//#include #ifdef __cplusplus extern "C" { #endif diff --git a/code/parafeed.h b/code/parafeed.h index b9a5884..49a9ee8 100644 --- a/code/parafeed.h +++ b/code/parafeed.h @@ -16,9 +16,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ +#if !defined(PARAFEED_H) +#define PARAFEED_H #include #include #include +#include //#include //#include -//#include +#endif From 136bbb43c7f19de54a99a679dc7891c0787be699 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Mon, 4 May 2026 20:42:03 -0600 Subject: [PATCH 10/11] Minor clarifications in the README.md. --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 55d639f..20e5d85 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,17 @@ CMake-based build system requires `cmake` version 3 or later. Use the following mkdir build cd build cmake -gmake +make +``` +The `-DGNUREADLINE=OFF` option to `cmake` will disable the use of the [GNU Readline library](https://en.wikipedia.org/wiki/GNU_Readline) for bash-style commandline editing and command history capabilities. The `-DENABLE_TESTING=ON` option also builds the application for unit testing, which can be executed by the following commands + +``` +make test + +or + +ctest ``` -The `-DGNUREADLINE=OFF` option to `cmake` will disable the use of the [GNU Readline library](https://en.wikipedia.org/wiki/GNU_Readline) for bash-style commandline editing and command history capabilities. The `-DENABLE_TESTING=ON` option will enable unit testing. While the hand-written `makefiles` have been tested with `make` version 3 only, they do not depend on a specific version of `make`. These `makefiles` are in the `code/nocmake_makefiles` directory. Using the command `cd code; make -f nocmake_makefiles/makefile` should build the _parafeed_ project. From 06bd44a938066a1e538d40f5e8b9a978c4ad7c68 Mon Sep 17 00:00:00 2001 From: Sanjay Bhatnagar Date: Fri, 8 May 2026 17:59:56 -0600 Subject: [PATCH 11/11] Minor clean up in ParafeedTests.h. --- code/test/unittest/ParafeedTest.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/code/test/unittest/ParafeedTest.h b/code/test/unittest/ParafeedTest.h index f985544..14764f8 100644 --- a/code/test/unittest/ParafeedTest.h +++ b/code/test/unittest/ParafeedTest.h @@ -85,7 +85,6 @@ auto makeCanonicalArgs=[](std::string defFile=std::string(), auto FactoryCanonicalTest=[]() { int i; - // bool bool b = false; SMap watchPoints; @@ -199,28 +198,28 @@ auto FactoryCanonicalTest=[]() EXPECT_EQ(strarr[1], "v2"); // farray - std::vector fv={3.14,2*3.14,3*3.14}; - std::vector fv0; int N = 0; int count; // Test that the values returned after the "go" command are actually // filled from internal symbol table. + + // Registeration Pass: fv is used for factory setting. + std::vector fv={3.14,2*3.14,3*3.14}; if (cl_Pass == 0) { - // Registeration Pass: fv is used for factory setting. count = clgetValp("farray", fv, N); } else { // Get the values in a vector different from the vector used to // set the defaults (fv) + std::vector fv0; count = clgetValp("farray", fv0, N); - EXPECT_FLOAT_EQ(fv0[0], 3.14f); - EXPECT_FLOAT_EQ(fv0[1], 2*3.14f); - EXPECT_FLOAT_EQ(fv0[2], 3*3.14f); + EXPECT_EQ(fv0,fv); } - EXPECT_EQ(count, 3); + EXPECT_EQ(count, fv.size()); + EXPECT_EQ(count, N); }; // //--------------------------------------------------------------------