Handle separate parsing rules for ID_SCH and ID_PCB.

This removes the existing constructors so that all parsing must
be explicit and callers are made aware that they need to think
about illegal characters, malformed ids, etc.

Fixes: lp:1783474
* https://bugs.launchpad.net/kicad/+bug/1783474
This commit is contained in:
Jeff Young 2018-07-26 15:38:30 +01:00
parent 9ec6efbf13
commit cb61525394
34 changed files with 167 additions and 182 deletions

View File

@ -56,17 +56,16 @@ FOOTPRINT_INFO* FOOTPRINT_LIST::GetModuleInfo( const wxString& aFootprintName )
if( aFootprintName.IsEmpty() ) if( aFootprintName.IsEmpty() )
return NULL; 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 ) 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() ) if( libNickname == fp->GetNickname() && footprintName == fp->GetFootprintName() )
return &*fp; return &*fp;
} }

View File

@ -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(); clear();
@ -127,7 +127,7 @@ int LIB_ID::Parse( const UTF8& aId )
const char* rev = EndsWithRev( buffer, buffer+aId.length(), '/' ); const char* rev = EndsWithRev( buffer, buffer+aId.length(), '/' );
size_t revNdx; size_t revNdx;
size_t partNdx; size_t partNdx;
int offset; int offset = -1;
//=====<revision>========================================= //=====<revision>=========================================
// in a LIB_ID like discret:R3/rev4 // 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 ) ); offset = SetLibNickname( aId.substr( 0, partNdx ) );
if( offset > -1 ) if( offset > -1 )
{
return offset; return offset;
}
++partNdx; // skip ':' ++partNdx; // skip ':'
} }
@ -165,48 +163,24 @@ int LIB_ID::Parse( const UTF8& aId )
if( partNdx >= revNdx ) if( partNdx >= revNdx )
return partNdx; // Error: no library item name. return partNdx; // Error: no library item name.
UTF8 fpname = aId.substr( partNdx, revNdx-partNdx );
// Be sure the item name is valid. // Be sure the item name is valid.
// Some chars can be found in legacy files converted files from other EDA tools. // Some chars can be found in legacy files converted files from other EDA tools.
std::string fpname = aId.substr( partNdx, revNdx-partNdx ); if( aFix )
ReplaceIllegalFileNameChars( &fpname, '_' ); fpname = FixIllegalChars( fpname, aType, false );
SetLibItemName( UTF8( fpname ) ); else
offset = HasIllegalChars( fpname, aType );
if( offset > -1 )
return offset;
SetLibItemName( fpname );
return -1; 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, LIB_ID::LIB_ID( const wxString& aLibName, const wxString& aLibItemName,
const wxString& aRevision ) : const wxString& aRevision ) :
nickname( aLibName ), 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 ) for( auto ch : aLibItemName )
{ {
if( !isLegalChar( ch, aType ) ) 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 LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType )
{ {
bool const colon_allowed = ( aType == ID_ALIAS ); 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 < ' ' ) if( aUniChar < ' ' )
return false; return false;
@ -400,7 +379,10 @@ bool LIB_ID::isLegalChar( unsigned aUniChar, LIB_ID_TYPE aType )
{ {
case '/': case '/':
case '\\': case '\\':
return false; case '<':
case '>':
case '"':
return illegal_filename_chars_allowed;
case ':': case ':':
return colon_allowed; return colon_allowed;

View File

@ -429,7 +429,7 @@ MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
{ {
LIB_ID fpid; 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." ), DisplayInfoMessage( this, wxString::Format( _( "Footprint ID \"%s\" is not valid." ),
GetChars( aFootprintName ) ) ); GetChars( aFootprintName ) ) );

View File

@ -99,9 +99,8 @@ void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName, int aIndex )
if( !aFootprintName.IsEmpty() ) if( !aFootprintName.IsEmpty() )
{ {
wxCHECK_RET( fpid.Parse( aFootprintName ) < 0, wxCHECK_RET( fpid.Parse( aFootprintName, LIB_ID::ID_PCB ) < 0,
wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), wxString::Format( _( "\"%s\" is not a valid LIB_ID." ), aFootprintName ) );
GetChars( aFootprintName ) ) );
} }
component->SetFPID( fpid ); component->SetFPID( fpid );

