Loading pcbnew/netlist.cpp +165 −149 Original line number Original line Diff line number Diff line Loading @@ -101,7 +101,6 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL m_useCmpFile = true; m_useCmpFile = true; } } ~NETLIST_READER() ~NETLIST_READER() { { // Free new modules list: // Free new modules list: Loading @@ -111,7 +110,6 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL m_newModulesList.clear(); m_newModulesList.clear(); } } /** /** * Function ReadNetList * Function ReadNetList * The main function to read a netlist, and update the board * The main function to read a netlist, and update the board Loading @@ -125,13 +123,13 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL const wxString& aCmplistFileName ); const wxString& aCmplistFileName ); /** /** * Function BuildFootprintListFromNetlist * Function BuildComponentsListFromNetlist * Fill aBufName with footprints references read from the netlist. * Fill aBufName with component references read from the netlist. * @param aNetlistFilename = netlist full file name * @param aNetlistFilename = netlist full file name * @param aBufName = wxArrayString to fill with footprint names * @param aBufName = wxArrayString to fill with component references * @return the footprint count, or -1 if netlist file cannot opened * @return the component count, or -1 if netlist file cannot opened */ */ int BuildFootprintListFromNetlist( const wxString& aNetlistFilename, int BuildComponentsListFromNetlist( const wxString& aNetlistFilename, wxArrayString& aBufName ); wxArrayString& aBufName ); /** /** Loading Loading @@ -175,15 +173,16 @@ private: void loadNewModules(); void loadNewModules(); /** /** * function readModulesComponentsTable * function readModuleComponentLinkfile * read the *.cmp file ( filename in m_cmplistFullName ) * read the *.cmp file ( filename in m_cmplistFullName ) * giving the equivalence beteween modules and components * giving the equivalence between footprint names and components * @return true and the module name in aModuleName, false if not found * to find the footprint name corresponding to aCmpIdent * @return true and the module name in aFootprintName, false if not found * * * @param aCmpIdent = component identification: schematic reference or time stamp * @param aCmpIdent = component identification: schematic reference or time stamp * @param aModuleName the footprint name corresponding to the component identification * @param aFootprintName the footprint name corresponding to the component identification */ */ bool readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName ); bool readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName ); }; }; /** /** Loading Loading @@ -289,14 +288,12 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, // Rebuild the board connectivity: // Rebuild the board connectivity: Compile_Ratsnest( NULL, true ); Compile_Ratsnest( NULL, true ); if( GetBoard()->m_Track ) if( aDeleteBadTracks && GetBoard()->m_Track ) { if( aDeleteBadTracks ) // Remove erroneous tracks { { // Remove erroneous tracks RemoveMisConnectedTracks( NULL ); RemoveMisConnectedTracks( NULL ); Compile_Ratsnest( NULL, true ); Compile_Ratsnest( NULL, true ); } } } GetBoard()->DisplayInfo( this ); GetBoard()->DisplayInfo( this ); DrawPanel->Refresh(); DrawPanel->Refresh(); Loading @@ -309,26 +306,26 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, */ */ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) { { wxArrayString modulesInNetlist; wxArrayString componentsInNetlist; // Build list of modules in the netlist // Build list of modules in the netlist int modulesCount = int modulesCount = BuildFootprintListFromNetlist( aNetlistFileName, modulesInNetlist ); BuildComponentsListFromNetlist( aNetlistFileName, componentsInNetlist ); if( modulesCount == 0 ) if( modulesCount == 0 ) return; return; MODULE* NextModule; MODULE* nextModule; MODULE* Module = m_pcbframe->GetBoard()->m_Modules; MODULE* module = m_pcbframe->GetBoard()->m_Modules; bool ask_user = true; bool ask_user = true; for( ; Module != NULL; Module = NextModule ) for( ; module != NULL; module = nextModule ) { { int ii; int ii; NextModule = Module->Next(); nextModule = module->Next(); if( Module->m_ModuleStatus & MODULE_is_LOCKED ) if( module->m_ModuleStatus & MODULE_is_LOCKED ) continue; continue; for( ii = 0; ii < modulesCount; ii++ ) for( ii = 0; ii < modulesCount; ii++ ) { { if( Module->m_Reference->m_Text.CmpNoCase( modulesInNetlist[ii] ) == 0 ) if( module->m_Reference->m_Text.CmpNoCase( componentsInNetlist[ii] ) == 0 ) break; /* Module is found in net list. */ break; /* Module is found in net list. */ } } Loading @@ -341,7 +338,7 @@ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) _( "Ok to delete not locked footprints not found in netlist?" ) ) ) _( "Ok to delete not locked footprints not found in netlist?" ) ) ) break; break; } } Module->DeleteStructure(); module->DeleteStructure(); } } } } } } Loading Loading @@ -371,8 +368,8 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, const wxString& aNetlistFileName, const wxString& aNetlistFileName, const wxString& aCmplistFileName ) const wxString& aCmplistFileName ) { { int State = 0; int state = 0; int Comment = 0; bool is_comment = false; m_netlistFullName = aNetlistFileName; m_netlistFullName = aNetlistFileName; m_cmplistFullName = aCmplistFileName; m_cmplistFullName = aCmplistFileName; Loading @@ -387,35 +384,35 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, { { char* line = StrPurge( netlineReader.Line() ); char* line = StrPurge( netlineReader.Line() ); if( Comment ) /* Comments in progress */ if( is_comment ) /* Comments in progress */ { { // Test for end of the current comment // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *line == '{' ) /* Start Comment */ if( *line == '{' ) /* Start Comment */ { { Comment = 1; is_comment = true; if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; } } if( *line == '(' ) if( *line == '(' ) State++; state++; if( *line == ')' ) if( *line == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { ReadNetlistModuleDescr( line, TESTONLY ); ReadNetlistModuleDescr( line, TESTONLY ); continue; continue; } } if( State >= 3 ) // First pass: pad descriptions are not read here. if( state >= 3 ) // First pass: pad descriptions are not read here. { { State--; state--; } } } } Loading @@ -427,30 +424,32 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, */ */ netlineReader.Rewind(); netlineReader.Rewind(); m_currModule = NULL; m_currModule = NULL; state = 0; is_comment = false; while( netlineReader.ReadLine() ) while( netlineReader.ReadLine() ) { { char* line = StrPurge( netlineReader.Line() ); char* line = StrPurge( netlineReader.Line() ); if( Comment ) // we are reading a comment if( is_comment ) // we are reading a comment { { // Test for end of the current comment // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *line == '{' ) // this is the beginning of a comment if( *line == '{' ) // this is the beginning of a comment { { Comment = 1; is_comment = true; if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; } } if( *line == '(' ) if( *line == '(' ) State++; state++; if( *line == ')' ) if( *line == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { m_currModule = ReadNetlistModuleDescr( line, READMODULE ); m_currModule = ReadNetlistModuleDescr( line, READMODULE ); if( m_currModule == NULL ) // the module could not be created (perhaps if( m_currModule == NULL ) // the module could not be created (perhaps Loading @@ -458,20 +457,20 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, continue; continue; else /* clear pads netnames */ else /* clear pads netnames */ { { D_PAD* PtPad = m_currModule->m_Pads; D_PAD* pad = m_currModule->m_Pads; for( ; PtPad != NULL; PtPad = PtPad->Next() ) for( ; pad != NULL; pad = pad->Next() ) { { PtPad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString ); } } } } continue; continue; } } if( State >= 3 ) if( state >= 3 ) { { if( m_currModule ) if( m_currModule ) SetPadNetName( line ); SetPadNetName( line ); State--; state--; } } } } Loading @@ -493,96 +492,106 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, * If false: the netlist only is used * If false: the netlist only is used * This flag is reset to false if the .cmp file is not found * This flag is reset to false if the .cmp file is not found * Analyze lines like: * Analyze lines like: * ($ 40C08647 noname R20 4.7 K Lib = R * ( /40C08647 $noname R20 4.7K {Lib=R} * (1 VCC) * (1 VCC) * (2 MODB_1) * (2 MODB_1) * ) */ */ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) { { char* text; char* text; wxString TimeStampPath; wxString timeStampPath; // the full time stamp read from netlist wxString TextNameLibMod; wxString textFootprintName; // the footprint name read from netlist wxString TextValeur; wxString textValue; // the component value read from netlist wxString TextCmpName; wxString textCmpReference; // the component schematic reference read from netlist wxString NameLibCmp; wxString cmpFootprintName; // the footprint name read from the *.cmp file int Error = 0; // giving the equivalence between footprint names and components char Line[1024]; bool error = false; char line[1024]; strcpy( Line, aText ); strcpy( line, aText ); TextValeur = wxT( "~" ); textValue = wxT( "~" ); if( ( text = strtok( Line, " ()\t\n" ) ) == NULL ) // Read descr line like /40C08647 $noname R20 4.7K {Lib=R} Error = 1; // Read time stamp (first word) if( ( text = strtok( line, " ()\t\n" ) ) == NULL ) error = true; else else TimeStampPath = FROM_UTF8( text ); timeStampPath = FROM_UTF8( text ); // Read footprint name (second word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = 1; error = true; else else TextNameLibMod = FROM_UTF8( text ); textFootprintName = FROM_UTF8( text ); // Read schematic reference (third word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = 1; error = true; else else TextCmpName = FROM_UTF8( text ); textCmpReference = FROM_UTF8( text ); // Read schematic value (forth word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = -1; error = true; else else TextValeur = FROM_UTF8( text ); textValue = FROM_UTF8( text ); if( Error > 0 ) if( error ) return NULL; return NULL; /* Test if module is already loaded. */ /* Test if module is already loaded. */ wxString * identMod = &TextCmpName; wxString * identMod = &textCmpReference; if( m_UseTimeStamp ) if( m_UseTimeStamp ) identMod = &TimeStampPath; identMod = &timeStampPath; MODULE* Module = m_pcbframe->GetBoard()->m_Modules; MODULE* module = m_pcbframe->GetBoard()->m_Modules; MODULE* NextModule; MODULE* nextModule; bool found = false; bool found = false; for( ; Module != NULL; Module = NextModule ) for( ; module != NULL; module = nextModule ) { { NextModule = Module->Next(); nextModule = module->Next(); if( m_UseTimeStamp ) /* identification by time stamp */ if( m_UseTimeStamp ) /* identification by time stamp */ { { if( TimeStampPath.CmpNoCase( Module->m_Path ) == 0 ) if( timeStampPath.CmpNoCase( module->m_Path ) == 0 ) found = true; found = true; } } else /* identification by Reference */ else /* identification by Reference */ { { if( TextCmpName.CmpNoCase( Module->m_Reference->m_Text ) == 0 ) if( textCmpReference.CmpNoCase( module->m_Reference->m_Text ) == 0 ) found = true; found = true; } } if( found ) // test footprint matching for existing modules: current if( found ) // The footprint corresponding to the component is already on board { { // m_LibRef and module name in netlist must match // We do do load the footprint, because it is already on board // but we compare m_LibRef (existing footprint name) and the footprint name from netlist // and change this footprint if differs from netlist (only on demand). if( aTstOnly != TESTONLY ) if( aTstOnly != TESTONLY ) { { NameLibCmp = TextNameLibMod; // Use footprint name from netlist cmpFootprintName = textFootprintName; // Use footprint name from netlist if( m_useCmpFile ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file { { m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp ); m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); } } /* Module mismatch: current module and module specified in /* Module mismatch: current fotprint and footprint specified in * net list are different. * net list are different. */ */ if( Module->m_LibRef.CmpNoCase( NameLibCmp ) != 0 ) if( module->m_LibRef.CmpNoCase( cmpFootprintName ) != 0 ) { { if( m_ChangeFootprints ) // footprint exchange allowed. if( m_ChangeFootprints ) // footprint exchange allowed. { { MODULE* NewModule = MODULE* newModule = m_pcbframe->Get_Librairie_Module( wxEmptyString, m_pcbframe->Get_Librairie_Module( wxEmptyString, NameLibCmp, cmpFootprintName, true ); true ); if( NewModule ) /* Change old module to the new module if( newModule ) * (and delete the old one) */ { { m_pcbframe->Exchange_Module( Module, NewModule, NULL ); // Change old module to the new module (and delete the old one) Module = NewModule; m_pcbframe->Exchange_Module( module, newModule, NULL ); module = newModule; } } } } else else Loading @@ -591,9 +600,9 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) msg.Printf( msg.Printf( _( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), GetChars( TextCmpName ), GetChars( textCmpReference ), GetChars( Module->m_LibRef ), GetChars( module->m_LibRef ), GetChars( NameLibCmp ) ); GetChars( cmpFootprintName ) ); if( m_messageWindow ) if( m_messageWindow ) m_messageWindow->AppendText( msg ); m_messageWindow->AppendText( msg ); Loading @@ -605,18 +614,18 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) } } } } if( Module == NULL ) /* a new module must be loaded from libs */ if( module == NULL ) // a new module must be loaded from libs { { NameLibCmp = TextNameLibMod; // Use footprint name from netlist cmpFootprintName = textFootprintName; // Use footprint name from netlist if( m_useCmpFile ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file { { m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp ); m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); } } if( aTstOnly == TESTONLY ) if( aTstOnly == TESTONLY ) { { MODULE_INFO* newMod; MODULE_INFO* newMod; newMod = new MODULE_INFO( NameLibCmp, TextCmpName, TimeStampPath ); newMod = new MODULE_INFO( cmpFootprintName, textCmpReference, timeStampPath ); m_newModulesList.push_back( newMod ); m_newModulesList.push_back( newMod ); } } else else Loading @@ -625,19 +634,19 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) { { wxString msg; wxString msg; msg.Printf( _( "Component [%s] not found" ), msg.Printf( _( "Component [%s] not found" ), GetChars( TextCmpName ) ); GetChars( textCmpReference ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); } } } } return NULL; /* The module could not be loaded. */ return NULL; // The module could not be loaded. } } /* Fields update ( reference, value and "Time Stamp") */ // Update current module ( reference, value and "Time Stamp") Module->m_Reference->m_Text = TextCmpName; module->m_Reference->m_Text = textCmpReference; Module->m_Value->m_Text = TextValeur; module->m_Value->m_Text = textValue; Module->m_Path = TimeStampPath; module->m_Path = timeStampPath; return Module; return module; } } Loading Loading @@ -762,7 +771,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( /* Build the list of references of the net list modules. */ /* Build the list of references of the net list modules. */ NETLIST_READER netList_Reader( this ); NETLIST_READER netList_Reader( this ); NbModulesNetListe = netList_Reader.BuildFootprintListFromNetlist( aNetlistFullFilename, tmp ); NbModulesNetListe = netList_Reader.BuildComponentsListFromNetlist( aNetlistFullFilename, tmp ); if( NbModulesNetListe < 0 ) if( NbModulesNetListe < 0 ) return; /* File not found */ return; /* File not found */ Loading Loading @@ -843,85 +852,91 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( /** /** * Function BuildFootprintListFromNetlist * Function BuildComponentsListFromNetlist * Fill BufName with footprints names read from the netlist. * Fill aBufName with component references read from the netlist. * @param aNetlistFilename = netlist full file name * @param aNetlistFilename = netlist full file name * @param aBufName = wxArrayString to fill with footprint names * @param aBufName = wxArrayString to fill with component references * @return Footprint count, or -1 if netlist file cannot opened * @return component count, or -1 if netlist file cannot opened */ */ int NETLIST_READER::BuildFootprintListFromNetlist( const wxString& aNetlistFilename, int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFilename, wxArrayString& aBufName ) wxArrayString& aBufName ) { { int nb_modules_lus; int component_count; int State, Comment; int state; char* Text, * LibModName; bool is_comment; char* text; FILE* netfile = OpenNetlistFile( aNetlistFilename ); FILE* netfile = OpenNetlistFile( aNetlistFilename ); if( netfile == NULL ) if( netfile == NULL ) return -1; return -1; FILE_LINE_READER netlineReader( netfile, aNetlistFilename ); FILE_LINE_READER netlineReader( netfile, aNetlistFilename ); // ctor will close netfile char* Line = netlineReader; char* Line = netlineReader; State = 0; Comment = 0; state = 0; nb_modules_lus = 0; is_comment = false; component_count = 0; while( netlineReader.ReadLine() ) while( netlineReader.ReadLine() ) { { Text = StrPurge( Line ); text = StrPurge( Line ); if( Comment ) if( is_comment ) { { if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( text = strchr( text, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *Text == '{' ) /* Comments. */ if( *text == '{' ) /* Comments. */ { { Comment = 1; is_comment = true; if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( text = strchr( text, '}' ) ) == NULL ) continue; continue; } } if( *Text == '(' ) if( *text == '(' ) State++; state++; if( *Text == ')' ) if( *text == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { int Error = 0; bool error = false; // skip TimeStamp: if( strtok( Line, " ()\t\n" ) == NULL ) if( strtok( Line, " ()\t\n" ) == NULL ) Error = 1; /* TimeStamp */ error = true; if( ( LibModName = strtok( NULL, " ()\t\n" ) ) == NULL ) // skip footprint name: Error = 1; if( ( strtok( NULL, " ()\t\n" ) ) == NULL ) /* Load the name of the component. */ error = true; if( ( Text = strtok( NULL, " ()\t\n" ) ) == NULL ) // Load the reference of the component: Error = 1; if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) nb_modules_lus++; error = true; aBufName.Add( FROM_UTF8( Text ) ); component_count++; aBufName.Add( FROM_UTF8( text ) ); continue; continue; } } if( State >= 3 ) if( state >= 3 ) { { State--; state--; } } } } return nb_modules_lus; return component_count; } } /* /* * function readModulesComponentsTable * function readModuleComponentLinkfile * read the *.cmp file ( filename in m_cmplistFullName ) * read the *.cmp file ( filename in m_cmplistFullName ) * giving the equivalence modules / components * giving the equivalence Footprint_names / components * return true and the module name in aModuleName, false if not found * to find the footprint name corresponding to aCmpIdent * return true and the module name in aFootprintName, false if not found * * * param aCmpIdent = component identification: schematic reference or time stamp * param aCmpIdent = component identification: schematic reference or time stamp * param aModuleName the footprint name corresponding to the component identification * param aFootprintName the footprint name corresponding to the component identification * Example file: * * Sample file: * * * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 * * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 * * BeginCmp * BeginCmp Loading @@ -939,7 +954,8 @@ int NETLIST_READER::BuildFootprintListFromNetlist( const wxString& aNetlistFilen * EndCmp * EndCmp * * */ */ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName ) bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName ) { { wxString refcurrcmp; // Stores value read from line like Reference = BUS1; wxString refcurrcmp; // Stores value read from line like Reference = BUS1; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67; Loading Loading @@ -1004,7 +1020,7 @@ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxSt { { if( aCmpIdent->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() ) if( aCmpIdent->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() ) { // Found { // Found aModuleName = idmod; aFootprintName = idmod; return true; return true; } } } } Loading @@ -1012,7 +1028,7 @@ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxSt { { if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 ) // Found! if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 ) // Found! { { aModuleName = idmod; aFootprintName = idmod; return true; return true; } } } } Loading Loading
pcbnew/netlist.cpp +165 −149 Original line number Original line Diff line number Diff line Loading @@ -101,7 +101,6 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL m_useCmpFile = true; m_useCmpFile = true; } } ~NETLIST_READER() ~NETLIST_READER() { { // Free new modules list: // Free new modules list: Loading @@ -111,7 +110,6 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL m_newModulesList.clear(); m_newModulesList.clear(); } } /** /** * Function ReadNetList * Function ReadNetList * The main function to read a netlist, and update the board * The main function to read a netlist, and update the board Loading @@ -125,13 +123,13 @@ public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NUL const wxString& aCmplistFileName ); const wxString& aCmplistFileName ); /** /** * Function BuildFootprintListFromNetlist * Function BuildComponentsListFromNetlist * Fill aBufName with footprints references read from the netlist. * Fill aBufName with component references read from the netlist. * @param aNetlistFilename = netlist full file name * @param aNetlistFilename = netlist full file name * @param aBufName = wxArrayString to fill with footprint names * @param aBufName = wxArrayString to fill with component references * @return the footprint count, or -1 if netlist file cannot opened * @return the component count, or -1 if netlist file cannot opened */ */ int BuildFootprintListFromNetlist( const wxString& aNetlistFilename, int BuildComponentsListFromNetlist( const wxString& aNetlistFilename, wxArrayString& aBufName ); wxArrayString& aBufName ); /** /** Loading Loading @@ -175,15 +173,16 @@ private: void loadNewModules(); void loadNewModules(); /** /** * function readModulesComponentsTable * function readModuleComponentLinkfile * read the *.cmp file ( filename in m_cmplistFullName ) * read the *.cmp file ( filename in m_cmplistFullName ) * giving the equivalence beteween modules and components * giving the equivalence between footprint names and components * @return true and the module name in aModuleName, false if not found * to find the footprint name corresponding to aCmpIdent * @return true and the module name in aFootprintName, false if not found * * * @param aCmpIdent = component identification: schematic reference or time stamp * @param aCmpIdent = component identification: schematic reference or time stamp * @param aModuleName the footprint name corresponding to the component identification * @param aFootprintName the footprint name corresponding to the component identification */ */ bool readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName ); bool readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName ); }; }; /** /** Loading Loading @@ -289,14 +288,12 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, // Rebuild the board connectivity: // Rebuild the board connectivity: Compile_Ratsnest( NULL, true ); Compile_Ratsnest( NULL, true ); if( GetBoard()->m_Track ) if( aDeleteBadTracks && GetBoard()->m_Track ) { if( aDeleteBadTracks ) // Remove erroneous tracks { { // Remove erroneous tracks RemoveMisConnectedTracks( NULL ); RemoveMisConnectedTracks( NULL ); Compile_Ratsnest( NULL, true ); Compile_Ratsnest( NULL, true ); } } } GetBoard()->DisplayInfo( this ); GetBoard()->DisplayInfo( this ); DrawPanel->Refresh(); DrawPanel->Refresh(); Loading @@ -309,26 +306,26 @@ bool PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFullFilename, */ */ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) { { wxArrayString modulesInNetlist; wxArrayString componentsInNetlist; // Build list of modules in the netlist // Build list of modules in the netlist int modulesCount = int modulesCount = BuildFootprintListFromNetlist( aNetlistFileName, modulesInNetlist ); BuildComponentsListFromNetlist( aNetlistFileName, componentsInNetlist ); if( modulesCount == 0 ) if( modulesCount == 0 ) return; return; MODULE* NextModule; MODULE* nextModule; MODULE* Module = m_pcbframe->GetBoard()->m_Modules; MODULE* module = m_pcbframe->GetBoard()->m_Modules; bool ask_user = true; bool ask_user = true; for( ; Module != NULL; Module = NextModule ) for( ; module != NULL; module = nextModule ) { { int ii; int ii; NextModule = Module->Next(); nextModule = module->Next(); if( Module->m_ModuleStatus & MODULE_is_LOCKED ) if( module->m_ModuleStatus & MODULE_is_LOCKED ) continue; continue; for( ii = 0; ii < modulesCount; ii++ ) for( ii = 0; ii < modulesCount; ii++ ) { { if( Module->m_Reference->m_Text.CmpNoCase( modulesInNetlist[ii] ) == 0 ) if( module->m_Reference->m_Text.CmpNoCase( componentsInNetlist[ii] ) == 0 ) break; /* Module is found in net list. */ break; /* Module is found in net list. */ } } Loading @@ -341,7 +338,7 @@ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) _( "Ok to delete not locked footprints not found in netlist?" ) ) ) _( "Ok to delete not locked footprints not found in netlist?" ) ) ) break; break; } } Module->DeleteStructure(); module->DeleteStructure(); } } } } } } Loading Loading @@ -371,8 +368,8 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, const wxString& aNetlistFileName, const wxString& aNetlistFileName, const wxString& aCmplistFileName ) const wxString& aCmplistFileName ) { { int State = 0; int state = 0; int Comment = 0; bool is_comment = false; m_netlistFullName = aNetlistFileName; m_netlistFullName = aNetlistFileName; m_cmplistFullName = aCmplistFileName; m_cmplistFullName = aCmplistFileName; Loading @@ -387,35 +384,35 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, { { char* line = StrPurge( netlineReader.Line() ); char* line = StrPurge( netlineReader.Line() ); if( Comment ) /* Comments in progress */ if( is_comment ) /* Comments in progress */ { { // Test for end of the current comment // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *line == '{' ) /* Start Comment */ if( *line == '{' ) /* Start Comment */ { { Comment = 1; is_comment = true; if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; } } if( *line == '(' ) if( *line == '(' ) State++; state++; if( *line == ')' ) if( *line == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { ReadNetlistModuleDescr( line, TESTONLY ); ReadNetlistModuleDescr( line, TESTONLY ); continue; continue; } } if( State >= 3 ) // First pass: pad descriptions are not read here. if( state >= 3 ) // First pass: pad descriptions are not read here. { { State--; state--; } } } } Loading @@ -427,30 +424,32 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, */ */ netlineReader.Rewind(); netlineReader.Rewind(); m_currModule = NULL; m_currModule = NULL; state = 0; is_comment = false; while( netlineReader.ReadLine() ) while( netlineReader.ReadLine() ) { { char* line = StrPurge( netlineReader.Line() ); char* line = StrPurge( netlineReader.Line() ); if( Comment ) // we are reading a comment if( is_comment ) // we are reading a comment { { // Test for end of the current comment // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *line == '{' ) // this is the beginning of a comment if( *line == '{' ) // this is the beginning of a comment { { Comment = 1; is_comment = true; if( ( line = strchr( line, '}' ) ) == NULL ) if( ( line = strchr( line, '}' ) ) == NULL ) continue; continue; } } if( *line == '(' ) if( *line == '(' ) State++; state++; if( *line == ')' ) if( *line == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { m_currModule = ReadNetlistModuleDescr( line, READMODULE ); m_currModule = ReadNetlistModuleDescr( line, READMODULE ); if( m_currModule == NULL ) // the module could not be created (perhaps if( m_currModule == NULL ) // the module could not be created (perhaps Loading @@ -458,20 +457,20 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, continue; continue; else /* clear pads netnames */ else /* clear pads netnames */ { { D_PAD* PtPad = m_currModule->m_Pads; D_PAD* pad = m_currModule->m_Pads; for( ; PtPad != NULL; PtPad = PtPad->Next() ) for( ; pad != NULL; pad = pad->Next() ) { { PtPad->SetNetname( wxEmptyString ); pad->SetNetname( wxEmptyString ); } } } } continue; continue; } } if( State >= 3 ) if( state >= 3 ) { { if( m_currModule ) if( m_currModule ) SetPadNetName( line ); SetPadNetName( line ); State--; state--; } } } } Loading @@ -493,96 +492,106 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, * If false: the netlist only is used * If false: the netlist only is used * This flag is reset to false if the .cmp file is not found * This flag is reset to false if the .cmp file is not found * Analyze lines like: * Analyze lines like: * ($ 40C08647 noname R20 4.7 K Lib = R * ( /40C08647 $noname R20 4.7K {Lib=R} * (1 VCC) * (1 VCC) * (2 MODB_1) * (2 MODB_1) * ) */ */ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) { { char* text; char* text; wxString TimeStampPath; wxString timeStampPath; // the full time stamp read from netlist wxString TextNameLibMod; wxString textFootprintName; // the footprint name read from netlist wxString TextValeur; wxString textValue; // the component value read from netlist wxString TextCmpName; wxString textCmpReference; // the component schematic reference read from netlist wxString NameLibCmp; wxString cmpFootprintName; // the footprint name read from the *.cmp file int Error = 0; // giving the equivalence between footprint names and components char Line[1024]; bool error = false; char line[1024]; strcpy( Line, aText ); strcpy( line, aText ); TextValeur = wxT( "~" ); textValue = wxT( "~" ); if( ( text = strtok( Line, " ()\t\n" ) ) == NULL ) // Read descr line like /40C08647 $noname R20 4.7K {Lib=R} Error = 1; // Read time stamp (first word) if( ( text = strtok( line, " ()\t\n" ) ) == NULL ) error = true; else else TimeStampPath = FROM_UTF8( text ); timeStampPath = FROM_UTF8( text ); // Read footprint name (second word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = 1; error = true; else else TextNameLibMod = FROM_UTF8( text ); textFootprintName = FROM_UTF8( text ); // Read schematic reference (third word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = 1; error = true; else else TextCmpName = FROM_UTF8( text ); textCmpReference = FROM_UTF8( text ); // Read schematic value (forth word) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) Error = -1; error = true; else else TextValeur = FROM_UTF8( text ); textValue = FROM_UTF8( text ); if( Error > 0 ) if( error ) return NULL; return NULL; /* Test if module is already loaded. */ /* Test if module is already loaded. */ wxString * identMod = &TextCmpName; wxString * identMod = &textCmpReference; if( m_UseTimeStamp ) if( m_UseTimeStamp ) identMod = &TimeStampPath; identMod = &timeStampPath; MODULE* Module = m_pcbframe->GetBoard()->m_Modules; MODULE* module = m_pcbframe->GetBoard()->m_Modules; MODULE* NextModule; MODULE* nextModule; bool found = false; bool found = false; for( ; Module != NULL; Module = NextModule ) for( ; module != NULL; module = nextModule ) { { NextModule = Module->Next(); nextModule = module->Next(); if( m_UseTimeStamp ) /* identification by time stamp */ if( m_UseTimeStamp ) /* identification by time stamp */ { { if( TimeStampPath.CmpNoCase( Module->m_Path ) == 0 ) if( timeStampPath.CmpNoCase( module->m_Path ) == 0 ) found = true; found = true; } } else /* identification by Reference */ else /* identification by Reference */ { { if( TextCmpName.CmpNoCase( Module->m_Reference->m_Text ) == 0 ) if( textCmpReference.CmpNoCase( module->m_Reference->m_Text ) == 0 ) found = true; found = true; } } if( found ) // test footprint matching for existing modules: current if( found ) // The footprint corresponding to the component is already on board { { // m_LibRef and module name in netlist must match // We do do load the footprint, because it is already on board // but we compare m_LibRef (existing footprint name) and the footprint name from netlist // and change this footprint if differs from netlist (only on demand). if( aTstOnly != TESTONLY ) if( aTstOnly != TESTONLY ) { { NameLibCmp = TextNameLibMod; // Use footprint name from netlist cmpFootprintName = textFootprintName; // Use footprint name from netlist if( m_useCmpFile ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file { { m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp ); m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); } } /* Module mismatch: current module and module specified in /* Module mismatch: current fotprint and footprint specified in * net list are different. * net list are different. */ */ if( Module->m_LibRef.CmpNoCase( NameLibCmp ) != 0 ) if( module->m_LibRef.CmpNoCase( cmpFootprintName ) != 0 ) { { if( m_ChangeFootprints ) // footprint exchange allowed. if( m_ChangeFootprints ) // footprint exchange allowed. { { MODULE* NewModule = MODULE* newModule = m_pcbframe->Get_Librairie_Module( wxEmptyString, m_pcbframe->Get_Librairie_Module( wxEmptyString, NameLibCmp, cmpFootprintName, true ); true ); if( NewModule ) /* Change old module to the new module if( newModule ) * (and delete the old one) */ { { m_pcbframe->Exchange_Module( Module, NewModule, NULL ); // Change old module to the new module (and delete the old one) Module = NewModule; m_pcbframe->Exchange_Module( module, newModule, NULL ); module = newModule; } } } } else else Loading @@ -591,9 +600,9 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) msg.Printf( msg.Printf( _( _( "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), "Component \"%s\": Mismatch! module is [%s] and netlist said [%s]\n" ), GetChars( TextCmpName ), GetChars( textCmpReference ), GetChars( Module->m_LibRef ), GetChars( module->m_LibRef ), GetChars( NameLibCmp ) ); GetChars( cmpFootprintName ) ); if( m_messageWindow ) if( m_messageWindow ) m_messageWindow->AppendText( msg ); m_messageWindow->AppendText( msg ); Loading @@ -605,18 +614,18 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) } } } } if( Module == NULL ) /* a new module must be loaded from libs */ if( module == NULL ) // a new module must be loaded from libs { { NameLibCmp = TextNameLibMod; // Use footprint name from netlist cmpFootprintName = textFootprintName; // Use footprint name from netlist if( m_useCmpFile ) // Try to get footprint name from .cmp file if( m_useCmpFile ) // Try to get footprint name from .cmp file { { m_useCmpFile = readModulesComponentsTable( identMod, NameLibCmp ); m_useCmpFile = readModuleComponentLinkfile( identMod, cmpFootprintName ); } } if( aTstOnly == TESTONLY ) if( aTstOnly == TESTONLY ) { { MODULE_INFO* newMod; MODULE_INFO* newMod; newMod = new MODULE_INFO( NameLibCmp, TextCmpName, TimeStampPath ); newMod = new MODULE_INFO( cmpFootprintName, textCmpReference, timeStampPath ); m_newModulesList.push_back( newMod ); m_newModulesList.push_back( newMod ); } } else else Loading @@ -625,19 +634,19 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) { { wxString msg; wxString msg; msg.Printf( _( "Component [%s] not found" ), msg.Printf( _( "Component [%s] not found" ), GetChars( TextCmpName ) ); GetChars( textCmpReference ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); } } } } return NULL; /* The module could not be loaded. */ return NULL; // The module could not be loaded. } } /* Fields update ( reference, value and "Time Stamp") */ // Update current module ( reference, value and "Time Stamp") Module->m_Reference->m_Text = TextCmpName; module->m_Reference->m_Text = textCmpReference; Module->m_Value->m_Text = TextValeur; module->m_Value->m_Text = textValue; Module->m_Path = TimeStampPath; module->m_Path = timeStampPath; return Module; return module; } } Loading Loading @@ -762,7 +771,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( /* Build the list of references of the net list modules. */ /* Build the list of references of the net list modules. */ NETLIST_READER netList_Reader( this ); NETLIST_READER netList_Reader( this ); NbModulesNetListe = netList_Reader.BuildFootprintListFromNetlist( aNetlistFullFilename, tmp ); NbModulesNetListe = netList_Reader.BuildComponentsListFromNetlist( aNetlistFullFilename, tmp ); if( NbModulesNetListe < 0 ) if( NbModulesNetListe < 0 ) return; /* File not found */ return; /* File not found */ Loading Loading @@ -843,85 +852,91 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( /** /** * Function BuildFootprintListFromNetlist * Function BuildComponentsListFromNetlist * Fill BufName with footprints names read from the netlist. * Fill aBufName with component references read from the netlist. * @param aNetlistFilename = netlist full file name * @param aNetlistFilename = netlist full file name * @param aBufName = wxArrayString to fill with footprint names * @param aBufName = wxArrayString to fill with component references * @return Footprint count, or -1 if netlist file cannot opened * @return component count, or -1 if netlist file cannot opened */ */ int NETLIST_READER::BuildFootprintListFromNetlist( const wxString& aNetlistFilename, int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFilename, wxArrayString& aBufName ) wxArrayString& aBufName ) { { int nb_modules_lus; int component_count; int State, Comment; int state; char* Text, * LibModName; bool is_comment; char* text; FILE* netfile = OpenNetlistFile( aNetlistFilename ); FILE* netfile = OpenNetlistFile( aNetlistFilename ); if( netfile == NULL ) if( netfile == NULL ) return -1; return -1; FILE_LINE_READER netlineReader( netfile, aNetlistFilename ); FILE_LINE_READER netlineReader( netfile, aNetlistFilename ); // ctor will close netfile char* Line = netlineReader; char* Line = netlineReader; State = 0; Comment = 0; state = 0; nb_modules_lus = 0; is_comment = false; component_count = 0; while( netlineReader.ReadLine() ) while( netlineReader.ReadLine() ) { { Text = StrPurge( Line ); text = StrPurge( Line ); if( Comment ) if( is_comment ) { { if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( text = strchr( text, '}' ) ) == NULL ) continue; continue; Comment = 0; is_comment = false; } } if( *Text == '{' ) /* Comments. */ if( *text == '{' ) /* Comments. */ { { Comment = 1; is_comment = true; if( ( Text = strchr( Text, '}' ) ) == NULL ) if( ( text = strchr( text, '}' ) ) == NULL ) continue; continue; } } if( *Text == '(' ) if( *text == '(' ) State++; state++; if( *Text == ')' ) if( *text == ')' ) State--; state--; if( State == 2 ) if( state == 2 ) { { int Error = 0; bool error = false; // skip TimeStamp: if( strtok( Line, " ()\t\n" ) == NULL ) if( strtok( Line, " ()\t\n" ) == NULL ) Error = 1; /* TimeStamp */ error = true; if( ( LibModName = strtok( NULL, " ()\t\n" ) ) == NULL ) // skip footprint name: Error = 1; if( ( strtok( NULL, " ()\t\n" ) ) == NULL ) /* Load the name of the component. */ error = true; if( ( Text = strtok( NULL, " ()\t\n" ) ) == NULL ) // Load the reference of the component: Error = 1; if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) nb_modules_lus++; error = true; aBufName.Add( FROM_UTF8( Text ) ); component_count++; aBufName.Add( FROM_UTF8( text ) ); continue; continue; } } if( State >= 3 ) if( state >= 3 ) { { State--; state--; } } } } return nb_modules_lus; return component_count; } } /* /* * function readModulesComponentsTable * function readModuleComponentLinkfile * read the *.cmp file ( filename in m_cmplistFullName ) * read the *.cmp file ( filename in m_cmplistFullName ) * giving the equivalence modules / components * giving the equivalence Footprint_names / components * return true and the module name in aModuleName, false if not found * to find the footprint name corresponding to aCmpIdent * return true and the module name in aFootprintName, false if not found * * * param aCmpIdent = component identification: schematic reference or time stamp * param aCmpIdent = component identification: schematic reference or time stamp * param aModuleName the footprint name corresponding to the component identification * param aFootprintName the footprint name corresponding to the component identification * Example file: * * Sample file: * * * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 * * Cmp-Mod V01 Genere by Pcbnew 29/10/2003-13: 11:6 * * BeginCmp * BeginCmp Loading @@ -939,7 +954,8 @@ int NETLIST_READER::BuildFootprintListFromNetlist( const wxString& aNetlistFilen * EndCmp * EndCmp * * */ */ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxString& aModuleName ) bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, wxString& aFootprintName ) { { wxString refcurrcmp; // Stores value read from line like Reference = BUS1; wxString refcurrcmp; // Stores value read from line like Reference = BUS1; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67; wxString timestamp; // Stores value read from line like TimeStamp = /32307DE2/AA450F67; Loading Loading @@ -1004,7 +1020,7 @@ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxSt { { if( aCmpIdent->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() ) if( aCmpIdent->CmpNoCase( timestamp ) == 0 && !timestamp.IsEmpty() ) { // Found { // Found aModuleName = idmod; aFootprintName = idmod; return true; return true; } } } } Loading @@ -1012,7 +1028,7 @@ bool NETLIST_READER::readModulesComponentsTable( const wxString* aCmpIdent, wxSt { { if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 ) // Found! if( aCmpIdent->CmpNoCase( refcurrcmp ) == 0 ) // Found! { { aModuleName = idmod; aFootprintName = idmod; return true; return true; } } } } Loading