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 + -
显示快捷键?