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 The KiCad Developers, see AUTHORS.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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <cstring>
23#include <memory>
24#include <wx/translation.h>
25#include <fmt/format.h>
26
27#include <ki_exception.h>
28#include <macros.h> // TO_UTF8()
29#include <lib_id.h>
30
31
32static int checkLibNickname( const UTF8& aField )
33{
34 // std::string::npos is largest positive number, casting to int makes it -1.
35 // Returning that means success.
36 return int( aField.find_first_of( ":" ) );
37}
38
39
41{
42 m_libraryName.clear();
43 m_itemName.clear();
44 m_subLibraryName.clear();
45}
46
47
48int LIB_ID::Parse( const UTF8& aId, bool aFix )
49{
50 clear();
51
52 size_t partNdx;
53 int offset = -1;
54
55 //=====<library nickname>=============================
56 if( ( partNdx = aId.find( ':' ) ) != aId.npos )
57 {
58 offset = SetLibNickname( aId.substr( 0, partNdx ) );
59
60 if( offset > -1 )
61 return offset;
62
63 ++partNdx; // skip ':'
64 }
65 else
66 {
67 partNdx = 0;
68 }
69
70 //=====<item name>====================================
71 UTF8 fpname = aId.substr( partNdx );
72
73 // Be sure the item name is valid.
74 // Some chars can be found in legacy files converted files from other EDA tools.
75 if( aFix )
76 fpname = FixIllegalChars( fpname, false );
77 else
78 offset = HasIllegalChars( fpname );
79
80 if( offset > -1 )
81 return offset;
82
83 SetLibItemName( fpname );
84
85 return -1;
86}
87
88
89LIB_ID::LIB_ID( const wxString& aLibraryName, const wxString& aItemName ) :
90 m_libraryName( aLibraryName ),
91 m_itemName( aItemName )
92{
93}
94
95
96int LIB_ID::SetLibNickname( const UTF8& aLibNickname )
97{
98 int offset = checkLibNickname( aLibNickname );
99
100 if( offset == -1 )
101 m_libraryName = aLibNickname;
102
103 return offset;
104}
105
106
107int LIB_ID::SetLibItemName( const UTF8& aLibItemName )
108{
109 m_itemName = aLibItemName;
110
111 return -1;
112}
113
114
116{
117 UTF8 ret;
118
119 if( m_libraryName.size() )
120 {
121 ret += m_libraryName;
122 ret += ':';
123 }
124
125 ret += m_itemName;
126
127 return ret;
128}
129
130
131UTF8 LIB_ID::Format( const UTF8& aLibraryName, const UTF8& aLibItemName )
132{
133 UTF8 ret;
134 int offset;
135
136 if( aLibraryName.size() )
137 {
138 offset = checkLibNickname( aLibraryName );
139
140 if( offset != -1 )
141 {
142 THROW_PARSE_ERROR( _( "Illegal character found in library nickname" ),
143 wxString::FromUTF8( aLibraryName.c_str() ), aLibraryName.c_str(),
144 0, offset );
145 }
146
147 ret += aLibraryName;
148 ret += ':';
149 }
150
151 ret += aLibItemName;
152
153 return ret;
154}
155
156
157int LIB_ID::compare( const LIB_ID& aLibId ) const
158{
159 // Don't bother comparing the same object.
160 if( this == &aLibId )
161 return 0;
162
163 int retv = m_libraryName.compare( aLibId.m_libraryName );
164
165 if( retv != 0 )
166 return retv;
167
168 return m_itemName.compare( aLibId.m_itemName );
169}
170
171
172int LIB_ID::HasIllegalChars( const UTF8& aLibItemName )
173{
174 int offset = 0;
175
176 for( auto& ch : aLibItemName )
177 {
178 if( !isLegalChar( ch ) )
179 return offset;
180 else
181 ++offset;
182 }
183
184 return -1;
185}
186
187
188UTF8 LIB_ID::FixIllegalChars( const UTF8& aLibItemName, bool aLib )
189{
190 UTF8 fixedName;
191
192 for( UTF8::uni_iter chIt = aLibItemName.ubegin(); chIt < aLibItemName.uend(); ++chIt )
193 {
194 auto ch = *chIt;
195 if( aLib )
196 fixedName += isLegalLibraryNameChar( ch ) ? ch : '_';
197 else
198 fixedName += isLegalChar( ch ) ? ch : '_';
199 }
200
201 return fixedName;
202}
203
204
205bool LIB_ID::isLegalChar( unsigned aUniChar )
206{
207 bool const space_allowed = true;
208 bool const illegal_filename_chars_allowed = false;
209
210 switch( aUniChar )
211 {
212 case ':':
213 case '\t':
214 case '\n':
215 case '\r':
216 return false;
217
218 case '\\':
219 case '<':
220 case '>':
221 case '"':
222 return illegal_filename_chars_allowed;
223
224 case ' ':
225 return space_allowed;
226
227 default:
228 return true;
229 }
230}
231
232
233unsigned LIB_ID::FindIllegalLibraryNameChar( const UTF8& aLibraryName )
234{
235 for( unsigned ch : aLibraryName )
236 {
237 if( !isLegalLibraryNameChar( ch ) )
238 return ch;
239 }
240
241 return 0;
242}
243
244
245bool LIB_ID::isLegalLibraryNameChar( unsigned aUniChar )
246{
247 bool const space_allowed = true;
248
249 if( aUniChar < ' ' )
250 return false;
251
252 switch( aUniChar )
253 {
254 case '\\':
255 case ':':
256 return false;
257
258 case ' ':
259 return space_allowed;
260
261 default:
262 return true;
263 }
264}
265
266
267const wxString LIB_ID::GetFullLibraryName() const
268{
269 if( m_subLibraryName.empty() )
270 return m_libraryName;
271
272 return wxString::Format( wxS( "%s - %s" ), m_libraryName.c_str(), m_subLibraryName.c_str() );
273}
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:48
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:107
LIB_ID()
Definition lib_id.h:47
static int HasIllegalChars(const UTF8 &aLibItemName)
Examine aLibItemName for invalid LIB_ID item name characters.
Definition lib_id.cpp:172
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:96
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:157
static bool isLegalChar(unsigned aUniChar)
Tests whether a Unicode character is a legal LIB_ID item name character.
Definition lib_id.cpp:205
static unsigned FindIllegalLibraryNameChar(const UTF8 &aLibraryName)
Looks for characters that are illegal in library nicknames.
Definition lib_id.cpp:233
UTF8 Format() const
Definition lib_id.cpp:115
UTF8 m_libraryName
The nickname of the library or empty.
Definition lib_id.h:267
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition lib_id.cpp:188
UTF8 m_itemName
The name of the entry in the logical library.
Definition lib_id.h:268
void clear()
Clear the contents of the library nickname, library entry name.
Definition lib_id.cpp:40
const wxString GetFullLibraryName() const
Definition lib_id.cpp:267
UTF8 m_subLibraryName
Optional sub-library name used for grouping within a library.
Definition lib_id.h:269
static bool isLegalLibraryNameChar(unsigned aUniChar)
Tests whether a Unicode character is a legal LIB_ID library nickname character.
Definition lib_id.cpp:245
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
Definition utf8.h:226
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition utf8.h:67
static constexpr std::string::size_type npos
Definition utf8.h:157
std::string::size_type find(char c) const
Definition utf8.h:107
std::string substr(size_t pos=0, size_t len=npos) const
Definition utf8.h:201
uni_iter uend() const
Return a uni_iter initialized to the end of "this" UTF8 byte sequence.
Definition utf8.h:309
std::string::size_type find_first_of(const std::string &str, std::string::size_type pos=0) const
Definition utf8.h:123
const char * c_str() const
Definition utf8.h:104
std::string::size_type size() const
Definition utf8.h:112
uni_iter ubegin() const
Returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
Definition utf8.h:301
#define _(s)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
static int checkLibNickname(const UTF8 &aField)
Definition lib_id.cpp:32
This file contains miscellaneous commonly used macros and functions.