Use case insensitivity when loading Altium files

Altium is case insensitive, so our match for internal names should be also
This commit is contained in:
Zenn Geeraerts 2025-02-20 10:08:53 +01:00 committed by Seth Hillbrand
parent 7d8b385a72
commit d31eeb5c1b
7 changed files with 74 additions and 14 deletions

View File

@ -168,9 +168,9 @@
Thomas Gambier Thomas Gambier
Ashutosh Gangwar Ashutosh Gangwar
Alessandro Gatti Alessandro Gatti
Zenn Geeraerts
Alex Gellen Alex Gellen
Robert Antoni Buj Gelonch Robert Antoni Buj Gelonch
Robert Antoni Buj Genlonch
Hal Gentz Hal Gentz
Lucas Gerads Lucas Gerads
Davide Gerhard Davide Gerhard
@ -228,6 +228,7 @@
Mario Hros Mario Hros
Hubert Hu Hubert Hu
Josue Huaroto Josue Huaroto
Eli Hughes
Huibean Huibean
Matt Huszagh Matt Huszagh
José Ignacio José Ignacio
@ -621,7 +622,7 @@
欠陥電気 欠陥電気
木 王 木 王
郝弘毅 郝弘毅
Eli Hughes
See git repo on GitLab for contributors at See git repo on GitLab for contributors at
https://gitlab.com/kicad/code/kicad/-/graphs/master https://gitlab.com/kicad/code/kicad/-/graphs/master

View File

