diff --git a/common/footprint_info.cpp b/common/footprint_info.cpp index 69a70318e9..7ccd0f87de 100644 --- a/common/footprint_info.cpp +++ b/common/footprint_info.cpp @@ -56,17 +56,16 @@ FOOTPRINT_INFO* FOOTPRINT_LIST::GetModuleInfo( const wxString& aFootprintName ) if( aFootprintName.IsEmpty() ) return NULL; + LIB_ID fpid; + + wxCHECK_MSG( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0, NULL, + wxString::Format( wxT( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) ); + + wxString libNickname = fpid.GetLibNickname(); + wxString footprintName = fpid.GetLibItemName(); + for( auto& fp : m_list ) { - LIB_ID fpid; - - wxCHECK_MSG( fpid.Parse( aFootprintName ) < 0, NULL, - wxString::Format( - wxT( "\"%s\" is not a valid LIB_ID." ), GetChars( aFootprintName ) ) ); - - wxString libNickname = fpid.GetLibNickname(); - wxString footprintName = fpid.GetLibItemName(); - if( libNickname == fp->GetNickname() && footprintName == fp->GetFootprintName() ) return &*fp; } diff --git a/common/lib_id.cpp b/common/lib_id.cpp index 86c9abde31..f014a47480 100644 --- a/common/lib_id.cpp +++ b/common/lib_id.cpp @@ -119,7 +119,7 @@ void LIB_ID::clear() } -int LIB_ID::Parse( const UTF8& aId ) +int LIB_ID::Parse( const UTF8& aId, LIB_ID_TYPE aType, bool aFix ) { clear(); @@ -127,7 +127,7 @@ int LIB_ID::Parse( const UTF8& aId ) const char* rev = EndsWithRev( buffer, buffer+aId.length(), '/' ); size_t revNdx; size_t partNdx; - int offset; + int offset = -1; //============================================== // in a LIB_ID like discret:R3/rev4 @@ -150,9 +150,7 @@ int LIB_ID::Parse( const UTF8& aId ) offset = SetLibNickname( aId.substr( 0, partNdx ) ); if( offset > -1 ) - { return offset; - } ++partNdx; // skip ':' } @@ -165,48 +163,24 @@ int LIB_ID::Parse( const UTF8& aId ) if( partNdx >= revNdx ) return partNdx; // Error: no library item name. + UTF8 fpname = aId.substr( partNdx, revNdx-partNdx ); + // Be sure the item name is valid. // Some chars can be found in legacy files converted files from other EDA tools. - std::string fpname = aId.substr( partNdx, revNdx-partNdx ); - ReplaceIllegalFileNameChars( &fpname, '_' ); - SetLibItemName( UTF8( fpname ) ); + if( aFix ) + fpname = FixIllegalChars( fpname, aType, false ); + else + offset = HasIllegalChars( fpname, aType ); + + if( offset > -1 ) + return offset; + + SetLibItemName( fpname ); return -1; } -LIB_ID::LIB_ID( const UTF8& aId ) -{ - int offset = Parse( aId ); - - if( offset != -1 ) - { - THROW_PARSE_ERROR( _( "Illegal character found in LIB_ID string" ), - wxString::FromUTF8( aId.c_str() ), - aId.c_str(), - 0, - offset ); - } -} - - -LIB_ID::LIB_ID( const wxString& aId ) -{ - UTF8 id = aId; - - int offset = Parse( id ); - - if( offset != -1 ) - { - THROW_PARSE_ERROR( _( "Illegal character found in LIB_ID string" ), - aId, - id.c_str(), - 0, - offset ); - } -} - - LIB_ID::LIB_ID( const wxString& aLibName, const wxString& aLibItemName, const wxString& aRevision ) : nickname( aLibName ), @@ -359,15 +333,19 @@ int LIB_ID::compare( const LIB_ID& aLibId ) const } -bool LIB_ID::HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType ) +int LIB_ID::HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType ) { + int offset = 0; + for( auto ch : aLibItemName ) { if( !isLegalChar( ch, aType ) ) - return true; + return offset; + else + ++offset; } - return false; + return -1; } @@ -391,7 +369,8 @@ UTF8 LIB_ID::FixIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType, bool bool LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType ) { bool const colon_allowed = ( aType == ID_ALIAS ); - bool const space_allowed = ( aType != ID_SCH ); + bool const space_allowed = ( aType == ID_ALIAS || aType == ID_PCB ); + bool const illegal_filename_chars_allowed = ( aType == ID_SCH || aType == ID_ALIAS ); if( aUniChar < ' ' ) return false; @@ -400,7 +379,10 @@ bool LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType ) { case '/': case '\\': - return false; + case '<': + case '>': + case '"': + return illegal_filename_chars_allowed; case ':': return colon_allowed; diff --git a/cvpcb/display_footprints_frame.cpp b/cvpcb/display_footprints_frame.cpp index e81ef62faf..d4c3cc3904 100644 --- a/cvpcb/display_footprints_frame.cpp +++ b/cvpcb/display_footprints_frame.cpp @@ -430,7 +430,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName ) { LIB_ID fpid; - if( fpid.Parse( aFootprintName ) >= 0 ) + if( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) >= 0 ) { DisplayInfoMessage( this, wxString::Format( _( "Footprint ID \"%s\" is not valid." ), GetChars( aFootprintName ) ) ); diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index bb6d0b1c83..76f3af3d32 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -99,9 +99,8 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex ) if( !aFootprintName.IsEmpty() ) { - wxCHECK_RET( fpid.Parse( aFootprintName ) < 0, - wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), - GetChars( aFootprintName ) ) ); + wxCHECK_RET( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0, + wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) ); } component->SetFPID( fpid ); diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index 84f2936e38..ec0c97bb3b 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -287,8 +287,7 @@ void LIB_PART::SetName( const wxString& aName ) else m_aliases[0]->SetName( aName ); - // LIB_ALIAS validates the name, reuse it instead of validating the name again - wxString validatedName( m_aliases[0]->GetName() ); + wxString validatedName = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH ); m_libId.SetLibItemName( validatedName, false ); LIB_FIELD& valueField = GetValueField(); diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp index b94a74238a..007b4b7c8e 100644 --- a/eeschema/dialogs/dialog_choose_component.cpp +++ b/eeschema/dialogs/dialog_choose_component.cpp @@ -301,7 +301,7 @@ void DIALOG_CHOOSE_COMPONENT::ShowFootprint( wxString const& aName ) { LIB_ID lib_id; - if( lib_id.Parse( aName ) == -1 && lib_id.IsValid() ) + if( lib_id.Parse( aName, LIB_ID::ID_PCB ) == -1 && lib_id.IsValid() ) { m_fp_view_ctrl->ClearStatus(); m_fp_view_ctrl->CacheFootprint( lib_id ); diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 405e76afbe..27a35237ba 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -258,7 +258,9 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnTestChipName( wxCommandEvent& event ) wxString msg; wxString partname = chipnameTextCtrl->GetValue(); - if( id.Parse( partname ) != -1 || !id.IsValid() ) + id.Parse( partname, LIB_ID::ID_SCH ); + + if( !id.IsValid() ) { msg.Printf( _( "\"%s\" is not a valid library symbol identifier." ), partname ); DisplayError( this, msg ); @@ -363,7 +365,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions() tmp.Replace( wxT( " " ), wxT( "_" ) ); - id.Parse( tmp ); + id.Parse( tmp, LIB_ID::ID_SCH ); // Save current flags which could be modified by next change settings STATUS_FLAGS flags = m_cmp->GetFlags(); diff --git a/eeschema/dialogs/dialog_edit_components_libid.cpp b/eeschema/dialogs/dialog_edit_components_libid.cpp index ccbef8466d..ec68f25b8b 100644 --- a/eeschema/dialogs/dialog_edit_components_libid.cpp +++ b/eeschema/dialogs/dialog_edit_components_libid.cpp @@ -358,7 +358,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::validateLibIds() // a new lib id is found. validate this new value LIB_ID id; - id.Parse( new_libid ); + id.Parse( new_libid, LIB_ID::ID_SCH ); if( !id.IsValid() ) { @@ -430,7 +430,8 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event ) wxString orphanLibid = m_grid->GetCellValue( m_OrphansRowIndexes[ii], COL_CURR_LIBID ); int grid_row_idx = m_OrphansRowIndexes[ii]; //row index in m_grid for the current item - LIB_ID curr_libid( orphanLibid ); + LIB_ID curr_libid; + curr_libid.Parse( orphanLibid, LIB_ID::ID_SCH, true ); wxString symbName = curr_libid.GetLibItemName(); // number of full LIB_ID candidates (because we search for a symbol name // inside all avaiable libraries, perhaps the same symbol name can be found @@ -438,7 +439,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event ) int libIdCandidateCount = 0; candidateSymbNames.Clear(); - // now try to fin a candidate + // now try to find a candidate for( auto &lib : libs ) { aliasNames.Clear(); @@ -555,7 +556,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::TransferDataFromWindow() // a new lib id is found and was already validated. // set this new value LIB_ID id; - id.Parse( new_libid ); + id.Parse( new_libid, LIB_ID::ID_SCH, true ); for( CMP_CANDIDATE& cmp : m_components ) { @@ -592,7 +593,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::revertChanges() continue; LIB_ID id; - id.Parse( cmp.m_InitialLibId ); + id.Parse( cmp.m_InitialLibId, LIB_ID::ID_SCH, true ); if( cmp.m_Component->GetLibId() != id ) { diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index bc64d6a694..cd08aa3d89 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -844,7 +844,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) if( !fpField->GetText().IsEmpty() ) { - LIB_ID fpId( fpField->GetText() ); + LIB_ID fpId; + fpId.Parse( fpField->GetText(), LIB_ID::ID_SCH, true ); fpId.SetLibNickname( newfilename.GetName() ); fpField->SetText( fpId.Format() ); } diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 49e803dd8a..f1ee28eed6 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -85,7 +85,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowse { LIB_ID id; - if( id.Parse( symbol ) == -1 ) + if( id.Parse( symbol, LIB_ID::ID_SCH ) == -1 ) sel.LibId = id; sel.Unit = viewlibFrame->GetUnit(); diff --git a/eeschema/project_rescue.cpp b/eeschema/project_rescue.cpp index c4911d31c7..37fed7c70e 100644 --- a/eeschema/project_rescue.cpp +++ b/eeschema/project_rescue.cpp @@ -258,10 +258,15 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer, // Test whether there is a conflict or if the symbol can only be found in the cache // and the symbol name does not have any illegal characters. - if( ( ( cache_match && lib_match - && !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) ) - || (!cache_match && lib_match ) ) && !LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) ) - continue; + if( LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) == -1 ) + { + if( cache_match && lib_match && + !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) ) + continue; + + if( !cache_match && lib_match ) + continue; + } // Check if the symbol has already been rescued. wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH ); @@ -379,12 +384,14 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues( continue; // Test whether there is a conflict or if the symbol can only be found in the cache. - if( ( ( cache_match && lib_match - && !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) ) - || (!cache_match && lib_match ) ) - && !LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) ) + if( LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) == -1 ) { - continue; + if( cache_match && lib_match && + !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) ) + continue; + + if( !cache_match && lib_match ) + continue; } // Fix illegal LIB_ID name characters. diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 4e644c32ba..e76313f7c0 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -1428,7 +1428,7 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader ) // parsing the symbol name with LIB_ID::Parse() would break symbol library links // that contained '/' and ':' characters. if( m_version > 3 ) - libId.Parse( libName ); + libId.Parse( libName, LIB_ID::ID_SCH, true ); else libId.SetLibItemName( libName, false ); diff --git a/eeschema/selpart.cpp b/eeschema/selpart.cpp index b7038c3656..b8ba28948a 100644 --- a/eeschema/selpart.cpp +++ b/eeschema/selpart.cpp @@ -46,7 +46,7 @@ static void DisplayCmpDocAndKeywords( wxString& aSelection, void* aData ) LIB_ID id; - if( id.Parse( aSelection ) != -1 ) + if( id.Parse( aSelection, LIB_ID::ID_SCH ) != -1 ) { aSelection = _( "Invalid symbol library identifier!" ); return; diff --git a/include/lib_id.h b/include/lib_id.h index 308ff524c2..f7b04b4b3a 100644 --- a/include/lib_id.h +++ b/include/lib_id.h @@ -52,25 +52,15 @@ class LIB_ID { public: - LIB_ID() {} - - /** - * Takes \a aId string and parses it. - * - * A typical LIB_ID string consists of a library nickname followed by a library item name. - * e.g.: "smt:R_0805", or - * e.g.: "mylib:R_0805", or - * e.g.: "ttl:7400" - * - * @param aId is a string to be parsed into the LIB_ID object. - */ - LIB_ID( const UTF8& aId ); - - LIB_ID( const wxString& aId ); - ///> Types of library identifiers enum LIB_ID_TYPE { ID_SCH, ID_ALIAS, ID_PCB }; + LIB_ID() {} + + // NOTE: don't define any constructors which call Parse() on their arguments. We want it + // to be obvious to callers that parsing is involved (and that valid IDs are guaranteed in + // the presence of disallowed characters, malformed ids, etc.). + /** * This LIB_ID ctor is a special version which ignores the parsing due to symbol * names allowing '/' as a valid character. This was causing the symbol names to @@ -87,13 +77,19 @@ public: /** * Parse LIB_ID with the information from @a aId. * + * A typical LIB_ID string consists of a library nickname followed by a library item name. + * e.g.: "smt:R_0805", or + * e.g.: "mylib:R_0805", or + * e.g.: "ttl:7400" + * * @param aId is the string to populate the #LIB_ID object. + * @param aType indicates the LIB_ID type for type-specific parsing (such as allowed chars). + * @param aFix indicates invalid chars should be replaced with '_'. * * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into * aId at which an error was detected. */ - int Parse( const UTF8& aId ); - + int Parse( const UTF8& aId, LIB_ID_TYPE aType, bool aFix = false ); /** * Return the logical library name portion of a LIB_ID. @@ -209,9 +205,9 @@ public: * * @param aLibItemName is the #LIB_ID name to test for illegal characters. * @param aType is the library identifier type - * @return true if \a aLibItemName contain illegal characters otherwise false. + * @return offset of first illegal character otherwise -1. */ - static bool HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType ); + static int HasIllegalChars( const UTF8& aLibItemName, LIB_ID_TYPE aType ); /** * Replace illegal #LIB_ID item name characters with underscores '_'. diff --git a/pcbnew/dialogs/dialog_exchange_footprints.cpp b/pcbnew/dialogs/dialog_exchange_footprints.cpp index 4aee9e4108..c700f2c6d4 100644 --- a/pcbnew/dialogs/dialog_exchange_footprints.cpp +++ b/pcbnew/dialogs/dialog_exchange_footprints.cpp @@ -204,6 +204,8 @@ void DIALOG_EXCHANGE_FOOTPRINTS::setMatchMode( int aMatchMode ) bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule ) { + LIB_ID specifiedID; + switch( getMatchMode() ) { case ID_MATCH_FP_ALL: @@ -221,7 +223,8 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule ) else return aModule->GetValue() == m_specifiedValue->GetValue(); case ID_MATCH_FP_ID: - return aModule->GetFPID() == m_specifiedID->GetValue(); + specifiedID.Parse( m_specifiedID->GetValue(), LIB_ID::ID_PCB ); + return aModule->GetFPID() == specifiedID; } return false; // just to quiet compiler warnings.... } @@ -359,11 +362,13 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::changeCurrentFootprint() if( m_updateMode ) return change_1_Module( m_currentModule, m_currentModule->GetFPID(), true ); - wxString newFPID = m_newID->GetValue(); + LIB_ID newFPID; + wxString newFPIDStr = m_newID->GetValue(); - if( newFPID == wxEmptyString ) + if( newFPIDStr == wxEmptyString ) return false; + newFPID.Parse( newFPIDStr, LIB_ID::ID_PCB, true ); return change_1_Module( m_currentModule, newFPID, true ); } @@ -373,15 +378,20 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::changeSameFootprints() MODULE* Module; MODULE* PtBack; bool change = false; - wxString newFPID = m_newID->GetValue(); + LIB_ID newFPID; wxString value; int ShowErr = 3; // Post 3 error messages max. if( m_parent->GetBoard()->m_Modules == NULL ) return false; - if( !m_updateMode && newFPID == wxEmptyString ) - return false; + if( !m_updateMode ) + { + newFPID.Parse( m_newID->GetValue(), LIB_ID::ID_PCB ); + + if( !newFPID.IsValid() ) + return false; + } /* The change is done from the last module because * change_1_Module () modifies the last item in the list. diff --git a/pcbnew/dialogs/dialog_get_footprint.cpp b/pcbnew/dialogs/dialog_get_footprint.cpp index ddff9b0457..7edfa41a0d 100644 --- a/pcbnew/dialogs/dialog_get_footprint.cpp +++ b/pcbnew/dialogs/dialog_get_footprint.cpp @@ -52,7 +52,9 @@ DIALOG_GET_FOOTPRINT::DIALOG_GET_FOOTPRINT( PCB_BASE_FRAME* parent, bool aShowBr for( size_t ii = 0; ii < s_HistoryList.size(); ++ii ) { - LIB_ID fpid( s_HistoryList[ ii ] ); + LIB_ID fpid; + fpid.Parse( s_HistoryList[ ii ], LIB_ID::ID_PCB ); + if( m_frame->CheckFootprint( fpid ) ) m_historyList->Append( s_HistoryList[ ii ] ); } diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index e0600b5a24..602e49e021 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1371,7 +1371,9 @@ MODULE* EAGLE_PLUGIN::makeModule( wxXmlNode* aPackage, const wxString& aPkgName { std::unique_ptr m( new MODULE( m_board ) ); - m->SetFPID( LIB_ID( UTF8( aPkgName ) ) ); + LIB_ID fpID; + fpID.Parse( aPkgName, LIB_ID::ID_PCB, true ); + m->SetFPID( fpID ); // Get the first package item and iterate wxXmlNode* packageItem = aPackage->GetChildren(); diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index 156503f0aa..bbc4c80b04 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -552,23 +552,21 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary() if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) ) { - wxString msg = wxString::Format( - _( "Library \"%s\" is read only" ), - GetChars( nickname ) - ); - + wxString msg = wxString::Format( _( "Library \"%s\" is read only" ), nickname ); DisplayError( this, msg ); return false; } - wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, - wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() ); + LIB_ID fpid; + wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, wxEmptyString, + wxEmptyString, Prj().PcbFootprintLibs() ); - if( !fpid_txt ) + fpid.Parse( fpid_txt, LIB_ID::ID_PCB ); + + if( !fpid.IsValid() ) return false; - LIB_ID fpid( fpid_txt ); - wxString fpname = fpid.GetLibItemName(); + wxString fpname = fpid.GetLibItemName(); // Confirmation wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() ); @@ -673,7 +671,7 @@ public: { m_module = aModule; m_savedFPID = aModule->GetFPID(); - m_module->SetFPID( LIB_ID( m_savedFPID.GetLibItemName() ) ); + m_module->SetFPID( LIB_ID( wxEmptyString, m_savedFPID.GetLibItemName() ) ); } ~LIBRARY_NAME_CLEARER() { @@ -859,7 +857,7 @@ MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName ) module->SetLastEditTime(); // Update its name in lib - module->SetFPID( LIB_ID( moduleName ) ); + module->SetFPID( LIB_ID( wxEmptyString, moduleName ) ); wxPoint default_pos; BOARD_DESIGN_SETTINGS& settings = GetDesignSettings(); diff --git a/pcbnew/footprint_viewer_frame.cpp b/pcbnew/footprint_viewer_frame.cpp index 24727485b4..e13d86efa3 100644 --- a/pcbnew/footprint_viewer_frame.cpp +++ b/pcbnew/footprint_viewer_frame.cpp @@ -621,22 +621,16 @@ bool FOOTPRINT_VIEWER_FRAME::ShowModal( wxString* aFootprint, wxWindow* aResulta { if( aFootprint && !aFootprint->IsEmpty() ) { - try - { - LIB_ID fpid( *aFootprint ); + LIB_ID fpid; - if( fpid.IsValid() ) - { - setCurNickname( fpid.GetLibNickname() ); - setCurFootprintName( fpid.GetLibItemName() ); - ReCreateFootprintList(); - SelectAndViewFootprint( NEW_PART ); - } - } - catch( ... ) + fpid.Parse( *aFootprint, LIB_ID::ID_PCB, true ); + + if( fpid.IsValid() ) { - // LIB_ID's constructor throws on some invalid footprint IDs. It'd be nicer - // if it just set it to !IsValid(), but it is what it is. + setCurNickname( fpid.GetLibNickname() ); + setCurFootprintName( fpid.GetLibItemName() ); + ReCreateFootprintList(); + SelectAndViewFootprint( NEW_PART ); } } diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp index 1ddaab5ee8..d450895b71 100644 --- a/pcbnew/github/github_plugin.cpp +++ b/pcbnew/github/github_plugin.cpp @@ -232,7 +232,7 @@ MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath, // any name found in the pretty file; any name in the pretty file // must be ignored here. Also, the library nickname is unknown in // this context so clear it just in case. - ret->SetFPID( aFootprintName ); + ret->SetFPID( LIB_ID( wxEmptyString, aFootprintName ) ); return ret; } diff --git a/pcbnew/gpcb_plugin.cpp b/pcbnew/gpcb_plugin.cpp index f5b18c7ed0..f3d8dd4875 100644 --- a/pcbnew/gpcb_plugin.cpp +++ b/pcbnew/gpcb_plugin.cpp @@ -276,7 +276,7 @@ void GPCB_FPL_CACHE::Load() MODULE* footprint = parseMODULE( &reader ); // The footprint name is the file name without the extension. - footprint->SetFPID( LIB_ID( fn.GetName() ) ); + footprint->SetFPID( LIB_ID( wxEmptyString, fn.GetName() ) ); m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) ); } catch( const IO_ERROR& ioe ) diff --git a/pcbnew/kicad_netlist_reader.cpp b/pcbnew/kicad_netlist_reader.cpp index 018cef2cdc..c4fd3747d8 100644 --- a/pcbnew/kicad_netlist_reader.cpp +++ b/pcbnew/kicad_netlist_reader.cpp @@ -368,7 +368,7 @@ void KICAD_NETLIST_PARSER::parseComponent() } } - if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 ) + if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 ) { wxString error; error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 7ed587aa2d..40b9e62c65 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -299,7 +299,7 @@ void FP_CACHE::Load() // The footprint name is the file name without the extension. wxString fpName = fullPath.GetName(); - footprint->SetFPID( LIB_ID( fpName ) ); + footprint->SetFPID( LIB_ID( wxEmptyString, fpName ) ); m_modules.insert( fpName, new FP_CACHE_ITEM( footprint, fullPath ) ); m_cache_timestamp += fullPath.GetModificationTime().GetValue().GetValue(); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 2876f6bfc7..ab650c8037 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -441,7 +441,7 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend ) ReplaceIllegalFileNameChars( &fpName ); if( !fpName.empty() ) - fpid = LIB_ID( UTF8( fpName ) ); + fpid.Parse( fpName, LIB_ID::ID_PCB, true ); module->SetFPID( fpid ); @@ -3314,7 +3314,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader ) ReplaceIllegalFileNameChars( &footprintName ); // set the footprint name first thing, so exceptions can use name. - module->SetFPID( LIB_ID( UTF8( footprintName ) ) ); + module->SetFPID( LIB_ID( wxEmptyString, footprintName ) ); m_owner->loadMODULE( module.get() ); @@ -3369,7 +3369,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader ) { nameOK = true; - m->SetFPID( LIB_ID( UTF8( newName ) ) ); + m->SetFPID( LIB_ID( wxEmptyString, newName ) ); std::pair r = m_modules.insert( newName, m ); wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) ); diff --git a/pcbnew/load_select_footprint.cpp b/pcbnew/load_select_footprint.cpp index 3c6b07558e..56762af140 100644 --- a/pcbnew/load_select_footprint.cpp +++ b/pcbnew/load_select_footprint.cpp @@ -245,9 +245,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU LIB_ID fpid; - wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL, - wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ), - GetChars( moduleName ) ) ); + wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL, + wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) ); try { @@ -275,9 +274,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU } else { - wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL, - wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ), - GetChars( moduleName ) ) ); + wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL, + wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) ); try { diff --git a/pcbnew/microwave/microwave_inductor.cpp b/pcbnew/microwave/microwave_inductor.cpp index 90f399fec8..c589ef7520 100644 --- a/pcbnew/microwave/microwave_inductor.cpp +++ b/pcbnew/microwave/microwave_inductor.cpp @@ -345,7 +345,7 @@ MODULE* MWAVE::CreateMicrowaveInductor( INDUCTOR_PATTERN& inductorPattern, MODULE* module = aPcbFrame->CreateNewModule( msg ); aPcbFrame->AddModuleToBoard( module ); - module->SetFPID( LIB_ID( wxString( "mw_inductor" ) ) ); + module->SetFPID( LIB_ID( wxEmptyString, wxT( "mw_inductor" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( inductorPattern.m_End ); diff --git a/pcbnew/netlist_reader.cpp b/pcbnew/netlist_reader.cpp index 14fe4f83fe..212e4c9e8c 100644 --- a/pcbnew/netlist_reader.cpp +++ b/pcbnew/netlist_reader.cpp @@ -175,7 +175,7 @@ bool CMP_READER::Load( NETLIST* aNetlist ) { LIB_ID fpid; - if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 ) + if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 ) { wxString error; error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ), diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp index ec039b3b59..e0feddde4b 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp @@ -520,7 +520,9 @@ void PCB_MODULE::AddToBoard() module->SetTimeStamp( 0 ); module->SetLastEditTime( 0 ); - module->SetFPID( LIB_ID( m_compRef ) ); + LIB_ID fpID; + fpID.Parse( m_compRef, LIB_ID::ID_PCB, true ); + module->SetFPID( fpID ); module->SetAttributes( MOD_DEFAULT | MOD_CMS ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index bacf543e8f..d9ecfa8829 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1796,7 +1796,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments ) name = FromUTF8(); - if( !name.IsEmpty() && fpid.Parse( FromUTF8() ) >= 0 ) + if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 ) { wxString error; error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),