void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR ) { wxString text; while( ( token = NextTok() ) != T_EOF ) { if( token == T_LEFT ) token = NextTok(); if( token == T_components ) { // The section comp starts here. while( ( token = NextTok() ) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); if( token == T_comp ) { // A comp section if found. Read it COMPONENT_INFO* cmp_info = ParseComp(); netlist_reader->AddModuleInfo( cmp_info ); } } if( netlist_reader->BuildModuleListOnlyOpt() ) return; // at this point, the module list is read and built. // Load new footprints netlist_reader->InitializeModules(); netlist_reader->TestFootprintsMatchingAndExchange(); } if( token == T_nets ) { // The section nets starts here. while( ( token = NextTok() ) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); if( token == T_net ) { // A net section if found. Read it ParseNet( aBrd ); } } } if( token == T_libparts && netlist_reader->ReadLibpartSectionOpt() ) { // The section libparts starts here. while( ( token = NextTok() ) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); if( token == T_libpart ) { // A libpart section if found. Read it ParseKicadLibpartList(); } } } } }
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, const wxString& aCmpFileName, REPORTER* aReporter, bool aChangeFootprints, bool aDeleteUnconnectedTracks, bool aDeleteExtraFootprints, bool aSelectByTimeStamp, bool aDeleteSinglePadNets, bool aIsDryRun ) { wxString msg; NETLIST netlist; NETLIST_READER* netlistReader; netlist.SetIsDryRun( aIsDryRun ); netlist.SetFindByTimeStamp( aSelectByTimeStamp ); netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints ); netlist.SetReplaceFootprints( aChangeFootprints ); try { netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFileName, aCmpFileName ); if( netlistReader == NULL ) { msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFileName ) ); wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR, this ); return; } std::auto_ptr< NETLIST_READER > nlr( netlistReader ); SetLastNetListRead( aNetlistFileName ); netlistReader->LoadNetlist(); loadFootprints( netlist, aReporter ); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); return; } // Clear undo and redo lists to avoid inconsistencies between lists if( !netlist.IsDryRun() ) GetScreen()->ClearUndoRedoList(); netlist.SortByReference(); GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter ); // If it was a dry run, nothing has changed so we're done. if( netlist.IsDryRun() ) return; OnModify(); SetCurItem( NULL ); if( aDeleteUnconnectedTracks && GetBoard()->m_Track ) { // Remove erroneous tracks. This should probably pushed down to the #BOARD object. RemoveMisConnectedTracks(); } // Rebuild the board connectivity: Compile_Ratsnest( NULL, true ); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); }
/* Read the section "libparts" like: * (libparts * (libpart (lib device) (part C) * (description "Condensateur non polarise") * (footprints * (fp SM*) * (fp C?) * (fp C1-1)) * (fields * (field (name Reference) C) * (field (name Value) C)) * (pins * (pin (num 1) (name ~) (type passive)) * (pin (num 2) (name ~) (type passive)))) * * And add the strings giving the footprint filter (subsection footprints) * of the corresponding module info */ void NETLIST_READER_KICAD_PARSER::ParseKicadLibpartList() throw( IO_ERROR, PARSE_ERROR ) { /* Parses a section like * (libpart (lib device) (part C) * (description "Condensateur non polarise") * (footprints * (fp SM*) * (fp C?) * (fp C1-1)) * (fields * (field (name Reference) C) * (field (name Value) C)) * (pins * (pin (num 1) (name ~) (type passive)) * (pin (num 2) (name ~) (type passive)))) * * Currently footprints section/fp are read and data stored * other fields (unused) are skipped */ wxString device; wxString filter; LIPBART_INFO* libpart_info = NULL; // The last token read was libpart, so read the next token while( (token = NextTok()) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); switch( token ) { case T_part: NeedSYMBOLorNUMBER(); device = FROM_UTF8( CurText() ); NeedRIGHT(); libpart_info = new LIPBART_INFO( device ); netlist_reader->AddLibpartInfo( libpart_info ); break; case T_footprints: // Ensure "(part C)" was already read if( libpart_info == NULL ) Expecting( T_part ); // Read all fp elements (footprint filter item) while( (token = NextTok()) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); if( token != T_fp ) Expecting( T_fp ); NeedSYMBOLorNUMBER(); filter = FROM_UTF8( CurText() ); NeedRIGHT(); libpart_info->m_FootprintFilter.Add( filter ); } break; default: // Skip not used data (i.e all other tokens) SkipCurrent(); break; } } }
void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR ) { /* Parses a section like * (net (code 20) (name /PC-A0) * (node (ref BUS1) (pin 62)) * (node (ref U3) (pin 3)) * (node (ref U9) (pin M6))) */ wxString code; wxString name; wxString cmpref; wxString pin; int nodecount = 0; std::vector<D_PAD*> padList; // The token net was read, so the next data is (code <number>) while( (token = NextTok()) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); switch( token ) { case T_code: NeedSYMBOLorNUMBER(); code = FROM_UTF8( CurText() ); NeedRIGHT(); break; case T_name: NeedSYMBOLorNUMBER(); name = FROM_UTF8( CurText() ); NeedRIGHT(); if( name.IsEmpty() ) // Give a dummy net name like N-000109 name = wxT("N-00000") + code; break; case T_node: while( (token = NextTok()) != T_RIGHT ) { if( token == T_LEFT ) token = NextTok(); switch( token ) { case T_ref: NeedSYMBOLorNUMBER(); cmpref = FROM_UTF8( CurText() ); NeedRIGHT(); break; case T_pin: NeedSYMBOLorNUMBER(); pin = FROM_UTF8( CurText() ); NeedRIGHT(); break; default: SkipCurrent(); break; } } netlist_reader->SetPadsNetName( cmpref, pin, name, padList ); nodecount++; break; default: SkipCurrent(); break; } } // When there is only one item in net, clear pad netname // Remember one can have more than one pad in list, because a footprint // can have many pads with the same pad name if( nodecount < 2 ) for( unsigned ii = 0; ii < padList.size(); ii++ ) padList[ii]->SetNetname( wxEmptyString ); }
bool DIALOG_NETLIST::verifyFootprints( const wxString& aNetlistFilename, const wxString & aCmpFilename, std::vector< MODULE* >& aDuplicates, wxArrayString& aMissing, std::vector< MODULE* >& aNotInNetlist ) { wxString msg; MODULE* module; MODULE* nextModule; NETLIST netlist; wxBusyCursor dummy; // Shows an hourglass while calculating. NETLIST_READER* netlistReader; COMPONENT* component; try { netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename, aCmpFilename ); if( netlistReader == NULL ) { msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) ); wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR ); return false; } std::auto_ptr< NETLIST_READER > nlr( netlistReader ); netlistReader->LoadNetlist(); } catch( const IO_ERROR& ioe ) { msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() ); wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR ); return false; } BOARD* pcb = m_parent->GetBoard(); // Search for duplicate footprints. module = pcb->m_Modules; for( ; module != NULL; module = module->Next() ) { nextModule = module->Next(); for( ; nextModule != NULL; nextModule = nextModule->Next() ) { if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 ) { aDuplicates.push_back( module ); break; } } } // Search for component footprints in the netlist but not on the board. for( unsigned ii = 0; ii < netlist.GetCount(); ii++ ) { component = netlist.GetComponent( ii ); module = pcb->FindModuleByReference( component->GetReference() ); if( module == NULL ) { aMissing.Add( component->GetReference() ); aMissing.Add( component->GetValue() ); } } // Search for component footprints found on board but not in netlist. module = pcb->m_Modules; for( ; module != NULL; module = module->Next() ) { component = netlist.GetComponentByReference( module->GetReference() ); if( component == NULL ) aNotInNetlist.push_back( module ); } return true; }