@ -4580,9 +4580,10 @@ std::vector<LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibComponent( const std::map<wxStri
} }
std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumLibFile ) CASE_INSENSITIVE_MAP<LIB_SYMBOL*>
SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumLibFile )
{ {
std::map<wxString,LIB_SYMBOL*> ret; CASE_INSENSITIVE_MAP<LIB_SYMBOL*> ret;
std::vector<int> fontSizes; std::vector<int> fontSizes;
struct SYMBOL_PIN_FRAC struct SYMBOL_PIN_FRAC
{ {
@ -4858,11 +4859,11 @@ void SCH_IO_ALTIUM::ensureLoadedLibrary( const wxString& aLibraryPath,
} }
} }
std::map<wxString, LIB_SYMBOL*>& cacheMapRef = m_libCache[aLibraryPath]; CASE_INSENSITIVE_MAP<LIB_SYMBOL*>& cacheMapRef = m_libCache[aLibraryPath];
for( auto& altiumSchFilePtr : compoundFiles ) for( auto& altiumSchFilePtr : compoundFiles )
{ {
std::map<wxString, LIB_SYMBOL*> parsed = ParseLibFile( *altiumSchFilePtr ); CASE_INSENSITIVE_MAP<LIB_SYMBOL*> parsed = ParseLibFile( *altiumSchFilePtr );
cacheMapRef.insert( parsed.begin(), parsed.end() ); cacheMapRef.insert( parsed.begin(), parsed.end() );
} }

View File

@ -32,6 +32,7 @@
#include <sch_io/sch_io_mgr.h> #include <sch_io/sch_io_mgr.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <case_insensitive_map.h>
#include "altium_parser_sch.h" #include "altium_parser_sch.h"
@ -70,6 +71,17 @@ struct HARNESS
HARNESS_PORT m_entry; HARNESS_PORT m_entry;
}; };
namespace DETAIL
{
struct CASE_INSENSITIVE_COMPARER final
{
bool operator()( const wxString& aLhs, const wxString& aRhs ) const noexcept
{
return aLhs.CompareTo( aRhs, wxString::caseCompare::ignoreCase );
}
};
} // namespace DETAIL
class SCH_IO_ALTIUM : public SCH_IO class SCH_IO_ALTIUM : public SCH_IO
{ {
public: public:
@ -199,7 +211,7 @@ private:
void ParseImplementation( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym ); void ParseImplementation( const std::map<wxString, wxString>& aProperties, std::vector<LIB_SYMBOL*>& aSymbol = nullsym );
void ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, std::vector<int>& aFontSizes ); void ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, std::vector<int>& aFontSizes );
std::map<wxString,LIB_SYMBOL*> ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); CASE_INSENSITIVE_MAP<LIB_SYMBOL*> ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
std::vector<LIB_SYMBOL*> ParseLibComponent( const std::map<wxString, wxString>& aProperties ); std::vector<LIB_SYMBOL*> ParseLibComponent( const std::map<wxString, wxString>& aProperties );
void doEnumerateSymbolLib( const wxString& aLibraryPath, const std::map<std::string, UTF8>* aProperties, void doEnumerateSymbolLib( const wxString& aLibraryPath, const std::map<std::string, UTF8>* aProperties,
@ -252,7 +264,7 @@ private:
static bool checkFileHeader( const wxString& aFileName ); static bool checkFileHeader( const wxString& aFileName );
std::map<wxString, long long> m_timestamps; std::map<wxString, long long> m_timestamps;
std::map<wxString, std::map<wxString, LIB_SYMBOL*>> m_libCache; std::map<wxString, CASE_INSENSITIVE_MAP<LIB_SYMBOL*>> m_libCache;
// List of available fonts with font name and font size in pt // List of available fonts with font name and font size in pt
std::vector<std::pair<wxString, int>> m_fonts; std::vector<std::pair<wxString, int>> m_fonts;

View File

@ -0,0 +1,45 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef CASE_INSENSITIVE_MAP_H
#define CASE_INSENSITIVE_MAP_H
#include <wx/string.h>
#include <map>
namespace DETAIL
{
struct CASE_INSENSITIVE_COMPARER final
{
bool operator()( const wxString& aLhs, const wxString& aRhs ) const noexcept
{
return aLhs.CmpNoCase( aRhs ) < 0;
}
};
} // namespace DETAIL
template <typename ValueType>
using CASE_INSENSITIVE_MAP = std::map<wxString, ValueType, DETAIL::CASE_INSENSITIVE_COMPARER>;
#endif

View File

@ -39,7 +39,7 @@ ALTIUM_PCB_COMPOUND_FILE::~ALTIUM_PCB_COMPOUND_FILE()
{ {
} }
std::map<wxString, wxString> ALTIUM_PCB_COMPOUND_FILE::ListLibFootprints() CASE_INSENSITIVE_MAP<wxString> ALTIUM_PCB_COMPOUND_FILE::ListLibFootprints()
{ {
if( m_libFootprintDirNameCache.empty() ) if( m_libFootprintDirNameCache.empty() )
cacheLibFootprintNames(); cacheLibFootprintNames();

View File

@ -27,6 +27,7 @@
#include <memory> #include <memory>
#include <altium_parser_pcb.h> #include <altium_parser_pcb.h>
#include <io/altium/altium_binary_parser.h> #include <io/altium/altium_binary_parser.h>
#include <case_insensitive_map.h>
class ALTIUM_PCB_COMPOUND_FILE : public ALTIUM_COMPOUND_FILE class ALTIUM_PCB_COMPOUND_FILE : public ALTIUM_COMPOUND_FILE
@ -38,7 +39,7 @@ public:
ALTIUM_PCB_COMPOUND_FILE( const void* aBuffer, size_t aLen ); ALTIUM_PCB_COMPOUND_FILE( const void* aBuffer, size_t aLen );
~ALTIUM_PCB_COMPOUND_FILE(); ~ALTIUM_PCB_COMPOUND_FILE();
std::map<wxString, wxString> ListLibFootprints(); CASE_INSENSITIVE_MAP<wxString> ListLibFootprints();
std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> FindLibFootprintDirName( const wxString& aFpUnicodeName ); std::tuple<wxString, const CFB::COMPOUND_FILE_ENTRY*> FindLibFootprintDirName( const wxString& aFpUnicodeName );
@ -49,9 +50,9 @@ private:
void cacheLibFootprintNames(); void cacheLibFootprintNames();
std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> m_libFootprintNameCache; CASE_INSENSITIVE_MAP<const CFB::COMPOUND_FILE_ENTRY*> m_libFootprintNameCache;
std::map<wxString, wxString> m_libFootprintDirNameCache; CASE_INSENSITIVE_MAP<wxString> m_libFootprintDirNameCache;
std::map<wxString, std::pair<AMODEL, std::vector<char>>> m_libModelsCache; CASE_INSENSITIVE_MAP<std::pair<AMODEL, std::vector<char>>> m_libModelsCache;
}; };
#endif // ALTIUM_PCB_COMPOUND_FILE_H #endif // ALTIUM_PCB_COMPOUND_FILE_H

View File

@ -230,7 +230,7 @@ void PCB_IO_ALTIUM_DESIGNER::FootprintEnumerate( wxArrayString& aFootprintNames
for( auto& altiumLibFile : it->second ) for( auto& altiumLibFile : it->second )
{ {
// Map code-page-dependent names to unicode names // Map code-page-dependent names to unicode names
std::map<wxString, wxString> patternMap = altiumLibFile->ListLibFootprints(); CASE_INSENSITIVE_MAP<wxString> patternMap = altiumLibFile->ListLibFootprints();
const std::vector<std::string> streamName = { "Library", "Data" }; const std::vector<std::string> streamName = { "Library", "Data" };
const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName ); const CFB::COMPOUND_FILE_ENTRY* libraryData = altiumLibFile->FindStream( streamName );