?? netlist.cpp
字號:
//*****************************************************************************// NetList.cpp *// ------------- *// Started : 01/09/2003 *// Last Update : 14/07/2005 *// Copyright : (C) 2003 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 "NetList.hpp"//*****************************************************************************// Constructor.NetList::NetList( void ){}//*****************************************************************************// Destructor.NetList::~NetList( ){}//*****************************************************************************// Compare algorithm for sorting strings alpha/numerically.//// Arguments:// ros1 - a reference to the first string to be compared// ros2 - a reference to the second string to be compared//// Return Values:// >0 - ros1 is greater than ros2// =0 - ros1 is equal to ros2// <0 - ros1 is less than ros2int NetList::iCompare( const wxString & ros1, const wxString & ros2 ){ unsigned long ulNum1, ulNum2; size_t szt1, szt2; wxString osNum1; wxString osNum2; for( szt1=0; szt1<ros1.Length( ) && szt1<ros2.Length( ); szt1++ ) { // Compare numbers as a whole if( isdigit( ros1[szt1] ) && isdigit( ros2[szt1] ) ) { // Extract the number from each string osNum1 += osNum2 = wxT(""); for( szt2=szt1; szt2<ros1.Length( ); szt2++ ) osNum1 += ros1[szt2]; for( szt2=szt1; szt2<ros2.Length( ); szt2++ ) osNum2 += ros2[szt2]; // Convert to unsigned long integers osNum1.ToULong( &ulNum1 ); osNum2.ToULong( &ulNum2 ); // Compare the two numbers if( ulNum1 > ulNum2 ) return( 1 ); if( ulNum1 < ulNum2 ) return( -1 ); // Increment the loop counter szt1 = osNum1.Length( ) - 1; continue; } // Compare characters one at a time if( ros1[szt1] > ros2[szt1] ) return( 1 ); if( ros1[szt1] < ros2[szt1] ) return( -1 ); } // If characters match compare string length if( ros1.Length( ) > ros2.Length( ) ) return( 1 ); if( ros1.Length( ) < ros2.Length( ) ) return( -1 ); // The strings are identical return( 0 );}//*****************************************************************************// This function indicates whether a line in a sequence of line falls within a // sub-circuit definition block.//// Argument List:// A line in a sequence of lines to be tested//// Return Values:// TRUE - The line does falls within a su-circuit definition block// FALSE - The line doesn't falls within a su-circuit definition blockbool NetList::bIsSubCkt( wxString & roLine ){ static bool bIsSubCkt=FALSE; wxString os1; os1 = roLine; os1.MakeUpper( ); if( os1.StartsWith( wxT(".SUBCKT") ) ) bIsSubCkt = TRUE; if( os1.StartsWith( wxT(".ENDS") ) ) bIsSubCkt = FALSE; return( bIsSubCkt );}//*****************************************************************************// Extract the title for the circuit description which is traditionally the// first line in the file. An '*' seems to be used as a comment designator.//// Return Values:// TRUE - Success// FALSE - Failurebool NetList::bExtractTitle( void ){ // Check that the circuit isn't empty if( IsEmpty( ) ) return( FALSE ); // If the first line is empty assume there is no title wxString os1 = Item( 0 ); if( os1.IsEmpty( ) ) return( FALSE ); // If the first line doesn't begin with an '*' assume first line is the title if( os1.GetChar( 0 ) != wxT('*') ) { m_oasTitle.Add( os1 ); return( TRUE ); } // Take all lines beginning with an '*" as the title for( size_t szt1=0; szt1<GetCount( ); szt1++ ) { os1 = Item( szt1 ); if( os1.IsEmpty( ) ) break; if( os1.GetChar( 0 ) != wxT('*') ) break; m_oasTitle.Add( os1 ); } if( m_oasTitle.IsEmpty( ) ) return( FALSE ); return( TRUE );}//*****************************************************************************// Extract any include directives.//// Return Values:// TRUE - Success// FALSE - Failurebool NetList::bExtractIncludes( void ){ wxString os1, os2; size_t szt1; // Need at least a title line, 2 components and an include directive if( GetCount( ) < 4 ) return( TRUE ); // There are no include directives // Scan circuit description for include directives for( szt1=0; szt1<GetCount( ); szt1++ ) { os1 = Item( szt1 ); if( bIsSubCkt( os1 ) ) continue; if( os1.IsEmpty( ) ) continue; os2 = os1; os2.MakeUpper( ); if( os2.StartsWith( wxT(".INCLUDE ") ) ) m_oasIncludes.Add( os1 ); } return( TRUE );}//*****************************************************************************// Extract all the component description lines from the circuit description.// A component line is identified if the first character in the line is an// alpha character and its length is greater than 8. The following examples// shows a component description of minimum length (a resistor connected to// nodes 1 and 0 of value 9 Ohm)://// R1 1 0 9//// Return Values:// TRUE - Success// FALSE - Failurebool NetList::bExtractCpnts( void ){ wxString os1, os2; size_t szt1; Component oCpnt; // Need at least a title line and 2 components if( GetCount( ) < 3 ) return( FALSE ); // There are insufficient lines // Reset sub-circuit detection function os1 = wxT(".ENDS"); bIsSubCkt( os1 ); // Scan circuit description for components for( szt1=0; szt1<GetCount( ); szt1++ ) { // Retrieve the next line from the net list os1 = Item( szt1 ); // Ignore all component definitions inside a sub-circuit block if( bIsSubCkt( os1 ) ) continue; // Determine if this line is a component description if( ! oCpnt.bSetLine( os1.c_str( ) ) ) continue; // A component description was found os1.Trim( ); m_oasCpnts.Add( os1 ); } // Circuit description must have components if( m_oasCpnts.IsEmpty( ) ) return( FALSE ); m_oasCpnts.Sort( &iCompare ); return( TRUE );}//*****************************************************************************// Extract all the model description lines from the circuit description.// A model description can consist of 1 or more lines and is identified if the// line begins with ".MODEL ". Subsequent lines beginning with a '+' character// are appended to the model description. The format is illustrated in the// following example://// .MODEL CMOSN NMOS (LEVEL=2 LD=0.265073u TOX=418.0e-10// + NSUB=1.53142e+16 VTO=0.844345 KP=4.15964e-05 GAMMA=0.863074// + CJ=0.0003844 MJ=0.488400 CJSW=5.272e-10 MJSW=0.300200 PB=0.700000)//// Return Values:// TRUE - Success// FALSE - Failurebool NetList::bExtractModels( void ){ wxString osModel; wxString os1, os2; size_t szt1; // Need at least a title line, 2 components and a model description line if( GetCount( ) < 4 ) return( TRUE ); // There are no model descriptions // Reset sub-circuit detection function os1 = wxT(".ENDS"); bIsSubCkt( os1 ); // Scan circuit description for models for( szt1=0; szt1<GetCount( ); szt1++ ) { os1 = Item( szt1 ); if( bIsSubCkt( os1 ) ) continue; if( os1.IsEmpty( ) && osModel.IsEmpty( ) ) continue; os2 = os1; os2.MakeUpper( ); if( os2.StartsWith( wxT(".MODEL ") ) ) { // First line of model description found if( ! osModel.IsEmpty( ) ) m_oasModels.Add( osModel ); osModel = os1; } else if( os1.GetChar( 0 ) == wxT('+') ) { // Intermediate line of model description found if( osModel.Length( ) > 1 ) osModel << wxT('\n') << os1; } else if( ! osModel.IsEmpty( ) ) { // Last line of model description found m_oasModels.Add( osModel ); osModel.Empty( ); } } return( TRUE );}//*****************************************************************************// Extract any sub-circuit descriptions from the circuit description (net list).// 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 - Failurebool NetList::bExtractSubCcts( void ){ wxString osSubCct; wxString os1, os2; size_t szt1; // Need at least a title line, 2 components and a sub-circuit description // containing 2 lines if( GetCount( ) < 7 ) return( TRUE ); // There are no sub-cct descriptions // Scan circuit description for sub-circuits for( szt1=0; szt1<GetCount( ); szt1++ ) { os1 = Item( szt1 ); if( os1.IsEmpty( ) && osSubCct.IsEmpty( ) ) continue; os2 = os1; os2.MakeUpper( ); if( os2.StartsWith( wxT(".SUBCKT ") ) ) { // First line in sub-circuit description found osSubCct = os1; } else if( os2.StartsWith( wxT(".ENDS") ) ) { // Last line in sub-circuit description found if( ! osSubCct.IsEmpty( ) ) { osSubCct << wxT('\n') << os1; m_oasSubCcts.Add( osSubCct ); osSubCct.Empty( ); } } else if( ! osSubCct.IsEmpty( ) ) { // Intermediate line in sub-circuit description found osSubCct << wxT('\n') << os1; } } return( TRUE );}//*****************************************************************************// Extract all nodes labels from the component line string array.//// Return Values:// TRUE - Success// FALSE - Failurebool NetList::bExtractNodeLbls( void ){ // Check that there are some components if( m_oasCpnts.GetCount( ) <= 0 ) return( FALSE ); wxStringTokenizer oStrTok; wxString os1; size_t szt1; char cCpnt; for( szt1=0; szt1<m_oasCpnts.GetCount( ); szt1++ ) { os1 = m_oasCpnts.Item( szt1 ); oStrTok.SetString( os1 ); // Need at least 3 fields the first is assumed to be the component label if( oStrTok.CountTokens( ) < 3 ) continue; os1 = oStrTok.GetNextToken( ); // Discard component label
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -