prcbase.cpp
来自「gspiceui电子CAD仿真程序.用于电路参数模拟仿真」· C++ 代码 · 共 415 行
CPP
415 行
//*****************************************************************************// PrcBase.cpp *// ------------- *// Started : 29/01/2004 *// Last Update : 08/06/2005 *// Copyright : (C) 2004 by MSWaters *// Email : M.Waters@bom.gov.au *//*****************************************************************************//*****************************************************************************// *// 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. *// *//*****************************************************************************#include "PrcBase.hpp"//*****************************************************************************// Constructor.PrcBase::PrcBase( int iFlags ) : wxProcess( iFlags ){ m_iPid = -1; // Clear the process ID number m_osError = wxT(""); // Clear the error message m_oFnmLog = DEFLOGFILE; // Set the default log file path and name}//*****************************************************************************// Destructor.PrcBase::~PrcBase( ){ // Delete the process log file bRmLogFile( );}//*****************************************************************************// Find a binary using the user's PATH environment variable given the binary// name.//// Argument List:// oFnmBin - The binary name without the path//// Return Values:// TRUE - Success (path prepended to oFnmBin)// FALSE - Failurebool PrcBase::bFindBinary( wxFileName & oFnmBin ){ wxStringTokenizer oTokPath; wxFileName oFnm1; wxString os1; uint ui1, ui2; if( ! oFnmBin.IsOk( ) ) return( FALSE ); if( ! wxGetEnv( wxT("PATH"), &os1 ) ) return( FALSE ); oTokPath.SetString( os1, wxT(":") ); ui2 = oTokPath.CountTokens( ); for( ui1=0; ui1<=ui2; ui1++ ) { os1 = oTokPath.GetNextToken( ); if( os1.Length( )>0 && os1.Last( )!=wxT('/') ) os1 += wxT('/'); os1 += oFnmBin.GetFullName( ); if( wxFileExists( os1 ) && !wxDirExists( os1 ) ) { oFnm1 = os1; break; } } if( !oFnm1.IsOk( ) || !oFnm1.FileExists( ) ) { m_osError.Empty( ); m_osError << wxT("Can't find the binary : ") << oFnmBin.GetFullName( ) << wxT("\nYour PATH is : ") << oTokPath.GetString( ); return( FALSE ); } oFnmBin = oFnm1; return( TRUE );}//*****************************************************************************// Get the console output after a process has been initiated and record it in// the log file.//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bLogOutput( void ){ wxString os1, os2; size_t szt1; wxChar oc1; // Check that the log file name is valid if( ! m_oFnmLog.IsOk( ) ) return( FALSE ); // Open the file wxTextFile oFileLog( m_oFnmLog.GetFullPath( ) ); if( oFileLog.Exists( ) ) { if( ! oFileLog.Open( ) ) return( FALSE ); } else { if( ! oFileLog.Create( ) ) return( FALSE ); } // Clear the file if it contains lines for( szt1=oFileLog.GetLineCount( ); szt1>0; szt1-- ) oFileLog.RemoveLine( 0 ); // Read the console input while( bIsExec( ) || IsInputAvailable( ) || IsErrorAvailable( ) ) { // Get a line of data from stdout while( IsInputAvailable( ) ) { oc1 = GetInputStream( )->GetC( ); if( oc1==wxT('\t') || (oc1>31 && oc1!=127) ) os1 << oc1; if( oc1 == wxT('\n') ) { oFileLog.AddLine( os1 ); os1 = wxT(""); } } // Get a line of data from stderr while( IsErrorAvailable( ) ) { oc1 = GetErrorStream( )->GetC( ); if( oc1==wxT('\t') || (oc1>31 && oc1!=127) ) os2 << oc1; if( oc1 == wxT('\n') ) { oFileLog.AddLine( os2 ); os2 = wxT(""); } } wxYield( ); // Yield CPU to other processes } if( ! os1.IsEmpty( ) ) oFileLog.AddLine( os1 ); if( ! os2.IsEmpty( ) ) oFileLog.AddLine( os2 ); oFileLog.Write( ); // Save the changes to disk oFileLog.Close( ); // Close the results file return( TRUE );}//*****************************************************************************// Does the binary exist?//// Return Values:// TRUE - The binary does exist// FALSE - The binary doesn't existbool PrcBase::bBinExists( void ){ if( !m_oFnmBinary.FileExists( ) || !m_oFnmBinary.IsOk( ) ) { m_osError.Empty( ); m_osError << wxT("The binary : ") << m_oFnmBinary.GetFullPath( ) << wxT(" doesn't exist."); return( FALSE ); } return( TRUE );}//*****************************************************************************// Set the file name of the binary to be executed.//// Argument List:// rosFName - A string containing the binary file name//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bSetBinary( const wxString & rosFName ){ wxFileName oFnm1; if( rosFName.IsEmpty( ) ) return( FALSE ); oFnm1 = rosFName; if( ! bFindBinary( oFnm1 ) ) return( FALSE ); m_oFnmBinary = oFnm1; return( TRUE );}//*****************************************************************************// Set the argument list to be appended to the binary name.//// Argument List:// rosArgLst - A string containing the argument list//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bSetArgLst( const wxString & rosArgLst ){ if( rosArgLst.IsEmpty( ) ) return( FALSE ); m_osArgLst = rosArgLst; return( TRUE );}//*****************************************************************************// Set the process log file name.// (If set all process output can be captured to this file.)//// Argument List:// rosFName - A string containing the full path and file name//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bSetLogFile( const wxString & rosFName ){ wxFileName oFName; oFName = rosFName; if( ! oFName.IsOk( ) ) return( FALSE ); if( oFName.GetPath( ).IsEmpty( ) ) oFName.SetPath( wxT(".") ); m_oFnmLog = oFName; return( TRUE );}//*****************************************************************************// Execute a task synchronously (ie. wait for it to terminate).//// ???//bool PrcBase::bExecSync( const wxString & rosCmd )//{// long liRtn;// wxEnableTopLevelWindows( FALSE );// liRtn = wxExecute( rosCmd, wxEXEC_SYNC );// wxEnableTopLevelWindows( TRUE );// if( liRtn != 0 ) return( false );// return( TRUE );// This is how I'd like to do it but it doesn't work 20/11/2003 ???// wxEnableTopLevelWindows( FALSE );// int iRtn = (int) wxExecute( osCmd, wxEXEC_SYNC );// wxEnableTopLevelWindows( TRUE );// wxProcess oProcess( wxPROCESS_DEFAULT );// iPid = (int) wxExecute( osCmd, wxEXEC_SYNC );// if( iPid == 0 )// { // Error gnetlist could not be executed// cerr << "The command:\n " << osCmd << "\ncould not be executed.";// return( FALSE );// }// for( ui1=0; ui1<300; ui1++ )// { // Wait up to 30 seconds for the process to complete//cerr << iPid << '\n';// wxUsleep( 100 ); // Sleep for 100msec// if( ! oProcess.Exists( iPid ) ) break;// }// if( oProcess.Exists( iPid ) )// { // Error gnetlist had to be terminated prematurely// oProcess.Kill( iPid );// cerr << "The command:\n " << osCmd << "\ntook more than 30 sec. to "// << "execute and so was terminated prematurely.";// return( FALSE );// }//}//*****************************************************************************// Remove the log file.//// Return Value:// Success - TRUE// Failure - FALSEbool PrcBase::bRmLogFile( void ){ if( m_oFnmLog.GetFullPath( ).IsEmpty( ) ) return( TRUE ); return( ::wxRemoveFile( m_oFnmLog.GetFullPath( ) ) );}//*****************************************************************************// Execute a process.//// Arguments:// psArgList - The argument list to be passed to the binary//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bExec( const wxChar * psArgLst ){ static wxString os1; // Only execute simulation if it isn't already running if( bIsExec( ) ) return( FALSE ); // Clear error attributes m_osError.Clear( ); // Check that the binary exists if( ! bBinExists( ) ) { m_osError = wxT("Can't find the binary : ") + m_oFnmBinary.GetFullPath( ); return( FALSE ); } // Set the command arguments if( psArgLst != NULL ) { if( ! bSetArgLst( psArgLst ) ) { m_osError = wxT("Invalid arguments : ") + m_osArgLst; return( FALSE ); } } // Construct the command line to be executed os1 = roGetBinary( ).GetFullPath( ); if( ! wxIsEmpty( psGetArgLst( ) ) ) os1 << wxT(' ') << psGetArgLst( ); // Attempt to execute the simulation m_iPid = (int) wxExecute( os1, wxEXEC_ASYNC, this ); if( m_iPid <= 0 ) { m_osError = wxT("Couldn't start process : ") + os1; return( FALSE ); } return( TRUE );}//*****************************************************************************// Stop the simulation currently in progress.//// Return Values:// TRUE - Success// FALSE - Failurebool PrcBase::bKill( void ){ if( ! bIsExec( ) ) return( TRUE ); if( ! Exists( m_iPid ) ) return( TRUE ); if( Kill( m_iPid, wxSIGTERM ) != wxKILL_OK ) return( FALSE ); m_iPid = -1; return( TRUE );}//*****************************************************************************// Call-back function called when the simulator process terminates.// (WARNING: Be careful of this function definition, if it is incorrect the// applicastion can segment fault.)//// Arguments:// iPid - The PID of the process which just terminated// iStatus - The exit code of the processvoid PrcBase::OnTerminate( int iPid, int iStatus ){ m_iPid = -1;}//*****************************************************************************// Collect the output from the simulator and print to a text control.//// Argument List:// roTxtCtl - The text control to contain the simulator outputvoid PrcBase::Print( TextCtrl & roTxtCtl ){ roTxtCtl.Clear( ); // Clear the text control // Print the process command roTxtCtl << wxT(" ") << wxT("*************** PROCESS COMMAND ***************\n\n") << roGetBinary( ).GetFullPath( ); if( ! wxIsEmpty( psGetArgLst( ) ) ) roTxtCtl << wxT(' ') << psGetArgLst( ); roTxtCtl << wxT("\n\n"); if( ! m_oFnmLog.GetFullPath( ).IsEmpty( ) ) { // Print the process command response roTxtCtl << wxT(" ") << wxT("*************** PROCESS RESPONSE **************\n\n"); if( m_oFnmLog.IsOk( ) && m_oFnmLog.FileExists( ) ) roTxtCtl.bAppendFile( m_oFnmLog.GetFullPath( ) ); else roTxtCtl << wxT("Couldn't load the file containing the process ouput : ") << m_oFnmLog.GetFullPath( ); }}//*****************************************************************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?