View File

@ -287,8 +287,7 @@ void LIB_PART::SetName( const wxString& aName )
else else
m_aliases[0]->SetName( aName ); m_aliases[0]->SetName( aName );
// LIB_ALIAS validates the name, reuse it instead of validating the name again wxString validatedName = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
wxString validatedName( m_aliases[0]->GetName() );
m_libId.SetLibItemName( validatedName, false ); m_libId.SetLibItemName( validatedName, false );
LIB_FIELD& valueField = GetValueField(); LIB_FIELD& valueField = GetValueField();

View File

@ -57,15 +57,15 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const
bool aShowFootprints ) bool aShowFootprints )
: DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, wxDefaultSize, : DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
m_hsplitter( nullptr ),
m_vsplitter( nullptr ),
m_fp_sel_ctrl( nullptr ), m_fp_sel_ctrl( nullptr ),
m_fp_view_ctrl( nullptr ), m_fp_view_ctrl( nullptr ),
m_parent( aParent ), m_parent( aParent ),
m_deMorganConvert( aDeMorganConvert >= 0 ? aDeMorganConvert : 0 ), m_deMorganConvert( aDeMorganConvert >= 0 ? aDeMorganConvert : 0 ),
m_allow_field_edits( aAllowFieldEdits ), m_allow_field_edits( aAllowFieldEdits ),
m_show_footprints( aShowFootprints ), m_show_footprints( aShowFootprints ),
m_external_browser_requested( false ), m_external_browser_requested( false )
m_hsplitter( nullptr ),
m_vsplitter( nullptr )
{ {
auto sizer = new wxBoxSizer( wxVERTICAL ); auto sizer = new wxBoxSizer( wxVERTICAL );
wxHtmlWindow* details = nullptr; wxHtmlWindow* details = nullptr;
@ -325,7 +325,7 @@ void DIALOG_CHOOSE_COMPONENT::ShowFootprint( wxString const& aName )
{ {
LIB_ID lib_id; 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->ClearStatus();
m_fp_view_ctrl->CacheFootprint( lib_id ); m_fp_view_ctrl->CacheFootprint( lib_id );

View File

@ -301,7 +301,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnBrowseLibrary( wxCommandEvent& event
SCH_BASE_FRAME::HISTORY_LIST dummy; SCH_BASE_FRAME::HISTORY_LIST dummy;
LIB_ID id; LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue() ); id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
auto sel = GetParent()->SelectComponentFromLibrary( nullptr, dummy, true, 0, 0, false, &id ); auto sel = GetParent()->SelectComponentFromLibrary( nullptr, dummy, true, 0, 0, false, &id );
@ -349,7 +349,6 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnEditSpiceModel( wxCommandEvent& event
bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate() bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
{ {
wxString msg; wxString msg;
wxString tmp;
LIB_ID id; LIB_ID id;
// Commit any pending in-place edits and close the editor // Commit any pending in-place edits and close the editor
@ -365,9 +364,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
return false; return false;
} }
tmp = m_libraryNameTextCtrl->GetValue(); id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH );
tmp.Replace( wxT( " " ), wxT( "_" ) );
id.Parse( tmp );
if( !id.IsValid() ) if( !id.IsValid() )
{ {
@ -438,7 +435,8 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event
STATUS_FLAGS flags = m_cmp->GetFlags(); STATUS_FLAGS flags = m_cmp->GetFlags();
// Library symbol identifier // Library symbol identifier
LIB_ID id( m_libraryNameTextCtrl->GetValue() ); LIB_ID id;
id.Parse( m_libraryNameTextCtrl->GetValue(), LIB_ID::ID_SCH, true );
m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() ); m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() );
// For symbols with multiple shapes (De Morgan representation) Set the selected shape: // For symbols with multiple shapes (De Morgan representation) Set the selected shape:

View File

@ -560,7 +560,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::validateLibIds()
// a new lib id is found. validate this new value // a new lib id is found. validate this new value
LIB_ID id; LIB_ID id;
id.Parse( new_libid ); id.Parse( new_libid, LIB_ID::ID_SCH );
if( !id.IsValid() ) if( !id.IsValid() )
{ {
@ -629,7 +629,8 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event )
wxString orphanLibid = m_grid->GetCellValue( m_OrphansRowIndexes[ii], COL_CURR_LIBID ); 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 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(); wxString symbName = curr_libid.GetLibItemName();
// number of full LIB_ID candidates (because we search for a symbol name // 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 // inside all avaiable libraries, perhaps the same symbol name can be found
@ -637,7 +638,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::onClickOrphansButton( wxCommandEvent& event )
int libIdCandidateCount = 0; int libIdCandidateCount = 0;
candidateSymbNames.Clear(); candidateSymbNames.Clear();
// now try to fin a candidate // now try to find a candidate
for( auto &lib : libs ) for( auto &lib : libs )
{ {
aliasNames.Clear(); aliasNames.Clear();
@ -754,7 +755,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::TransferDataFromWindow()
// a new lib id is found and was already validated. // a new lib id is found and was already validated.
// set this new value // set this new value
LIB_ID id; LIB_ID id;
id.Parse( new_libid ); id.Parse( new_libid, LIB_ID::ID_SCH, true );
for( CMP_CANDIDATE& cmp : m_components ) for( CMP_CANDIDATE& cmp : m_components )
{ {
@ -791,7 +792,7 @@ void DIALOG_EDIT_COMPONENTS_LIBID::revertChanges()
continue; continue;
LIB_ID id; LIB_ID id;
id.Parse( cmp.m_InitialLibId ); id.Parse( cmp.m_InitialLibId, LIB_ID::ID_SCH, true );
if( cmp.m_Component->GetLibId() != id ) if( cmp.m_Component->GetLibId() != id )
{ {

View File

@ -96,33 +96,32 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescu
dc.SetFont( font ); dc.SetFont( font );
int padding = 30;
int width = dc.GetTextExtent( header ).GetWidth(); int width = dc.GetTextExtent( header ).GetWidth();
m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width, m_ListOfConflicts->AppendToggleColumn( header, wxDATAVIEW_CELL_ACTIVATABLE, width,
wxALIGN_CENTER ); wxALIGN_CENTER );
header = _( "Symbol Name" ); header = _( "Symbol Name" );
width = dc.GetTextExtent( header ).GetWidth() + padding; width = dc.GetTextExtent( header ).GetWidth() * 2;
m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width ); m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Action Taken" ); header = _( "Action Taken" );
width = dc.GetTextExtent( header ).GetWidth() + padding; width = dc.GetTextExtent( header ).GetWidth() * 10;
m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width ); m_ListOfConflicts->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Reference" ); header = _( "Reference" );
width = dc.GetTextExtent( header ).GetWidth() + padding; width = dc.GetTextExtent( header ).GetWidth() * 2;
m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width ); m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
header = _( "Value" ); header = _( "Value" );
width = dc.GetTextExtent( header ).GetWidth() + padding; width = dc.GetTextExtent( header ).GetWidth() * 10;
m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width ); m_ListOfInstances->AppendTextColumn( header, wxDATAVIEW_CELL_INERT, width );
m_componentViewOld->SetLayoutDirection( wxLayout_LeftToRight ); m_componentViewOld->SetLayoutDirection( wxLayout_LeftToRight );
m_componentViewNew->SetLayoutDirection( wxLayout_LeftToRight ); m_componentViewNew->SetLayoutDirection( wxLayout_LeftToRight );
Layout(); Layout();
SetSizeInDU( 280, 240 ); SetSizeInDU( 480, 240 );
// Make sure the HTML window is large enough. Some fun size juggling and // Make sure the HTML window is large enough. Some fun size juggling and
// fudge factors here but it does seem to work pretty reliably. // fudge factors here but it does seem to work pretty reliably.
@ -133,7 +132,7 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescu
m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height ); m_htmlPrompt->SetSizeHints( 2 * prompt_size.x / 3, approx_info_height );
Layout(); Layout();
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
SetSizeInDU( 280, 240 ); SetSizeInDU( 480, 240 );
Center(); Center();
} }

View File

@ -844,7 +844,8 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
if( !fpField->GetText().IsEmpty() ) 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() ); fpId.SetLibNickname( newfilename.GetName() );
fpField->SetText( fpId.Format() ); fpField->SetText( fpId.Format() );
} }

