//************************************************************************************************** // PrcSimEngBase.cpp * // ------------------- * // Started : 2004-04-25 * // Last Update : 2016-09-30 * // Copyright : (C) 2004-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // 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 3 of the License, or (at your option) any later version. * // * //************************************************************************************************** #include "PrcSimEngBase.hpp" //************************************************************************************************** // Constructor. PrcSimEngBase::PrcSimEngBase( void ) : PrcBase( wxPROCESS_REDIRECT ) { m_eSimEng = eSIMR_NONE; } //************************************************************************************************** // Destructor. PrcSimEngBase::~PrcSimEngBase( ) { } //************************************************************************************************** // Set the simulation results file name. // // Argument List : // rosFileName - A string containing the full path and file name // // Return Values : // true - Success // false - Failure bool PrcSimEngBase::bSetResultsFile( const wxString & rosFileName ) { wxFileName ofn1; ofn1 = rosFileName; if( ofn1.GetPath( ).IsEmpty( ) ) ofn1.SetPath( wxT(".") ); if( ! ofn1.IsOk( ) ) return( false ); m_oNameResults = ofn1; return( true ); } //************************************************************************************************** // Make the process argument list based on the contents of a simulation object. // // Argument List : // roSimn - The simulation object // // Return Values : // true - Success // false - Failure bool PrcSimEngBase::bMakeArgLst( SimnBase & roSimn ) { wxString os1; int i1; // Clear error attributes m_osErrMsg.Empty( ); // Only proceed if the simulator isn't already running if( bIsExec( ) ) { SetErrMsg( wxT("Simulator already running") ); return( false ); } // Create the results file name os1 = roSimn.roGetLoadFile( ).GetPath( ) + wxT('/') + roSimn.roGetLoadFile( ).GetName( ); i1 = os1.Find( wxT(".gspiceui") ); if( i1 > 0 ) os1 = os1.Truncate( (size_t) i1 ); os1 << wxT('.') << roGetBinFile( ).GetName( ); switch( roSimn.eGetAnaType( ) ) { case eCMD_OP : os1 << wxT(".op"); break; case eCMD_DC : os1 << wxT(".dc"); break; case eCMD_AC : os1 << wxT(".ac"); break; case eCMD_TR : os1 << wxT(".tr"); break; case eCMD_FO : os1 << wxT(".fo"); break; case eCMD_DI : os1 << wxT(".di"); break; case eCMD_NO : os1 << wxT(".no"); break; case eCMD_PZ : os1 << wxT(".pz"); break; case eCMD_SE : os1 << wxT(".se"); break; case eCMD_TF : os1 << wxT(".tf"); break; default : return( false ); } // Set the results file name if( ! PrcSimEngBase::bSetResultsFile( os1 ) ) { SetErrMsg( wxT("Couldn't set results file name") ); return( false ); } // Construct the default argument list os1 = roSimn.roGetSaveFile( ).GetFullPath( ); if( ! bSetArgLst( os1 ) ) { SetErrMsg( wxT("Couldn't set argument list") ); return( false ); } return( true ); } //************************************************************************************************** // Execute a simulation. // // Argument List : // roSimn - The simulation object // // Return Values : // true - Success // false - Failure bool PrcSimEngBase::bExec( void ) { wxString os1, os2; // Execute the simulation if( ! PrcBase::bExecAsync( ) ) return( false ); // Save the simulation results to the log file if( ! PrcBase::bLogOutput( ) ) return( false ); // Copy the log file to the results file os1 = roGetLogFile( ).GetFullPath( ); os2 = roGetResultsFile( ).GetFullPath( ); if( ! wxCopyFile( os1, os2 ) ) return( false ); return( true ); } //************************************************************************************************** // Format the results file. All this function does is aline the data in columns and packs the // columns together. // // Return Values : // true - Success // false - Failure bool PrcSimEngBase::bFmtResults( void ) { wxStringTokenizer ostk1; wxString os1, os2; size_t szColWd=0; size_t sz1; // This function requires the result file to have been opened if( ! m_oFileResults.IsOpened( ) ) return( false ); // Determine the width of the largest field in the results file // First check the column label widths ostk1.SetString( m_oFileResults.GetFirstLine( ) ); // Get the column header line while( ostk1.HasMoreTokens( ) ) { os1 = ostk1.GetNextToken( ); sz1 = os1.Length( ); if( os1[ 0 ] == wxT('#') ) sz1--; // Ignore the comment specifier character ie. a leading '#' if( sz1 > szColWd ) szColWd = sz1; } // Now check the data field widths ostk1.SetString( m_oFileResults.GetNextLine( ) ); // Get the first line of data while( ostk1.HasMoreTokens( ) ) { os1 = ostk1.GetNextToken( ); sz1 = os1.Length( ); if( os1[ 0 ] == wxT('-') ) sz1--; // Ignore minus signs because they are not alway present if( sz1 > szColWd ) szColWd = sz1; } // The total column width is made up of the column label and 2 space characters OR the data field // and a sign character and 1 space character szColWd += 2; // Pad the column labels so the columns are spaced evenly and everything lines up ostk1.SetString( m_oFileResults.GetFirstLine( ) ); // Get the column header line os1.Empty( ); while( ostk1.HasMoreTokens( ) ) { os1 << ostk1.GetNextToken( ); if( ! ostk1.HasMoreTokens( ) ) break; // The last token has been processed sz1 = szColWd - (os1.Length( ) % szColWd); os1.Append( wxT(' '), sz1+1 ); } m_oFileResults[ m_oFileResults.GetCurrentLine( ) ] = os1; // Pad the data fields so the columns are spaced evenly and everything lines up for( os1=m_oFileResults.GetNextLine(); !m_oFileResults.Eof(); os1=m_oFileResults.GetNextLine() ) { ostk1.SetString( os1 ); os1.Empty( ); while( ostk1.HasMoreTokens( ) ) { os2 = ostk1.GetNextToken( ); if( os2[ 0 ] != wxT('-') ) os1 << wxT(' '); // Make allowance for a leading sign character os1 << os2; if( ! ostk1.HasMoreTokens( ) ) break; // The last token has been processed sz1 = szColWd - (os1.Length( ) % szColWd); os1.Append( wxT(' '), sz1 ); } m_oFileResults[ m_oFileResults.GetCurrentLine( ) ] = os1; } return( true ); } //************************************************************************************************** // Print the object attributes. // // Argument List : // rosPrefix - A prefix to every line displayed (usually just spaces) void PrcSimEngBase::Print( const wxString & rosPrefix ) { bool bIsOpen; wxString os1; PrcBase::Print( rosPrefix + wxT("PrcBase::") ); std::cout << rosPrefix.mb_str( ) << "m_eSimEng : "; switch( m_eSimEng ) { case eSIMR_GNUCAP : std::cout << "eSIMR_GNUCAP" ; break; // GNU-Cap case eSIMR_NGSPICE : std::cout << "eSIMR_NGSPICE" ; break; // NG-Spice default : std::cout << "eSIMR_NONE"; } std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_oNameResults : " << m_oNameResults.GetFullPath( ).mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_oFileResults :"; bIsOpen = m_oFileResults.IsOpened( ); if( ! bIsOpen ) #if wxCHECK_VERSION( 3,0,0 ) if( m_oNameResults.Exists( ) ) #else if( m_oNameResults.FileExists( ) ) #endif m_oFileResults.Open( m_oNameResults.GetFullPath( ) ); if( m_oFileResults.IsOpened( ) ) { if( m_oFileResults.GetLineCount( ) > 0 ) { std::cout << '\n'; for( os1=m_oFileResults.GetFirstLine(); !m_oFileResults.Eof(); os1=m_oFileResults.GetNextLine() ) std::cout << rosPrefix.mb_str( ) << " " << os1.mb_str( ) << '\n'; } else std::cout << " Is empty\n"; } else std::cout << " Doesn't exist\n"; if( ! bIsOpen ) if( m_oFileResults.IsOpened( ) ) m_oFileResults.Close( ); } //**************************************************************************************************