//************************************************************************************************** // NetList.cpp * // ------------- * // Started : 2003-09-01 * // Last Update : 2016-10-25 * // Copyright : (C) 2003-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 "NetList.hpp" //************************************************************************************************** // Allocate storage for static data members. wxFileName NetList::m_ofnLoadFile; wxFileName NetList::m_ofnSaveFile; ArrayFileName NetList::m_oaSchemFiles; wxArrayString NetList::m_osaNetLst; wxArrayString NetList::m_osaTitle; wxArrayString NetList::m_osaIncludes; ArrayComponent NetList::m_oaCpnts; wxArrayString NetList::m_osaModels; wxArrayString NetList::m_osaSubCcts; wxArrayString NetList::m_osaNodeLbls; bool NetList::m_bIsValid=false; //************************************************************************************************** // Constructor. NetList::NetList( void ) { } //************************************************************************************************** // Destructor. NetList::~NetList( ) { } //************************************************************************************************** // Extract the title for the netlist. // // Noyes : - Traditionally the first line in the netlist is the title. // - An '*' at the start of a line seems to be used as a comment designator. // - If the file was created by gnetlist or gSpiceUI throw it away. // // Return Values : // true - Success // false - Failure bool NetList::bLoadTitle( void ) { // Clear the title string array object attribute m_osaTitle.Clear( ); // Check that the circuit isn't empty if( m_osaNetLst.IsEmpty( ) ) return( false ); // If the first line is empty assume there is no title wxString os1 = m_osaNetLst.Item( 0 ); if( os1.IsEmpty( ) ) return( true ); // If the first line doesn't begin with an '*' then assume it is the title if( os1.GetChar( 0 ) != wxT('*') ) { os1 = wxT("* ") + os1; m_osaTitle.Add( os1 ); return( true ); } // If the netlist was created using gnetlist the first line will look something like the // following : // gnetlist -v -g spice-sdb -o filter-lp-1.ckt filter-lp-1.sch if( os1.Contains( wxT("gnetlist") ) ) return( true ); // If the netlist was created by gSpiceUI the start of the file will look something like this : // ******************************************************************************** // * Electronic circuit simulation file generated by gSpiceUI * // * Version 0.9.93 (2015-04-03) * // ******************************************************************************** if( m_osaNetLst.Item( 0 ).find_first_not_of( wxT('*') ) != wxString::npos ) ; else if( ! m_osaNetLst.Item( 1 ).Contains( APP_NAME ) ) ; else if( ! m_osaNetLst.Item( 2 ).Contains( wxT("Version") ) ) ; else if( m_osaNetLst.Item( 3 ).find_first_not_of( wxT('*') ) != wxString::npos ) ; else return( true ); // Accept all lines beginning with an '*' as the title for( size_t sz1=0; sz1 1 ) osModel << wxT('\n') << os1; } else if( ! osModel.IsEmpty( ) ) { // Last line of model description found m_osaModels.Add( osModel ); osModel.Empty( ); } } return( true ); } //************************************************************************************************** // Extract any sub-circuit descriptions from the circuit description (netlist). // // The format of a sub-circuit description is illustrated in the following example : // // .SUBCKT CCTNAME 1 5 // R1 1 2 1K // R2 2 3 2K // R3 3 4 3K // R4 4 5 4K // .ENDS CCTNAME // // Return Values : // true - Success // false - Failure bool NetList::bLoadSubCcts( void ) { wxString osSubCct; wxString os1, os2; size_t sz1; // Clear the sub-circuit string array object attribute m_osaSubCcts.Clear( ); // Need at least a title line, 2 components and a sub-circuit description containing 2 lines if( m_osaNetLst.GetCount( ) < 7 ) return( true ); // Scan circuit description for sub-circuits for( sz1=0; sz1/circuit1.sch /circuit2.sch" // // Return Values : // true - Success // false - Failure bool NetList::bLoadSchemFiles( void ) { wxString os1, os2; size_t sz1; // Scan the netlist for a reference any schematic file name/s it was derived from for( sz1=0; sz1 0 ) m_osaNetLst.Add( os1 ); oFileCct.Close( ); // Close the netlist file return( true ); } //************************************************************************************************** // Save (or resave) the circuit description to file. // // Argument List : // rosFName - The name of the file to be saved // // Return Values : // true - Success // false - Failure bool NetList::bSaveFile( const wxString & rosFName ) { size_t sz1; // Is this a save or resave? if( ! rosFName.IsEmpty( ) ) { if( ! bSetSaveFile( rosFName ) ) return( false ); } else { if( ! m_ofnSaveFile.IsOk( ) ) return( false ); } // Open the file wxTextFile oFileCct( m_ofnSaveFile.GetFullPath( ) ); if( oFileCct.Exists( ) ) { if( ! oFileCct.Open( ) ) return( false ); } else { if( ! oFileCct.Create( ) ) return( false ); } // Clear the file if it contains lines for( sz1=oFileCct.GetLineCount( ); sz1>0; sz1-- ) oFileCct.RemoveLine( 0 ); // Save the contents of the netlist string array to file for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_osaNetLst.Item( sz1 ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osaTitle[ ] : "; if( ! m_osaTitle.IsEmpty( ) ) { for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_osaTitle.Item( sz1 ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osaIncludes[ ] : "; if( ! m_osaIncludes.IsEmpty( ) ) { for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_osaIncludes.Item( sz1 ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_oaCpnts[ ] : "; if( ! m_oaCpnts.IsEmpty( ) ) { for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_oaCpnts.Item( sz1 ).rosGetString( ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osaModels[ ] : "; if( ! m_osaModels.IsEmpty( ) ) { for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_osaModels.Item( sz1 ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osaSubCcts[ ] : "; if( ! m_osaSubCcts.IsEmpty( ) ) { for( sz1=0; sz1 0 ) std::cout << rosPrefix.mb_str( ) << " "; std::cout << m_osaSubCcts.Item( sz1 ).mb_str( ) << '\n'; } } else std::cout << '\n'; std::cout << rosPrefix.mb_str( ) << "m_bIsValid : " << ( m_bIsValid ? "true" : "false") << '\n'; } //************************************************************************************************** // Test Utility * //************************************************************************************************** #ifdef TEST_NETLIST using namespace std; // Function prototypes void Usage( char * psAppName ); //************************************************************************************************** int main( int argc, char * argv[ ] ) { // This function is used in wxBase only and only if an wxApp object isn't created at all. In this // case wxInitialize( ) must be called in main( ) before calling any other wxWidgets functions. if( ! wxInitialize( ) ) exit( EXIT_FAILURE ); wxString osCpnt; wxString os1; // Validate the argument count passed to the application if( argc > 3 ) { Usage( argv[ 0 ] ); exit( EXIT_FAILURE ); } // Process the command line arguments if( argc > 1 ) { os1 = wxConvLibc.cMB2WC( argv[ 1 ] ); if( os1.at( 0 ) == wxT('-') ) { if( os1.at( 1 ) == wxT('h') ) { Usage( argv[ 0 ] ); exit( EXIT_SUCCESS ); } else { Usage( argv[ 0 ] ); exit( EXIT_FAILURE ); } } } else { Usage( argv[ 0 ] ); exit( EXIT_FAILURE ); } // Display the utility banner cout << "\n Netlist Class Test Utility" << "\n Version 1.03 (2016-09-27)\n"; // Create a NetList object NetList oNetLst; cout << "\nLoad the netlist file : "; if( oNetLst.bLoadFile( os1 ) ) cout << "Success"; else cout << "Failure"; cout << "\n"; cout << "\ntNetLst.Print( ) :\n"; oNetLst.Print( ); cout << "\n"; // This function must be called for each successful call to wxInitialize( ). Clean up; the library // can't be used any more. wxInitialize( ); exit( EXIT_SUCCESS ); } //************************************************************************************************** void Usage( char * psAppName ) { cout << "\nUsage : " << psAppName << " [-OPTIONS] [FILE]" << "\nOptions : -h : Print usage (this message)" << "\n FILE : A circuit description (NetList) file" << "\n\n"; } #endif // TEST_NETLIST //**************************************************************************************************