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 The 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(),
62 wxT( "Must pass absolute path in aBaseDir" ) );
63 fn.MakeRelativeTo( aBaseDir );
64 }
65
66 return fn.GetFullPath();
67}
68
69
71 const wxString& aFullFilename, const wxString& aBaseDir )
72{
73 wxFileName fn = aFullFilename;
74 wxString filename = aFullFilename;
75
76 unsigned pathlen = fn.GetPath().Len(); // path len, used to find the better (shortest)
77 // subpath within defaults paths
78
79 for( unsigned kk = 0; kk < GetCount(); kk++ )
80 {
81 fn = aFullFilename;
82
83 // Search for the shortest subpath within 'this':
84 if( fn.MakeRelativeTo( base_dir( (*this)[kk], aBaseDir ) ) )
85 {
86 if( fn.GetPathWithSep().StartsWith( wxT("..") ) ) // Path outside KiCad libs paths
87 continue;
88
89 if( pathlen > fn.GetPath().Len() ) // A better (shortest) subpath is found
90 {
91 filename = fn.GetPathWithSep() + fn.GetFullName();
92 pathlen = fn.GetPath().Len();
93 }
94 }
95 }
96
97 return filename;
98}
99
100
101void SEARCH_STACK::RemovePaths( const wxString& aPaths )
102{
103 bool isCS = wxFileName::IsCaseSensitive();
104 wxArrayString paths;
105
106 Split( &paths, aPaths );
107
108 for( unsigned i=0; i<paths.GetCount(); ++i )
109 {
110 wxString path = paths[i];
111
112 if( Index( path, isCS ) != wxNOT_FOUND )
113 {
114 Remove( path );
115 }
116 }
117}
118
119
120void SEARCH_STACK::AddPaths( const wxString& aPaths, int aIndex )
121{
122 bool isCS = wxFileName::IsCaseSensitive();
123 wxArrayString paths;
124
125 Split( &paths, aPaths );
126
127 // appending all of them, on large or negative aIndex
128 if( unsigned( aIndex ) >= GetCount() )
129 {
130 for( unsigned i=0; i<paths.GetCount(); ++i )
131 {
132 wxString path = paths[i];
133
134 if( wxFileName::IsDirReadable( path )
135 && Index( path, isCS ) == wxNOT_FOUND )
136 {
137 Add( path );
138 }
139 }
140 }
141
142 // inserting all of them:
143 else
144 {
145 for( unsigned i=0; i<paths.GetCount(); ++i )
146 {
147 wxString path = paths[i];
148
149 if( wxFileName::IsDirReadable( path )
150 && Index( path, isCS ) == wxNOT_FOUND )
151 {
152 Insert( path, aIndex );
153 aIndex++;
154 }
155 }
156 }
157}
158
159
160#if 1 // this function is too convoluted for words.
161
162const wxString SEARCH_STACK::LastVisitedPath( const wxString& aSubPathToSearch )
163{
164 wxString path;
165
166 // Initialize default path to the main default lib path
167 // this is the second path in list (the first is the project path).
168 unsigned pcount = GetCount();
169
170 if( pcount )
171 {
172 unsigned ipath = 0;
173
174 if( (*this)[0] == wxGetCwd() )
175 ipath = 1;
176
177 // First choice of path:
178 if( ipath < pcount )
179 path = (*this)[ipath];
180
181 // Search a sub path matching this SEARCH_PATH
182 if( !IsEmpty() )
183 {
184 for( ; ipath < pcount; ipath++ )
185 {
186 if( (*this)[ipath].Contains( aSubPathToSearch ) )
187 {
188 path = (*this)[ipath];
189 break;
190 }
191 }
192 }
193 }
194
195 if( path.IsEmpty() )
196 path = wxGetCwd();
197
198 return path;
199}
200#endif
201
202
203#if defined( DEBUG )
204void SEARCH_STACK::Show( const wxString& aPrefix ) const
205{
206 wxLogTrace( tracePathsAndFiles, "%s SEARCH_STACK:", aPrefix );
207
208 for( unsigned i = 0; i < GetCount(); ++i )
209 {
210 wxLogTrace( tracePathsAndFiles, " [%2u]:%s", i, TO_UTF8( ( *this )[i] ) );
211 }
212}
213#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:398
wxLogTrace helper definitions.