View File

@ -85,7 +85,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowse
{ {
LIB_ID id; LIB_ID id;
if( id.Parse( symbol ) == -1 ) if( id.Parse( symbol, LIB_ID::ID_SCH ) == -1 )
sel.LibId = id; sel.LibId = id;
sel.Unit = viewlibFrame->GetUnit(); sel.Unit = viewlibFrame->GetUnit();

View File

@ -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 // 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. // and the symbol name does not have any illegal characters.
if( ( ( cache_match && lib_match if( LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) == -1 )
&& !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) ) {
|| (!cache_match && lib_match ) ) && !LIB_ID::HasIllegalChars( part_name, LIB_ID::ID_SCH ) ) if( cache_match && lib_match &&
continue; !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. // Check if the symbol has already been rescued.
wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH ); wxString new_name = LIB_ID::FixIllegalChars( part_name, LIB_ID::ID_SCH );
@ -379,12 +384,14 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
continue; continue;
// Test whether there is a conflict or if the symbol can only be found in the cache. // Test whether there is a conflict or if the symbol can only be found in the cache.
if( ( ( cache_match && lib_match if( LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) == -1 )
&& !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
|| (!cache_match && lib_match ) )
&& !LIB_ID::HasIllegalChars( part_id.GetLibItemName(), LIB_ID::ID_SCH ) )
{ {
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. // Fix illegal LIB_ID name characters.

View File

@ -1431,7 +1431,7 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
// parsing the symbol name with LIB_ID::Parse() would break symbol library links // parsing the symbol name with LIB_ID::Parse() would break symbol library links
// that contained '/' and ':' characters. // that contained '/' and ':' characters.
if( m_version > 3 ) if( m_version > 3 )
libId.Parse( libName ); libId.Parse( libName, LIB_ID::ID_SCH, true );
else else
libId.SetLibItemName( libName, false ); libId.SetLibItemName( libName, false );

View File

@ -46,7 +46,7 @@ static void DisplayCmpDocAndKeywords( wxString& aSelection, void* aData )
LIB_ID id; LIB_ID id;
if( id.Parse( aSelection ) != -1 ) if( id.Parse( aSelection, LIB_ID::ID_SCH ) != -1 )
{ {
aSelection = _( "Invalid symbol library identifier!" ); aSelection = _( "Invalid symbol library identifier!" );
return; return;

View File

@ -52,25 +52,15 @@ class LIB_ID
{ {
public: 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 ///> Types of library identifiers
enum LIB_ID_TYPE { ID_SCH, ID_ALIAS, ID_PCB }; 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 * 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 * 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. * 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 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 * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into
* aId at which an error was detected. * 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. * 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 aLibItemName is the #LIB_ID name to test for illegal characters.
* @param aType is the library identifier type * @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 '_'. * Replace illegal #LIB_ID item name characters with underscores '_'.

View File

@ -36,13 +36,13 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow
m_itemsGrid->SetMargins( 0, 0 ); m_itemsGrid->SetMargins( 0, 0 );
// Columns // Columns
m_itemsGrid->SetColSize( 0, 120 ); m_itemsGrid->SetColSize( 0, 116 );
m_itemsGrid->SetColSize( 1, 48 ); m_itemsGrid->SetColSize( 1, 53 );
m_itemsGrid->SetColSize( 2, 90 ); m_itemsGrid->SetColSize( 2, 90 );
m_itemsGrid->SetColSize( 3, 90 ); m_itemsGrid->SetColSize( 3, 90 );
m_itemsGrid->SetColSize( 4, 90 ); m_itemsGrid->SetColSize( 4, 90 );
m_itemsGrid->SetColSize( 5, 48 ); m_itemsGrid->SetColSize( 5, 53 );
m_itemsGrid->SetColSize( 6, 112 ); m_itemsGrid->SetColSize( 6, 106 );
m_itemsGrid->SetColSize( 7, 90 ); m_itemsGrid->SetColSize( 7, 90 );
m_itemsGrid->SetColSize( 8, 90 ); m_itemsGrid->SetColSize( 8, 90 );
m_itemsGrid->SetColSize( 9, 90 ); m_itemsGrid->SetColSize( 9, 90 );
@ -424,14 +424,14 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow
m_modelsGrid->SetMargins( 0, 0 ); m_modelsGrid->SetMargins( 0, 0 );
// Columns // Columns
m_modelsGrid->SetColSize( 0, 662 ); m_modelsGrid->SetColSize( 0, 650 );
m_modelsGrid->SetColSize( 1, 53 ); m_modelsGrid->SetColSize( 1, 65 );
m_modelsGrid->EnableDragColMove( false ); m_modelsGrid->EnableDragColMove( false );
m_modelsGrid->EnableDragColSize( false ); m_modelsGrid->EnableDragColSize( false );
m_modelsGrid->SetColLabelSize( 22 ); m_modelsGrid->SetColLabelSize( 22 );
m_modelsGrid->SetColLabelValue( 0, _("3D Model(s)") ); m_modelsGrid->SetColLabelValue( 0, _("3D Model(s)") );
m_modelsGrid->SetColLabelValue( 1, _("Preview") ); m_modelsGrid->SetColLabelValue( 1, _("Preview") );
m_modelsGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); m_modelsGrid->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows // Rows
m_modelsGrid->EnableDragRowSize( false ); m_modelsGrid->EnableDragRowSize( false );

View File

@ -303,7 +303,7 @@
<property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Keep Upright&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property> <property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Keep Upright&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property> <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">11</property> <property name="cols">11</property>
<property name="column_sizes">120,48,90,90,90,48,112,90,90,90,90</property> <property name="column_sizes">116,53,90,90,90,53,106,90,90,90,90</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
<property name="default_pane">0</property> <property name="default_pane">0</property>
@ -4589,12 +4589,12 @@
<property name="cell_vert_alignment">wxALIGN_TOP</property> <property name="cell_vert_alignment">wxALIGN_TOP</property>
<property name="center_pane">0</property> <property name="center_pane">0</property>
<property name="close_button">1</property> <property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_LEFT</property> <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
<property name="col_label_size">22</property> <property name="col_label_size">22</property>
<property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property> <property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property> <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">2</property> <property name="cols">2</property>
<property name="column_sizes">662,53</property> <property name="column_sizes">650,65</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
<property name="default_pane">0</property> <property name="default_pane">0</property>

View File

@ -36,13 +36,13 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
m_itemsGrid->SetMargins( 0, 0 ); m_itemsGrid->SetMargins( 0, 0 );
// Columns // Columns
m_itemsGrid->SetColSize( 0, 120 ); m_itemsGrid->SetColSize( 0, 116 );
m_itemsGrid->SetColSize( 1, 48 ); m_itemsGrid->SetColSize( 1, 53 );
m_itemsGrid->SetColSize( 2, 96 ); m_itemsGrid->SetColSize( 2, 96 );
m_itemsGrid->SetColSize( 3, 96 ); m_itemsGrid->SetColSize( 3, 96 );
m_itemsGrid->SetColSize( 4, 96 ); m_itemsGrid->SetColSize( 4, 96 );
m_itemsGrid->SetColSize( 5, 48 ); m_itemsGrid->SetColSize( 5, 53 );
m_itemsGrid->SetColSize( 6, 112 ); m_itemsGrid->SetColSize( 6, 106 );
m_itemsGrid->SetColSize( 7, 80 ); m_itemsGrid->SetColSize( 7, 80 );
m_itemsGrid->SetColSize( 8, 48 ); m_itemsGrid->SetColSize( 8, 48 );
m_itemsGrid->SetColSize( 9, 96 ); m_itemsGrid->SetColSize( 9, 96 );
@ -332,8 +332,8 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
m_modelsGrid->SetMargins( 0, 0 ); m_modelsGrid->SetMargins( 0, 0 );
// Columns // Columns
m_modelsGrid->SetColSize( 0, 662 ); m_modelsGrid->SetColSize( 0, 650 );
m_modelsGrid->SetColSize( 1, 53 ); m_modelsGrid->SetColSize( 1, 65 );
m_modelsGrid->EnableDragColMove( false ); m_modelsGrid->EnableDragColMove( false );
m_modelsGrid->EnableDragColSize( false ); m_modelsGrid->EnableDragColSize( false );
m_modelsGrid->SetColLabelSize( 22 ); m_modelsGrid->SetColLabelSize( 22 );

View File

@ -302,7 +302,7 @@
<property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Unconstrained&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property> <property name="col_label_values">&quot;Text Items&quot; &quot;Show&quot; &quot;Width&quot; &quot;Height&quot; &quot;Thickness&quot; &quot;Italic&quot; &quot;Layer&quot; &quot;Orientation&quot; &quot;Unconstrained&quot; &quot;X Offset&quot; &quot;Y Offset&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property> <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">11</property> <property name="cols">11</property>
<property name="column_sizes">120,48,96,96,96,48,112,80,48,96,96</property> <property name="column_sizes">116,53,96,96,96,53,106,80,48,96,96</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
<property name="default_pane">0</property> <property name="default_pane">0</property>
@ -3734,7 +3734,7 @@
<property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property> <property name="col_label_values">&quot;3D Model(s)&quot; &quot;Preview&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTRE</property> <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
<property name="cols">2</property> <property name="cols">2</property>
<property name="column_sizes">662,53</property> <property name="column_sizes">650,65</property>
<property name="context_help"></property> <property name="context_help"></property>
<property name="context_menu">1</property> <property name="context_menu">1</property>
<property name="default_pane">0</property> <property name="default_pane">0</property>

View File

@ -187,6 +187,8 @@ void DIALOG_EXCHANGE_FOOTPRINTS::setMatchMode( int aMatchMode )
bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule ) bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule )
{ {
LIB_ID specifiedID;
switch( getMatchMode() ) switch( getMatchMode() )
{ {
case ID_MATCH_FP_ALL: case ID_MATCH_FP_ALL:
@ -203,7 +205,8 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::isMatch( MODULE* aModule )
else else
return aModule->GetValue() == m_specifiedValue->GetValue(); return aModule->GetValue() == m_specifiedValue->GetValue();
case ID_MATCH_FP_ID: 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.... return false; // just to quiet compiler warnings....
} }
@ -325,7 +328,7 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::processCurrentModule()
if( newFPIDStr.IsEmpty() ) if( newFPIDStr.IsEmpty() )
return false; return false;
newFPID = LIB_ID( newFPIDStr ); newFPID.Parse( newFPIDStr, LIB_ID::ID_PCB, true );
} }
return processModule( m_currentModule, newFPID ); return processModule( m_currentModule, newFPID );
@ -337,14 +340,19 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::processMatchingModules()
MODULE* Module; MODULE* Module;
MODULE* PtBack; MODULE* PtBack;
bool change = false; bool change = false;
wxString newFPID = m_newID->GetValue(); LIB_ID newFPID;
wxString value; wxString value;
if( !m_parent->GetBoard()->m_Modules ) if( !m_parent->GetBoard()->m_Modules )
return false; return false;
if( !m_updateMode && newFPID == wxEmptyString ) if( !m_updateMode )
return false; {
newFPID.Parse( m_newID->GetValue(), LIB_ID::ID_PCB );
if( !newFPID.IsValid() )
return false;
}
/* The change is done from the last module because processModule() modifies the last item /* The change is done from the last module because processModule() modifies the last item
* in the list. * in the list.

View File

@ -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 ) 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 ) ) if( m_frame->CheckFootprint( fpid ) )
m_historyList->Append( s_HistoryList[ ii ] ); m_historyList->Append( s_HistoryList[ ii ] );
} }

View File

@ -1346,7 +1346,9 @@ MODULE* EAGLE_PLUGIN::makeModule( wxXmlNode* aPackage, const wxString& aPkgName
{ {
std::unique_ptr<MODULE> m( new MODULE( m_board ) ); std::unique_ptr<MODULE> 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 // Get the first package item and iterate
wxXmlNode* packageItem = aPackage->GetChildren(); wxXmlNode* packageItem = aPackage->GetChildren();

View File

@ -550,23 +550,21 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) ) if( !Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ) )
{ {
wxString msg = wxString::Format( wxString msg = wxString::Format( _( "Library \"%s\" is read only" ), nickname );
_( "Library \"%s\" is read only" ),
GetChars( nickname )
);
DisplayError( this, msg ); DisplayError( this, msg );
return false; return false;
} }
wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname, LIB_ID fpid;
wxEmptyString, wxEmptyString, Prj().PcbFootprintLibs() ); 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; return false;
LIB_ID fpid( fpid_txt ); wxString fpname = fpid.GetLibItemName();
wxString fpname = fpid.GetLibItemName();
// Confirmation // Confirmation
wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() ); wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
@ -671,7 +669,7 @@ public:
{ {
m_module = aModule; m_module = aModule;
m_savedFPID = aModule->GetFPID(); m_savedFPID = aModule->GetFPID();
m_module->SetFPID( LIB_ID( m_savedFPID.GetLibItemName() ) ); m_module->SetFPID( LIB_ID( wxEmptyString, m_savedFPID.GetLibItemName() ) );
} }
~LIBRARY_NAME_CLEARER() ~LIBRARY_NAME_CLEARER()
{ {
@ -855,7 +853,7 @@ MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName )
module->SetLastEditTime(); module->SetLastEditTime();
// Update its name in lib // Update its name in lib
module->SetFPID( LIB_ID( moduleName ) ); module->SetFPID( LIB_ID( wxEmptyString, moduleName ) );
wxPoint default_pos; wxPoint default_pos;
BOARD_DESIGN_SETTINGS& settings = GetDesignSettings(); BOARD_DESIGN_SETTINGS& settings = GetDesignSettings();

View File

@ -621,22 +621,16 @@ bool FOOTPRINT_VIEWER_FRAME::ShowModal( wxString* aFootprint, wxWindow* aResulta
{ {
if( aFootprint && !aFootprint->IsEmpty() ) if( aFootprint && !aFootprint->IsEmpty() )
{ {
try LIB_ID fpid;
{
LIB_ID fpid( *aFootprint );
if( fpid.IsValid() ) fpid.Parse( *aFootprint, LIB_ID::ID_PCB, true );
{
setCurNickname( fpid.GetLibNickname() ); if( fpid.IsValid() )
setCurFootprintName( fpid.GetLibItemName() );
ReCreateFootprintList();
SelectAndViewFootprint( NEW_PART );
}
}
catch( ... )
{ {
// LIB_ID's constructor throws on some invalid footprint IDs. It'd be nicer setCurNickname( fpid.GetLibNickname() );
// if it just set it to !IsValid(), but it is what it is. setCurFootprintName( fpid.GetLibItemName() );
ReCreateFootprintList();
SelectAndViewFootprint( NEW_PART );
} }
} }

View File

@ -232,7 +232,7 @@ MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
// any name found in the pretty file; any name in the pretty file // any name found in the pretty file; any name in the pretty file
// must be ignored here. Also, the library nickname is unknown in // must be ignored here. Also, the library nickname is unknown in
// this context so clear it just in case. // this context so clear it just in case.
ret->SetFPID( aFootprintName ); ret->SetFPID( LIB_ID( wxEmptyString, aFootprintName ) );
return ret; return ret;
} }

View File

@ -276,7 +276,7 @@ void GPCB_FPL_CACHE::Load()
MODULE* footprint = parseMODULE( &reader ); MODULE* footprint = parseMODULE( &reader );
// The footprint name is the file name without the extension. // 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() ) ); m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) );
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )

View File

@ -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; wxString error;
error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),

View File

@ -299,7 +299,7 @@ void FP_CACHE::Load()
// The footprint name is the file name without the extension. // The footprint name is the file name without the extension.
wxString fpName = fullPath.GetName(); 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_modules.insert( fpName, new FP_CACHE_ITEM( footprint, fullPath ) );
m_cache_timestamp += fullPath.GetModificationTime().GetValue().GetValue(); m_cache_timestamp += fullPath.GetModificationTime().GetValue().GetValue();

View File

@ -441,7 +441,7 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )
ReplaceIllegalFileNameChars( &fpName ); ReplaceIllegalFileNameChars( &fpName );
if( !fpName.empty() ) if( !fpName.empty() )
fpid = LIB_ID( UTF8( fpName ) ); fpid.Parse( fpName, LIB_ID::ID_PCB, true );
module->SetFPID( fpid ); module->SetFPID( fpid );
@ -3317,7 +3317,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader )
ReplaceIllegalFileNameChars( &footprintName ); ReplaceIllegalFileNameChars( &footprintName );
// set the footprint name first thing, so exceptions can use name. // 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() ); m_owner->loadMODULE( module.get() );
@ -3372,7 +3372,7 @@ void LP_CACHE::LoadModules( LINE_READER* aReader )
{ {
nameOK = true; nameOK = true;
m->SetFPID( LIB_ID( UTF8( newName ) ) ); m->SetFPID( LIB_ID( wxEmptyString, newName ) );
std::pair<MODULE_ITER, bool> r = m_modules.insert( newName, m ); std::pair<MODULE_ITER, bool> r = m_modules.insert( newName, m );
wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) ); wxASSERT_MSG( r.second, wxT( "error doing cache insert using guaranteed unique name" ) );

View File

@ -245,9 +245,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU
LIB_ID fpid; LIB_ID fpid;
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL, wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ), wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) );
GetChars( moduleName ) ) );
try try
{ {
@ -275,9 +274,8 @@ MODULE* PCB_BASE_FRAME::LoadModuleFromLibrary( const wxString& aLibrary, bool aU
} }
else else
{ {
wxCHECK_MSG( fpid.Parse( moduleName ) < 0, NULL, wxCHECK_MSG( fpid.Parse( moduleName, LIB_ID::ID_PCB ) < 0, NULL,
wxString::Format( wxT( "Could not parse LIB_ID string \"%s\"." ), wxString::Format( wxT( "Could not parse LIB_ID \"%s\"." ), moduleName ) );
GetChars( moduleName ) ) );
try try
{ {

View File

@ -345,7 +345,7 @@ MODULE* MWAVE::CreateMicrowaveInductor( INDUCTOR_PATTERN& inductorPattern,
MODULE* module = aPcbFrame->CreateNewModule( msg ); MODULE* module = aPcbFrame->CreateNewModule( msg );
aPcbFrame->AddModuleToBoard( module ); 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->SetAttributes( MOD_VIRTUAL | MOD_CMS );
module->ClearFlags(); module->ClearFlags();
module->SetPosition( inductorPattern.m_End ); module->SetPosition( inductorPattern.m_End );

View File

@ -175,7 +175,7 @@ bool CMP_READER::Load( NETLIST* aNetlist )
{ {
LIB_ID fpid; LIB_ID fpid;
if( !footprint.IsEmpty() && fpid.Parse( footprint ) >= 0 ) if( !footprint.IsEmpty() && fpid.Parse( footprint, LIB_ID::ID_PCB, true ) >= 0 )
{ {
wxString error; wxString error;
error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ), error.Printf( _( "invalid footprint ID in\nfile: \"%s\"\nline: %d" ),

View File

@ -520,7 +520,9 @@ void PCB_MODULE::AddToBoard()
module->SetTimeStamp( 0 ); module->SetTimeStamp( 0 );
module->SetLastEditTime( 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 ); module->SetAttributes( MOD_DEFAULT | MOD_CMS );

View File

@ -1808,7 +1808,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
name = FromUTF8(); name = FromUTF8();
if( !name.IsEmpty() && fpid.Parse( FromUTF8() ) >= 0 ) if( !name.IsEmpty() && fpid.Parse( name, LIB_ID::ID_PCB, true ) >= 0 )
{ {
wxString error; wxString error;
error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), error.Printf( _( "Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),