bool NETLIST_EXPORTER_CADSTAR::Write( const wxString& aOutFileName, unsigned aNetlistOptions ) { (void)aNetlistOptions; //unused int ret = 0; FILE* f = NULL; if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL ) { wxString msg; msg.Printf( _( "Failed to create file '%s'" ), GetChars( aOutFileName ) ); DisplayError( NULL, msg ); return false; } wxString StartCmpDesc = StartLine + wxT( "ADD_COM" ); wxString msg; wxString footprint; SCH_SHEET_PATH* sheet; EDA_ITEM* DrawList; SCH_COMPONENT* component; wxString title = wxT( "Eeschema " ) + GetBuildVersion(); ret |= fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) ); ret |= fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) ); ret |= fprintf( f, "%sAPP ", TO_UTF8( StartLine ) ); ret |= fprintf( f, "\"%s\"\n", TO_UTF8( title ) ); ret |= fprintf( f, "\n" ); // Prepare list of nets generation for( unsigned ii = 0; ii < m_masterList->size(); ii++ ) m_masterList->GetItem( ii )->m_Flag = 0; // Create netlist module section m_ReferencesAlreadyFound.Clear(); SCH_SHEET_LIST SheetList; for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) { for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) { DrawList = component = findNextComponentAndCreatePinList( DrawList, sheet ); if( component == NULL ) break; /* doing nothing with footprint if( !component->GetField( FOOTPRINT )->IsVoid() ) { footprint = component->GetField( FOOTPRINT )->m_Text; footprint.Replace( wxT( " " ), wxT( "_" ) ); } else footprint = wxT( "$noname" ); */ msg = component->GetRef( sheet ); ret |= fprintf( f, "%s ", TO_UTF8( StartCmpDesc ) ); ret |= fprintf( f, "%s", TO_UTF8( msg ) ); msg = component->GetField( VALUE )->GetText(); msg.Replace( wxT( " " ), wxT( "_" ) ); ret |= fprintf( f, " \"%s\"", TO_UTF8( msg ) ); ret |= fprintf( f, "\n" ); } } ret |= fprintf( f, "\n" ); m_SortedComponentPinList.clear(); if( ! writeListOfNets( f ) ) ret = -1; // set error ret |= fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) ); fclose( f ); return ret >= 0; }
XNODE* NETLIST_EXPORTER_GENERIC::makeComponents() { XNODE* xcomps = node( wxT( "components" ) ); wxString timeStamp; // some strings we need many times, but don't want to construct more // than once for performance. These are used within loops so the // enclosing wxString constructor would fire on each loop iteration if // they were in a nested scope. // these are actually constructor invocations, not assignments as it appears: wxString sFields = wxT( "fields" ); wxString sField = wxT( "field" ); wxString sComponent = wxT( "comp" ); // use "part" ? wxString sName = wxT( "name" ); wxString sRef = wxT( "ref" ); wxString sPins = wxT( "pins" ); wxString sPin = wxT( "pin" ); wxString sValue = wxT( "value" ); wxString sSheetPath = wxT( "sheetpath" ); wxString sFootprint = wxT( "footprint" ); wxString sDatasheet = wxT( "datasheet" ); wxString sTStamp = wxT( "tstamp" ); wxString sTStamps = wxT( "tstamps" ); wxString sTSFmt = wxT( "%8.8lX" ); // comp->m_TimeStamp wxString sLibSource = wxT( "libsource" ); wxString sLibPart = wxT( "libpart" ); wxString sLib = wxT( "lib" ); wxString sPart = wxT( "part" ); wxString sNames = wxT( "names" ); m_ReferencesAlreadyFound.Clear(); SCH_SHEET_LIST sheetList( g_RootSheet ); // Output is xml, so there is no reason to remove spaces from the field values. // And XML element names need not be translated to various languages. for( unsigned i = 0; i < sheetList.size(); i++ ) { for( EDA_ITEM* schItem = sheetList[i].LastDrawList(); schItem; schItem = schItem->Next() ) { SCH_COMPONENT* comp = findNextComponentAndCreatePinList( schItem, &sheetList[i] ); if( !comp ) break; // No component left schItem = comp; XNODE* xcomp; // current component being constructed // Output the component's elements in order of expected access frequency. // This may not always look best, but it will allow faster execution // under XSL processing systems which do sequential searching within // an element. xcomps->AddChild( xcomp = node( sComponent ) ); xcomp->AddAttribute( sRef, comp->GetRef( &sheetList[i] ) ); xcomp->AddChild( node( sValue, comp->GetField( VALUE )->GetText() ) ); if( !comp->GetField( FOOTPRINT )->IsVoid() ) xcomp->AddChild( node( sFootprint, comp->GetField( FOOTPRINT )->GetText() ) ); if( !comp->GetField( DATASHEET )->IsVoid() ) xcomp->AddChild( node( sDatasheet, comp->GetField( DATASHEET )->GetText() ) ); // Export all user defined fields within the component, // which start at field index MANDATORY_FIELDS. Only output the <fields> // container element if there are any <field>s. if( comp->GetFieldCount() > MANDATORY_FIELDS ) { XNODE* xfields; xcomp->AddChild( xfields = node( sFields ) ); for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx ) { SCH_FIELD* f = comp->GetField( fldNdx ); // only output a field if non empty and not just "~" if( !f->IsVoid() ) { XNODE* xfield; xfields->AddChild( xfield = node( sField, f->GetText() ) ); xfield->AddAttribute( sName, f->GetName() ); } } } XNODE* xlibsource; xcomp->AddChild( xlibsource = node( sLibSource ) ); // "logical" library name, which is in anticipation of a better search // algorithm for parts based on "logical_lib.part" and where logical_lib // is merely the library name minus path and extension. LIB_PART* part = m_libs->FindLibPart( comp->GetLibId() ); if( part ) xlibsource->AddAttribute( sLib, part->GetLib()->GetLogicalName() ); // We only want the symbol name, not the full LIB_ID. xlibsource->AddAttribute( sPart, comp->GetLibId().GetLibItemName() ); XNODE* xsheetpath; xcomp->AddChild( xsheetpath = node( sSheetPath ) ); xsheetpath->AddAttribute( sNames, sheetList[i].PathHumanReadable() ); xsheetpath->AddAttribute( sTStamps, sheetList[i].Path() ); timeStamp.Printf( sTSFmt, (unsigned long)comp->GetTimeStamp() ); xcomp->AddChild( node( sTStamp, timeStamp ) ); } } return xcomps; }
bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl ) { const wxString delimiters( "{:,; }" ); SCH_SHEET_LIST sheetList( g_RootSheet ); // Set of reference names, to check for duplications std::set<wxString> refNames; // Prepare list of nets generation (not used here, but... for( unsigned ii = 0; ii < m_masterList->size(); ii++ ) m_masterList->GetItem( ii )->m_Flag = 0; m_netMap.clear(); m_netMap["GND"] = 0; // 0 is reserved for "GND" int netIdx = 1; m_libraries.clear(); m_ReferencesAlreadyFound.Clear(); UpdateDirectives( aCtl ); for( unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ ) { // Process component attributes to find Spice directives for( EDA_ITEM* item = sheetList[sheet_idx].LastDrawList(); item; item = item->Next() ) { SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, &sheetList[sheet_idx] ); if( !comp ) break; item = comp; SPICE_ITEM spiceItem; spiceItem.m_parent = comp; // Obtain Spice fields SCH_FIELD* fieldLibFile = comp->FindField( GetSpiceFieldName( SF_LIB_FILE ) ); SCH_FIELD* fieldSeq = comp->FindField( GetSpiceFieldName( SF_NODE_SEQUENCE ) ); spiceItem.m_primitive = GetSpiceField( SF_PRIMITIVE, comp, aCtl )[0]; spiceItem.m_model = GetSpiceField( SF_MODEL, comp, aCtl ); spiceItem.m_refName = comp->GetRef( &sheetList[sheet_idx] ); // Duplicate references will result in simulation errors if( refNames.count( spiceItem.m_refName ) ) { DisplayError( NULL, wxT( "There are duplicate components. " "You need to annotate schematics first." ) ); return false; } refNames.insert( spiceItem.m_refName ); // Check to see if component should be removed from Spice netlist spiceItem.m_enabled = StringToBool( GetSpiceField( SF_ENABLED, comp, aCtl ) ); if( fieldLibFile && !fieldLibFile->GetText().IsEmpty() ) m_libraries.insert( fieldLibFile->GetText() ); wxArrayString pinNames; // Store pin information for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ ) { NETLIST_OBJECT* pin = m_SortedComponentPinList[ii]; // NETLIST_EXPORTER marks removed pins by setting them to NULL if( !pin ) continue; spiceItem.m_pins.push_back( pin ); pinNames.Add( pin->GetPinNumText() ); // Create net mapping const wxString& netName = pin->GetNetName(); if( m_netMap.count( netName ) == 0 ) m_netMap[netName] = netIdx++; } // Check if an alternative pin sequence is available: if( fieldSeq ) { // Get the string containing the sequence of nodes: wxString nodeSeqIndexLineStr = fieldSeq->GetText(); // Verify field exists and is not empty: if( !nodeSeqIndexLineStr.IsEmpty() ) { // Get Alt Pin Name Array From User: wxStringTokenizer tkz( nodeSeqIndexLineStr, delimiters ); while( tkz.HasMoreTokens() ) { wxString pinIndex = tkz.GetNextToken(); int seq; // Find PinName In Standard List assign Standard List Index to Name: seq = pinNames.Index( pinIndex ); if( seq != wxNOT_FOUND ) spiceItem.m_pinSequence.push_back( seq ); } } } m_spiceItems.push_back( spiceItem ); } } return true; }