KiCad PCB EDA Suite
Loading...
Searching...
No Matches
search_stack.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) 2014 CERN
5 * Copyright (C) 2014-2018 KiCad Developers, see AUTHORS.TXT for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <search_stack.h>
26#include <string_utils.h>
27#include <trace_helpers.h>
28#include <wx/tokenzr.h>
29#include <wx/log.h>
30
31
32#if defined(_WIN32)
33 #define PATH_SEPS wxT( ";\r\n" )
34#else
35 #define PATH_SEPS wxT( ":;\r\n" ) // unix == linux | mac
36#endif
37
38
39int SEARCH_STACK::Split( wxArrayString* aResult, const wxString& aPathString )
40{
41 wxStringTokenizer tokenizer( aPathString, PATH_SEPS, wxTOKEN_STRTOK );
42
43 while( tokenizer.HasMoreTokens() )
44 {
45 wxString path = tokenizer.GetNextToken();
46
47 aResult->Add( path );
48 }
49
50 return aResult->GetCount();
51}
52
53
54// Convert aRelativePath to an absolute path based on aBaseDir
55static wxString base_dir( const wxString& aRelativePath, const wxString& aBaseDir )
56{
57 wxFileName fn = aRelativePath;
58
59 if( !fn.IsAbsolute() && !!aBaseDir )
60 {
61 wxASSERT_MSG( wxFileName( aBaseDir ).IsAbsolute(), wxT( "Must pass absolute path in aBaseDir" ) );
62 fn.MakeRelativeTo( aBaseDir );
63 }
64
65 return fn.GetFullPath();
66}
67
68
70 const wxString& aFullFilename, const wxString& aBaseDir )
71{
72 wxFileName fn = aFullFilename;
73 wxString filename = aFullFilename;
74
75 unsigned pathlen = fn.GetPath().Len(); // path len, used to find the better (shortest)
76 // subpath within defaults paths
77
78 for( unsigned kk = 0; kk < GetCount(); kk++ )
79 {
80 fn = aFullFilename;
81
82 // Search for the shortest subpath within 'this':
83 if( fn.MakeRelativeTo( base_dir( (*this)[kk], aBaseDir ) ) )
84 {
85 if( fn.GetPathWithSep().StartsWith( wxT("..") ) ) // Path outside kicad libs paths
86 continue;
87
88 if( pathlen > fn.GetPath().Len() ) // A better (shortest) subpath is found
89 {
90 filename = fn.GetPathWithSep() + fn.GetFullName();
91 pathlen = fn.GetPath().Len();
92 }
93 }
94 }
95
96 return filename;
97}
98
99
100void SEARCH_STACK::RemovePaths( const wxString& aPaths )
101{
102 bool isCS = wxFileName::IsCaseSensitive();
103 wxArrayString paths;
104
105 Split( &paths, aPaths );
106
107 for( unsigned i=0; i<paths.GetCount(); ++i )
108 {
109 wxString path = paths[i];
110
111 if( Index( path, isCS ) != wxNOT_FOUND )
112 {
113 Remove( path );
114 }
115 }
116}
117
118
119void SEARCH_STACK::AddPaths( const wxString& aPaths, int aIndex )
120{
121 bool isCS = wxFileName::IsCaseSensitive();
122 wxArrayString paths;
123
124 Split( &paths, aPaths );
125
126 // appending all of them, on large or negative aIndex
127 if( unsigned( aIndex ) >= GetCount() )
128 {
129 for( unsigned i=0; i<paths.GetCount(); ++i )
130 {
131 wxString path = paths[i];
132
133 if( wxFileName::IsDirReadable( path )
134 && Index( path, isCS ) == wxNOT_FOUND )
135 {
136 Add( path );
137 }
138 }
139 }
140
141 // inserting all of them:
142 else
143 {
144 for( unsigned i=0; i<paths.GetCount(); ++i )
145 {
146 wxString path = paths[i];
147
148 if( wxFileName::IsDirReadable( path )
149 && Index( path, isCS ) == wxNOT_FOUND )
150 {
151 Insert( path, aIndex );
152 aIndex++;
153 }
154 }
155 }
156}
157
158
159#if 1 // this function is too convoluted for words.
160
161const wxString SEARCH_STACK::LastVisitedPath( const wxString& aSubPathToSearch )
162{
163 wxString path;
164
165 // Initialize default path to the main default lib path
166 // this is the second path in list (the first is the project path).
167 unsigned pcount = GetCount();
168
169 if( pcount )
170 {
171 unsigned ipath = 0;
172
173 if( (*this)[0] == wxGetCwd() )
174 ipath = 1;
175
176 // First choice of path:
177 if( ipath < pcount )
178 path = (*this)[ipath];
179
180 // Search a sub path matching this SEARCH_PATH
181 if( !IsEmpty() )
182 {
183 for( ; ipath < pcount; ipath++ )
184 {
185 if( (*this)[ipath].Contains( aSubPathToSearch ) )
186 {
187 path = (*this)[ipath];
188 break;
189 }
190 }
191 }
192 }
193
194 if( path.IsEmpty() )
195 path = wxGetCwd();
196
197 return path;
198}
199#endif
200
201
202#if defined(DEBUG)
203void SEARCH_STACK::Show( const wxString& aPrefix ) const
204{
205 wxLogTrace( tracePathsAndFiles, "%s SEARCH_STACK:", aPrefix );
206
207 for( unsigned i=0; i<GetCount(); ++i )
208 {
209 wxLogTrace( tracePathsAndFiles, " [%2u]:%s", i, TO_UTF8( (*this)[i] ) );
210 }
211}
212#endif
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
A quirky function inherited from old code that seems to serve particular needs in the UI.
static int Split(wxArrayString *aResult, const wxString &aPathString)
Separate aPathString into individual paths.
void AddPaths(const wxString &aPaths, int aIndex=-1)
Insert or append path(s).
void RemovePaths(const wxString &aPaths)
Remove the given path(s) from the library path list.
wxString FilenameWithRelativePathInSearchList(const wxString &aFullFilename, const wxString &aBaseDir)
Return the shortest possible path which can be use later to find a full path from this SEARCH_STACK.
const wxChar *const tracePathsAndFiles
Flag to enable path and file name debug output.
#define PATH_SEPS
static wxString base_dir(const wxString &aRelativePath, const wxString &aBaseDir)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391
wxLogTrace helper definitions.