KiCad PCB EDA Suite
Loading...
Searching...
No Matches
lib_id.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2010-2020 KiCad Developers, see change_log.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <cstring>
27#include <memory>
28#include <wx/translation.h>
29
30#include <ki_exception.h>
31#include <macros.h> // TO_UTF8()
32#include <lib_id.h>
33
34
35static int checkLibNickname( const UTF8& aField )
36{
37 // std::string::npos is largest positive number, casting to int makes it -1.
38 // Returning that means success.
39 return int( aField.find_first_of( ":" ) );
40}
41
42
44{
48}
49
50
51int LIB_ID::Parse( const UTF8& aId, bool aFix )
52{
53 clear();
54
55 size_t partNdx;
56 int offset = -1;
57
58 //=====<library nickname>=============================
59 if( ( partNdx = aId.find( ':' ) ) != aId.npos )
60 {
61 offset = SetLibNickname( aId.substr( 0, partNdx ) );
62
63 if( offset > -1 )
64 return offset;
65
66 ++partNdx; // skip ':'
67 }
68 else
69 {
70 partNdx = 0;
71 }
72
73 //=====<item name>====================================
74 UTF8 fpname = aId.substr( partNdx );
75
76 // Be sure the item name is valid.
77 // Some chars can be found in legacy files converted files from other EDA tools.
78 if( aFix )
79 fpname = FixIllegalChars( fpname, false );
80 else
81 offset = HasIllegalChars( fpname );
82
83 if( offset > -1 )
84 return offset;
85
86 SetLibItemName( fpname );
87
88 return -1;
89}
90
91
92LIB_ID::LIB_ID( const wxString& aLibraryName, const wxString& aItemName ) :
93 m_libraryName( aLibraryName ),
94 m_itemName( aItemName )
95{
96}
97
98
99int LIB_ID::SetLibNickname( const UTF8& aLibNickname )
100{
101 int offset = checkLibNickname( aLibNickname );
102
103 if( offset == -1 )
104 m_libraryName = aLibNickname;
105
106 return offset;
107}
108
109
110int LIB_ID::SetLibItemName( const UTF8& aLibItemName )
111{
112 m_itemName = aLibItemName;
113
114 return -1;
115}
116
117
119{
120 UTF8 ret;
121
122 if( m_libraryName.size() )
123 {
124 ret += m_libraryName;
125 ret += ':';
126 }
127
128 ret += m_itemName;
129
130 return ret;
131}
132
133
134UTF8 LIB_ID::Format( const UTF8& aLibraryName, const UTF8& aLibItemName )
135{
136 UTF8 ret;
137 int offset;
138
139 if( aLibraryName.size() )
140 {
141 offset = checkLibNickname( aLibraryName );
142
143 if( offset != -1 )
144 {
145 THROW_PARSE_ERROR( _( "Illegal character found in library nickname" ),
146 wxString::FromUTF8( aLibraryName.c_str() ), aLibraryName.c_str(),
147 0, offset );
148 }
149
150 ret += aLibraryName;
151 ret += ':';
152 }
153
154 ret += aLibItemName;
155
156 return ret;
157}
158
159
160int LIB_ID::compare( const LIB_ID& aLibId ) const
161{
162 // Don't bother comparing the same object.
163 if( this == &aLibId )
164 return 0;
165
166 int retv = m_libraryName.compare( aLibId.m_libraryName );
167
168 if( retv != 0 )
169 return retv;
170
171 return m_itemName.compare( aLibId.m_itemName );
172}
173
174
175int LIB_ID::HasIllegalChars( const UTF8& aLibItemName )
176{
177 int offset = 0;
178
179 for( auto& ch : aLibItemName )
180 {
181 if( !isLegalChar( ch ) )
182 return offset;
183 else
184 ++offset;
185 }
186
187 return -1;
188}
189
190
191UTF8 LIB_ID::FixIllegalChars( const UTF8& aLibItemName, bool aLib )
192{
193 UTF8 fixedName;
194
195 for( UTF8::uni_iter chIt = aLibItemName.ubegin(); chIt < aLibItemName.uend(); ++chIt )
196 {
197 auto ch = *chIt;
198 if( aLib )
199 fixedName += isLegalLibraryNameChar( ch ) ? ch : '_';
200 else
201 fixedName += isLegalChar( ch ) ? ch : '_';
202 }
203
204 return fixedName;
205}
206
207
208bool LIB_ID::isLegalChar( unsigned aUniChar )
209{
210 bool const space_allowed = true;
211 bool const illegal_filename_chars_allowed = false;
212
213 if( aUniChar < ' ' )
214 return false;
215
216 // This list of characters is also duplicated in validators.cpp and footprint.cpp
217 // TODO: Unify forbidden character lists - Warning, invalid filename characters are not the same
218 // as invalid LIB_ID characters. We will need to separate the FP filenames from FP names before this
219 // can be unified
220 switch( aUniChar )
221 {
222 case ':':
223 case '\t':
224 case '\n':
225 case '\r':
226 return false;
227
228 case '\\':
229 case '<':
230 case '>':
231 case '"':
232 return illegal_filename_chars_allowed;
233
234 case ' ':
235 return space_allowed;
236
237 default:
238 return true;
239 }
240}
241
242
243unsigned LIB_ID::FindIllegalLibraryNameChar( const UTF8& aLibraryName )
244{
245 for( unsigned ch : aLibraryName )
246 {
247 if( !isLegalLibraryNameChar( ch ) )
248 return ch;
249 }
250
251 return 0;
252}
253
254
255bool LIB_ID::isLegalLibraryNameChar( unsigned aUniChar )
256{
257 bool const space_allowed = true;
258
259 if( aUniChar < ' ' )
260 return false;
261
262 switch( aUniChar )
263 {
264 case '\\':
265 case ':':
266 return false;
267
268 case ' ':
269 return space_allowed;
270
271 default:
272 return true;
273 }
274}
275
276
277const wxString LIB_ID::GetFullLibraryName() const
278{
279 wxString suffix = m_subLibraryName.wx_str().IsEmpty()
280 ? wxString( wxS( "" ) )
281 : wxString::Format( wxT( " - %s" ), m_subLibraryName.wx_str() );
282 return wxString::Format( wxT( "%s%s" ), m_libraryName.wx_str(), suffix );
283}
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition: lib_id.cpp:51
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:110
LIB_ID()
Definition: lib_id.h:51
static int HasIllegalChars(const UTF8 &aLibItemName)
Examine aLibItemName for invalid LIB_ID item name characters.
Definition: lib_id.cpp:175
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition: lib_id.cpp:99
int compare(const LIB_ID &aLibId) const
Compare the contents of LIB_ID objects by performing a std::string comparison of the library nickname...
Definition: lib_id.cpp:160
static bool isLegalChar(unsigned aUniChar)
Tests whether a Unicode character is a legal LIB_ID item name character.
Definition: lib_id.cpp:208
static unsigned FindIllegalLibraryNameChar(const UTF8 &aLibraryName)
Looks for characters that are illegal in library nicknames.
Definition: lib_id.cpp:243
UTF8 Format() const
Definition: lib_id.cpp:118
UTF8 m_libraryName
The nickname of the library or empty.
Definition: lib_id.h:271
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:191
UTF8 m_itemName
The name of the entry in the logical library.
Definition: lib_id.h:272
void clear()
Clear the contents of the library nickname, library entry name.
Definition: lib_id.cpp:43
const wxString GetFullLibraryName() const
Definition: lib_id.cpp:277
UTF8 m_subLibraryName
Optional sub-library name used for grouping within a library.
Definition: lib_id.h:273
static bool isLegalLibraryNameChar(unsigned aUniChar)
Tests whether a Unicode character is a legal LIB_ID library nickname character.
Definition: lib_id.cpp:255
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
Definition: utf8.h:209
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:72
static constexpr std::string::size_type npos
Definition: utf8.h:156
std::string::size_type find(char c) const
Definition: utf8.h:106
void clear()
Definition: utf8.h:109
std::string substr(size_t pos=0, size_t len=npos) const
Definition: utf8.h:183
uni_iter uend() const
Return a uni_iter initialized to the end of "this" UTF8 byte sequence.
Definition: utf8.h:292
int compare(const std::string &s) const
Definition: utf8.h:112
std::string::size_type find_first_of(const std::string &str, std::string::size_type pos=0) const
Definition: utf8.h:122
const char * c_str() const
Definition: utf8.h:103
std::string::size_type size() const
Definition: utf8.h:111
wxString wx_str() const
Definition: utf8.cpp:45
uni_iter ubegin() const
Returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
Definition: utf8.h:284
#define _(s)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:165
static int checkLibNickname(const UTF8 &aField)
Definition: lib_id.cpp:35
This file contains miscellaneous commonly used macros and functions.