diff --git a/src/ancrec.cpp b/src/ancrec.cpp index 35a6af4c7..6a6552d04 100644 --- a/src/ancrec.cpp +++ b/src/ancrec.cpp @@ -353,7 +353,7 @@ RC record::CkSet( // verify that required member has been set // code that calls here not updated to match (defaults do not set FsSET). return oer( MH_S0493, // "Required member '%s' has not been set,\n" // " and apparently no message about it appeared above" - MNAME(b->fir + fn) ); // macro (srd.h) accesses mName, possibly in special segment + b->fir[fn].fi_GetMName() ); // accesses fi_mName } // record::CkSet //----------------------------------------------------------------------------- /*virtual*/ int record::ReportBalErrorsIf( @@ -863,7 +863,7 @@ basAnc::basAnc( int flags, SFIR * _fir, USI _nFlds, const char * _what, USI _eSz sOff = _sOff; // .. mn = 1; // min record subscript 1 (overwritten with 0 if static) // ptr() = 0; // is done in derived class constructor (deriv vf not avail here; ptr is pure!) - an_pCULT = pCULT; // pointer to associated input CULT table, nullptr = unknown + ba_pCULT = pCULT; // pointer to associated input CULT table, nullptr = unknown if (!dontRegister) regis(); // conditionally include anchor for nextAnc() iteration } // basAnc::basAnc @@ -1351,7 +1351,6 @@ const char* basAnc::getChoiTx( // return text of given value for a choice data *pIsHid = pTyX == chtyHIDDEN; return chtx; } // basAnc::getChoiTx -//----------------------------------------------------------------------------- //============================================================================= //***************************************************************************** @@ -1434,7 +1433,6 @@ const char* getFileName( int fileIx) // get text for file name index return "(bug)"; // (or memory was full at name save) } // getFileName - -//*************************************************** IF-OUTS ************************************************************* +//----------------------------------------------------------------------------- // end of ancrec.cpp diff --git a/src/ancrec.h b/src/ancrec.h index 4bff66b58..3ff57953b 100644 --- a/src/ancrec.h +++ b/src/ancrec.h @@ -85,8 +85,11 @@ class basAnc // base class for record anchors: basAnc // members setable by application user language (cul.cpp) BP tyB; // 0 or ptr to user language TYPES anchor in heap (destructor deletes) BP ownB; // 0 or ptr to anchor whose objects own this anchor's objects (record.ownTi) - const CULT* an_pCULT; // NULL or associated CULT input table for records of this type + const CULT* ba_pCULT; // NULL or associated CULT input table for records of this type // simplifies back translation of input names + const MODERNIZEPAIR* ba_probeModernizeTable; // table of old / new probe names re handling renamed record members + // nullptr if none; see cuprobe.cpp + basAnc(); basAnc( int flags, SFIR * fir, USI nFlds, const char * what, USI eSz, RCT rt, USI sOff, const CULT* pCult, int dontRegister=0 ); void FC regis(); @@ -117,15 +120,18 @@ class basAnc // base class for record anchors: basAnc const char* getChoiTx( int fn, int options=0, SI chan=-1, BOOL* bIsHid=NULL) const; const char* culMbrIdTx(int fn) const; int culMbrArrayDim(int fn) const; - void an_SetCULTLink( const CULT* pCULT) { an_pCULT = pCULT; } - static void an_SetCULTLinks(); + void ba_SetCULTLink( const CULT* pCULT) { ba_pCULT = pCULT; } int GetCount() const; int GetCountMax() const { return n-mn+1; // max possible # records (includes unused) // faster than GetCount() } int MakeRecordList(char* list, size_t listDim, const char* brk, const char* (*proc)(const record* pR)=nullptr) const; - + void ba_SetProbeModernizeTable(const MODERNIZEPAIR* pMP) { + ba_probeModernizeTable = pMP; + } + const char* ba_ModernizeProbeName(const char* inputName) const; + protected: virtual void conRec( TI i, SI noZ=0) = 0; // execute constructor for record i virtual void desRec( TI i) = 0; // .. destructor @@ -380,8 +386,7 @@ template class anc : public basAnc int GetChildCount(const record* pParent) const; RC CheckChildCount(const record* pParent, std::pair countLimits, const char*& msg) const; RC GetIthChild(const record* pParent, int iSought, T* &pRRet, int erOp=ERR) const; - - + protected: virtual void desRec( TI i) { if (p[i].r_status) @@ -563,7 +568,7 @@ template RC anc::RunDup( // duplicate records for run // delete old records, alloc to needed size for min fragmentation RC rc = al(src.n+nxRecs, erOp, _ownB); - an_pCULT = src.an_pCULT; // assume same associated CULT + ba_pCULT = src.ba_pCULT; // assume same associated CULT const T* pT; RLUP( src, pT) diff --git a/src/cncult.cpp b/src/cncult.cpp index cd175830c..d3e82e3f1 100644 --- a/src/cncult.cpp +++ b/src/cncult.cpp @@ -3208,9 +3208,9 @@ void FC cnPreInit() // preliminary cncult.cpp initialization [needed before sho // 'showProbeNames' displays member names of all registered rats for CSE -p. // It is executed before most initialization and can be executed without doing a run. -{ - basAnc::an_SetCULTLinks(); // link record anchors to associated input language CULTs +// note rats are now 'registered' in cse.cpp so input and run rats can be intermixed. +{ // clear/Init the "Top input RAT" which holds once-only input parameters, set mainly via cnTopCult[] TopiR.statSetup(Topi, 1); // init cncult:TopiR as basAnc with 1 static record cncult:Topi. // and zero record Topi and init its front members. @@ -3224,15 +3224,9 @@ void FC cnPreInit() // preliminary cncult.cpp initialization [needed before sho WthrR.ba_flags |= RFNOEX; WthrNxHrR.ba_flags |= RFNOEX; - // note rats are now 'registered' in cse.cpp so input and run rats can be intermixed. + SetupProbeModernizeTables(); } // cnPreInit -//----------------------------------------------------------------------------- -/*static*/ void basAnc::an_SetCULTLinks() -{ - // an_pCULT links set during anc creation (via makAncXXX()) - // nothing further required -} // basAnc::an_SetCULTLinks //============================================================================================ /////////////////////////////////////////////////////////////////////////////// @@ -3383,91 +3377,4 @@ int culShowDoc( // public function: display CULT tree } // culDoc1 //============================================================================= -/************************************************ rest of file is if-outs ***************************************************/ - -#if 0 //ifdef OLDAT // undefined in cnglob.h, 5-92 -o /*------------------------ TERMINAL command (for zone) ----------------------*/ -o -o //-------------------------------------------- terminal pre-input fcn: limit # -o // note: pre-input not Itf used so ownTi (=zi) already set in RAT for errmsg. -o LOCAL RC tuxPrf( CULT *c, TUX *p, ZNI *p2, void *p3) /*ARGSUSED*/ -o{ -o TUX *tu; SI n=0; -o -o // check for too many terminals for zone. -o // NOTE zone terminal tables are in ZNR (not ZNI) -- setup deferred until topTu() below. -o -o // count terminals for same zone. Current one will be included. -o RLUP( TuxiB, tu) // loop TUX records -o if (tu->ownTi==p2->ss) // if terminal belongs to cur zone (reference type, need not check FsVAL 12-91) -o n++; // count it -o -o // error if too many -o if (n > MAX_ZONETUS) // =3, cndefns.h -o return oer( p, "More than %d terminals for zone '%s'", MAX_ZONETUS, p2->Name() ); -o -o return RCOK; -o} // tuxPrf -o -o static CULT tuxT[] = //------------------------- TERMINALX subCmd table for ZONE -o // id cs fn f uc evf ty b dfls p2 ckf -{ -o //-------- ---- ------------------- -------------- -- ----- ----- ----- --------- ------- --- -o "*", STAR, 0, PRFP, 0, 0, 0, 0, N, 0.f, v tuxPrf, N), -o -o "tuxZone", DAT, TUX_OWNTI, NO_INP|RDFLIN, 0, 0, TYIREF, &ZiB, N, 0.f, N, N), -o "tuxTLH", DAT, TUX_TUXTLH, 0, 0, VHRLY, TYFL, 0, N, 68.f, N, N), -o "tuxMxLH", DAT, TUX_TUXMXLH, 0, 0, VHRLY, TYFL, 0, N, 0.f, N, N), -o "tuxMnLH", DAT, TUX_TUXMNLH, 0, 0, VHRLY, TYFL, 0, N, 0.f, N, N), -o #ifdef OLDAT // undefined in cnglob.h, 5-92 -o o "tuxAhu", DAT, TUX_TUXAHI, 0, 0, VEOI, TYREF, &AhuxiB,N, 0, N, N), -o #endif -o "tuxTH", DAT, TUX_TUXTH, 0, 0, VHRLY, TYFL, 0, N, 68.f, N, N), -o "tuxTC", DAT, TUX_TUXTC, 0, 0, VHRLY, TYFL, 0, N, 78.f, N, N), -o "tuxCMn", DAT, TUX_TUXCMN, 0, 0, VHRLY, TYFL, 0, N, 0.f, N, N), -o "tuxCMxH", DAT, TUX_TUXCMXH, 0, 0, VHRLY, TYFL, 0, N, 0.f, N, N), -o "tuxCMxC", DAT, TUX_TUXCMXC, 0, 0, VHRLY, TYFL, 0, N, 0.f, N, N), -o -o "endTerminalx",ENDER,0, 0, 0, 0, 0, 0, N, 0.f, N, N), -oCULT() -o -}; // tuxT -#endif - -// znT deletions: -#ifdef OLDNV // 1-92 cndefns.h -o//natVent -o "nvAHi", DAT, ZI(NVAHI), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "nvALo", DAT, ZI(NVALO), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "nvHD", DAT, ZI(NVHD), 0, 0, VEOI, TYFL, 0, N, 2.f, N, N), -o "nvAzmI", DAT, ZI(NVAZMI), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "nvStEM", DAT, ZI(NVSTEM), 0, 0, VEOI, TYFL, 0, N, 1.f, N, N), -o "nvDdEM", DAT, ZI(NVDDEM), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "nvDiEM", DAT, ZI(NVDIEM), 0, 0, VEOI, TYFL, 0, N, .5f, N, N), -o "nvTD", DAT, ZI(NVTD), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -#endif -#ifdef OLDFV -o//fanvent -o "fvCfm", DAT, ZI(FVCFM), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "fvKW", DAT, ZI(FVKW), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "fvFz", DAT, ZI(FVFZ), 0, 0, VEOI, TYFL, 0, N, 1.f, N, N), -o "fvDECeff", DAT, ZI(FVDECEFF), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "fvIEDeff", DAT, ZI(FVIECEFF), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "fvTD", DAT, ZI(FVTD), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "fvWbMax", DAT, ZI(FVWBMAX), 0, 0, VEOI, TYFL, 0, N, 999.f, N, N), -#endif -#ifdef OLDCF -o//ceiling fan -o "cfKW", DAT, ZI(CFKW), 0, 0, VEOI, TYFL, 0, N, 0.f, N, N), -o "cfFz", DAT, ZI(CFFZ), 0, 0, VEOI, TYFL, 0, N, 1.f, N, N), -#endif -#ifdef OLDNV // old comments, moved to facilitate edit -o//natVent. want erMsg (at end zone) for only 1 of ahigh, alow > 0. -o /* 1-91: chip to verify traditional dH default: something like 2 for 1 story, 8 for 2 stories. 2-91: his memo shows 0. */ -o // 12-90: otta require azmI iff ddEM is non-0. later. -#endif -#if 0 //ifdef OLDAT // undefined in cnglob.h, 5-92 -o "terminalx", RATE, 0, 0, 0, 0, 0, &TuxiB, N, 0.f, tuxT, N), -#endif - // end of cncult.cpp diff --git a/src/cul.cpp b/src/cul.cpp index b59e40219..b0911503a 100644 --- a/src/cul.cpp +++ b/src/cul.cpp @@ -3088,8 +3088,6 @@ LOCAL RC CDEC perNxE( MSGORHANDLE ms, ...) return RCSKIP2END; /* ret special value. eg culRun tests for this value and calls skip2end() (next) */ } // perNxE - -// new 1-19-91. old skip2end is in cul.4 and cul.ifo. //=========================================================================== LOCAL SI FC skip2end( @@ -4687,8 +4685,8 @@ const char* basAnc::culMbrIdTx( // return record field id from cult table int fn) const // field number { // use basAnc's associated CULT - if (an_pCULT) // if basAnc has an associated CULT - { for (const CULT* c=an_pCULT; c->id; c++) + if (ba_pCULT) // if basAnc has an associated CULT + { for (const CULT* c=ba_pCULT; c->id; c++) { if (c->cs==DAT && c->fn==fn) return c->id; } @@ -4726,7 +4724,7 @@ x xSp->b->rt==b->rt // (match rt not b so run basAncs, types basAncs work) (void *)xSp, (void *)xStk ); // casts are to make far. return strtprintf( MH_S0277, // not found. "[%s not found by cul.cpp:culMbrId]". - MNAME( fir + fn) ); // punt, using name of member of record structure. + fir[fn].fi_GetMName() ); // punt, using name of member of record structure. } // basAnc::culMbrIdTx //----------------------------------------------------------------------------- @@ -4737,9 +4735,9 @@ int basAnc::culMbrArrayDim( // return field array dimension cult table int arrayDim = -1; // use basAnc's associated CULT - if (an_pCULT) // if basAnc has an associated CULT + if (ba_pCULT) // if basAnc has an associated CULT { - for (const CULT* c = an_pCULT; c->id; c++) + for (const CULT* c = ba_pCULT; c->id; c++) { if (c->cs==DAT && c->fn==fn && (c->f & ARRAY)) arrayDim = int(intptr_t( c->p2)); diff --git a/src/cuparse.cpp b/src/cuparse.cpp index 7f2493b23..24fa5e2ce 100644 --- a/src/cuparse.cpp +++ b/src/cuparse.cpp @@ -583,7 +583,7 @@ LOCAL SYTBH symtab = { NULL, 0 }; LOCAL OPTBL * opp = NULL; // ptr to opTbl entry for token const char * ttTx = NULL; // saveable ptr to static token descriptive text (opp->tx) for errMsgs. cul.cpp uses. LOCAL void * stbk = NULL; // symbol table value ptr, set by toke() for already-decl identifiers, type varies... - SI isWord = 0; // nz if word: undef (CUTID), user-def (CUTUF, CUTUV), or reserved (CUTVRB CUTSF etc). + bool isWord = false; // true iff word: undef (CUTID), user-def (CUTUF, CUTUV), or reserved (CUTVRB CUTSF etc). /*--- CURRENT EXPRESSION INFO, exOrk to expr and callees. */ USI evfOk = 0xffff; // evaluation frequencies allowed bits for current expression, ffff-->no limits. @@ -4194,7 +4194,7 @@ SI FC toke() /* local token-getter -- cutok.cpp:cuTok + unary/binary resolution stbk: for previously declared identifiers only: block ptr from symbol table: ptr to VRBST, UFST, SVST, etc per type. - isWord: non-0 if a word even if not CUTID: + isWord: true if a word even if not CUTID: permits specific errMsgs for misused reserved words and use of reserved words as class and member names (probe) and variables cuTok() sets: cuTok.cpp:cuToktx[], cuIntval, cuFlval. */ @@ -4234,10 +4234,10 @@ SI FC toke() /* local token-getter -- cutok.cpp:cuTok + unary/binary resolution /* set isWord for all words, reserved or not, for smart error msgs. */ if (tokTy != CUTID) - isWord = 0; + isWord = false; else // is an identifier { - isWord = 1; + isWord = true; /* classify already-declared identifiers using symbol table. 3rd arg 0 causes token to match symtab entries different in capitalization only if flagged "case insensitive" */ diff --git a/src/cuparse.h b/src/cuparse.h index 52c253043..0040f0425 100644 --- a/src/cuparse.h +++ b/src/cuparse.h @@ -44,5 +44,6 @@ void FC curLine( int retokPar, int* pFileIx, int* pline, int* pcol, char *s, siz // cuprobe.cpp void FC showProbeNames(int showAll); +RC SetupProbeModernizeTables(); // end of cuparse.h \ No newline at end of file diff --git a/src/cuparsex.h b/src/cuparsex.h index 459e7e5cc..642d28adb 100644 --- a/src/cuparsex.h +++ b/src/cuparsex.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file. -// cuparsex.h: parsing-related stuff shared between cuparse.cpp and [obsolete file cumain.cpp] and cuprobe.cpp +// cuparsex.h: parsing-related stuff shared between cuparse.cpp and cuprobe.cpp /* 12-91: Extending this file to stuff shared with files split off of cuparse.cpp: initially, cuprobe.cpp. @@ -27,7 +27,7 @@ extern SI nextPrec; // "prec" of ungotten (ie next) token, only valid after exp //extern OPTBL * opp; // ptr to opTbl entry for token extern const char * ttTx; // saveable ptr to static token descriptive text (opp->tx) for errMsgs. cul.cpp uses. // extern void * stbk; // symbol table value ptr, set by toke() for already-decl identifiers, type varies... -extern SI isWord; // non-0 if word: reserved, defined, or CUTID. +extern bool isWord; // true iff word: reserved, defined, or CUTID. /*--- CURRENT EXPRESSION INFO, exOrk to expr and callees, incl cuprobe.cpp. */ extern USI evfOk; // evaluation frequencies allowed bits for current expression, diff --git a/src/cuprobe.cpp b/src/cuprobe.cpp index 34d3fee2a..4bc6c83db 100644 --- a/src/cuprobe.cpp +++ b/src/cuprobe.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file. -// ***** tryImInProbe TYSTR access needs to use owner else ratLuu, like run. +// ***** PROBEOBJECT::po_TryImInProbe TYSTR access needs to use owner else ratLuu, like run. // cuprobe.cpp portion of cuparse.cpp for compiling "probes" (references) to input and run record data @@ -11,7 +11,7 @@ /*------------------------------- INCLUDES --------------------------------*/ #include "cnglob.h" -#include "srd.h" // SFIR MNAME +#include "srd.h" // SFIR #include "ancrec.h" // record: base class for rccn.h classes #include "rccn.h" // needed before cncult.h 2-92 #include "msghans.h" // MH_U0001 @@ -33,27 +33,62 @@ /*--------------------------- DEFINES and TYPES ---------------------------*/ struct PROBEOBJECT // info probe() shares with callees: pass single pointer { - BP inB; // 0 or input basAnc found with given name, 0'd if member name not found (0 is "near NULL") - BP runB; // 0 or run basAnc found with given name, 0'd if member name not found - const char* what; // name (.what) of basAnc(s) whose records being probed - SFIR* inF, * runF; // pointers to "fields-in-record" tables (srfd.cpp) for input and run rats - const char* mName; // name of member being probed - USI inFn, runFn; // input and run basAnc field numbers - USI ssTy; // data type of record subscript: TYSTR or TYINT - SI ssIsK; // non-0 if record subscript is constant - void * pSsV; // pointer to subscript value - USI sz, dt, ty; // size, cu TY- type, and DT- data type, of probed field(s) + BP po_inB; // 0 or input basAnc found with given name, 0'd if member name not found (0 is "near NULL") + BP po_runB; // 0 or run basAnc found with given name, 0'd if member name not found + const char* po_what; // name (.what) of basAnc(s) whose records being probed + const SFIR* po_inF; // pointer to "fields-in-record" tables (srfd.cpp) for input rat + const SFIR* po_runF; // pointer to "fields-in-record" tables (srfd.cpp) for run rat + const char* po_mName; // name of member being probed + USI po_inFn; // input basAnc field number + USI po_runFn; // run basAnc field number + USI po_ssTy; // data type of record subscript: TYSTR or TYINT + SI po_ssIsK; // non-0 if record subscript is constant + void* po_pSsV; // pointer to subscript value + USI po_sz, po_dt, po_ty; // size, cu TY- type, and DT- data type, of probed field(s) PROBEOBJECT() { memset(this, 0, sizeof(PROBEOBJECT)); } + RC po_DoProbe(); + RC po_FindMember(); + RC po_TryImInProbe(); }; /*----------------------- LOCAL FUNCTION DECLARATIONS ---------------------*/ -LOCAL RC FC findMember( PROBEOBJECT *o); -LOCAL RC FC tryImInProbe( PROBEOBJECT *o); LOCAL RC FC lopNty4dt( USI dt, USI *pTy, USI *pSz, PSOP *pLop, const char** pErrSub); LOCAL void FC disMember( SFIR *f1, SI isIn, SI isRun, SI showAll); - +//----------------------------------------------------------------------------- +RC SetupProbeModernizeTables() +{ + RC rc = RCOK; + static MODERNIZEPAIR RSYS_PMTable[]{ {"fanPwrC", "fanSFPC"}, {nullptr, nullptr} }; + RSiB.ba_SetProbeModernizeTable(RSYS_PMTable); + RsR.ba_SetProbeModernizeTable(RSYS_PMTable); + + static MODERNIZEPAIR ZONE_PMTable[]{ {"tzx", "tz"}, {nullptr, nullptr} }; + // ZiB.ba_SetProbeModernizeTable(ZONE_PMTable); + ZrB.ba_SetProbeModernizeTable(ZONE_PMTable); + + return rc; +} // ::SetupProbeModernizeTables +//----------------------------------------------------------------------------- +const char* basAnc::ba_ModernizeProbeName( + const char* probeName) const +{ + if (ba_probeModernizeTable) + { + const char* probeNameWas{ probeName }; + for (const MODERNIZEPAIR* pMP = ba_probeModernizeTable; !pMP->mp_IsEnd(); pMP++) + { + if (pMP->mp_ModernizeIf( probeName)) + { + info("Updating %s name '%s' to '%s'", + what, probeNameWas, probeName); + break; + } + } + } + return probeName; +} // basAnc::ba_ModernizeProbeName //========================================================================== RC FC probe() @@ -62,100 +97,107 @@ RC FC probe() // syntax: @ [ ] . { -// get class name (basAnc 'what') and find input and/or run basAnc + // get class name (basAnc 'what') and find input and/or run basAnc toke(); // get token if (!isWord) // accept any word even if predefined or reserved - return perNx( MH_U0001); // "U0001: Expected word for class name after '@'" + return perNx(MH_U0001); // "U0001: Expected word for class name after '@'" + + PROBEOBJECT o; // contains local variables passed to callees. + // CAUTION: recursion possible, don't use statics. + return o.po_DoProbe(); +} // ::probe +//----------------------------------------------------------------------------- +RC PROBEOBJECT::po_DoProbe() +{ BP b = nullptr; - PROBEOBJECT o; // contains local variables passed to callees. CAUTION: recursion possible, don't use statics. for (size_t ancN = 0; basAnc::ancNext( ancN, &b ); ) // loop 'registered' record anchors using ancrec.cpp fcn { if (b->ba_flags & RFTYS) // if a "types" basAnc continue; // accept no probes; keep looking for input & run rats with same name if (!_stricmp( b->what, cuToktx)) // will probably need to take _'s as spaces ... 12-91 { - if (b->ba_flags & RFINP ? o.inB : o.runB) + if (b->ba_flags & RFINP ? po_inB : po_runB) return perNx( MH_U0002, // "U0002: Internal error: Ambiguous class name '%s':\n" // " there are TWO %s rats with that .what. Change one of them.", b->what, b->ba_flags & RFINP ? "input" : "run" ); if (b->ba_flags & RFINP) - o.inB = b; + po_inB = b; else - o.runB = b; - o.what = b->what; // for many error messages + po_runB = b; + po_what = b->what; // for many error messages } } - if (!o.runB && !o.inB) + if (!po_runB && !po_inB) return perNx( MH_U0003, cuToktx); // "U0003: Unrecognized class name '%s'" // parse & emit record identifier in []'s: unquoted identifier, string name expression, numeric subscript expression - b = o.inB ? o.inB : o.runB; // single pointer to base of (one of) the basAnc(s) found + b = po_inB ? po_inB : po_runB; // single pointer to base of (one of) the basAnc(s) found RC rc = RCOK; // used in CSE_E if (tokeIf(CUTLB)) // get token / if [ next (else unget the token) (cuparse.cpp) { CSE_E( expTy( PRRGR, TYSI|TYID, "className[", 0) ) // compile integer or string expr to new stk frame. // TYID: like TYSTR, plus assume quotes around unreserved identifiers. - CSE_E( konstize( &o.ssIsK, &o.pSsV, 0 ) ) // determine if constant/get value, re immediate input probes, below. + CSE_E( konstize( &po_ssIsK, &po_pSsV, 0 ) ) // determine if constant/get value, re immediate input probes, below. // evals if evaluable and un-eval'd, rets flag and pointer if (tokeNot(CUTRB)) return perNx( MH_U0004, // "U0004: Expected ']' after object %s" - o.ssTy==TYSI ? "subscript" : "name"); + po_ssTy==TYSI ? "subscript" : "name"); } else // for single-record static basAnc such as Top, allow omission of subscript; supply constant 0 - if ( b->ba_flags & RFSTAT // if a static-record basAnc (expect 1 entry only; inB/runB assumed consistent) + if ( b->ba_flags & RFSTAT // if a static-record basAnc (expect 1 entry only; po_inB/po_runB assumed consistent) && b->n < 1 // without more than 1 entry (yet)(insurance) && tokeIf(CUTPER) ) // if period next -- what would follow subscript { static SI iZero = 0; CSE_E( newSf()) // use separate stack frame to be like expression case CSE_E( emiKon( TYSI, &iZero, 0, NULL ) ) // emit code for a 0 contant - o.pSsV = parSp->psp1 + 1; // where the constant 0 value is, as from curparse.cpp:isKonExp via cuparse:konstize. - o.ssIsK = 1; // say subscript is constant, as from konstize as called in [expr] case above. + po_pSsV = parSp->psp1 + 1; // where the constant 0 value is, as from curparse.cpp:isKonExp via cuparse:konstize. + po_ssIsK = 1; // say subscript is constant, as from konstize as called in [expr] case above. parSp->ty = TYSI; // have integer value unToke(); // unget the . and fall thru } else return perNx( MH_U0005); // "U0005: Expected '[' after @ and class name" - o.ssTy = parSp->ty; // save type of subscript expression: TYSI or TYSTR + po_ssTy = parSp->ty; // save type of subscript expression: TYSI or TYSTR // get . and composite field 'name'. 'name' can be: abc, abc.def, abc[0], abc[0].def, etc. if (tokeNot(CUTPER)) return perNx( MH_U0006); // "U0006: Expected '.' after ']'" require . - if (findMember(&o)) // get & look up composite member name (below) / ret if not found or other err. - return RCBAD; // ... sets o.inF and/or o.runF; clears o.inB/o.runB if input does not match. + if (po_FindMember()) // get & look up composite member name (below) / ret if not found or other err. + return RCBAD; // ... sets po_inF and/or po_runF; clears po_inB/po_runB if input does not match. // if here, have match in one OR BOTH tables. - SFIR* f = o.inB ? o.inF : o.runF; // single nonNULL pointer to a fir entry - o.mName = MNAME(f); // point member name text for many errMsgs. srd.h macro may access special segment. + const SFIR* f = po_inB ? po_inF : po_runF; // single nonNULL pointer to a fir entry + po_mName = f->fi_GetMName(); // point member name text for many errMsgs // determine DT___ and TY___ data types, and size of type USI inDt = 0, runDt = 0; - if (o.inB) inDt = sFdtab[o.inF->fi_fdTy].dtype; // fetch recdef DT_____ data type for input record member - if (o.runB) runDt = sFdtab[o.runF->fi_fdTy].dtype; // ... run record member - if (o.inB && o.runB && inDt != runDt) // error if inconsistent + if (po_inB) inDt = sFdtab[po_inF->fi_fdTy].dtype; // fetch recdef DT_____ data type for input record member + if (po_runB) runDt = sFdtab[po_runF->fi_fdTy].dtype; // ... run record member + if (po_inB && po_runB && inDt != runDt) // error if inconsistent return perNx( MH_U0007, //"U0007: Internal error: %s member '%s'\n" //" has data type (dt) %d in input rat but %d in run rat.\n" //" It cannot be probed until tables are made consistent.\n", - o.what, o.mName, inDt, runDt ); - o.dt = o.inB ? inDt : runDt; // get a single data type value + po_what, po_mName, inDt, runDt ); + po_dt = po_inB ? inDt : runDt; // get a single data type value PSOP lop; const char* errSub; - if (lopNty4dt( o.dt, &o.ty, &o.sz, &lop, &errSub)) // get ty, size, and instruction for dt, below / if bad + if (lopNty4dt( po_dt, &po_ty, &po_sz, &lop, &errSub)) // get ty, size, and instruction for dt, below / if bad return perNx( MH_U0008, // "U0007: %s member '%s' has %s data type (dt) %d" - o.what, o.mName, errSub, o.dt ); + po_what, po_mName, errSub, po_dt ); // decide probe method to use // nb giving input time probes priority assumes run member @@ -166,24 +208,24 @@ RC FC probe() USI minEvf = 0; USI fn = 0; - if (o.inB // if have input record basAnc - && !(o.inF->fi_evf &~EVEOI) // if probed member has no rutime & no EVFFAZ variation + if (po_inB // if have input record basAnc + && !(po_inF->fi_evf &~EVEOI) // if probed member has no rutime & no EVFFAZ variation && evfOk & EVEOI ) // if end-of-input time variation ok for expr being evaluated by caller { minEvf = EVEOI; // minimum variability, applicable here if f->fi_evf has no variability - b = o.inB; - f = o.inF; - fn = o.inFn; // use input record: set basAnc, SFIR entry, field # for code emit below + b = po_inB; + f = po_inF; + fn = po_inFn; // use input record: set basAnc, SFIR entry, field # for code emit below // note if other operands in expr vary at runtime, cuparse's evf logic will promote expression's evf appropriately. } - else if ( o.inB // if have input record basAnc - && !(o.inF->fi_evf &~(EVEOI|EVFFAZ)) // if probed member has no rutime variation + else if ( po_inB // if have input record basAnc + && !(po_inF->fi_evf &~(EVEOI|EVFFAZ)) // if probed member has no rutime variation && evfOk & EVFFAZ ) // if "phasely" variation ok for expr being evaluated by caller { minEvf = EVFFAZ; // minimum variability, applicable here if f->fi_evf has no variability - b = o.inB; - f = o.inF; - fn = o.inFn; // use input record: set basAnc, SFIR entry, field # for code emit below + b = po_inB; + f = po_inF; + fn = po_inFn; // use input record: set basAnc, SFIR entry, field # for code emit below // note if other operands in expr vary at runtime, cuparse's evf logic will promote expression's evf appropriately. } else @@ -191,7 +233,7 @@ RC FC probe() // else try immediate probe to input member -- only possible if member already set { - rc = tryImInProbe(&o); // below + rc = po_TryImInProbe(); // below if (rc != RCCANNOT) // unless cannot use this type of probe here but no error return rc; // return to caller: success, done, or error, message issued @@ -204,27 +246,27 @@ RC FC probe() // changes at runtime named the same as input member (should be changed; meanwhile, probe run basAnc). minEvf = EVFRUN; // minimum variabilty: applies if member itself has none - if (o.runB) // if have a run basAnc, use it - { b = o.runB; - f = o.runF; - fn = o.runFn; // set basAnc, fields-in-record tbl entry ptr, fld # + if (po_runB) // if have a run basAnc, use it + { b = po_runB; + f = po_runF; + fn = po_runFn; // set basAnc, fields-in-record tbl entry ptr, fld # } else // else must have input basAnc if here - { b = o.inB; - f = o.inF; - fn = o.inFn; // use it. + { b = po_inB; + f = po_inF; + fn = po_inFn; // use it. } } // emit eoi or runtime probe code: PSRATRN / PSRATROS & inline args, PSRATLODx & field #. Subscr/name expr already emitted. CSE_E( combSf() ) // combine stack frame & code & evf from subscr expr above with preceding code - CSE_E( emit( o.ssTy==TYSTR + CSE_E( emit( po_ssTy==TYSTR ? PSRATROS // access record by ownTi & name: string on stack, leave pointer : PSRATRN ) ) // access record by number: SI value on stack, leave pointer on stack CSE_E( emit2(b->ancN) ) // basAnc number follows inline, from basAnc - if (o.ssTy==TYSTR) // for lookup by name - CSE_E( emit2( ratDefO(o.inB ? o.inB : b) ) ); // also emit inline owning input record subsc per context, or 0. cul.cpp. + if (po_ssTy==TYSTR) // for lookup by name + CSE_E( emit2( ratDefO(po_inB ? po_inB : b) ) ); // also emit inline owning input record subsc per context, or 0. cul.cpp. /* ratDefO returns subscript of input record in b->ownB of context in which current expr is being evaluated, if any, for resolving ambiguous names. Returns 0 if not ownable-record basAnc (none remain 7-92?) or its ownB unset or not embedded @@ -238,23 +280,53 @@ RC FC probe() b->ba_flags |= RFPROBED; // say have compiled a probe into a record of basAnc: do not free its (input records) block b4 run. // ... not needed for EVEOI/EVFFAZ probe, but set where if another operand changes evf to runtime? - parSp->ty = o.ty; // data type resulting from this probe + parSp->ty = po_ty; // data type resulting from this probe parSp->evf |= // with evf of any preceding sub-expr and subscr/name expr above, if any, combine... f->fi_evf // probed member's evalfreq bits fields-in-record table, and | minEvf; // min evalFreq, applicable if 0 in f->fi_evf. expr keeps only ruling evf bit. prec = PROP; // say have an operand return RCOK; // many other returns above, incl in E macros. caller ERREX's. -} // probe +} // PROBEOBJECT::po_DoProbe //========================================================================== -LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name in o.inB and/or o.runB fir tables + +//----------------------------------------------------------------------------- +/*static*/ void po_SearchSFIR( + BP& pB, + const SFIR* &pFi, + const SFIR* &pF1, + USI& Fn, + int &m, + int &l) + +{ + const char* mNameSought = pB->ba_ModernizeProbeName(cuToktx); + l = strlenInt(mNameSought); // length of the token to match now + + pF1 = pFi; // fir entry for which preceding tokens (m chars) match + while (_strnicmp( mNameSought, pFi->fi_GetMName() + m, l) // while token does not match (continuation of) member name + || isalnumW(pFi->fi_GetMName()[m]) // .. or matching word/number in table + && isalnumW(pFi->fi_GetMName()[m+l]) ) // .. continues w/o delimiter (ie only initial substring given) + { + pFi++; + Fn++; // try next fir table entry, incr field number + if ( !pFi->fi_fdTy // if end fir table, not found + || m && _strnicmp( pF1->fi_GetMName(), pFi->fi_GetMName(), m) ) /* if preceding m chars of this entry don't match + (all entries with same beginning are together) */ + { + pB = nullptr; + break; // say mbr not found in input basAnc. errMsg done after run basAnc search. + } + } +} +RC PROBEOBJECT::po_FindMember() // parse and look up probe member name in po_inB and/or po_runB fir tables // uses multiple input tokens as necessary. // composite field 'name' can be: abc, abc.def, abc[0], abc[0].def, etc. -// inputs: o.inB, o.runB, +// inputs: po_inB, po_runB, -// outputs: o.inF, o.runF: BOTH nonNULL if both .inB and .runB were nonNULL and matches found in both input and run rats. -// o.inB, o.runB set NULL when input does not match that basAnc's fir table. +// outputs: po_inF, po_runF: BOTH nonNULL if both po_inB and po_runB were nonNULL and matches found in both input and run rats. +// po_inB, po_runB set NULL when input does not match that basAnc's fir table. // returns: non-RCOK if error, message already issued. { @@ -264,74 +336,90 @@ LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name i if (!isWord) return perNx( MH_U0010, // "U0010: Expected a word for object member name, found '%s'" cuToktx ); + -// loop to match composite field name, using additional input tokens as necessary, in inB AND runB fir tables (rest of fcn). +// loop to match composite field name, using additional input tokens as necessary, in po_inB AND po_runB fir tables (rest of fcn). - o->inF = o->inB ? o->inB->fir : NULL; // search pointers into fields-in-records tables - o->runF = o->runB ? o->runB->fir : NULL; // .. of the rats found above. + po_inF = po_inB ? po_inB->fir : NULL; // search pointers into fields-in-records tables + po_runF = po_runB ? po_runB->fir : NULL; // .. of the rats found above. int m = 0; // # chars matched by preceding tokens in multitoken member name for ( ; ; ) // loop over input tokens until break or error return { - SFIR *f1 = nullptr; // fir entry for which preceding m chars match - int l = strlenInt(cuToktx); // length of the token to match now + const SFIR *f1 = nullptr; // fir entry for which preceding m chars match + int l = 0; + +#if 1 + if (po_inB) + po_SearchSFIR(po_inB, po_inF, f1, po_inFn, m, l); + if (po_runB) + po_SearchSFIR(po_runB, po_runF, f1, po_runFn, m, l); + +#else // search for input & run fir entries that match current token, and any preceding input tokens (m chars) - if (o->inB) // if input basAnc found (by caller) & name matches so far here + if (po_inB) // if input basAnc found (by caller) & name matches so far here { - f1 = o->inF; // fir entry for which preceding tokens (m chars) match - while (_strnicmp( cuToktx, MNAME(o->inF) + m, l) // while token does not match (continuation of) member name - || isalnumW(MNAME(o->inF)[m]) // .. or matching word/number in table - && isalnumW(MNAME(o->inF)[m+l]) ) // .. continues w/o delimiter (ie only initial substring given) + const char* mNameSought = po_inB->ApplyAlias(cuToktx); + l = strlenInt(mNameSought); // length of the token to match now + + f1 = po_inF; // fir entry for which preceding tokens (m chars) match + while (_strnicmp( mNameSought, po_inF->fi_GetMName() + m, l) // while token does not match (continuation of) member name + || isalnumW(po_inF->fi_GetMName()[m]) // .. or matching word/number in table + && isalnumW(po_inF->fi_GetMName()[m+l]) ) // .. continues w/o delimiter (ie only initial substring given) { - o->inF++; - o->inFn++; // try next fir table entry, incr field number - if ( !o->inF->fi_fdTy // if end fir table, not found - || m && _strnicmp( MNAME(f1), MNAME(o->inF), m) ) /* if preceding m chars of this entry don't match + po_inF++; + po_inFn++; // try next fir table entry, incr field number + if ( !po_inF->fi_fdTy // if end fir table, not found + || m && _strnicmp( f1->fi_GetMName(), po_inF->fi_GetMName(), m) ) /* if preceding m chars of this entry don't match (all entries with same beginning are together) */ { - o->inB = 0; + po_inB = 0; break; // say mbr not found in input basAnc. errMsg done after run basAnc search. } } } - if (o->runB) // if run basAnc found (by caller) & name matches so far here + if (po_runB) // if run basAnc found (by caller) & name matches so far here { - f1 = o->runF; // fir entry for which preceding tokens (m chars) match - while (_strnicmp( cuToktx, MNAME(o->runF) + m, l) // while token does not match (continuation of) member name - || isalnumW(MNAME(o->runF)[m]) // .. or while matching word/number in table - && isalnumW(MNAME(o->runF)[m+l]) ) // .. continues w/o delimiter (only initial substring given) + const char* mNameSought = po_runB->ApplyAlias(cuToktx); + l = strlenInt(mNameSought); // length of the token to match now + + f1 = po_runF; // fir entry for which preceding tokens (m chars) match + while (_strnicmp( mNameSought, po_runF->fi_GetMName() + m, l) // while token does not match (continuation of) member name + || isalnumW( po_runF->fi_GetMName()[m]) // .. or while matching word/number in table + && isalnumW(po_runF->fi_GetMName()[m+l]) ) // .. continues w/o delimiter (only initial substring given) { - o->runF++; - o->runFn++; // try next fir table entry; //incr field number - if ( !o->runF->fi_fdTy // if end fir table, not found - || m && _strnicmp( MNAME(f1), MNAME(o->runF), m) ) /* if preceding m chars of this entry don't match - (all entries with same beginning are together) */ + po_runF++; + po_runFn++; // try next fir table entry; //incr field number + if ( !po_runF->fi_fdTy // if end fir table, not found + || m && _strnicmp( f1->fi_GetMName(), po_runF->fi_GetMName(), m) ) // if preceding m chars of this entry don't match + // (all entries with same beginning are together) { - o->runB = 0; + po_runB = 0; break; // say member not found in run basAnc } } } +#endif // if not found, issue error message. syntax ok if here. - if (!o->inB && !o->runB) // if found in neither input nor run records basAnc + if (!po_inB && !po_runB) // if found in neither input nor run records basAnc if (!m) // if first token of name - return perNx( MH_U0011, o->what, cuToktx); // "U0011: %s member '%s' not found" - else // fancier error message for partial match - { - char* foundPart = strncpy0( NULL, MNAME( f1), m+1); // truncate to Tmpstr, lib\strpak.cpp + return perNx( MH_U0011, po_what, cuToktx); // "U0011: %s member '%s' not found" + else + { // fancier error message for partial match + const char* foundPart = strncpy0( NULL, f1->fi_GetMName(), m+1); // truncate to Tmpstr return perNx( MH_U0012, //"U0012: %s member '%s%s' not found: \n" //" matched \"%s\" but could not match \"%s\"." - o->what, foundPart, cuToktx, foundPart, cuToktx ); + po_what, foundPart, cuToktx, foundPart, cuToktx ); } // match found for current token. Done if end fir table member text; error if tables continue differently. m += l; // add token length to # chars matched - if (o->inB && o->runB && MNAME(o->inF)[m] != MNAME(o->runF)[m]) + if (po_inB && po_runB && po_inF->fi_GetMName()[m] != po_runF->fi_GetMName()[m]) /* matching input and run field names continue differently. Error -- or could enhance following code to use whichever one matches input. @@ -341,10 +429,10 @@ LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name i //"U0013: Internal error: inconsistent %s member naming: \n" //" input member name %s vs run member name %s. \n" //" member will be un-probe-able until tables corrected or \n" - //" match algorithm (cuprobe.cpp:findMember()) enhanced.", - o->what, MNAME(o->inF), MNAME(o->runF) ); + //" match algorithm (PROBEOBJECT::po_FindMember()) enhanced.", + po_what, po_inF->fi_GetMName(), po_runF->fi_GetMName() ); - char c = o->inB ? MNAME(o->inF)[m] : MNAME(o->runF)[m]; // next char to match: \0, . [ ] digit alpha _ + const char c = po_inB ? po_inF->fi_GetMName()[m] : po_runF->fi_GetMName()[m]; // next char to match: \0, . [ ] digit alpha _ if (c=='\0') // if end of member name in fir table break; // done! complete matching entry found. leave "for ( ; ; )". @@ -362,7 +450,7 @@ LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name i case ']': if (c != cuToktx[0]) return perNx( MH_U0014, //"U0014: Expected '%c' next in %s member specification,\n" - c, o->what, cuToktx ); //" found '%s'" + c, po_what, cuToktx ); //" found '%s'" break; default: @@ -370,19 +458,19 @@ LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name i { case '_': if (!isWord) return perNx( MH_U0015, //"U0015: Expected word next in %s member specification,\n" - o->what, cuToktx); //" found '%s'" + po_what, cuToktx); //" found '%s'" } else if (isdigitW(c)) { if (tokTy != CUTSI) return perNx( MH_U0016, //"U0016: Expected number (subscript) next in %s \n" - o->what, cuToktx ); //" member specification, found '%s'" + po_what, cuToktx ); //" member specification, found '%s'" /* probably will want to add a (constant) numeric expression parse then canonicalize the value into cuToktx before continuing to text match */ } else return perNx( MH_U0017, //"U0017: Internal error: unexpected next character '%c'" - c, o->what); //" in %s fir table member name", + c, po_what); //" in %s fir table member name", break; } // switch (c) @@ -391,9 +479,9 @@ LOCAL RC FC findMember( PROBEOBJECT *o) // parse and look up probe member name i } // for ( ; ; ) composite field name match loop return RCOK; -} // findMember -//========================================================================== -LOCAL RC FC tryImInProbe( PROBEOBJECT *o) +} // PROBEOBJECT::po_FindMember +//----------------------------------------------------------------------------- +RC PROBEOBJECT::po_TryImInProbe() // do immediate input probe of already set member if possible, producing constant or reference to same expression as in member. @@ -403,50 +491,52 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) RCBAD: error, message issued. RCCANNOT: can't do immediate probe; caller should try another method. */ { - record *e = NULL; - char *name="", iBuf[10]; - TI defO; - SI i; - UCH fs; - void *v, *pv; - USI h, exEvf, exTy; - RC trc; - - if ( !o->inB // cannot if did not find an input basAnc - || !o->ssIsK) // cannot do if record subscript is not a constant -- don't know which record to probe. + + + if ( !po_inB // cannot if did not find an input basAnc + || !po_ssIsK) // cannot do if record subscript is not a constant -- don't know which record to probe. return RCCANNOT; - BP b = o->inB; + + BP b = po_inB; + record *e = NULL; + const char* name = ""; + char iBuf[10]; // access record - switch (o->ssTy) // cases by type of subscript expr. "not found" errmsg below switch if e NULL. + switch (po_ssTy) // cases by type of subscript expr. "not found" errmsg below switch if e NULL. { case TYSI: - i = *(SI*)o->pSsV; + { + SI i = *(SI*)po_pSsV; if (i > 0 && i <= b->n) // if subscript in range, - e = &b->rec(*(SI*)o->pSsV); // point to record by number, else leave e NULL. - snprintf( iBuf, sizeof(iBuf), "[%d]", i); + e = &b->rec(*(SI*)po_pSsV); // point to record by number, else leave e NULL. + snprintf(iBuf, sizeof(iBuf), "[%d]", i); name = iBuf; // make 'name' text for error messages break; + } case TYSTR: - name = *(char**)o->pSsV; // name for lookup and error messages + { + name = *(char**)po_pSsV; // name for lookup and error messages // conditionally use owner per context of probe to resolve name ambiguity - defO = ratDefO(b); /* get 0 or input record subscript in b->ownB of context in which current - expr is being evaluated. Returns 0 if not "owned record" basAnc, if its .ownB - is 0, or cur expr not embedded in stmt group for such a record. cul.cpp. */ - if (defO) - trc = b->findRecByNmDefO( name, defO, &e, NULL); // seek record (ancrec.cpp) by name & defO, ret ptr if found. - else - trc = b->findRecByNmU( name, NULL, &e); // seek unique record (ancpak.cpp) by name, ret ptr if found. + TI defO = ratDefO(b); /* get 0 or input record subscript in b->ownB of context in which current + expr is being evaluated. Returns 0 if not "owned record" basAnc, if its .ownB + is 0, or cur expr not embedded in stmt group for such a record. cul.cpp. */ + RC trc = defO + ? b->findRecByNmDefO(name, defO, &e, NULL) // seek record (ancrec.cpp) by name & defO, ret ptr if found. + : b->findRecByNmU(name, NULL, &e); // seek unique record (ancpak.cpp) by name, ret ptr if found. /*if (!evfOk) as below; add if found ambiguity error occurs here when caller fallthru to runtime probe could work */ if (trc==RCBAD2) // if ambiguity (not resolved by defO) - return perNx( MH_U0020, // "U0020: %s name '%s' is ambiguous: 2 or more records found.\n" - b->what, name ); // " Change to unique names." + return perNx(MH_U0020, // "U0020: %s name '%s' is ambiguous: 2 or more records found.\n" + b->what, name); // " Change to unique names." + break; + } // fall thru not found check or return for caller to try other methods - default: ; // other unexpected; leaves e NULL. + default: // other unexpected; leaves e NULL. + break; } if (!e) // if (unique) record not found, can't probe its member. { @@ -456,7 +546,7 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) return perNx( MH_U0021, //"U0021: %s '%s' has not been defined yet.\n" //" A constant value is required %s a forward reference cannot be used.\n" //" Try reordering your input.", - o->what, name, + po_what, name, ermTx // context per global if nonNULL ? strtprintf(MH_U0021a, ermTx) // "for '%s' --\n " : "--" ); @@ -466,7 +556,7 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) // access field, check set - fs = *((UCH *)e + b->sOff + o->inFn); // fetch member's field status byte + UCH fs = e->fStat()[ po_inFn]; // fetch member's field status byte if (!(fs & FsSET)) // if field[inFn] not set according to field status byte { if (!evfOk) /* if constant req'd in this expr's context (not even EVEOI/EVFFAZ permitted), do our own @@ -476,15 +566,15 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) return perNx( MH_U0022, //"U0022: %s '%s' member %s has not been set yet.\n" //" A constant value is required %s a forward reference cannot be used.\n" //" Try reordering your input." - o->what, name, o->mName, + po_what, name, po_mName, ermTx // context per global if nonNULL ? strtprintf(MH_U0021a, ermTx) // "for '%s' --\n " : "--" ); return RCCANNOT; /* record not found and evfOk not 0. A non-immediate probe method may work, and expr's msg isn't so bad for other variabilities, so let caller fall thru. */ } - pv = (char *)e + o->inF->fi_off; // point to member - v = *(void **)pv; // fetch member as 4-byte quantity + void* pv = (char *)e + po_inF->fi_off; // point to member + void* v = *(void **)pv; // fetch member as 4-byte quantity // if set to constant value, generate constant for same value @@ -492,8 +582,8 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) { // generate code for constant value to which member already set dropSfs( 0, 1); // now discard the subscript code (drop parStk frame) - emiKon( o->ty, o->ty==TYSTR ? v : pv, 0, NULL); // emit constant for probe'd field's value - parSp->ty = o->ty; // set type of emitted code + emiKon( po_ty, po_ty==TYSTR ? v : pv, 0, NULL); // emit constant for probe'd field's value + parSp->ty = po_ty; // set type of emitted code prec = PROP; // say have an operand // no evf: is constant return RCOK; // ok immediate probe to previously set constant input value @@ -501,28 +591,29 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) // test whether set to expression we can access - if (o->sz < 4) // if too small to hold a nandle + if (po_sz < 4) // if too small to hold a nandle return RCCANNOT; // cannot access expression via member (seek in exTab?) //FsSet & ! FsVAL implies expr nandle. insurance check: if (! ISNANDLE(v) // if not a nandle || ISASING(v) // or value is being determined by autosize || ISUNSET(v) ) // or is plain unset (required) data (bug here) return RCCANNOT; // we can't do immediate access. - h = EXN(v); // get expr's expression number + USI h = EXN(v); // get expr's expression number + USI exEvf, exTy; if (exInfo( h, &exEvf, &exTy, NULL)) // get expr's type and variability / if h bad (no msg done)(exman.cpp) { // debug aid msg; shd be ok to continue to other cases return perNx( MH_U0023, // "U0023: Internal error: %s '%s' member '%s' \n" - o->what, name, o->mName, h ); // " contains reference to bad expression # (0x%x)" + po_what, name, po_mName, h ); // " contains reference to bad expression # (0x%x)" } - else if (exTy != o->ty) // if expression type does not match member type + else if (exTy != po_ty) // if expression type does not match member type { // here add code to resolve any resolvable differences as they become understood // msg mainly as debug aid -- shd be ok to continue to other cases (return RCCANNOT): return perNx( MH_U0024, // "U0024: Internal error: %s '%s' member '%s', \n" - o->what, name, o->mName, h, // " containing expression (#%d):\n" - o->ty, exTy ); // " member type (ty), %d and expression type, %d, do not match.", + po_what, name, po_mName, h, // " containing expression (#%d):\n" + po_ty, exTy ); // " member type (ty), %d and expression type, %d, do not match.", } // generate code to reference same expression as member is already set to @@ -535,7 +626,7 @@ LOCAL RC FC tryImInProbe( PROBEOBJECT *o) parSp->evf |= exEvf; // use only vblty of the expr. shd be <= that of probed member. return RCOK; // ok immediate probe to previously set expression input value // another good return and several error returns above. -} // tryImInProbe +} // PROBEOBJECT::po_TryImInProbe //========================================================================== LOCAL RC FC lopNty4dt( // for DT- data type, get TY- type and PSOP to load it from a record of a basAnc @@ -779,7 +870,7 @@ void FC showProbeNames(int showAll) // display a member of only table or that matches in both tables - if (!inF || !runF || !_stricmp(MNAME(inF), MNAME(runF)) ) + if (!inF || !runF || !_stricmp(inF->fi_GetMName(), runF->fi_GetMName()) ) { disMember( inF ? inF : runF, inF != NULL, runF != NULL, showAll); if (inF) inF++; @@ -803,16 +894,16 @@ void FC showProbeNames(int showAll) for (j = 0; j <= k; j++) // compare kth member of each table to 0..kth of other { if ( (!inMax || j < inMax) && (!runMax || k < runMax) ) - if (!_stricmp( MNAME(inF+j), MNAME(runF+k)) ) // compare member names + if (!_stricmp( inF[j].fi_GetMName(), runF[k].fi_GetMName()) ) // compare member names goto breakBreak; // found match after j input items, k run items if (j != k) // reverse test wastes time if j==k if ( (!inMax || k < inMax) && (!runMax || j < runMax) ) // compare with subscripts interchanged - if (!_stricmp( MNAME(inF+k), MNAME(runF+j)) ) + if (!_stricmp( inF[k].fi_GetMName(), runF[j].fi_GetMName()) ) { i = j; j = k; k = i; // swap j and k - goto breakBreak; // found match after j input items, k run items + goto breakBreak; // found match after j input items, k run items } } } @@ -855,7 +946,7 @@ LOCAL void FC disMember( SFIR *f1, SI isIn, SI isRun, SI showAll) // display inf : evfTx( f1->fi_evf, 0); printf( " %20s %s %s %-15s %s\n", - MNAME(f1), + f1->fi_GetMName(), isIn ? "I" : " ", isRun ? "R" : " ", tySubTx, diff --git a/src/exman.cpp b/src/exman.cpp index 2cab16e85..58b14dd7a 100644 --- a/src/exman.cpp +++ b/src/exman.cpp @@ -1492,7 +1492,7 @@ const char* FC whatEx( USI h) BP b = ex->ext_srcB; if (b) // if baseAnc specified in exTab: insurance return strtprintf( "%s of %s%s %s", - MNAME(b->fir + ex->ext_srcFn), // field member name in record (srd.h macro may access special segment) + b->fir[ ex->ext_srcFn].fi_GetMName(), // field member name in record b->what, // rat name: ZONE etc ex->ext_srcIsType ? " type" : "", // "type" if pertinent b->ptr() // note 1 @@ -1521,7 +1521,7 @@ const char* FC whatNio( USI ancN, TI i, USI off) // error message insert descri const char* mName = nullptr; for (SFIR *fir = b->fir; fir && fir->fi_fdTy; fir++) // find member name in rat's fields-in-record table if (fir->fi_off==off) - mName = MNAME(fir); // srd.h macro points to name text, possibly in special segment + mName = fir->fi_GetMName(); // point to name text if (!mName) mName = strtprintf( MH_E0109, off); // if member not found, show offset in msg "member at offset %d" diff --git a/src/msgtbl.cpp b/src/msgtbl.cpp index 7f061c6cd..6cb7fffe7 100644 --- a/src/msgtbl.cpp +++ b/src/msgtbl.cpp @@ -1002,7 +1002,7 @@ x { MH_T0003, "\nReport file name: %s" }, MH_U0013, "U0013: Internal error: inconsistent %s member naming: \n" " input member name %s vs run member name %s. \n" " member will be un-probe-able until tables corrected or \n" - " match algorithm (cuprobe.cpp:findMember()) enhanced." + " match algorithm (PROBEOBJECT::po_findMember()) enhanced." }, { MH_U0014, "U0014: Expected '%c' next in %s member specification,\n found '%s'" }, { MH_U0015, "U0015: Expected word next in %s member specification,\n found '%s'" }, diff --git a/src/srd.h b/src/srd.h index 60b79da3f..f4bd1e88a 100644 --- a/src/srd.h +++ b/src/srd.h @@ -135,11 +135,10 @@ struct SFIR // supports e.g. general record::Copy(). 6-2023 USI fi_off; // member offset in rec. 14 bits needed 6-95. const char* fi_mName; // record struct MEMBER name. for arrays & nested structs, contains composite with .'s and/or [n]'s. + int fi_GetDT() const { return sFdtab[fi_fdTy].dtype; } + const char* fi_GetMName() const { return fi_mName; } }; - //--- Historical macro to point to member name in SFIRstr s - #define MNAME(s) ((s)->fi_mName) - /*--- Field Flag bits, for SFIR.fi_ff */ inline constexpr UCH FFHIDE{ 1}; // hide field: omit field from probe info report (CSE -p) @@ -191,6 +190,39 @@ struct VALNDT }; #endif // NODTYPES +//============================================================================= +// struct MODERNIZEPAIR: single word modernize, maps old -> current +// used re providing input file backwards compatibility +// e.g. probe name moderization +struct MODERNIZEPAIR // single word modernize: old -> current +{ +private: + const char* mp_oldWord; // prior word + const char* mp_curWord; // current (modern) equivalent + +public: + MODERNIZEPAIR(const char* oldWord, const char* curWord) + : mp_oldWord{ oldWord }, mp_curWord{ curWord } + {} + bool mp_IsEnd() const + { + return mp_oldWord==nullptr; + } + bool mp_ModernizeIf( + const char* &word) const // word that may need modernizing + // e.g. from user input + // returned updated if needed + // returns true iff word modernized (word updated) + // else false + { + bool bMatch = _strcmpi(word, mp_oldWord) == 0; + if (bMatch) + word = mp_curWord; + return bMatch; + } + +}; // struct MODERNIZEPAIR + #endif // ifndef SRD_H at start file // end of srd.h diff --git a/test/dhw_dr.cse b/test/dhw_dr.cse index 43008b139..096a41134 100644 --- a/test/dhw_dr.cse +++ b/test/dhw_dr.cse @@ -4640,6 +4640,7 @@ WSCHAR (1) #define TOTIN( h) (@DHWHEATER[ h].inElecTot + @DHWHEATER[ h].inFuelTot) #define WHCHAR(h) REPORT rptype=UDT rpFreq=YEAR rpTitle = "DHWHEATER HPWH" \ +ReportCol colhead = "Desc" colVal = @DHWHEATER[ h].desc colWid=50 \ ReportCol colhead = "Count" colVal = @DHWHEATER[ h].mult colWid=5 \ ReportCol colhead = "VolEa" colVal = @DHWHEATER[ h].vol colDec=1 colWid = 6 \ ReportCol colhead = "VolTot" colVal = @DHWHEATER[ h].vol * @DHWHEATER[ h].mult colDec=1 colWid=6 \ diff --git a/test/ref-win32-msvc/DHW_DR.REP b/test/ref-win32-msvc/DHW_DR.REP index 3a1500f60..6c2374914 100644 --- a/test/ref-win32-msvc/DHW_DR.REP +++ b/test/ref-win32-msvc/DHW_DR.REP @@ -2,9 +2,9 @@ DHWHEATER HPWH - Count VolEa VolTot totHARL totOut totIn - ----- ------ ------ -------- -------- -------- - 1 58.5 58.5 21570756 490218 10296750 + Desc Count VolEa VolTot totHARL totOut totIn + -------------------------------------------------- ----- ------ ------ -------- -------- -------- + ASHPX SmallStorage Rheem2020Prem65 1 58.5 58.5 21570756 490218 10296750 @@ -384,7 +384,7 @@ Day 39.430 0 0 0 10.206 25.961 0 0 0 0 0 ! Log for Run 001: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console @@ -5032,6 +5032,7 @@ Input for Run 001: # #define TOTIN( h) (@DHWHEATER[ h].inElecTot + @DHWHEATER[ h].inFuelTot) # #define WHCHAR(h) REPORT rptype=UDT rpFreq=YEAR rpTitle = "DHWHEATER HPWH" \ +# ReportCol colhead = "Desc" colVal = @DHWHEATER[ h].desc colWid=50 \ # ReportCol colhead = "Count" colVal = @DHWHEATER[ h].mult colWid=5 \ # ReportCol colhead = "VolEa" colVal = @DHWHEATER[ h].vol colDec=1 colWid = 6 \ # ReportCol colhead = "VolTot" colVal = @DHWHEATER[ h].vol * @DHWHEATER[ h].mult colDec=1 colWid=6 \ @@ -5088,9 +5089,9 @@ Input for Run 001: DHWHEATER HPWH - Count VolEa VolTot totHARL totOut totIn - ----- ------ ------ -------- -------- -------- - 1 58.5 58.5 21570756 473507 8591061 + Desc Count VolEa VolTot totHARL totOut totIn + -------------------------------------------------- ----- ------ ------ -------- -------- -------- + ASHPX SmallStorage Rheem2020Prem65 1 58.5 58.5 21570756 473507 8591061 @@ -5470,7 +5471,7 @@ Day 35.682 0 0 0 11.241 21.202 0 0 0 0 0 ! Log for Run 002: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console @@ -5485,9 +5486,9 @@ Input for Run 002: DHWHEATER HPWH - Count VolEa VolTot totHARL totOut totIn - ----- ------ ------ -------- -------- -------- - 1 58.5 58.5 21570756 583743 8692494 + Desc Count VolEa VolTot totHARL totOut totIn + -------------------------------------------------- ----- ------ ------ -------- -------- -------- + ASHPX SmallStorage Rheem2020Prem65 1 58.5 58.5 21570756 583743 8692494 @@ -5867,7 +5868,7 @@ Day 36.089 0 0 0 11.375 22.382 0 0 0 0 0 ! Log for Run 003: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console @@ -5882,9 +5883,9 @@ Input for Run 003: DHWHEATER HPWH - Count VolEa VolTot totHARL totOut totIn - ----- ------ ------ -------- -------- -------- - 1 58.5 58.5 21570756 469673 7587664 + Desc Count VolEa VolTot totHARL totOut totIn + -------------------------------------------------- ----- ------ ------ -------- -------- -------- + ASHPX SmallStorage Rheem2020Prem65 1 58.5 58.5 21570756 469673 7587664 @@ -6264,7 +6265,7 @@ Day 31.636 0 0 0 12.737 15.399 0 0 0 0 0 ! Log for Run 004: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console @@ -6279,9 +6280,9 @@ Input for Run 004: DHWHEATER HPWH - Count VolEa VolTot totHARL totOut totIn - ----- ------ ------ -------- -------- -------- - 1 58.5 58.5 21570756 391393 6960310 + Desc Count VolEa VolTot totHARL totOut totIn + -------------------------------------------------- ----- ------ ------ -------- -------- -------- + ASHPX SmallStorage Rheem2020Prem65 1 58.5 58.5 21570756 391393 6960310 @@ -6661,7 +6662,7 @@ Day 28.734 0 0 0 13.654 12.446 0 0 0 0 0 ! Log for Run 005: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console @@ -6677,18 +6678,18 @@ Input for Run 005: -! CSE 0.921.0+wudays-check.d4ed889a.60.dirty for Win32 console run(s) done: Tue 27-Feb-24 11:28:38 am +! CSE 0.923.0+alias.5cb86fa6.4.dirty for Win32 console run(s) done: Fri 27-Dec-24 1:3 pm -! Executable: d:\cse\msvc\cse.exe -! 26-Feb-24 5:13 pm (VS 14.29 2873344 bytes) (HPWH 1.23.0+HEAD.4609465.28) +! Executable: d:\cse\builds\cse.exe +! 27-Dec-24 1:2 pm (VS 14.29 2941952 bytes) (HPWH 1.24.0) ! Command line: -x! -t1 dhw_dr ! Input file: D:\cse\test\dhw_dr.cse ! Report file: D:\CSE\TEST\DHW_DR.REP ! Timing info -- -! Input: Time = 0.57 Calls = 5 T/C = 0.1138 +! Input: Time = 0.59 Calls = 5 T/C = 0.1176 ! AutoSizing: Time = 0.00 Calls = 0 T/C = 0.0000 -! Simulation: Time = 4.85 Calls = 5 T/C = 0.9706 -! Reports: Time = 0.01 Calls = 5 T/C = 0.0018 -! Total: Time = 5.44 Calls = 1 T/C = 5.4420 +! Simulation: Time = 4.43 Calls = 5 T/C = 0.8860 +! Reports: Time = 0.01 Calls = 5 T/C = 0.0016 +! Total: Time = 5.04 Calls = 1 T/C = 5.0420