@@ -301,7 +301,7 @@ class LUTAB
301301// /////////////////////////////////////////////////////////////////////////////
302302
303303/* ============================= LOCAL ROUTINES ===========================*/
304- LOCAL void Do_Dtypes ( FILE* file_dtypesh);
304+ LOCAL void Do_Dtypes (const char * fnameDtypesDef, FILE* file_dtypesh);
305305LOCAL void wdtypes ( FILE *f);
306306LOCAL void wChoices ( FILE* f);
307307LOCAL void wDttab ( void );
@@ -330,6 +330,8 @@ LOCAL void wSrfd3( FILE *f);
330330LOCAL void sumry ( void );
331331LOCAL FILE * rcfopen ( const char *s, char **argv, int argi);
332332LOCAL void rcderr ( const char *s, ...);
333+ static void msgWrite (const char * msg, ...);
334+ static void msgWriteV (const char * msg, va_list ap = nullptr );
333335LOCAL int update ( const char * old, const char * nu);
334336LOCAL void newsec ( const char *);
335337LOCAL const char * enquote ( const char *s);
@@ -378,8 +380,9 @@ const int GTERR = 3; // conversion error or *END in pos other than first. Erro
378380
379381struct INFILE
380382{
381- FILE* Fpm; // current input stream, read by GetToks(). Note several files are opened
382- // during command line checking; Fpm is set to each in sequence as they are used.
383+ FILE* Fpm; // current input stream, read by GetToks()
384+
385+ const char * inf_what; // Description of this file/stream e.g. for msgs
383386
384387 int gtokRet; // return value from most recent GetToks() / PeepToks()
385388
@@ -408,8 +411,10 @@ struct INFILE
408411 }
409412
410413
411- INFILE () : Fpm(nullptr ), gtokRet(GTERR) { ClearVals (); }
412- int Close () { fclose (Fpm); return 0 ; }
414+ INFILE () : Fpm(nullptr ), inf_what( nullptr ), gtokRet(GTERR) { ClearVals (); }
415+ ~INFILE () { Close (); }
416+ int Close () { if (Fpm) fclose (Fpm); Fpm = nullptr ; return 0 ; }
417+ bool Open (const char * fName , const char * what);
413418 void ClearVals ();
414419 int SetInputFile ( FILE* fInput );
415420 long GetFilePos ();
@@ -517,11 +522,11 @@ int CDEC main( int argc, char * argv[] )
517522 // Check number of arguments
518523 if (argc <= REQUIRED_ARGS || argc > REQUIRED_ARGS+2 )
519524 {
520- printf (" \n Exactly %d or %d args are required\n " ,
525+ msgWrite (" \n Exactly %d or %d args are required\n " ,
521526 REQUIRED_ARGS, REQUIRED_ARGS+1 );
522- exit (2 ); // do nothing if args not all present
527+ byebye (2 ); // do nothing if args not all present
523528 // (Note reserving errorlevel 1 for possible
524- // future alternate good exit, 12-89 )
529+ // future alternate good exit)
525530 }
526531
527532 try
@@ -531,8 +536,10 @@ int CDEC main( int argc, char * argv[] )
531536 for (int i = 0 ; i <= REQUIRED_ARGS; i++)
532537 argNotNUL[i] = _stricmp ( argv[i], " NUL" ) != 0 ;
533538
539+ const char * fNameDtypes = argv[1 ];
540+
534541 /* Get and check input file names from command line */
535- FILE* file_dtypes = rcfopen ( " data types" , argv, 1 );
542+ // FILE* file_dtypes = rcfopen( "data types", argv, 1);
536543 FILE* file_units = rcfopen ( " units" , argv, 2 );
537544 FILE* file_limits = rcfopen ( " limits" , argv, 3 );
538545 FILE* file_fields = rcfopen ( " fields" , argv, 4 );
@@ -623,16 +630,14 @@ int CDEC main( int argc, char * argv[] )
623630
624631 /* ************* Data types ************** */
625632
626- InFile.SetInputFile (file_dtypes); // Set input file for InFile.GetToks(). fopen() is in command line checking at beg of main
627633 FILE* fdtyph = NULL ;
628634 if (HFILESOUT) // not if not outputting .h files
629635 {
630636 xfjoinpath (incdir, " dtypes.hx" , fdtyphname);
631637 fdtyph = fopen ( fdtyphname," w" ); // open in main becuase left open til end for record structure typedefs
632638 }
633- Do_Dtypes ( fdtyph); // local fcn, after main. sets many globals.
634- InFile.Close ();
635-
639+ Do_Dtypes (fNameDtypes , fdtyph);
640+
636641 /* ************ Unit definitions ************* */
637642
638643 InFile.SetInputFile (file_units); // Set input file for token-reader InFile.GetToks(). fopen()'d in cmd line checking at beg of main.
@@ -748,17 +753,18 @@ static SWTABLE declSize[] =
748753} // determine_size
749754// ======================================================================
750755LOCAL void Do_Dtypes ( // do data types
751- FILE* file_dtypesh) // where to write dtypes.h[x]
756+ const char * fNameDtypesDef ,
757+ FILE* file_dtypesh) // where to write dtypes.h[x]
758+ // nullptr if not writing, else assumed open
752759{
753760
754-
755- // global Fpm assumed preset to file_dtypes
756- // global file fdtyph assumed open if HFILESOUT
757-
758761 newsec (" DATA TYPES" );
759762
763+ INFILE fInDT ;
764+ if (!fInDT .Open (fNameDtypesDef , " Data type definitions" ))
765+ return ;
760766
761- // Init memory table that holds our sequential array subscripts for the sparse data types, for retreival later in rcdef.
767+ // Init memory table that holds our sequential array subscripts for the sparse data types, for retreival later in rcdef.
762768
763769 /* input format example:
764770
@@ -783,7 +789,7 @@ LOCAL void Do_Dtypes( // do data types
783789 const int STK1 = 1 ;
784790 dttabsz = 1 ; // next free word in Dttab
785791 // (reserve 0 for automatically generated DTNONE)
786- while (InFile .GetToks (" ss" )==GTOK) // 2 tokens: typeName, Extern, or: *choicb/n, typeName.
792+ while (fInDT .GetToks (" ss" )==GTOK) // 2 tokens: typeName, Extern, or: *choicb/n, typeName.
787793 // Sets gtokRet to ret val, used after loop.
788794 {
789795 if (ndtypes >= MAXDT) // prevent overflow of internal arrays
@@ -800,32 +806,32 @@ LOCAL void Do_Dtypes( // do data types
800806 const char * cp = nullptr ;
801807 int choicb = 0 ; // not (yet) a choice data type
802808 int choicn = 0 ;
803- if (*InFile .SVal (STK0) == ' *' ) // is it "*choicb"?
809+ if (*fInDT .SVal (STK0) == ' *' ) // is it "*choicb"?
804810 {
805- if (_stricmp ( InFile .SVal (STK0) + 1 , " choicb" )==0 )
811+ if (_stricmp ( fInDT .SVal (STK0) + 1 , " choicb" )==0 )
806812 choicb = 1 ;
807- else if (_stricmp ( InFile .SVal (STK0) + 1 , " choicn" )==0 )
813+ else if (_stricmp ( fInDT .SVal (STK0) + 1 , " choicn" )==0 )
808814 choicn = 1 ;
809815 else
810816 {
811- rcderr ( " unrecognized data type *-word '%s':\n expect '*choicb' or '*choicn'" , InFile .SVal (STK0) );
817+ rcderr ( " unrecognized data type *-word '%s':\n expect '*choicb' or '*choicn'" , fInDT .SVal (STK0) );
812818 continue ; // recovery imperfect
813819 }
814- InFile .SetSVal ( STK0, InFile .SVal ( STK1)); // move next token (name) back
820+ fInDT .SetSVal ( STK0, fInDT .SVal ( STK1)); // move next token (name) back
815821 }
816822 else // no *-word, not a choice type
817- cp = (InFile .SVal (STK1)[1 ] == ' -' ) // if "--" given for external name
823+ cp = (fInDT .SVal (STK1)[1 ] == ' -' ) // if "--" given for external name
818824 ? (char *)NULL // tell wdtypes to make no ext decl
819- : InFile .StashSVal (STK1); // save extern type name in next Stbuf slot, set cp to it. Used below.
820- if (dtlut.lu_Find ( InFile .SVal (STK0)) != LUFAIL) // check for duplicate
825+ : fInDT .StashSVal (STK1); // save extern type name in next Stbuf slot, set cp to it. Used below.
826+ if (dtlut.lu_Find ( fInDT .SVal (STK0)) != LUFAIL) // check for duplicate
821827 {
822- rcderr (" Duplicate data type '%s' omitted." , InFile .SVal (STK1));
828+ rcderr (" Duplicate data type '%s' omitted." , fInDT .SVal (STK1));
823829 continue ;
824830 }
825831
826832 // common processing of choice, var, non-var data types
827833
828- int val = dtlut.lu_Add ( InFile .StashSVal ( STK0)); // same typeName in nxt Stbuf space, enter ptr to saved name in tbl.
834+ int val = dtlut.lu_Add ( fInDT .StashSVal ( STK0)); // same typeName in nxt Stbuf space, enter ptr to saved name in tbl.
829835 // Sets dtnames[]. Subscript val is also used for other dt arrays
830836 // dtMap.emplace(STK0, 0);
831837
@@ -848,25 +854,25 @@ LOCAL void Do_Dtypes( // do data types
848854 dtsize[val] = choicn ? sizeof (float ) : sizeof (SI);
849855 dttype[val] = dttabsz // type: Dttab index, plus
850856 | (choicn ? DTBCHOICN : DTBCHOICB); // appropriate choice bit
851- if (InFile .GetToks (" s" )) // gobble the {
857+ if (fInDT .GetToks (" s" )) // gobble the {
852858 rcderr (" choice data type { error." );
853859
854860 // loop over choices list
855861
856862 int nchoices = 0 ;
857- while (!InFile .GetToks (" p" )) // peek at next char / while ok
863+ while (!fInDT .GetToks (" p" )) // peek at next char / while ok
858864 {
859- if (InFile .SVal (0 )[0 ] ==' }' ) // if next char }, not next handle #
865+ if (fInDT .SVal (0 )[0 ] ==' }' ) // if next char }, not next handle #
860866 {
861- InFile .GetToks (" s" );
867+ fInDT .GetToks (" s" );
862868 break ; // gobble final } and stop
863869 }
864- if (InFile .GetToks (" sq" )) // read name, text
870+ if (fInDT .GetToks (" sq" )) // read name, text
865871 rcderr ( " Choicb problem." );
866872
867- if (getChoiTxTyX ( InFile .SVal (0 )) != 0 )
868- rcderr ( " Disallowed prefix on choicb/n name '%s' --\n choib.h will be bad." , InFile .SVal (0 ) );
869- dtcdecl[ val][ nchoices]= InFile .StashSVal (0 ); // save choicb/n name
873+ if (getChoiTxTyX ( fInDT .SVal (0 )) != 0 )
874+ rcderr ( " Disallowed prefix on choicb/n name '%s' --\n choib.h will be bad." , fInDT .SVal (0 ) );
875+ dtcdecl[ val][ nchoices]= fInDT .StashSVal (0 ); // save choicb/n name
870876
871877 // choice TEXT may specify aliases ("MAIN|ALIAS1|ALIAS2")
872878 // Items may begin with prefix
@@ -876,14 +882,14 @@ LOCAL void Do_Dtypes( // do data types
876882 // else "normal"
877883 // NOTE: only MAIN yields #define C_XXX_xxx
878884
879- const char * chStr = InFile .StashSVal (1 ); // choicb/n text
885+ const char * chStr = fInDT .StashSVal (1 ); // choicb/n text
880886
881887 // choicb/n index: indeces 1,2,3 used.
882888 int chan = nchoices + 1 ; // 1, 2, 3, ... here for error msg; regenerated in wChoices().
883889
884- int tyX = getChoiTxTyX ( InFile .SVal ( 1 ));
890+ int tyX = getChoiTxTyX ( fInDT .SVal ( 1 ));
885891 if (tyX >= chtyALIAS)
886- rcderr ( " choicb/n '%s' -- main choice cannot be alias" , InFile .SVal (0 ));
892+ rcderr ( " choicb/n '%s' -- main choice cannot be alias" , fInDT .SVal (0 ));
887893
888894 if (nchoices >= MAXDTC)
889895 rcderr ( " Discarding choices in excess of %d." , MAXDTC);
@@ -901,7 +907,7 @@ LOCAL void Do_Dtypes( // do data types
901907 *pli = ULI (chStr); // choicb / n text snake offset to Dttab :
902908 nchoices++; // count choices for this data type
903909 }
904- } // while (!InFile .GetToks("p")) choices loop
910+ } // while (!fInDT .GetToks("p")) choices loop
905911
906912 // set Dttab[masked dt] for choice type
907913 Dttab[dttabsz++] = SetHiLo16Bits ( nchoices, // Hi16 is # choices
@@ -913,11 +919,11 @@ LOCAL void Do_Dtypes( // do data types
913919
914920 // get rest of non-choice data type input and process
915921
916- if (InFile .GetToks (" q" )) // get decl
922+ if (fInDT .GetToks (" q" )) // get decl
917923 rcderr (" Bad datatype definition" );
918924
919925 dtxnm[val] = cp; // NULL or external type text, saved above.
920- dtdecl[val] = InFile .StashSVal (0 ); // save decl text, set array
926+ dtdecl[val] = fInDT .StashSVal (0 ); // save decl text, set array
921927 dtsize[val] = determine_size (dtdecl[val]); // size to array
922928 *(Dttab + dttabsz) = dtsize[val]; // size to Dttab
923929 dttype[val] = dttabsz++; // type: Dttab index
@@ -929,7 +935,7 @@ LOCAL void Do_Dtypes( // do data types
929935 ndtypes++; // count data types
930936 } // data types token while loop
931937
932- if (InFile .gtokRet != GTEND) // if 1st token not *END (InFile .GetToks at loop top)
938+ if (fInDT .gtokRet != GTEND) // if 1st token not *END (fInDT .GetToks at loop top)
933939 rcderr (" Data types definitions do not end properly" );
934940
935941// Write data type definitions to dtypes.hx, dttab.cpp
@@ -3205,6 +3211,21 @@ LOCAL FILE* rcfopen( // Open an existing input file from the command l
32053211 }
32063212 return f;
32073213} // rcfopen
3214+ // ======================================================================
3215+ bool INFILE::Open (
3216+ const char * fName ,
3217+ const char * what)
3218+ {
3219+ inf_what = stash (what);
3220+ Fpm = fopen (fName , " r" );
3221+ if (Fpm == nullptr )
3222+ {
3223+ msgWrite (" Can't open %s '%s'" , what, fName );
3224+ Errcount++;
3225+ return false ;
3226+ }
3227+ return true ;
3228+ }
32083229// ----------------------------------------------------------------------
32093230void INFILE::ClearVals ()
32103231{
@@ -3473,6 +3494,24 @@ int INFILE::GetToks( // Retrieve tokens from input stream accordin
34733494 return (gtokRet = GTEOF);
34743495} // gtoks
34753496// ======================================================================
3497+ #if 1
3498+ LOCAL void rcderr (const char * s, ...) // Print an error message with optional arguments and count error
3499+
3500+ // s is Error message, with optional %'s as for printf; any necessary arguments follow.
3501+ {
3502+ va_list ap;
3503+ va_start (ap, s); // point at args, if any
3504+
3505+ msgWrite (s, ap);
3506+ msgWrite ( " Error occurred near : %s\n " , Stbp);
3507+ Errcount++;
3508+
3509+ /* #define ABORTONERROR */
3510+ #ifdef ABORTONERROR
3511+ exit (2 ); // (exit(1) reserved for poss alt good exit, 12-89)
3512+ #endif
3513+ } // rcderr
3514+ #else
34763515LOCAL void rcderr( const char *s, ...) // Print an error message with optional arguments and count error
34773516
34783517// s is Error message, with optional %'s as for printf; any necessary arguments follow.
@@ -3503,6 +3542,33 @@ LOCAL void rcderr( const char *s, ...) // Print an error message
35033542 exit(2); // (exit(1) reserved for poss alt good exit, 12-89)
35043543#endif
35053544} // rcderr
3545+ #endif
3546+ // ----------------------------------------------------------------------
3547+ static void msgWrite ( // write msg to stdOut and rcdef.err
3548+ const char * msg, // text to write (may include printf-style formatting
3549+ ...)
3550+ {
3551+ va_list ap;
3552+ va_start (ap, msg);
3553+ msgWriteV (msg, ap);
3554+ }
3555+ // -----------------------------------------------------------------------------
3556+ static void msgWriteV ( // write msg to stdOut and rcdef.err
3557+ const char * msg, // text to write (may include printf-style formatting
3558+ va_list ap /* = nullptr*/ ) // optional arg list
3559+ {
3560+ static FILE* errFile = nullptr ;
3561+ if (!errFile)
3562+ errFile = fopen (" rcdef.err" , " w" );
3563+
3564+ const char * ss = ap ? strtvprintf (msg, ap) : msg;
3565+ for (int i = 0 ; i < 2 ; i++)
3566+ {
3567+ FILE* stream = i ? errFile : stdout;
3568+ if (stream)
3569+ fprintf (stream, " \n %s\n " , ss);
3570+ }
3571+ } // msgWriteV
35063572// ======================================================================
35073573LOCAL void newsec (const char *s) // Output heading (s) for new section of run
35083574{
0 commit comments